mirror of https://github.com/apache/jclouds.git
merged bridged iface changes
This commit is contained in:
commit
0c55cf581b
|
@ -42,11 +42,9 @@ import org.jclouds.compute.domain.OperatingSystem;
|
|||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.functions.IdentityFunction;
|
||||
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
|
|
@ -78,7 +78,7 @@ public class CloudSigmaComputeServiceContextModule
|
|||
|
||||
@Override
|
||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||
return template.osFamily(OsFamily.UBUNTU).imageNameMatches(".*automated SSH Access.*");
|
||||
return template.osFamily(OsFamily.UBUNTU).imageNameMatches(".*[Aa]utomated SSH Access.*").os64Bit(true);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
|
|
|
@ -64,6 +64,7 @@ import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
|
|||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.KeyPair;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.predicates.Retryables;
|
||||
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -195,7 +196,7 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
}
|
||||
}
|
||||
|
||||
protected void cleanUpIncidentalResources(String region, String group){
|
||||
protected void cleanUpIncidentalResources(final String region, final String group){
|
||||
// For issue #445, tries to delete security groups first: ec2 throws exception if in use, but
|
||||
// deleting a key pair does not.
|
||||
// This is "belt-and-braces" because deleteKeyPair also does extractIdsFromInstances & usingKeyPairAndNotDead
|
||||
|
@ -203,14 +204,26 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
// There is (probably?) still a race if someone is creating instances at the same time as deleting them:
|
||||
// we may delete the key-pair just when the node-being-created was about to rely on the incidental
|
||||
// resources existing.
|
||||
try {
|
||||
logger.debug(">> deleting incidentalResources(%s @ %s)", region, group);
|
||||
deleteSecurityGroup(region, group);
|
||||
deleteKeyPair(region, group); // not executed if securityGroup was in use
|
||||
logger.debug("<< deleted incidentalResources(%s @ %s)", region, group);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.debug("<< inUse incidentalResources(%s @ %s)", region, group);
|
||||
}
|
||||
|
||||
// Also in #445, in aws-ec2 the deleteSecurityGroup sometimes fails after terminating the final VM using a
|
||||
// given security group, if called very soon after the VM's state reports terminated. Emprically, it seems that
|
||||
// waiting a small time (e.g. enabling logging or debugging!) then the tests pass. We therefore retry.
|
||||
final int maxAttempts = 3;
|
||||
Retryables.retryNumTimes(new Predicate<Void>() {
|
||||
@Override
|
||||
public boolean apply(Void input) {
|
||||
try {
|
||||
logger.debug(">> deleting incidentalResources(%s @ %s)", region, group);
|
||||
deleteSecurityGroup(region, group);
|
||||
deleteKeyPair(region, group); // not executed if securityGroup was in use
|
||||
logger.debug("<< deleted incidentalResources(%s @ %s)", region, group);
|
||||
return true;
|
||||
} catch (IllegalStateException e) {
|
||||
logger.debug("<< inUse incidentalResources(%s @ %s)", region, group);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}, (Void)null, maxAttempts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
@ -50,6 +52,10 @@ public class Link {
|
|||
* a permanent link to a resource that is appropriate for long term storage.
|
||||
*/
|
||||
BOOKMARK,
|
||||
/**
|
||||
*
|
||||
*/
|
||||
DESCRIBEDBY,
|
||||
/**
|
||||
* an alternate representation of the resource. For example, an OpenStack Compute image may
|
||||
* have an alternate representation in the OpenStack Image service.
|
||||
|
@ -75,9 +81,13 @@ public class Link {
|
|||
}
|
||||
|
||||
public static Link create(Relation relation, URI href) {
|
||||
return new Link(relation, href);
|
||||
return new Link(relation, null, href);
|
||||
}
|
||||
|
||||
|
||||
public static Link create(Relation relation,String type, URI href) {
|
||||
return new Link(relation, type, href);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
@ -88,6 +98,7 @@ public class Link {
|
|||
|
||||
public static class Builder {
|
||||
protected Relation relation;
|
||||
protected String type;
|
||||
protected URI href;
|
||||
|
||||
/**
|
||||
|
@ -98,25 +109,39 @@ public class Link {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Link#getType()
|
||||
*/
|
||||
public Builder type(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Link#getHref()
|
||||
*/
|
||||
protected Builder href(URI href) {
|
||||
public Builder href(URI href) {
|
||||
this.href = checkNotNull(href, "href");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Link build(){
|
||||
return new Link(relation, type, href);
|
||||
}
|
||||
|
||||
public Builder fromLink(Link from) {
|
||||
return relation(from.getRelation()).href(from.getHref());
|
||||
return relation(from.getRelation()).type(from.getType()).href(from.getHref());
|
||||
}
|
||||
}
|
||||
|
||||
@SerializedName("rel")
|
||||
protected final Relation relation;
|
||||
protected final String type;
|
||||
protected final URI href;
|
||||
|
||||
protected Link(Relation relation, URI href) {
|
||||
protected Link(Relation relation, @Nullable String type, URI href) {
|
||||
this.relation = checkNotNull(relation, "relation");
|
||||
this.type = type;
|
||||
this.href = checkNotNull(href, "href");
|
||||
}
|
||||
|
||||
|
@ -134,7 +159,15 @@ public class Link {
|
|||
public Relation getRelation() {
|
||||
return relation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the type of the resource or null if not specified
|
||||
*/
|
||||
@Nullable
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the href of the resource
|
||||
*/
|
||||
|
@ -149,7 +182,7 @@ public class Link {
|
|||
}
|
||||
if (object instanceof Link) {
|
||||
final Link other = Link.class.cast(object);
|
||||
return equal(relation, other.relation) && equal(href, other.href);
|
||||
return equal(relation, other.relation) && equal(type, other.type) && equal(href, other.href);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -157,12 +190,12 @@ public class Link {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(relation, href);
|
||||
return Objects.hashCode(relation, type, href);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").add("relation", relation).add("href", href).toString();
|
||||
return toStringHelper("").add("relation", relation).add("type", type).add("href", href).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public class Resource implements Comparable<Resource> {
|
|||
}
|
||||
if (object instanceof Resource) {
|
||||
final Resource other = Resource.class.cast(object);
|
||||
return equal(id, other.id) && equal(name, other.name) && equal(links, other.links);
|
||||
return equal(getId(), other.getId()) && equal(name, other.name) && equal(links, other.links);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -140,12 +140,12 @@ public class Resource implements Comparable<Resource> {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(id, name, links);
|
||||
return Objects.hashCode(getId(), name, links);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").add("id", id).add("name", name).add("links", links).toString();
|
||||
return toStringHelper("").add("id", getId()).add("name", name).add("links", links).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -154,7 +154,7 @@ public class Resource implements Comparable<Resource> {
|
|||
return 1;
|
||||
if (this == that)
|
||||
return 0;
|
||||
return this.id.compareTo(that.id);
|
||||
return this.getId().compareTo(that.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
* Predicates handy when working with Link Types
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
||||
public class LinkPredicates {
|
||||
/**
|
||||
* matches links of the given relation
|
||||
*
|
||||
* @param rel relation of the link
|
||||
* @return predicate that will match links of the given rel
|
||||
*/
|
||||
public static Predicate<Link> relationEquals(final Relation rel) {
|
||||
checkNotNull(rel, "rel must be defined");
|
||||
|
||||
return new Predicate<Link>() {
|
||||
@Override
|
||||
public boolean apply(Link link) {
|
||||
return rel.equals(link.getRelation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "relEquals(" + rel + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* matches links of the given href
|
||||
*
|
||||
* @param href
|
||||
* @return predicate that will match links of the given href
|
||||
*/
|
||||
public static Predicate<Link> hrefEquals(final URI href) {
|
||||
checkNotNull(href, "href must be defined");
|
||||
|
||||
return new Predicate<Link>() {
|
||||
@Override
|
||||
public boolean apply(Link link) {
|
||||
return href.equals(link.getHref());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "hrefEquals(" + href + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* matches links of the given type
|
||||
*
|
||||
* @param type
|
||||
* ex. application/pdf
|
||||
* @return predicate that will match links of the given type
|
||||
*/
|
||||
public static Predicate<Link> typeEquals(final String type) {
|
||||
checkNotNull(type, "type must be defined");
|
||||
|
||||
return new Predicate<Link>() {
|
||||
@Override
|
||||
public boolean apply(Link link) {
|
||||
return type.equals(link.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "typeEquals(" + type + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package org.jclouds.openstack.predicates;
|
||||
|
||||
import static org.jclouds.openstack.predicates.LinkPredicates.hrefEquals;
|
||||
import static org.jclouds.openstack.predicates.LinkPredicates.relationEquals;
|
||||
import static org.jclouds.openstack.predicates.LinkPredicates.typeEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "LinkPredicatesTest")
|
||||
public class LinkPredicatesTest {
|
||||
Link ref = Link.builder().type("application/pdf").relation(Relation.DESCRIBEDBY).href(
|
||||
URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).build();
|
||||
|
||||
@Test
|
||||
public void testRelationEqualsWhenEqual() {
|
||||
assert relationEquals(Relation.DESCRIBEDBY).apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelationEqualsWhenNotEqual() {
|
||||
assert !relationEquals(Relation.UNRECOGNIZED).apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeEqualsWhenEqual() {
|
||||
assert typeEquals("application/pdf").apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeEqualsWhenNotEqual() {
|
||||
assert !typeEquals("foo").apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHrefEqualsWhenEqual() {
|
||||
assert hrefEquals(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHrefEqualsWhenNotEqual() {
|
||||
assert !hrefEquals(URI.create("foo")).apply(ref);
|
||||
}
|
||||
}
|
|
@ -130,6 +130,7 @@ public interface ComputeServiceAdapter<N, H, I, L> {
|
|||
|
||||
N getNode(String id);
|
||||
|
||||
//TODO consider making reboot/resume/suspend return the node they affected
|
||||
void destroyNode(String id);
|
||||
|
||||
void rebootNode(String id);
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
|
@ -36,6 +37,6 @@ public class AtomicNodeSuspended extends RefreshAndDoubleCheckOnFailUnlessStateI
|
|||
|
||||
@Inject
|
||||
public AtomicNodeSuspended(GetNodeMetadataStrategy client) {
|
||||
super(NodeState.SUSPENDED, client);
|
||||
super(NodeState.SUSPENDED, ImmutableSet.of(NodeState.ERROR, NodeState.TERMINATED), client);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,31 +116,36 @@ public class AdaptingComputeServiceStrategies<N, H, I, L> implements CreateNodeW
|
|||
return nodeMetadataAdapter.apply(node);
|
||||
}
|
||||
|
||||
//TODO: make reboot/resume/suspend return the node they affected
|
||||
@Override
|
||||
public NodeMetadata rebootNode(String id) {
|
||||
NodeMetadata node = getNode(checkNotNull(id, "id"));
|
||||
if (node == null || node.getState() == NodeState.TERMINATED)
|
||||
return node;
|
||||
checkStateAvailable(node);
|
||||
client.rebootNode(id);
|
||||
return node;
|
||||
// invalidate state of node
|
||||
return getNode(checkNotNull(id, "id"));
|
||||
}
|
||||
|
||||
private void checkStateAvailable(NodeMetadata node) {
|
||||
checkState(node != null && node.getState() != NodeState.TERMINATED, "node %s terminated or unavailable!", node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata resumeNode(String id) {
|
||||
NodeMetadata node = getNode(checkNotNull(id, "id"));
|
||||
if (node == null || node.getState() == NodeState.TERMINATED || node.getState() == NodeState.RUNNING)
|
||||
return node;
|
||||
checkStateAvailable(node);
|
||||
client.resumeNode(id);
|
||||
return node;
|
||||
// invalidate state of node
|
||||
return getNode(checkNotNull(id, "id"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata suspendNode(String id) {
|
||||
NodeMetadata node = getNode(checkNotNull(id, "id"));
|
||||
if (node == null || node.getState() == NodeState.TERMINATED || node.getState() == NodeState.SUSPENDED)
|
||||
return node;
|
||||
checkStateAvailable(node);
|
||||
client.suspendNode(id);
|
||||
return node;
|
||||
// invalidate state of node
|
||||
return getNode(checkNotNull(id, "id"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* 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.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* Retries a condition until it is met or the max number of retries have occurred.
|
||||
* maxAttempts parameter is required.
|
||||
* Initial retry period and retry maxPeriod are optionally configurable,
|
||||
* defaulting to 50ms and 1000ms respectively,
|
||||
* with the retrier increasing the interval by a factor of 1.5 each time within these constraints.
|
||||
*
|
||||
* @author Aled Sage
|
||||
*/
|
||||
public class RetryableNumTimesPredicate<T> implements Predicate<T> {
|
||||
private final int maxAttempts;
|
||||
private final long period;
|
||||
private final long maxPeriod;
|
||||
private final Predicate<T> predicate;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public RetryableNumTimesPredicate(Predicate<T> predicate, int maxAttempts, long period, long maxPeriod, TimeUnit unit) {
|
||||
this.predicate = checkNotNull(predicate);
|
||||
this.maxAttempts = maxAttempts;
|
||||
this.period = unit.toMillis(period);
|
||||
this.maxPeriod = unit.toMillis(maxPeriod);
|
||||
checkArgument(maxAttempts >= 0, "maxAttempts must be greater than zero, but was "+maxAttempts);
|
||||
checkArgument(period >= 0, "period must be greater than zero, but was "+period);
|
||||
checkArgument(maxPeriod >= 0, "maxPeriod must be greater than zero, but was "+maxPeriod);
|
||||
checkArgument(maxPeriod >= period, "maxPeriod must be greater than or equal to period, but was "+maxPeriod+" < "+period);
|
||||
}
|
||||
|
||||
public RetryableNumTimesPredicate(Predicate<T> predicate, int maxAttempts, long period, TimeUnit unit) {
|
||||
this(predicate, maxAttempts, period, period*10, unit);
|
||||
}
|
||||
|
||||
public RetryableNumTimesPredicate(Predicate<T> predicate, int maxAttempts) {
|
||||
this(predicate, maxAttempts, 50l, 1000l, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(T input) {
|
||||
try {
|
||||
for (int i = 1; i <= maxAttempts; Thread.sleep(nextMaxInterval(i++))) {
|
||||
if (predicate.apply(input)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn(e, "predicate %s on %s interrupted, returning false", input, predicate);
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (RuntimeException e) {
|
||||
if (getFirstThrowableOfType(e, ExecutionException.class) != null) {
|
||||
logger.warn(e, "predicate %s on %s errored [%s], returning false", input, predicate, e.getMessage());
|
||||
return false;
|
||||
} else if (getFirstThrowableOfType(e, IllegalStateException.class) != null) {
|
||||
logger.warn(e, "predicate %s on %s illegal state [%s], returning false", input, predicate, e.getMessage());
|
||||
return false;
|
||||
} else if (getFirstThrowableOfType(e, CancellationException.class) != null) {
|
||||
logger.warn(e, "predicate %s on %s cancelled [%s], returning false", input, predicate, e.getMessage());
|
||||
return false;
|
||||
} else if (getFirstThrowableOfType(e, TimeoutException.class) != null) {
|
||||
logger.warn(e, "predicate %s on %s timed out [%s], returning false", input, predicate, e.getMessage());
|
||||
return false;
|
||||
} else
|
||||
throw e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected long nextMaxInterval(long attempt) {
|
||||
// Interval increases exponentially, at a rate of nextInterval *= 1.5
|
||||
// Note that attempt starts counting at 1
|
||||
long interval = (long) (period * Math.pow(1.5, (attempt-1)));
|
||||
return (interval > maxPeriod ? maxPeriod : interval);
|
||||
}
|
||||
}
|
|
@ -39,6 +39,14 @@ public class Retryables {
|
|||
return new RetryablePredicate<Input>(predicate, maxWait, period, unit).apply(input);
|
||||
}
|
||||
|
||||
public static <Input> boolean retryNumTimes(Predicate<Input> predicate, Input input, int maxAttempts) {
|
||||
return new RetryableNumTimesPredicate<Input>(predicate, maxAttempts).apply(input);
|
||||
}
|
||||
|
||||
public static <Input> boolean retryNumTimes(Predicate<Input> predicate, Input input, int maxAttempts, long period, long maxPeriod, TimeUnit unit) {
|
||||
return new RetryableNumTimesPredicate<Input>(predicate, maxAttempts, period, maxPeriod, unit).apply(input);
|
||||
}
|
||||
|
||||
public static <Input> void assertEventually(Predicate<Input> predicate, Input input,
|
||||
long maxWaitMillis, String failureMessage) {
|
||||
if (!new RetryablePredicate<Input>(predicate, maxWaitMillis).apply(input))
|
||||
|
@ -51,11 +59,11 @@ public class Retryables {
|
|||
throw (AssertionError)new AssertionError(failureMessage).initCause(predicate.getLastFailure());
|
||||
return predicate.getResult();
|
||||
}
|
||||
|
||||
public static <Input,Result> Result retryGettingResultOrFailing(PredicateWithResult<Input,Result> predicate,
|
||||
Input input, long maxWait, long period, TimeUnit unit, String failureMessage) {
|
||||
if (!new RetryablePredicate<Input>(predicate, maxWait, period, unit).apply(input))
|
||||
throw (AssertionError)new AssertionError(failureMessage).initCause(predicate.getLastFailure());
|
||||
return predicate.getResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
/**
|
||||
* 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.predicates;
|
||||
|
||||
import static org.jclouds.predicates.RetryablePredicateTest.assertCallTimes;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.predicates.RetryablePredicateTest.RepeatedAttemptsPredicate;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", singleThreaded = true)
|
||||
public class RetryableNumTimesPredicateTest {
|
||||
// Grace must be reasonably big; Thread.sleep can take a bit longer to wake up sometimes...
|
||||
public static int SLOW_BUILD_SERVER_GRACE = 250;
|
||||
|
||||
// Sometimes returns sooner than timer would predict (e.g. observed 2999ms, when expected 3000ms)
|
||||
public static int EARLY_RETURN_GRACE = 10;
|
||||
|
||||
private Stopwatch stopwatch;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() {
|
||||
stopwatch = new Stopwatch();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFalseOnIllegalStateExeception() {
|
||||
ensureImmediateReturnFor(new IllegalStateException());
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Test
|
||||
void testFalseOnExecutionException() {
|
||||
ensureImmediateReturnFor(new ExecutionException() {
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Test
|
||||
void testFalseOnTimeoutException() {
|
||||
ensureImmediateReturnFor(new TimeoutException() {
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Test(expectedExceptions = RuntimeException.class)
|
||||
void testPropagateOnException() {
|
||||
ensureImmediateReturnFor(new Exception() {
|
||||
});
|
||||
}
|
||||
|
||||
private void ensureImmediateReturnFor(final Exception ex) {
|
||||
RetryableNumTimesPredicate<Supplier<String>> predicate = new RetryableNumTimesPredicate<Supplier<String>>(
|
||||
new Predicate<Supplier<String>>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Supplier<String> input) {
|
||||
return "goo".equals(input.get());
|
||||
}
|
||||
|
||||
}, 3, 1L, TimeUnit.SECONDS);
|
||||
|
||||
stopwatch.start();
|
||||
assert !predicate.apply(new Supplier<String>() {
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
});
|
||||
long duration = stopwatch.elapsedMillis();
|
||||
assertOrdered(duration, SLOW_BUILD_SERVER_GRACE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAlwaysTrue() {
|
||||
// will call once immediately
|
||||
RetryableNumTimesPredicate<String> predicate = new RetryableNumTimesPredicate<String>(Predicates.<String> alwaysTrue(),
|
||||
1, 1L, TimeUnit.SECONDS);
|
||||
stopwatch.start();
|
||||
predicate.apply("");
|
||||
long duration = stopwatch.elapsedMillis();
|
||||
assertOrdered(duration, SLOW_BUILD_SERVER_GRACE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAlwaysFalseMillis() {
|
||||
// maxAttempts=3; period=1; maxPeriod defaults to 1*10
|
||||
// will call at 0, 1, 1+(1*1.5) = 2.5secs
|
||||
RetryableNumTimesPredicate<String> predicate = new RetryableNumTimesPredicate<String>(Predicates.<String> alwaysFalse(),
|
||||
3, 1L, TimeUnit.SECONDS);
|
||||
stopwatch.start();
|
||||
predicate.apply("");
|
||||
long duration = stopwatch.elapsedMillis();
|
||||
assertOrdered(2500-EARLY_RETURN_GRACE, duration, 2500+SLOW_BUILD_SERVER_GRACE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testThirdTimeTrue() {
|
||||
// maxAttempts=3; period=1; maxPeriod defaults to 1*10
|
||||
// will call at 0, 1, 1+(1*1.5)
|
||||
RepeatedAttemptsPredicate rawPredicate = new RepeatedAttemptsPredicate(2);
|
||||
RetryableNumTimesPredicate<String> predicate = new RetryableNumTimesPredicate<String>(rawPredicate,
|
||||
4, 1, TimeUnit.SECONDS);
|
||||
|
||||
stopwatch.start();
|
||||
predicate.apply("");
|
||||
long duration = stopwatch.elapsedMillis();
|
||||
|
||||
assertOrdered(2500-EARLY_RETURN_GRACE, duration, 2500+SLOW_BUILD_SERVER_GRACE);
|
||||
assertCallTimes(rawPredicate.callTimes, 0, 1000, 1000+1500);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testThirdTimeTrueLimitedMaxInterval() {
|
||||
// maxAttempts=3; period=1; maxPeriod=1
|
||||
// will call at 0, 1, 1+1
|
||||
RepeatedAttemptsPredicate rawPredicate = new RepeatedAttemptsPredicate(2);
|
||||
RetryableNumTimesPredicate<String> predicate = new RetryableNumTimesPredicate<String>(rawPredicate,
|
||||
3, 1L, 1L, TimeUnit.SECONDS);
|
||||
|
||||
stopwatch.start();
|
||||
predicate.apply("");
|
||||
long duration = stopwatch.elapsedMillis();
|
||||
|
||||
assertOrdered(2000-EARLY_RETURN_GRACE, duration, 2000+SLOW_BUILD_SERVER_GRACE);
|
||||
assertCallTimes(rawPredicate.callTimes, 0, 1000, 2000);
|
||||
}
|
||||
|
||||
private static void assertOrdered(long... values) {
|
||||
long prevVal = values[0];
|
||||
for (long val : values) {
|
||||
if (val < prevVal) {
|
||||
fail(String.format("%s should be ordered", Arrays.toString(values)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -159,7 +159,7 @@ public class RetryablePredicateTest {
|
|||
assertCallTimes(rawPredicate.callTimes, 0, 1000, 2000);
|
||||
}
|
||||
|
||||
private static class RepeatedAttemptsPredicate implements Predicate<String> {
|
||||
public static class RepeatedAttemptsPredicate implements Predicate<String> {
|
||||
final List<Long> callTimes = new ArrayList<Long>();
|
||||
private final int succeedOnAttempt;
|
||||
private final Stopwatch stopwatch;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.hpcloud.compute.features;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.features.FloatingIPClientLiveTest;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* 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.features;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.features.ImageClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "live", testName = "HPCloudComputeImageClientLiveTest")
|
||||
public class HPCloudComputeImageClientLiveTest extends ImageClientLiveTest {
|
||||
public HPCloudComputeImageClientLiveTest() {
|
||||
provider = "hpcloud-compute";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* 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.features;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "live", testName = "HPCloudComputeKeyPairClientLiveTest")
|
||||
public class HPCloudComputeKeyPairClientLiveTest extends KeyPairClientLiveTest {
|
||||
public HPCloudComputeKeyPairClientLiveTest() {
|
||||
provider = "hpcloud-compute";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* 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.features;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "live", testName = "HPCloudComputeSecurityGroupClientLiveTest")
|
||||
public class HPCloudComputeSecurityGroupClientLiveTest extends SecurityGroupClientLiveTest {
|
||||
public HPCloudComputeSecurityGroupClientLiveTest() {
|
||||
provider = "hpcloud-compute";
|
||||
}
|
||||
}
|
|
@ -23,11 +23,12 @@ import java.util.Set;
|
|||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FloatingIPAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.KeyPairAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.SecurityGroupAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
@ -65,6 +66,13 @@ public interface NovaAsyncClient {
|
|||
@Delegate
|
||||
FlavorAsyncClient getFlavorClientForRegion(
|
||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionAsyncClient getExtensionClientForRegion(
|
||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Image features.
|
||||
|
|
|
@ -25,11 +25,12 @@ import org.jclouds.concurrent.Timeout;
|
|||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ExtensionClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FloatingIPClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.KeyPairClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.SecurityGroupClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
@ -68,6 +69,13 @@ public interface NovaClient {
|
|||
FlavorClient getFlavorClientForRegion(
|
||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionClient getExtensionClientForRegion(
|
||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Image features.
|
||||
*/
|
||||
|
|
|
@ -22,12 +22,9 @@ import java.util.Map;
|
|||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Address;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.ServerStatus;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -40,21 +37,6 @@ import com.google.common.collect.Iterables;
|
|||
public class ServerToNodeMetadata implements Function<Server, NodeMetadata>
|
||||
{
|
||||
|
||||
@VisibleForTesting
|
||||
public static final Map<ServerStatus, NodeState> serverToNodeState = ImmutableMap.<ServerStatus, NodeState>builder()
|
||||
.put(ServerStatus.ACTIVE, NodeState.RUNNING)
|
||||
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)
|
||||
.put(ServerStatus.DELETED, NodeState.TERMINATED)
|
||||
.put(ServerStatus.RESIZE, NodeState.PENDING)
|
||||
.put(ServerStatus.VERIFY_RESIZE, NodeState.PENDING)
|
||||
.put(ServerStatus.BUILD, NodeState.PENDING)
|
||||
.put(ServerStatus.PASSWORD, NodeState.PENDING)
|
||||
.put(ServerStatus.REBUILD, NodeState.PENDING)
|
||||
.put(ServerStatus.REBOOT, NodeState.PENDING)
|
||||
.put(ServerStatus.HARD_REBOOT, NodeState.PENDING)
|
||||
.put(ServerStatus.UNKNOWN, NodeState.UNRECOGNIZED)
|
||||
.put(ServerStatus.UNRECOGNIZED, NodeState.UNRECOGNIZED).build();
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(Server server)
|
||||
{
|
||||
|
@ -66,6 +48,7 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata>
|
|||
.publicAddresses(Iterables.transform(server.getPublicAddresses(), new AddressToStringTransformationFunction()))
|
||||
.privateAddresses(Iterables.transform(server.getPrivateAddresses(), new AddressToStringTransformationFunction()))
|
||||
.state(server.getStatus().getNodeState())
|
||||
.userMetadata(ImmutableMap.copyOf(server.getMetadata()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,16 +28,18 @@ import org.jclouds.http.annotation.ServerError;
|
|||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ExtensionClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FloatingIPAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FloatingIPClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.KeyPairAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.KeyPairClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.SecurityGroupAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.SecurityGroupClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
||||
import org.jclouds.openstack.nova.v1_1.handlers.NovaErrorHandler;
|
||||
|
@ -59,6 +61,7 @@ public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsync
|
|||
.put(ServerClient.class, ServerAsyncClient.class)//
|
||||
.put(FlavorClient.class, FlavorAsyncClient.class)
|
||||
.put(ImageClient.class, ImageAsyncClient.class)
|
||||
.put(ExtensionClient.class, ExtensionAsyncClient.class)
|
||||
.put(FloatingIPClient.class, FloatingIPAsyncClient.class)
|
||||
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)
|
||||
.put(KeyPairClient.class, KeyPairAsyncClient.class)
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
* 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, Name 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 static com.google.common.base.Objects.toStringHelper;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Resource;
|
||||
|
||||
/**
|
||||
* The OpenStack Compute API is extensible. Extensions serve two purposes: They allow the
|
||||
* introduction of new features in the API without requiring a version change and they allow the
|
||||
* introduction of vendor specific niche functionality.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href= "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||
* />
|
||||
*/
|
||||
public class Extension extends Resource {
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().fromExtension(this);
|
||||
}
|
||||
|
||||
public static class Builder extends Resource.Builder {
|
||||
|
||||
private URI namespace;
|
||||
private String alias;
|
||||
private Date updated;
|
||||
private String description;
|
||||
|
||||
public Builder namespace(URI namespace) {
|
||||
this.namespace = namespace;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder alias(String alias) {
|
||||
this.alias = alias;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder updated(Date updated) {
|
||||
this.updated = updated;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Extension build() {
|
||||
return new Extension(name, links, namespace, alias, updated, description);
|
||||
}
|
||||
|
||||
public Builder fromExtension(Extension in) {
|
||||
return fromResource(in).namespace(in.getNamespace()).alias(in.getAlias()).updated(in.getUpdated())
|
||||
.description(in.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
return alias(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder name(String name) {
|
||||
return Builder.class.cast(super.name(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder links(Set<Link> links) {
|
||||
return Builder.class.cast(super.links(links));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Builder fromResource(Resource in) {
|
||||
return Builder.class.cast(super.fromResource(in));
|
||||
}
|
||||
}
|
||||
|
||||
private URI namespace;
|
||||
private String alias;
|
||||
private Date updated;
|
||||
private String description;
|
||||
|
||||
protected Extension(String name, Set<Link> links, URI namespace, String alias, Date updated,
|
||||
String description) {
|
||||
super(alias, name, links);
|
||||
this.namespace = namespace;
|
||||
this.alias = alias;
|
||||
this.updated = updated;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public URI getNamespace() {
|
||||
return this.namespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.alias;
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return this.alias;
|
||||
}
|
||||
|
||||
public Date getUpdated() {
|
||||
return this.updated;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").add("id", getId()).add("name", name).add("links", links).add("namespace", namespace).add(
|
||||
"alias", alias).add("updated", updated).add("description", description).toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* 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, Name 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.extensions;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Extension namespaces
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href= "http://nova.openstack.org/api_ext/" />
|
||||
*/
|
||||
public interface ExtensionNamespaces {
|
||||
public static URI KEYPAIRS = URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1");
|
||||
public static URI VOLUMES = URI.create("http://docs.openstack.org/ext/volumes/api/v1.1");
|
||||
public static URI SECURITY_GROUPS = URI.create("http://docs.openstack.org/ext/securitygroups/api/v1.1");
|
||||
public static URI FLOATING_IPS = URI.create("http://docs.openstack.org/ext/floating_ips/api/v1.1");
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -31,6 +31,7 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
|
@ -48,6 +49,10 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
*
|
||||
* @see FloatingIPClient
|
||||
* @author Jeremy Daggett
|
||||
* @see ExtensionAsyncClient
|
||||
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html" />
|
||||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://wiki.openstack.org/os_api_floating_ip"/>
|
||||
*/
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -32,6 +32,7 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.KeyPair;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ExtensionAsyncClient;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
|
@ -49,6 +50,10 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
*
|
||||
* @see KeyPairClient
|
||||
* @author Jeremy Daggett
|
||||
* @see ExtensionAsyncClient
|
||||
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html" />
|
||||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://nova.openstack.org/api_ext/ext_keypairs.html" />
|
||||
*/
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -50,6 +50,9 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
*
|
||||
* @see SecurityGroupClient
|
||||
* @author Jeremy Daggett
|
||||
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html" />
|
||||
* @see <a href="http://nova.openstack.org/api_ext" />
|
||||
* @see <a href="http://wiki.openstack.org/os-security-groups" />
|
||||
*/
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Extensions via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see ExtensionClient
|
||||
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@SkipEncoding({ '/', '=' })
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
public interface ExtensionAsyncClient {
|
||||
|
||||
/**
|
||||
* @see ExtensionClient#listExtensions
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("extensions")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/extensions")
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<Set<Extension>> listExtensions();
|
||||
|
||||
|
||||
/**
|
||||
* @see ExtensionClient#getExtensionByAlias
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("extension")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/extensions/{alias}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<Extension> getExtensionByAlias(@PathParam("alias") String id);
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Extensions via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see ExtensionClient
|
||||
* @see <a href="http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
|
||||
* />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface ExtensionClient {
|
||||
|
||||
/**
|
||||
* List all available extensions
|
||||
*
|
||||
* @return all extensions
|
||||
*/
|
||||
Set<Extension> listExtensions();
|
||||
|
||||
/**
|
||||
* Extensions may also be queried individually by their unique alias.
|
||||
*
|
||||
* @param id
|
||||
* id of the extension
|
||||
* @return extension or null if not found
|
||||
*/
|
||||
Extension getExtensionByAlias(String alias);
|
||||
|
||||
}
|
|
@ -35,7 +35,7 @@ import org.jclouds.openstack.nova.v1_1.domain.Flavor;
|
|||
* />
|
||||
* @author Jeremy Daggett
|
||||
*/
|
||||
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface FlavorClient {
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,7 +75,7 @@ public interface ImageAsyncClient {
|
|||
* @see ImageClient#getImage
|
||||
*/
|
||||
@GET
|
||||
@SelectJson("flavor")
|
||||
@SelectJson("image")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images/{id}")
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
* Predicates handy when working with Extensions
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
||||
public class ExtensionPredicates {
|
||||
|
||||
/**
|
||||
* matches namespace of the given extension
|
||||
*
|
||||
* @param namespace
|
||||
* ex {@code http://docs.openstack.org/ext/keypairs/api/v1.1}
|
||||
* @return predicate that will match namespace of the given extension
|
||||
*/
|
||||
public static Predicate<Extension> namespaceEquals(final URI namespace) {
|
||||
checkNotNull(namespace, "namespace must be defined");
|
||||
|
||||
return new Predicate<Extension>() {
|
||||
@Override
|
||||
public boolean apply(Extension ext) {
|
||||
return namespace.equals(ext.getNamespace());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "namespaceEquals(" + namespace + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* matches alias of the given extension
|
||||
*
|
||||
* @param alias
|
||||
* ex. {@code os-keypairs}
|
||||
* @return predicate that will alias of the given extension
|
||||
*/
|
||||
public static Predicate<Extension> aliasEquals(final String alias) {
|
||||
checkNotNull(alias, "alias must be defined");
|
||||
|
||||
return new Predicate<Extension>() {
|
||||
@Override
|
||||
public boolean apply(Extension ext) {
|
||||
return alias.equals(ext.getAlias());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "aliasEquals(" + alias + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.compute.functions;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
|
@ -47,6 +49,7 @@ public class ServerToNodeMetadataTest
|
|||
.privateAddresses(Address.createV4("10.0.0.1"))
|
||||
.publicAddresses(Address.createV4("1.0.1.1"))
|
||||
.status(ServerStatus.ACTIVE)
|
||||
.metadata(ImmutableMap.of("test", "testing"))
|
||||
.build();
|
||||
|
||||
ServerToNodeMetadata converter = new ServerToNodeMetadata();
|
||||
|
@ -65,5 +68,9 @@ public class ServerToNodeMetadataTest
|
|||
assertNotNull(convertedNodeMetadata.getPublicAddresses());
|
||||
assertEquals(convertedNodeMetadata.getPublicAddresses().size(), 1);
|
||||
assertEquals(convertedNodeMetadata.getPublicAddresses().iterator().next(), "1.0.1.1");
|
||||
|
||||
assertNotNull(convertedNodeMetadata.getUserMetadata());
|
||||
assertEquals(convertedNodeMetadata.getUserMetadata().size(), 1);
|
||||
assertEquals(convertedNodeMetadata.getUserMetadata().get("test"),"testing");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
@ -30,6 +30,10 @@ import org.jclouds.openstack.nova.v1_1.domain.Address;
|
|||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.ServerStatus;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/**
|
||||
* 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.extensions;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseKeyPairListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseKeyPairTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests annotation parsing of {@code KeyPairAsyncClient}
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "KeyPairClientExpectTest")
|
||||
public class KeyPairClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
|
||||
public void testListKeyPairsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listKeyPairs = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-keypairs"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listKeyPairsResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/keypair_list.json")).build();
|
||||
|
||||
NovaClient clientWhenServersExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
listKeyPairs, listKeyPairsResponse);
|
||||
|
||||
assertEquals(clientWhenServersExist.getConfiguredRegions(),
|
||||
ImmutableSet.of("North"));
|
||||
|
||||
assertEquals(clientWhenServersExist.getKeyPairClientForRegion("North")
|
||||
.listKeyPairs().toString(), new ParseKeyPairListTest().expected()
|
||||
.toString());
|
||||
}
|
||||
|
||||
public void testListKeyPairsWhenResponseIs404() throws Exception {
|
||||
HttpRequest listKeyPairs = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-keypairs"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listKeyPairsResponse = HttpResponse.builder().statusCode(404)
|
||||
.build();
|
||||
|
||||
NovaClient clientWhenNoServersExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
listKeyPairs, listKeyPairsResponse);
|
||||
|
||||
assertTrue(clientWhenNoServersExist.getKeyPairClientForRegion("North")
|
||||
.listKeyPairs().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
public void testCreateKeyPair() throws Exception {
|
||||
HttpRequest createKeyPair = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-keypairs"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build())
|
||||
.payload(payloadFromStringWithContentType("{\"keypair\":{\"name\":\"testkeypair\"}}",
|
||||
"application/json")).build();
|
||||
|
||||
HttpResponse createKeyPairResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/keypair_created.json")).build();
|
||||
|
||||
NovaClient clientWhenServersExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
createKeyPair, createKeyPairResponse);
|
||||
|
||||
assertEquals(clientWhenServersExist.getKeyPairClientForRegion("North")
|
||||
.createKeyPair("testkeypair").toString(),
|
||||
new ParseKeyPairTest().expected().toString());
|
||||
|
||||
}
|
||||
|
||||
public void testCreateKeyPairWithPublicKey() throws Exception {
|
||||
HttpRequest createKeyPair = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-keypairs"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build())
|
||||
.payload(payloadFromStringWithContentType("{\"keypair\":{\"name\":\"testkeypair\",\"public_key\":\"ssh-rsa AAAXB3NzaC1yc2EAAAADAQABAAAAgQDFNyGjgs6c9akgmZ2ou/fJf7Pdrc23hC95/gM/33OrG4GZABACE4DTioa/PGN+7rHv9YUavUCtXrWayhGniKq/wCuI5fo5TO4AmDNv7/sCGHIHFumADSIoLx0vFhGJIetXEWxL9r0lfFC7//6yZM2W3KcGjbMtlPXqBT9K9PzdyQ== nova@nv-aw2az1-api0001\n\"}}",
|
||||
"application/json")).build();
|
||||
|
||||
HttpResponse createKeyPairResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/keypair_created.json")).build();
|
||||
|
||||
NovaClient clientWhenServersExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
createKeyPair, createKeyPairResponse);
|
||||
|
||||
assertEquals(clientWhenServersExist.getKeyPairClientForRegion("North")
|
||||
.createKeyPairWithPublicKey("testkeypair", "ssh-rsa AAAXB3NzaC1yc2EAAAADAQABAAAAgQDFNyGjgs6c9akgmZ2ou/fJf7Pdrc23hC95/gM/33OrG4GZABACE4DTioa/PGN+7rHv9YUavUCtXrWayhGniKq/wCuI5fo5TO4AmDNv7/sCGHIHFumADSIoLx0vFhGJIetXEWxL9r0lfFC7//6yZM2W3KcGjbMtlPXqBT9K9PzdyQ== nova@nv-aw2az1-api0001\n")
|
||||
.toString(),
|
||||
new ParseKeyPairTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testDeleteKeyPair() throws Exception {
|
||||
HttpRequest deleteKeyPair = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-keypairs/testkeypair"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "*/*")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
|
||||
HttpResponse deleteKeyPairResponse = HttpResponse.builder().statusCode(202).build();
|
||||
|
||||
NovaClient clientWhenServersExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
deleteKeyPair, deleteKeyPairResponse);
|
||||
|
||||
assertTrue(clientWhenServersExist.getKeyPairClientForRegion("North").deleteKeyPair("testkeypair"));
|
||||
}
|
||||
}
|
|
@ -16,9 +16,10 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
package org.jclouds.openstack.nova.v1_1.extensions;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.KeyPair;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* 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.extensions;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests annotation parsing of {@code SecurityGroupAsyncClient}
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "SecurityGroupClientExpectTest")
|
||||
public class SecurityGroupClientExpectTest {
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* 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.extensions;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroupRule;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code SecurityGroupClient}
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "live", testName = "SecurityGroupClientLiveTest")
|
||||
public class SecurityGroupClientLiveTest extends BaseNovaClientLiveTest {
|
||||
|
||||
public static final String SECURITY_GROUP_NAME = "testsg";
|
||||
|
||||
public void listSecurityGroups() throws Exception {
|
||||
for (String regionId : context.getApi().getConfiguredRegions()) {
|
||||
SecurityGroupClient client = context.getApi().getSecurityGroupClientForRegion(regionId);
|
||||
Set<SecurityGroup> securityGroupsList = client.listSecurityGroups();
|
||||
assertNotNull(securityGroupsList);
|
||||
}
|
||||
}
|
||||
|
||||
public void createGetAndDeleteSecurityGroup() throws Exception {
|
||||
for(String regionId : context.getApi().getConfiguredRegions()) {
|
||||
SecurityGroupClient client = context.getApi().getSecurityGroupClientForRegion(regionId);
|
||||
SecurityGroup securityGroup = null;
|
||||
String id;
|
||||
try {
|
||||
securityGroup = client.createSecurityGroup(SECURITY_GROUP_NAME, "test security group");
|
||||
assertNotNull(securityGroup);
|
||||
id = securityGroup.getId();
|
||||
SecurityGroup theGroup = client.getSecurityGroup(id);
|
||||
assertNotNull(theGroup);
|
||||
} finally {
|
||||
if (securityGroup != null) {
|
||||
client.deleteSecurityGroup(securityGroup.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void createAndDeleteSecurityGroupRule() throws Exception {
|
||||
for(String regionId : context.getApi().getConfiguredRegions()) {
|
||||
SecurityGroupClient client = context.getApi().getSecurityGroupClientForRegion(regionId);
|
||||
SecurityGroup securityGroup = null;
|
||||
|
||||
try {
|
||||
securityGroup = client.createSecurityGroup(SECURITY_GROUP_NAME, "test security group");
|
||||
assertNotNull(securityGroup);
|
||||
|
||||
SecurityGroupRule rule = client.createSecurityGroupRule(
|
||||
"tcp", "443", "443", "0.0.0.0/0", "", securityGroup.getId());
|
||||
assertNotNull(rule);
|
||||
|
||||
} finally {
|
||||
if (securityGroup != null) {
|
||||
client.deleteSecurityGroup(securityGroup.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseExtensionListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseExtensionTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Tests annotation parsing of {@code ExtensionAsyncClient}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ExtensionClientExpectTest")
|
||||
public class ExtensionClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
|
||||
public void testListExtensionsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listExtensions = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/extensions"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listExtensionsResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/extension_list.json")).build();
|
||||
|
||||
NovaClient clientWhenExtensionsExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
listExtensions, listExtensionsResponse);
|
||||
|
||||
assertEquals(clientWhenExtensionsExist.getConfiguredRegions(),
|
||||
ImmutableSet.of("North"));
|
||||
|
||||
assertEquals(clientWhenExtensionsExist.getExtensionClientForRegion("North")
|
||||
.listExtensions().toString(), new ParseExtensionListTest().expected()
|
||||
.toString());
|
||||
}
|
||||
|
||||
public void testListExtensionsWhenReponseIs404IsEmpty() throws Exception {
|
||||
HttpRequest listExtensions = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/extensions"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listExtensionsResponse = HttpResponse.builder().statusCode(404)
|
||||
.build();
|
||||
|
||||
NovaClient clientWhenNoServersExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
listExtensions, listExtensionsResponse);
|
||||
|
||||
assertTrue(clientWhenNoServersExist.getExtensionClientForRegion("North")
|
||||
.listExtensions().isEmpty());
|
||||
}
|
||||
|
||||
// TODO: gson deserializer for Multimap
|
||||
public void testGetExtensionByAliasWhenResponseIs2xx() throws Exception {
|
||||
|
||||
HttpRequest getExtension = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/extensions/RS-PIE"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse getExtensionResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/extension_details.json")).build();
|
||||
|
||||
NovaClient clientWhenExtensionsExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
getExtension, getExtensionResponse);
|
||||
|
||||
assertEquals(clientWhenExtensionsExist.getExtensionClientForRegion("North")
|
||||
.getExtensionByAlias("RS-PIE").toString(),
|
||||
new ParseExtensionTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testGetExtensionByAliasWhenResponseIs404() throws Exception {
|
||||
HttpRequest getExtension = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/extensions/RS-PIE"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse getExtensionResponse = HttpResponse.builder().statusCode(404)
|
||||
.payload(payloadFromResource("/extension_details.json")).build();
|
||||
|
||||
NovaClient clientWhenNoExtensionsExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
getExtension, getExtensionResponse);
|
||||
|
||||
assertNull(clientWhenNoExtensionsExist.getExtensionClientForRegion("North").getExtensionByAlias("RS-PIE"));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code ExtensionClient}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", testName = "ExtensionClientLiveTest")
|
||||
public class ExtensionClientLiveTest extends BaseNovaClientLiveTest {
|
||||
|
||||
/**
|
||||
* Tests the listing of Extensions (getExtension() is tested too!)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testListExtensions() throws Exception {
|
||||
for (String regionId : context.getApi().getConfiguredRegions()) {
|
||||
ExtensionClient client = context.getApi().getExtensionClientForRegion(regionId);
|
||||
Set<Extension> response = client.listExtensions();
|
||||
assert null != response;
|
||||
assertTrue(response.size() >= 0);
|
||||
for (Extension extension : response) {
|
||||
Extension newDetails = client.getExtensionByAlias(extension.getId());
|
||||
assertEquals(newDetails.getId(), extension.getId());
|
||||
assertEquals(newDetails.getName(), extension.getName());
|
||||
assertEquals(newDetails.getDescription(), extension.getDescription());
|
||||
assertEquals(newDetails.getNamespace(), extension.getNamespace());
|
||||
assertEquals(newDetails.getUpdated(), extension.getUpdated());
|
||||
assertEquals(newDetails.getLinks(), extension.getLinks());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseImageTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseImageListTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests annotation parsing of {@code ImageAsyncClient}
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ImageAsyncClientTest")
|
||||
public class ImageClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
public void testListImagesWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listImages = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/images"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listImagesResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/image_list.json")).build();
|
||||
|
||||
NovaClient clientWhenImagesExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
listImages, listImagesResponse);
|
||||
|
||||
assertEquals(clientWhenImagesExist.getConfiguredRegions(),
|
||||
ImmutableSet.of("North"));
|
||||
|
||||
assertEquals(clientWhenImagesExist.getImageClientForRegion("North")
|
||||
.listImages().toString(), new ParseImageListTest().expected()
|
||||
.toString());
|
||||
}
|
||||
|
||||
public void testListImagesWhenReponseIs404IsEmpty() throws Exception {
|
||||
HttpRequest listImages = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/images"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listImagesResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NovaClient clientWhenNoServersExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
listImages, listImagesResponse);
|
||||
|
||||
assertTrue(clientWhenNoServersExist.getImageClientForRegion("North")
|
||||
.listImages().isEmpty());
|
||||
}
|
||||
|
||||
public void testGetImageWhenResponseIs2xx() throws Exception {
|
||||
|
||||
HttpRequest getImage = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/images/52415800-8b69-11e0-9b19-734f5736d2a2"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse getImageResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/image_details.json")).build();
|
||||
|
||||
NovaClient clientWhenImagesExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
getImage, getImageResponse);
|
||||
|
||||
assertEquals(clientWhenImagesExist.getImageClientForRegion("North")
|
||||
.getImage("52415800-8b69-11e0-9b19-734f5736d2a2").toString(),
|
||||
new ParseImageTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testGetImageWhenResponseIs404() throws Exception {
|
||||
HttpRequest getImage = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/images/52415800-8b69-11e0-9b19-734f5736d2a2"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse getImageResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NovaClient clientWhenNoImagesExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
getImage, getImageResponse);
|
||||
|
||||
assertNull(clientWhenNoImagesExist.getImageClientForRegion("North")
|
||||
.getImage("52415800-8b69-11e0-9b19-734f5736d2a2"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
|
||||
import org.jclouds.openstack.domain.Resource;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code ImageClient}
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "live", testName = "ImageClientLiveTest")
|
||||
public class ImageClientLiveTest extends BaseNovaClientLiveTest {
|
||||
|
||||
@Test
|
||||
public void testListImages() throws Exception {
|
||||
for (String regionId : context.getApi().getConfiguredRegions()) {
|
||||
ImageClient client = context.getApi().getImageClientForRegion(regionId);
|
||||
Set<Resource> response = client.listImages();
|
||||
assertNotNull(response);
|
||||
assertTrue(response.size() >= 0);
|
||||
for (Resource image : response) {
|
||||
Image newDetails = client.getImage(image.getId());
|
||||
assertNotNull(newDetails);
|
||||
assertEquals(newDetails.getId(), image.getId());
|
||||
assertEquals(newDetails.getName(), image.getName());
|
||||
assertEquals(newDetails.getLinks(), image.getLinks());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListImagesInDetail() throws Exception {
|
||||
for (String regionId : context.getApi().getConfiguredRegions()) {
|
||||
ImageClient client = context.getApi().getImageClientForRegion(regionId);
|
||||
Set<Image> response = client.listImagesInDetail();
|
||||
assertNotNull(response);
|
||||
assertTrue(response.size() >= 0);
|
||||
for (Image image : response) {
|
||||
Image newDetails = client.getImage(image.getId());
|
||||
assertNotNull(newDetails);
|
||||
assertEquals(newDetails.getId(), image.getId());
|
||||
assertEquals(newDetails.getName(), image.getName());
|
||||
assertEquals(newDetails.getLinks(), image.getLinks());
|
||||
assertEquals(newDetails.getCreated(), image.getCreated());
|
||||
assertEquals(newDetails.getMinDisk(), image.getMinDisk());
|
||||
assertEquals(newDetails.getMinRam(), image.getMinRam());
|
||||
assertEquals(newDetails.getProgress(), image.getProgress());
|
||||
assertEquals(newDetails.getStatus(), image.getStatus());
|
||||
assertEquals(newDetails.getServer(), image.getServer());
|
||||
assertEquals(newDetails.getTenantId(), image.getTenantId());
|
||||
assertEquals(newDetails.getUpdated(), image.getUpdated());
|
||||
assertEquals(newDetails.getUserId(), image.getUserId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +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.features;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseKeyPairListTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests annotation parsing of {@code KeyPairAsyncClient}
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "KeyPairClientExpectTest")
|
||||
public class KeyPairClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||
|
||||
public void testListKeyPairsWhenResponseIs2xx() throws Exception {
|
||||
HttpRequest listKeyPairs = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-keypairs"))
|
||||
.headers(
|
||||
ImmutableMultimap.<String, String> builder()
|
||||
.put("Accept", "application/json")
|
||||
.put("X-Auth-Token", authToken).build()).build();
|
||||
|
||||
HttpResponse listKeyPairsResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/keypair_list.json")).build();
|
||||
|
||||
NovaClient clientWhenFloatingIPsExist = requestsSendResponses(
|
||||
keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess,
|
||||
listKeyPairs, listKeyPairsResponse);
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getConfiguredRegions(),
|
||||
ImmutableSet.of("North"));
|
||||
|
||||
assertEquals(clientWhenFloatingIPsExist.getKeyPairClientForRegion("North")
|
||||
.listKeyPairs().toString(), new ParseKeyPairListTest().expected()
|
||||
.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* 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.parse;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.json.BaseSetParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ParseExtensionListNormalTest")
|
||||
public class ParseExtensionListNormalTest extends BaseSetParserTest<Extension> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/extension_list_normal.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SelectJson("extensions")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Set<Extension> expected() {
|
||||
return ImmutableSet
|
||||
.of(Extension
|
||||
.builder()
|
||||
.alias("os-keypairs")
|
||||
.name("Keypairs")
|
||||
.namespace(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1"))
|
||||
.updated(
|
||||
new SimpleDateFormatDateService()
|
||||
.iso8601SecondsDateParse("2011-08-08T00:00:00+00:00"))
|
||||
.description("Keypair Support")
|
||||
.build(),
|
||||
Extension
|
||||
.builder()
|
||||
.alias("os-volumes")
|
||||
.name("Volumes")
|
||||
.namespace(URI.create("http://docs.openstack.org/ext/volumes/api/v1.1"))
|
||||
.updated(
|
||||
new SimpleDateFormatDateService()
|
||||
.iso8601SecondsDateParse("2011-03-25T00:00:00+00:00"))
|
||||
.description("Volumes support")
|
||||
.build(),
|
||||
Extension
|
||||
.builder()
|
||||
.alias("security_groups")
|
||||
.name("SecurityGroups")
|
||||
.namespace(URI.create("http://docs.openstack.org/ext/securitygroups/api/v1.1"))
|
||||
.updated(
|
||||
new SimpleDateFormatDateService()
|
||||
.iso8601SecondsDateParse("2011-07-21T00:00:00+00:00"))
|
||||
.description("Security group support")
|
||||
.build(),
|
||||
Extension
|
||||
.builder()
|
||||
.alias("os-floating-ips")
|
||||
.name("Floating_ips")
|
||||
.namespace(URI.create("http://docs.openstack.org/ext/floating_ips/api/v1.1"))
|
||||
.updated(
|
||||
new SimpleDateFormatDateService()
|
||||
.iso8601SecondsDateParse("2011-06-16T00:00:00+00:00"))
|
||||
.description("Floating IPs support")
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
protected Injector injector() {
|
||||
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
* 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.parse;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.json.BaseSetParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ParseExtensionListTest")
|
||||
public class ParseExtensionListTest extends BaseSetParserTest<Extension> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/extension_list.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SelectJson("extensions")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Set<Extension> expected() {
|
||||
return ImmutableSet
|
||||
.of(Extension
|
||||
.builder()
|
||||
.alias("RAX-PIE")
|
||||
.name("Public Image Extension")
|
||||
.namespace(URI.create("http://docs.rackspacecloud.com/servers/api/ext/pie/v1.0"))
|
||||
.updated(
|
||||
new SimpleDateFormatDateService()
|
||||
.iso8601SecondsDateParse("2011-01-22T13:25:27-06:00"))
|
||||
.description("Adds the capability to share an image with other users.")
|
||||
.links(
|
||||
ImmutableSet.of(
|
||||
Link.create(
|
||||
Relation.DESCRIBEDBY,
|
||||
"application/pdf",
|
||||
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-pie-20111111.pdf")),
|
||||
Link.create(
|
||||
Relation.DESCRIBEDBY,
|
||||
"application/vnd.sun.wadl+xml",
|
||||
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-pie.wadl"))))
|
||||
.build(),
|
||||
Extension
|
||||
.builder()
|
||||
.alias("RAX-CBS")
|
||||
.name("Cloud Block Storage")
|
||||
.namespace(URI.create("http://docs.rackspacecloud.com/servers/api/ext/cbs/v1.0"))
|
||||
.updated(
|
||||
new SimpleDateFormatDateService()
|
||||
.iso8601SecondsDateParse("2011-01-12T11:22:33-06:00"))
|
||||
.description("Allows mounting cloud block storage volumes.")
|
||||
.links(
|
||||
ImmutableSet.of(
|
||||
Link.create(
|
||||
Relation.DESCRIBEDBY,
|
||||
"application/pdf",
|
||||
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-cbs-20111201.pdf")),
|
||||
Link.create(
|
||||
Relation.DESCRIBEDBY,
|
||||
"application/vnd.sun.wadl+xml",
|
||||
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-cbs.wadl"))))
|
||||
.build());
|
||||
}
|
||||
|
||||
protected Injector injector() {
|
||||
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* 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.parse;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ParseExtensionTest")
|
||||
public class ParseExtensionTest extends BaseItemParserTest<Extension> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/extension_details.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SelectJson("extension")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Extension expected() {
|
||||
return Extension
|
||||
.builder()
|
||||
.alias("RS-PIE")
|
||||
.name("Public Image Extension")
|
||||
.namespace(URI.create("http://docs.rackspacecloud.com/servers/api/ext/pie/v1.0"))
|
||||
.updated(
|
||||
new SimpleDateFormatDateService()
|
||||
.iso8601SecondsDateParse("2011-01-22T13:25:27-06:00"))
|
||||
.description("Adds the capability to share an image with other users.")
|
||||
.links(
|
||||
ImmutableSet.of(
|
||||
Link.create(
|
||||
Relation.DESCRIBEDBY,
|
||||
"application/pdf",
|
||||
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-pie-20111111.pdf")),
|
||||
Link.create(
|
||||
Relation.DESCRIBEDBY,
|
||||
"application/vnd.sun.wadl+xml",
|
||||
URI.create("http://docs.rackspacecloud.com/servers/api/ext/cs-pie.wadl"))))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
protected Injector injector() {
|
||||
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* 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.parse;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.BaseParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.KeyPair;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Michael Arnold
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ParseKeyPairTest")
|
||||
public class ParseKeyPairTest extends BaseItemParserTest<KeyPair> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/keypair_created.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SelectJson("keypair")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public KeyPair expected() {
|
||||
return KeyPair
|
||||
.builder()
|
||||
.publicKey("ssh-rsa AAAXB3NzaC1yc2EAAAADAQABAAAAgQDFNyGjgs6c9akgmZ2ou/fJf7Pdrc23hC95/gM/33OrG4GZABACE4DTioa/PGN+7rHv9YUavUCtXrWayhGniKq/wCuI5fo5TO4AmDNv7/sCGHIHFumADSIoLx0vFhGJIetXEWxL9r0lfFC7//6yZM2W3KcGjbMtlPXqBT9K9PzdyQ== nova@nv-aw2az1-api0001\n")
|
||||
.privateKey("-----BEGIN RSA PRIVATE KEY-----\nMIICXQIAAAKBgQDFNyGjgs6c9akgmZ2ou/fJf7Pdrc23hC95/gM/33OrG4GZABAC\nE4DTioa/PGN+7rHv9YUavUCtXrWayhGniKq/wCuI5fo5TO4AmDNv7/sCGHIHFumA\nDSIoLx0vFhGJIetXEWxL9r0lfFC7//6yZM2W3KcGjbMtlPXqBT9K9PzdyQIDAQAB\nAoGAW8Ww+KbpQK8smcgCTr/RqcmsSI8VeL2hXjJvDq0L5WbyYuFdkanDvCztUVZn\nsmyfDtwAqZXB4Ct/dN1tY7m8QpdyRaKRW4Q+hghGCAQpsG7rYDdvwdEyvMaW5RA4\ntucQyajMNyQ/tozU3wMx/v8A7RvGcE9tqoG0WK1C3kBu95UCQQDrOd+joYDkvccz\nFIVu5gNPMXEh3fGGzDxk225UlvESquYLzfz4TfmuUjH4Z1BL3wRiwfJsrrjFkm33\njIidDE8PAkEA1qHjxuaIS1yz/rfzErmcOVNlbFHMP4ihjGTTvh1ZctXlNeLwzENQ\nEDaQV3IpUY1KQR6rxcWb5AXgfF9D9PYFpwJBANucAqGAbRgh3lJgPFtXP4u2O0tF\nLPOOxmvbOdybt6KYD4LB5AXmts77SlACFMNhCXUyYaT6UuOSXDyb5gfJsB0CQQC3\nFaGXKU9Z+doQjhlq/6mjvN/nZl80Uvh7Kgb1RVPoAU1kihGeLE0/h0vZTCiyyDNv\nGRqtucMg32J+tUTi0HpBAkAwHiCZMHMeJWHUwIwlRQY/dnR86FWobRl98ViF2rCL\nDHkDVOeIser3Q6zSqU5/m99lX6an5g8pAh/R5LqnOQZC\n-----END RSA PRIVATE KEY-----\n")
|
||||
.name("testkeypair")
|
||||
.userId("65649731189278")
|
||||
.fingerprint("d2:1f:c9:2b:d8:90:77:5f:15:64:27:e3:9f:77:1d:e4")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
protected Injector injector() {
|
||||
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||
}
|
||||
}
|
|
@ -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.predicates;
|
||||
|
||||
import java.net.URI;
|
||||
import static org.jclouds.openstack.nova.v1_1.predicates.ExtensionPredicates.*;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ExtensionPredicatesTest")
|
||||
public class ExtensionPredicatesTest {
|
||||
Extension ref = Extension.builder().alias("os-keypairs").name("Keypairs").namespace(
|
||||
URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).updated(
|
||||
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description(
|
||||
"Keypair Support").build();
|
||||
|
||||
@Test
|
||||
public void testAliasEqualsWhenEqual() {
|
||||
assert aliasEquals("os-keypairs").apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasEqualsWhenNotEqual() {
|
||||
assert !aliasEquals("foo").apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamespaceEqualsWhenEqual() {
|
||||
assert namespaceEquals(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamespaceEqualsWhenNotEqual() {
|
||||
assert !namespaceEquals(URI.create("foo")).apply(ref);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"extension" : {
|
||||
"name" : "Public Image Extension",
|
||||
"namespace" : "http://docs.rackspacecloud.com/servers/api/ext/pie/v1.0",
|
||||
"alias" : "RS-PIE",
|
||||
"updated" : "2011-01-22T13:25:27-06:00",
|
||||
"description" : "Adds the capability to share an image with other users.",
|
||||
"links" : [
|
||||
{
|
||||
"rel" : "describedby",
|
||||
"type" : "application/pdf",
|
||||
"href" : "http://docs.rackspacecloud.com/servers/api/ext/cs-pie-20111111.pdf"
|
||||
},
|
||||
{
|
||||
"rel" : "describedby",
|
||||
"type" : "application/vnd.sun.wadl+xml",
|
||||
"href" : "http://docs.rackspacecloud.com/servers/api/ext/cs-pie.wadl"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"extensions": [
|
||||
{
|
||||
"name": "Public Image Extension",
|
||||
"namespace": "http://docs.rackspacecloud.com/servers/api/ext/pie/v1.0",
|
||||
"alias": "RAX-PIE",
|
||||
"updated": "2011-01-22T13:25:27-06:00",
|
||||
"description": "Adds the capability to share an image with other users.",
|
||||
"links": [
|
||||
{
|
||||
"rel": "describedby",
|
||||
"type": "application/pdf",
|
||||
"href": "http://docs.rackspacecloud.com/servers/api/ext/cs-pie-20111111.pdf"
|
||||
},
|
||||
{
|
||||
"rel": "describedby",
|
||||
"type": "application/vnd.sun.wadl+xml",
|
||||
"href": "http://docs.rackspacecloud.com/servers/api/ext/cs-pie.wadl"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Cloud Block Storage",
|
||||
"namespace": "http://docs.rackspacecloud.com/servers/api/ext/cbs/v1.0",
|
||||
"alias": "RAX-CBS",
|
||||
"updated": "2011-01-12T11:22:33-06:00",
|
||||
"description": "Allows mounting cloud block storage volumes.",
|
||||
"links": [
|
||||
{
|
||||
"rel": "describedby",
|
||||
"type": "application/pdf",
|
||||
"href": "http://docs.rackspacecloud.com/servers/api/ext/cs-cbs-20111201.pdf"
|
||||
},
|
||||
{
|
||||
"rel": "describedby",
|
||||
"type": "application/vnd.sun.wadl+xml",
|
||||
"href": "http://docs.rackspacecloud.com/servers/api/ext/cs-cbs.wadl"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"extensions": [{
|
||||
"updated": "2011-08-08T00:00:00+00:00",
|
||||
"name": "Keypairs",
|
||||
"links": [],
|
||||
"namespace": "http://docs.openstack.org/ext/keypairs/api/v1.1",
|
||||
"alias": "os-keypairs",
|
||||
"description": "Keypair Support"
|
||||
}, {
|
||||
"updated": "2011-03-25T00:00:00+00:00",
|
||||
"name": "Volumes",
|
||||
"links": [],
|
||||
"namespace": "http://docs.openstack.org/ext/volumes/api/v1.1",
|
||||
"alias": "os-volumes",
|
||||
"description": "Volumes support"
|
||||
}, {
|
||||
"updated": "2011-07-21T00:00:00+00:00",
|
||||
"name": "SecurityGroups",
|
||||
"links": [],
|
||||
"namespace": "http://docs.openstack.org/ext/securitygroups/api/v1.1",
|
||||
"alias": "security_groups",
|
||||
"description": "Security group support"
|
||||
}, {
|
||||
"updated": "2011-06-16T00:00:00+00:00",
|
||||
"name": "Floating_ips",
|
||||
"links": [],
|
||||
"namespace": "http://docs.openstack.org/ext/floating_ips/api/v1.1",
|
||||
"alias": "os-floating-ips",
|
||||
"description": "Floating IPs support"
|
||||
}]
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
<file>target/test-data/jclouds.log</file>
|
||||
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
|||
<file>target/test-data/jclouds-wire.log</file>
|
||||
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
|||
<file>target/test-data/jclouds-compute.log</file>
|
||||
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
<file>target/test-data/jclouds-ssh.log</file>
|
||||
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
|
|
|
@ -20,16 +20,19 @@ package org.jclouds.vcloud.director.v1_5;
|
|||
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.AdminOrg;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Catalog;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Group;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Media;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Org;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Session;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Task;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.User;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Vdc;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.ovf.Network;
|
||||
import org.jclouds.vcloud.director.v1_5.features.AdminCatalogAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.AdminOrgAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.AdminVdcAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.CatalogAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.GroupAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.NetworkAsyncClient;
|
||||
|
@ -37,6 +40,7 @@ import org.jclouds.vcloud.director.v1_5.features.OrgAsyncClient;
|
|||
import org.jclouds.vcloud.director.v1_5.features.QueryAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.TaskAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.UploadAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.UserAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.VAppTemplateAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.VdcAsyncClient;
|
||||
|
||||
|
@ -128,4 +132,16 @@ public interface VCloudDirectorAsyncClient {
|
|||
*/
|
||||
@Delegate
|
||||
AdminOrgAsyncClient getAdminOrgClient();
|
||||
|
||||
/**
|
||||
* @return asynchronous access to {@link User} features
|
||||
*/
|
||||
@Delegate
|
||||
UserAsyncClient getUserClient();
|
||||
|
||||
/**
|
||||
* @return asynchronous access to {@link AdminVdc} features
|
||||
*/
|
||||
@Delegate
|
||||
AdminVdcAsyncClient getAdminVdcClient();
|
||||
}
|
||||
|
|
|
@ -23,16 +23,19 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.AdminOrg;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Catalog;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Group;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Media;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Org;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Session;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Task;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.User;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Vdc;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.ovf.Network;
|
||||
import org.jclouds.vcloud.director.v1_5.features.AdminCatalogClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.AdminOrgClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.AdminVdcClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.CatalogClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.GroupClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.MediaClient;
|
||||
|
@ -41,6 +44,7 @@ import org.jclouds.vcloud.director.v1_5.features.OrgClient;
|
|||
import org.jclouds.vcloud.director.v1_5.features.QueryClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.TaskClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.UploadClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.UserClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.VAppTemplateClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.VdcClient;
|
||||
|
||||
|
@ -131,4 +135,16 @@ public interface VCloudDirectorClient {
|
|||
*/
|
||||
@Delegate
|
||||
AdminOrgClient getAdminOrgClient();
|
||||
|
||||
/**
|
||||
* @return synchronous access to {@link User} features
|
||||
*/
|
||||
@Delegate
|
||||
UserClient getUserClient();
|
||||
|
||||
/**
|
||||
* @return synchronous access to {@link AdminVdc} features
|
||||
*/
|
||||
@Delegate
|
||||
AdminVdcClient getAdminVdcClient();
|
||||
}
|
||||
|
|
|
@ -153,6 +153,12 @@ public class VCloudDirectorMediaType {
|
|||
|
||||
public static final String ADMIN_ORG_NETWORK = "application/vnd.vmware.admin.orgNetwork+xml";
|
||||
|
||||
public static final String USER = "application/vnd.vmware.admin.user+xml";
|
||||
|
||||
public static final String ROLE = "application/vnd.vmware.admin.role+xml";
|
||||
|
||||
public static final String ADMIN_VDC = "application/vnd.vmware.admin.vdc+xml";
|
||||
|
||||
/**
|
||||
* All acceptable media types.
|
||||
*
|
||||
|
@ -173,6 +179,6 @@ public class VCloudDirectorMediaType {
|
|||
PUBLISH_CATALOG_PARAMS, GROUP, ORG_VAPP_TEMPLATE_LEASE_SETTINGS,
|
||||
ORG_LEASE_SETTINGS, ORG_PASSWORD_POLICY_SETTINGS, ORG_LDAP_SETTINGS,
|
||||
ORG_GENERAL_SETTINGS, ORG_EMAIL_SETTINGS, ORG_SETTINGS, ADMIN_NETWORK,
|
||||
ADMIN_ORG_NETWORK
|
||||
ADMIN_ORG_NETWORK, USER, ROLE, ADMIN_VDC
|
||||
);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ import org.jclouds.vcloud.director.v1_5.features.TaskAsyncClient;
|
|||
import org.jclouds.vcloud.director.v1_5.features.TaskClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.UploadAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.UploadClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.UserAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.UserClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.VAppTemplateAsyncClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.VAppTemplateClient;
|
||||
import org.jclouds.vcloud.director.v1_5.features.VdcAsyncClient;
|
||||
|
@ -109,6 +111,7 @@ public class VCloudDirectorRestClientModule extends RestClientModule<VCloudDirec
|
|||
.put(AdminCatalogClient.class, AdminCatalogAsyncClient.class)
|
||||
.put(AdminOrgClient.class, AdminOrgAsyncClient.class)
|
||||
.put(GroupClient.class, GroupAsyncClient.class)
|
||||
.put(UserClient.class, UserAsyncClient.class)
|
||||
.build();
|
||||
|
||||
public VCloudDirectorRestClientModule() {
|
||||
|
|
|
@ -0,0 +1,323 @@
|
|||
/**
|
||||
* 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.vcloud.director.v1_5.domain;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Provides an administrative view of a vDC. Includes all members
|
||||
* of the Vdc element, and adds several elements that can be
|
||||
* viewed and modified only by administrators.
|
||||
*
|
||||
*
|
||||
* <p>Java class for AdminVdc complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType name="AdminVdc">
|
||||
* <complexContent>
|
||||
* <extension base="{http://www.vmware.com/vcloud/v1.5}VdcType">
|
||||
* <sequence>
|
||||
* <element name="ResourceGuaranteedMemory" type="{http://www.w3.org/2001/XMLSchema}double" minOccurs="0"/>
|
||||
* <element name="ResourceGuaranteedCpu" type="{http://www.w3.org/2001/XMLSchema}double" minOccurs="0"/>
|
||||
* <element name="VCpuInMhz" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
|
||||
* <element name="IsThinProvision" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
* <element name="NetworkPoolReference" type="{http://www.vmware.com/vcloud/v1.5}ReferenceType" minOccurs="0"/>
|
||||
* <element name="ProviderVdcReference" type="{http://www.vmware.com/vcloud/v1.5}ReferenceType" minOccurs="0"/>
|
||||
* <element name="UsesFastProvisioning" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* <anyAttribute processContents='lax' namespace='##other'/>
|
||||
* </extension>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "AdminVdc", propOrder = {
|
||||
"resourceGuaranteedMemory",
|
||||
"resourceGuaranteedCpu",
|
||||
"vCpuInMhz",
|
||||
"isThinProvision",
|
||||
"networkPoolReference",
|
||||
"providerVdcReference",
|
||||
"usesFastProvisioning"
|
||||
})
|
||||
public class AdminVdc extends Vdc {
|
||||
public static Builder<?> builder() {
|
||||
return new ConcreteBuilder();
|
||||
}
|
||||
|
||||
public static abstract class Builder<T extends Builder<T>> extends Vdc.Builder<T> {
|
||||
private Double resourceGuaranteedMemory;
|
||||
private Double resourceGuaranteedCpu;
|
||||
private Long vCpuInMhz;
|
||||
private Boolean isThinProvision;
|
||||
private Reference networkPoolReference;
|
||||
private Reference providerVdcReference;
|
||||
private Boolean usesFastProvisioning;
|
||||
|
||||
/**
|
||||
* @see AdminVdc#getResourceGuaranteedMemory()
|
||||
*/
|
||||
public T resourceGuaranteedMemory(Double resourceGuaranteedMemory) {
|
||||
this.resourceGuaranteedMemory = resourceGuaranteedMemory;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AdminVdc#getResourceGuaranteedCpu()
|
||||
*/
|
||||
public T resourceGuaranteedCpu(Double resourceGuaranteedCpu) {
|
||||
this.resourceGuaranteedCpu = resourceGuaranteedCpu;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AdminVdc#getVCpuInMhz()
|
||||
*/
|
||||
public T vCpuInMhz(Long vCpuInMhz) {
|
||||
this.vCpuInMhz = vCpuInMhz;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AdminVdc#getIsThinProvision()
|
||||
*/
|
||||
public T isThinProvision(Boolean isThinProvision) {
|
||||
this.isThinProvision = isThinProvision;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AdminVdc#getNetworkPoolReference()
|
||||
*/
|
||||
public T networkPoolReference(Reference networkPoolReference) {
|
||||
this.networkPoolReference = networkPoolReference;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AdminVdc#getProviderVdcReference()
|
||||
*/
|
||||
public T providerVdcReference(Reference providerVdcReference) {
|
||||
this.providerVdcReference = providerVdcReference;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AdminVdc#getUsesFastProvisioning()
|
||||
*/
|
||||
public T usesFastProvisioning(Boolean usesFastProvisioning) {
|
||||
this.usesFastProvisioning = usesFastProvisioning;
|
||||
return self();
|
||||
}
|
||||
|
||||
public AdminVdc build() {
|
||||
return new AdminVdc(this);
|
||||
}
|
||||
|
||||
public T fromAdminVdc(AdminVdc in) {
|
||||
return fromVdc(in)
|
||||
.resourceGuaranteedMemory(in.getResourceGuaranteedMemory())
|
||||
.resourceGuaranteedCpu(in.getResourceGuaranteedCpu())
|
||||
.vCpuInMhz(in.getVCpuInMhz())
|
||||
.isThinProvision(in.isThinProvision())
|
||||
.networkPoolReference(in.getNetworkPoolReference())
|
||||
.providerVdcReference(in.getProviderVdcReference())
|
||||
.usesFastProvisioning(in.usesFastProvisioning());
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
|
||||
@Override protected ConcreteBuilder self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private AdminVdc() {
|
||||
// For JAXB
|
||||
}
|
||||
|
||||
public AdminVdc(Builder<?> b) {
|
||||
super(b);
|
||||
resourceGuaranteedMemory = b.resourceGuaranteedMemory;
|
||||
resourceGuaranteedCpu = b.resourceGuaranteedCpu;
|
||||
vCpuInMhz = b.vCpuInMhz;
|
||||
isThinProvision = b.isThinProvision;
|
||||
networkPoolReference = b.networkPoolReference;
|
||||
providerVdcReference = b.providerVdcReference;
|
||||
usesFastProvisioning = b.usesFastProvisioning;
|
||||
}
|
||||
|
||||
@XmlElement(name = "ResourceGuaranteedMemory")
|
||||
protected Double resourceGuaranteedMemory;
|
||||
@XmlElement(name = "ResourceGuaranteedCpu")
|
||||
protected Double resourceGuaranteedCpu;
|
||||
@XmlElement(name = "VCpuInMhz")
|
||||
protected Long vCpuInMhz;
|
||||
@XmlElement(name = "IsThinProvision")
|
||||
protected Boolean isThinProvision;
|
||||
@XmlElement(name = "NetworkPoolReference")
|
||||
protected Reference networkPoolReference;
|
||||
@XmlElement(name = "ProviderVdcReference")
|
||||
protected Reference providerVdcReference;
|
||||
@XmlElement(name = "UsesFastProvisioning")
|
||||
protected Boolean usesFastProvisioning;
|
||||
|
||||
/**
|
||||
* Gets the value of the resourceGuaranteedMemory property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Double }
|
||||
*
|
||||
*/
|
||||
public Double getResourceGuaranteedMemory() {
|
||||
return resourceGuaranteedMemory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the resourceGuaranteedCpu property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Double }
|
||||
*
|
||||
*/
|
||||
public Double getResourceGuaranteedCpu() {
|
||||
return resourceGuaranteedCpu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the vCpuInMhz property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Long }
|
||||
*
|
||||
*/
|
||||
public Long getVCpuInMhz() {
|
||||
return vCpuInMhz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the isThinProvision property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isThinProvision() {
|
||||
return isThinProvision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the networkPoolReference property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Reference }
|
||||
*
|
||||
*/
|
||||
public Reference getNetworkPoolReference() {
|
||||
return networkPoolReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the providerVdcReference property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Reference }
|
||||
*
|
||||
*/
|
||||
public Reference getProviderVdcReference() {
|
||||
return providerVdcReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the usesFastProvisioning property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean usesFastProvisioning() {
|
||||
return usesFastProvisioning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
AdminVdc that = AdminVdc.class.cast(o);
|
||||
return super.equals(that) &&
|
||||
equal(resourceGuaranteedMemory, that.resourceGuaranteedMemory) &&
|
||||
equal(resourceGuaranteedCpu, that.resourceGuaranteedCpu) &&
|
||||
equal(vCpuInMhz, that.vCpuInMhz) &&
|
||||
equal(isThinProvision, that.isThinProvision) &&
|
||||
equal(networkPoolReference, that.networkPoolReference) &&
|
||||
equal(providerVdcReference, that.providerVdcReference) &&
|
||||
equal(usesFastProvisioning, that.usesFastProvisioning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(super.hashCode(),
|
||||
resourceGuaranteedMemory,
|
||||
resourceGuaranteedCpu,
|
||||
vCpuInMhz,
|
||||
isThinProvision,
|
||||
networkPoolReference,
|
||||
providerVdcReference,
|
||||
usesFastProvisioning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToStringHelper string() {
|
||||
return super.string()
|
||||
.add("resourceGuaranteedMemory", resourceGuaranteedMemory)
|
||||
.add("resourceGuaranteedCpu", resourceGuaranteedCpu)
|
||||
.add("vCpuInMhz", vCpuInMhz)
|
||||
.add("isThinProvision", isThinProvision)
|
||||
.add("networkPoolReference", networkPoolReference)
|
||||
.add("providerVdcReference", providerVdcReference)
|
||||
.add("usesFastProvisioning", usesFastProvisioning);
|
||||
}
|
||||
|
||||
}
|
|
@ -22,13 +22,17 @@ import static com.google.common.base.Objects.equal;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
|
@ -88,7 +92,7 @@ import com.google.common.collect.Sets;
|
|||
"deployedVmQuota",
|
||||
"role",
|
||||
"password",
|
||||
"groupReferences"
|
||||
"groups"
|
||||
})
|
||||
public class User
|
||||
extends EntityType<User>
|
||||
|
@ -122,7 +126,7 @@ public class User
|
|||
private Integer deployedVmQuota;
|
||||
private Reference role;
|
||||
private String password;
|
||||
private Object /* GroupsList */ groupReferences;
|
||||
private List<Reference> groups = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* @see User#getFullName()
|
||||
|
@ -261,22 +265,37 @@ public class User
|
|||
}
|
||||
|
||||
/**
|
||||
* @see User#getGroupReferences()
|
||||
* @see User#getGroups()
|
||||
*/
|
||||
public Builder groupReferences(Object /* GroupsList */ groupReferences) {
|
||||
this.groupReferences = groupReferences;
|
||||
public Builder groups(List<Reference> groups) {
|
||||
this.groups = groups == null ? null : ImmutableList.copyOf(groups);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see User#getGroups()
|
||||
*/
|
||||
public Builder group(Reference group) {
|
||||
this.groups.add(checkNotNull(group, "group"));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public User build() {
|
||||
return new User(href, type, links, description, tasks, id,
|
||||
name, fullName, emailAddress, telephone, isEnabled, isLocked,
|
||||
im, nameInSource, isAlertEnabled, alertEmailPrefix, alertEmail,
|
||||
isExternal, isDefaultCached, isGroupRole, storedVmQuota, deployedVmQuota,
|
||||
role, password, groupReferences);
|
||||
role, password, groups);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EntityType#getName()
|
||||
*/
|
||||
@Override
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EntityType#getId()
|
||||
|
@ -357,7 +376,7 @@ public class User
|
|||
.deployedVmQuota(in.getDeployedVmQuota())
|
||||
.role(in.getRole())
|
||||
.password(in.getPassword())
|
||||
.groupReferences(in.getGroupReferences());
|
||||
.groups(in.getGroups());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,14 +414,14 @@ public class User
|
|||
protected Reference role;
|
||||
@XmlElement(name = "Password")
|
||||
protected String password;
|
||||
@XmlElement(name = "GroupReferences")
|
||||
protected Object /* GroupsList */ groupReferences;
|
||||
@XmlElementWrapper(name = "GroupReferences")
|
||||
protected List<Reference> groups;
|
||||
|
||||
public User(URI href, String type, Set<Link> links, String description, Set<Task> tasks, String id,
|
||||
String name, String fullName, String emailAddress, String telephone, Boolean enabled, Boolean locked,
|
||||
String im, String nameInSource, Boolean alertEnabled, String alertEmailPrefix, String alertEmail,
|
||||
Boolean external, Boolean defaultCached, Boolean groupRole, Integer storedVmQuota, Integer deployedVmQuota,
|
||||
Reference role, String password, Object groupReferences) {
|
||||
Reference role, String password, List<Reference> groups) {
|
||||
super(href, type, links, description, tasks, id, name);
|
||||
this.fullName = fullName;
|
||||
this.emailAddress = emailAddress;
|
||||
|
@ -421,7 +440,7 @@ public class User
|
|||
this.deployedVmQuota = deployedVmQuota;
|
||||
this.role = role;
|
||||
this.password = password;
|
||||
this.groupReferences = groupReferences;
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
private User() {
|
||||
|
@ -605,8 +624,8 @@ public class User
|
|||
* @return possible object is
|
||||
* {@link GroupsListType }
|
||||
*/
|
||||
public Object /* GroupsList */ getGroupReferences() {
|
||||
return groupReferences;
|
||||
public List<Reference> getGroups() {
|
||||
return groups == null ? Lists.<Reference>newArrayList() : groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -633,7 +652,7 @@ public class User
|
|||
equal(deployedVmQuota, that.deployedVmQuota) &&
|
||||
equal(role, that.role) &&
|
||||
equal(password, that.password) &&
|
||||
equal(groupReferences, that.groupReferences);
|
||||
equal(groups, that.groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -655,7 +674,7 @@ public class User
|
|||
deployedVmQuota,
|
||||
role,
|
||||
password,
|
||||
groupReferences);
|
||||
groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -678,7 +697,6 @@ public class User
|
|||
.add("deployedVmQuota", deployedVmQuota)
|
||||
.add("role", role)
|
||||
.add("password", password)
|
||||
.add("groupReferences", groupReferences).toString();
|
||||
.add("groups", groups).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,9 +21,6 @@ package org.jclouds.vcloud.director.v1_5.domain;
|
|||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
@ -31,6 +28,7 @@ import javax.xml.bind.annotation.XmlSeeAlso;
|
|||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -78,23 +76,24 @@ import com.google.common.base.Objects;
|
|||
"isEnabled"
|
||||
})
|
||||
@XmlSeeAlso({
|
||||
// AdminVdc.class
|
||||
AdminVdc.class
|
||||
})
|
||||
public class Vdc
|
||||
extends EntityType<Vdc>
|
||||
|
||||
{
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
public class Vdc extends EntityType<Vdc> {
|
||||
public static Builder<?> builder() {
|
||||
return new ConcreteBuilder();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromVdc(this);
|
||||
public Builder<?> toNewBuilder() {
|
||||
return new ConcreteBuilder();
|
||||
}
|
||||
|
||||
public static class Builder extends EntityType.Builder<Vdc> {
|
||||
|
||||
|
||||
@Override
|
||||
public ResourceType.Builder<Vdc> toBuilder() {
|
||||
throw new UnsupportedOperationException("Use new builder");
|
||||
}
|
||||
|
||||
public abstract static class Builder<T extends Builder<T>> extends EntityType.NewBuilder<T> {
|
||||
private String allocationModel;
|
||||
private CapacityWithUsage storageCapacity;
|
||||
private ComputeCapacity computeCapacity;
|
||||
|
@ -110,174 +109,96 @@ public class Vdc
|
|||
/**
|
||||
* @see Vdc#getAllocationModel()
|
||||
*/
|
||||
public Builder allocationModel(String allocationModel) {
|
||||
public T allocationModel(String allocationModel) {
|
||||
this.allocationModel = allocationModel;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getStorageCapacity()
|
||||
*/
|
||||
public Builder storageCapacity(CapacityWithUsage storageCapacity) {
|
||||
public T storageCapacity(CapacityWithUsage storageCapacity) {
|
||||
this.storageCapacity = storageCapacity;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getComputeCapacity()
|
||||
*/
|
||||
public Builder computeCapacity(ComputeCapacity computeCapacity) {
|
||||
public T computeCapacity(ComputeCapacity computeCapacity) {
|
||||
this.computeCapacity = computeCapacity;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getResourceEntities()
|
||||
*/
|
||||
public Builder resourceEntities(ResourceEntities resourceEntities) {
|
||||
public T resourceEntities(ResourceEntities resourceEntities) {
|
||||
this.resourceEntities = resourceEntities;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getAvailableNetworks()
|
||||
*/
|
||||
public Builder availableNetworks(AvailableNetworks availableNetworks) {
|
||||
public T availableNetworks(AvailableNetworks availableNetworks) {
|
||||
this.availableNetworks = availableNetworks;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getCapabilities()
|
||||
*/
|
||||
public Builder capabilities(Capabilities capabilities) {
|
||||
public T capabilities(Capabilities capabilities) {
|
||||
this.capabilities = capabilities;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getNicQuota()
|
||||
*/
|
||||
public Builder nicQuota(int nicQuota) {
|
||||
public T nicQuota(int nicQuota) {
|
||||
this.nicQuota = nicQuota;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getNetworkQuota()
|
||||
*/
|
||||
public Builder networkQuota(int networkQuota) {
|
||||
public T networkQuota(int networkQuota) {
|
||||
this.networkQuota = networkQuota;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getVmQuota()
|
||||
*/
|
||||
public Builder vmQuota(Integer vmQuota) {
|
||||
public T vmQuota(Integer vmQuota) {
|
||||
this.vmQuota = vmQuota;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#isEnabled()
|
||||
*/
|
||||
public Builder isEnabled(Boolean isEnabled) {
|
||||
public T isEnabled(Boolean isEnabled) {
|
||||
this.isEnabled = isEnabled;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Vdc#getStatus()
|
||||
*/
|
||||
public Builder status(Integer status) {
|
||||
public T status(Integer status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public Vdc build() {
|
||||
return new Vdc(
|
||||
href, type, links, description, tasks, id, name, allocationModel, storageCapacity,
|
||||
computeCapacity, resourceEntities, availableNetworks, capabilities, nicQuota, networkQuota,
|
||||
vmQuota, isEnabled, status);
|
||||
return new Vdc(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EntityType#getName()
|
||||
*/
|
||||
public Builder name(String name) {
|
||||
super.name(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EntityType#getDescription()
|
||||
*/
|
||||
public Builder description(String description) {
|
||||
super.description(description);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EntityType#getId()
|
||||
*/
|
||||
@Override
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EntityType#getTasks()
|
||||
*/
|
||||
@Override
|
||||
public Builder tasks(Set<Task> tasks) {
|
||||
super.tasks(tasks);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ReferenceType#getHref()
|
||||
*/
|
||||
@Override
|
||||
public Builder href(URI href) {
|
||||
this.href = href;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ReferenceType#getType()
|
||||
*/
|
||||
@Override
|
||||
public Builder type(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EntityType#getLinks()
|
||||
*/
|
||||
@Override
|
||||
public Builder links(Set<Link> links) {
|
||||
super.links(links);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see EntityType#getLinks()
|
||||
*/
|
||||
@Override
|
||||
public Builder link(Link link) {
|
||||
super.link(link);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder fromEntityType(EntityType<Vdc> in) {
|
||||
return Builder.class.cast(super.fromEntityType(in));
|
||||
}
|
||||
|
||||
public Builder fromVdc(Vdc in) {
|
||||
public T fromVdc(Vdc in) {
|
||||
return fromEntityType(in)
|
||||
.allocationModel(in.getAllocationModel())
|
||||
.storageCapacity(in.getStorageCapacity())
|
||||
|
@ -292,26 +213,31 @@ public class Vdc
|
|||
.status(in.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
public Vdc(URI href, String type, Set<Link> links, String description, Set<Task> tasks, String id, String name, String allocationModel, CapacityWithUsage storageCapacity, ComputeCapacity computeCapacity, ResourceEntities resourceEntities, AvailableNetworks availableNetworks, Capabilities capabilities, int nicQuota, int networkQuota, Integer vmQuota, Boolean enabled, Integer status) {
|
||||
super(href, type, links, description, tasks, id, name);
|
||||
this.allocationModel = allocationModel;
|
||||
this.storageCapacity = storageCapacity;
|
||||
this.computeCapacity = computeCapacity;
|
||||
this.resourceEntities = resourceEntities;
|
||||
this.availableNetworks = availableNetworks;
|
||||
this.capabilities = capabilities;
|
||||
this.nicQuota = nicQuota;
|
||||
this.networkQuota = networkQuota;
|
||||
this.vmQuota = vmQuota;
|
||||
isEnabled = enabled;
|
||||
this.status = status;
|
||||
|
||||
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
|
||||
@Override protected ConcreteBuilder self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
private Vdc() {
|
||||
|
||||
protected Vdc() {
|
||||
// For JAXB
|
||||
}
|
||||
|
||||
public Vdc(Builder<?> b) {
|
||||
super(b.href, b.type, b.links, b.description, b.tasks, b.id, b.name);
|
||||
this.allocationModel = b.allocationModel;
|
||||
this.storageCapacity = b.storageCapacity;
|
||||
this.computeCapacity = b.computeCapacity;
|
||||
this.resourceEntities = b.resourceEntities;
|
||||
this.availableNetworks = b.availableNetworks;
|
||||
this.capabilities = b.capabilities;
|
||||
this.nicQuota = b.nicQuota;
|
||||
this.networkQuota = b.networkQuota;
|
||||
this.vmQuota = b.vmQuota;
|
||||
isEnabled = b.isEnabled;
|
||||
this.status = b.status;
|
||||
}
|
||||
|
||||
@XmlElement(name = "AllocationModel", required = true)
|
||||
protected String allocationModel;
|
||||
|
@ -447,7 +373,8 @@ public class Vdc
|
|||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
Vdc that = Vdc.class.cast(o);
|
||||
return equal(allocationModel, that.allocationModel) &&
|
||||
return super.equals(that) &&
|
||||
equal(allocationModel, that.allocationModel) &&
|
||||
equal(storageCapacity, that.storageCapacity) &&
|
||||
equal(computeCapacity, that.computeCapacity) &&
|
||||
equal(resourceEntities, that.resourceEntities) &&
|
||||
|
@ -462,7 +389,8 @@ public class Vdc
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(allocationModel,
|
||||
return Objects.hashCode(super.hashCode(),
|
||||
allocationModel,
|
||||
storageCapacity,
|
||||
computeCapacity,
|
||||
resourceEntities,
|
||||
|
@ -476,8 +404,8 @@ public class Vdc
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper("")
|
||||
public ToStringHelper string() {
|
||||
return super.string()
|
||||
.add("allocationModel", allocationModel)
|
||||
.add("storageCapacity", storageCapacity)
|
||||
.add("computeCapacity", computeCapacity)
|
||||
|
@ -488,7 +416,7 @@ public class Vdc
|
|||
.add("networkQuota", networkQuota)
|
||||
.add("vmQuota", vmQuota)
|
||||
.add("isEnabled", isEnabled)
|
||||
.add("status", status).toString();
|
||||
.add("status", status);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* 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.vcloud.director.v1_5.features;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.JAXBResponseParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
|
||||
import org.jclouds.vcloud.director.v1_5.filters.AddVCloudAuthorizationToRequest;
|
||||
import org.jclouds.vcloud.director.v1_5.functions.ThrowVCloudErrorOn4xx;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* @see AdminVdcClient
|
||||
* @author danikov
|
||||
*/
|
||||
@RequestFilters(AddVCloudAuthorizationToRequest.class)
|
||||
public interface AdminVdcAsyncClient extends VdcAsyncClient {
|
||||
|
||||
/**
|
||||
* @see AdminVdcClient#getVdc(URI)
|
||||
*/
|
||||
@GET
|
||||
@Consumes
|
||||
@JAXBResponseParser
|
||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||
ListenableFuture<AdminVdc> getVdc(@EndpointParam URI vdcRef);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* 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.vcloud.director.v1_5.features;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Network.
|
||||
* <p/>
|
||||
*
|
||||
* @see NetworkAsyncClient
|
||||
* @see <a href= "http://support.theenterprisecloud.com/kb/default.asp?id=984&Lang=1&SID=" />
|
||||
* @author danikov
|
||||
*/
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface AdminVdcClient extends VdcClient {
|
||||
|
||||
/**
|
||||
* Retrieves an admin view of virtual data center. The redwood admin can disable an
|
||||
* organization vDC. This will prevent any further allocation to be used by the organization.
|
||||
* Changing the state will not affect allocations already used. For example, if an organization
|
||||
* vDC is disabled, an organization user cannot deploy or create a new virtual machine in the
|
||||
* vDC (deploy uses memory and cpu allocations, and create uses storage allocation).
|
||||
*
|
||||
* @return the admin vDC or null if not found
|
||||
*/
|
||||
AdminVdc getVdc(URI vdcRef);
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* 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.vcloud.director.v1_5.features;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.JAXBResponseParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.binders.BindToXMLPayload;
|
||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.User;
|
||||
import org.jclouds.vcloud.director.v1_5.filters.AddVCloudAuthorizationToRequest;
|
||||
import org.jclouds.vcloud.director.v1_5.functions.ThrowVCloudErrorOn4xx;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* @see GroupClient
|
||||
* @author danikov
|
||||
*/
|
||||
@RequestFilters(AddVCloudAuthorizationToRequest.class)
|
||||
public interface UserAsyncClient {
|
||||
/**
|
||||
* @see UserClient#createUser(URI, User)
|
||||
*/
|
||||
@POST
|
||||
@Path("/users")
|
||||
@Consumes(VCloudDirectorMediaType.USER)
|
||||
@Produces(VCloudDirectorMediaType.USER)
|
||||
@JAXBResponseParser
|
||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||
ListenableFuture<User> createUser(@EndpointParam URI userRef,
|
||||
@BinderParam(BindToXMLPayload.class) User user);
|
||||
|
||||
/**
|
||||
* @see UserClient#getUser(URI)
|
||||
*/
|
||||
@GET
|
||||
@Consumes
|
||||
@JAXBResponseParser
|
||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||
ListenableFuture<User> getUser(@EndpointParam URI userRef);
|
||||
|
||||
/**
|
||||
* @see UserClient#updateUser(URI, User)
|
||||
*/
|
||||
@PUT
|
||||
@Consumes(VCloudDirectorMediaType.USER)
|
||||
@Produces(VCloudDirectorMediaType.USER)
|
||||
@JAXBResponseParser
|
||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||
ListenableFuture<User> updateUser(@EndpointParam URI userRef,
|
||||
@BinderParam(BindToXMLPayload.class) User user);
|
||||
|
||||
/**
|
||||
* @see UserClient#deleteUser(URI)
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes
|
||||
@JAXBResponseParser
|
||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||
ListenableFuture<Void> deleteUser(@EndpointParam URI userRef);
|
||||
|
||||
/**
|
||||
* @see UserClient#unlockUser(URI)
|
||||
*/
|
||||
@POST
|
||||
@Path("/action/unlock")
|
||||
@Consumes
|
||||
@JAXBResponseParser
|
||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||
ListenableFuture<Void> unlockUser(@EndpointParam URI userRef);
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* 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.vcloud.director.v1_5.features;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Group;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.User;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to {@link Group} objects.
|
||||
*
|
||||
* @see GroupAsyncClient
|
||||
* @author danikov
|
||||
*/
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface UserClient {
|
||||
/**
|
||||
* Creates or imports a user in an organization. The user could be enabled or disabled.
|
||||
*
|
||||
* <pre>
|
||||
* POST /admin/org/{id}/users
|
||||
* </pre>
|
||||
*
|
||||
* @param orgRef the reference for the org
|
||||
* @return the created user
|
||||
*/
|
||||
User createUser(URI orgRef, User user);
|
||||
|
||||
/**
|
||||
* Retrieves a user. This entity could be enabled or disabled.
|
||||
*
|
||||
* <pre>
|
||||
* GET /admin/user/{id}
|
||||
* </pre>
|
||||
*
|
||||
* @param userRef the reference for the user
|
||||
* @return a user
|
||||
*/
|
||||
User getUser(URI userRef);
|
||||
|
||||
/**
|
||||
* Modifies a user. The user object could be enabled or disabled.
|
||||
* Note: the lock status cannot be changed using this call: use unlockUser.
|
||||
*
|
||||
* <pre>
|
||||
* PUT /admin/user/{id}
|
||||
* </pre>
|
||||
*
|
||||
* @param userRef the reference for the user
|
||||
* @return the modified user
|
||||
*/
|
||||
User updateUser(URI userRef, User user);
|
||||
|
||||
/**
|
||||
* Deletes a user. Enabled and disabled users could be deleted.
|
||||
*
|
||||
* <pre>
|
||||
* DELETE /admin/catalog/{id}
|
||||
* </pre>
|
||||
*/
|
||||
void deleteUser(URI userRef);
|
||||
|
||||
/**
|
||||
* Unlocks a user.
|
||||
*
|
||||
* <pre>
|
||||
* POST /admin/user/{id}/action/unlock
|
||||
* </pre>
|
||||
*/
|
||||
void unlockUser(URI userRef);
|
||||
}
|
|
@ -66,7 +66,7 @@ public interface VdcAsyncClient {
|
|||
@Consumes
|
||||
@JAXBResponseParser
|
||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||
ListenableFuture<Vdc> getVdc(@EndpointParam URI vdcURI);
|
||||
ListenableFuture<? extends Vdc> getVdc(@EndpointParam URI vdcURI);
|
||||
|
||||
/**
|
||||
* @see VdcClient#captureVApp(URI, CaptureVAppParams)
|
||||
|
|
|
@ -748,4 +748,112 @@ public class Checks {
|
|||
// parent type
|
||||
checkResourceType(settings);
|
||||
}
|
||||
|
||||
public static void checkUser(User user) {
|
||||
// Check optional fields
|
||||
// NOTE fullName cannot be checked
|
||||
// NOTE isEnabled cannot be checked
|
||||
// NOTE isLocked cannot be checked
|
||||
// NOTE im cannot be checked
|
||||
// NOTE nameInSource cannot be checked
|
||||
// NOTE isAlertEnabled cannot be checked
|
||||
// NOTE alterEmailPrefix cannot be checked
|
||||
// NOTE isExternal cannot be checked
|
||||
// NOTE isDefaultCached cannot be checked
|
||||
// NOTE isGroupRole cannot be checked
|
||||
// NOTE password cannot be checked
|
||||
|
||||
if (user.getEmailAddress() != null) {
|
||||
checkEmailAddress(user.getEmailAddress());
|
||||
}
|
||||
if (user.getTelephone() != null) {
|
||||
checkTelephone(user.getTelephone());
|
||||
}
|
||||
if (user.getAlertEmail() != null) {
|
||||
checkEmailAddress(user.getAlertEmail());
|
||||
}
|
||||
if (user.getStoredVmQuota() != null) {
|
||||
assertTrue(user.getStoredVmQuota() >= 0, String.format(OBJ_FIELD_GTE_0,
|
||||
"User", "storedVmQuota", user.getStoredVmQuota()));
|
||||
}
|
||||
if (user.getDeployedVmQuota() != null) {
|
||||
assertTrue(user.getDeployedVmQuota() >= 0, String.format(OBJ_FIELD_GTE_0,
|
||||
"User", "deployedVmQuota", user.getDeployedVmQuota()));
|
||||
}
|
||||
if (user.getRole() != null) {
|
||||
checkReferenceType(user.getRole());
|
||||
}
|
||||
if (user.getGroups() != null) {
|
||||
for (Reference group : user.getGroups()) {
|
||||
checkReferenceType(group);
|
||||
}
|
||||
}
|
||||
|
||||
// parent type
|
||||
checkEntityType(user);
|
||||
}
|
||||
|
||||
public static void checkTelephone(String number) {
|
||||
// TODO: regex validate telephone
|
||||
}
|
||||
|
||||
public static void checkAdminVdc(AdminVdc vdc) {
|
||||
// optional
|
||||
// NOTE isThinProvision cannot be checked
|
||||
// NOTE usesFastProvisioning cannot be checked
|
||||
if (vdc.getResourceGuaranteedMemory() != null) {
|
||||
// TODO: between 0 and 1 inc.
|
||||
}
|
||||
if (vdc.getResourceGuaranteedCpu() != null) {
|
||||
// TODO: between 0 and 1 inc.
|
||||
}
|
||||
if (vdc.getVCpuInMhz() != null) {
|
||||
assertTrue(vdc.getVCpuInMhz() >= 0, String.format(OBJ_FIELD_GTE_0,
|
||||
"Vdc", "cCpuInMhz", vdc.getVCpuInMhz()));
|
||||
}
|
||||
if (vdc.getNetworkPoolReference() != null) {
|
||||
checkReferenceType(vdc.getNetworkPoolReference());
|
||||
}
|
||||
if (vdc.getProviderVdcReference() != null) {
|
||||
checkReferenceType(vdc.getProviderVdcReference());
|
||||
}
|
||||
|
||||
// parent type
|
||||
checkVdc(vdc);
|
||||
}
|
||||
|
||||
public static void checkVdc(Vdc vdc) {
|
||||
// required
|
||||
assertNotNull(vdc.getAllocationModel(), String.format(OBJ_FIELD_REQ, "Vdc", "allocationModel"));
|
||||
// one of: AllocationVApp, AllocationPool, ReservationPool
|
||||
assertNotNull(vdc.getStorageCapacity(), String.format(OBJ_FIELD_REQ, "Vdc", "storageCapacity"));
|
||||
checkCapacityWithUsage(vdc.getStorageCapacity());
|
||||
assertNotNull(vdc.getComputeCapacity(), String.format(OBJ_FIELD_REQ, "Vdc", "computeCapacity"));
|
||||
checkComputeCapacity(vdc.getComputeCapacity());
|
||||
assertNotNull(vdc.getNicQuota(), String.format(OBJ_FIELD_REQ, "Vdc", "nicQuota"));
|
||||
assertTrue(vdc.getNicQuota() >= 0, String.format(OBJ_FIELD_GTE_0,
|
||||
"Vdc", "nicQuota", vdc.getNicQuota()));
|
||||
assertNotNull(vdc.getNetworkQuota(), String.format(OBJ_FIELD_REQ, "Vdc", "networkQuota"));
|
||||
assertTrue(vdc.getNetworkQuota() >= 0, String.format(OBJ_FIELD_GTE_0,
|
||||
"Vdc", "networkQuota", vdc.getNetworkQuota()));
|
||||
|
||||
// optional
|
||||
// NOTE isEnabled cannot be checked
|
||||
if (vdc.getResourceEntities() != null) {
|
||||
checkResourceEntities(vdc.getResourceEntities());
|
||||
}
|
||||
if (vdc.getAvailableNetworks() != null) {
|
||||
checkAvailableNetworks(vdc.getAvailableNetworks());
|
||||
}
|
||||
if (vdc.getCapabilities() != null) {
|
||||
checkCapabilities(vdc.getCapabilities());
|
||||
}
|
||||
if (vdc.getVmQuota() != null) {
|
||||
assertTrue(vdc.getVmQuota() >= 0, String.format(OBJ_FIELD_GTE_0,
|
||||
"Vdc", "vmQuota", vdc.getVmQuota()));
|
||||
}
|
||||
|
||||
// parent type
|
||||
checkEntityType(vdc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.vcloud.director.v1_5.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorClient;
|
||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Reference;
|
||||
import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorRestClientExpectTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Allows us to test a client via its side effects.
|
||||
*
|
||||
* @author danikov
|
||||
*/
|
||||
@Test(groups = { "unit", "admin", "vdc" }, singleThreaded = true, testName = "AdminVdcClientExpectTest")
|
||||
public class AdminVdcClientExpectTest extends BaseVCloudDirectorRestClientExpectTest {
|
||||
|
||||
private Reference vdcRef = Reference.builder()
|
||||
.href(URI.create(endpoint + "???"))
|
||||
.build();
|
||||
|
||||
@Test( enabled = false )
|
||||
public void testGetVdc() {
|
||||
VCloudDirectorClient client = requestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
.apiCommand("GET", "/admin/vdc/???")
|
||||
.acceptAnyMedia()
|
||||
.httpRequestBuilder().build(),
|
||||
new VcloudHttpResponsePrimer()
|
||||
.xmlFilePayload("/vdc/admin/vdc.xml",
|
||||
VCloudDirectorMediaType.ADMIN_VDC)
|
||||
.httpResponseBuilder().build());
|
||||
|
||||
AdminVdc expected = adminVdc();
|
||||
|
||||
assertEquals(client.getAdminVdcClient().getVdc(vdcRef.getHref()), expected);
|
||||
}
|
||||
|
||||
public static final AdminVdc adminVdc() {
|
||||
return AdminVdc.builder().fromVdc(VdcClientExpectTest.getVdc())
|
||||
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
*(Link.builder().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(Link.builder().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.vcloud.director.v1_5.features;
|
||||
|
||||
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_REQ_LIVE;
|
||||
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.REF_REQ_LIVE;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Checks;
|
||||
import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorClientLiveTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@link NetworkClient}
|
||||
*
|
||||
* @author danikov
|
||||
*/
|
||||
@Test(groups = { "live", "admin", "vdc" }, singleThreaded = true, testName = "AdminVdcClientLiveTest")
|
||||
public class AdminVdcClientLiveTest extends BaseVCloudDirectorClientLiveTest {
|
||||
|
||||
public static final String VDC = "admin vdc";
|
||||
|
||||
/*
|
||||
* Convenience reference to API client.
|
||||
*/
|
||||
protected AdminVdcClient vdcClient;
|
||||
|
||||
@Override
|
||||
@BeforeClass(inheritGroups = true)
|
||||
public void setupRequiredClients() {
|
||||
vdcClient = context.getApi().getAdminVdcClient();
|
||||
}
|
||||
|
||||
@Test(testName = "GET /admin/vdc/{id}", enabled = false)
|
||||
public void testGetNetwork() {
|
||||
// required for testing
|
||||
assertNotNull(vdcURI, String.format(REF_REQ_LIVE, VDC));
|
||||
|
||||
AdminVdc vdc = vdcClient.getVdc(toAdminUri(vdcURI));
|
||||
assertNotNull(vdc, String.format(OBJ_REQ_LIVE, VDC));
|
||||
|
||||
// parent type
|
||||
Checks.checkAdminVdc(vdc);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* 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.vcloud.director.v1_5.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorClient;
|
||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Link;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Reference;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.User;
|
||||
import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorRestClientExpectTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Test the {@link GroupClient} by observing its side effects.
|
||||
*
|
||||
* @author danikov
|
||||
*/
|
||||
@Test(groups = { "unit", "admin", "adminUser"}, singleThreaded = true, testName = "UserClientExpectTest")
|
||||
public class UserClientExpectTest extends BaseVCloudDirectorRestClientExpectTest {
|
||||
|
||||
private Reference orgRef = Reference.builder()
|
||||
.href(URI.create(endpoint + "/admin/org/6f312e42-cd2b-488d-a2bb-97519cd57ed0"))
|
||||
.build();
|
||||
|
||||
private Reference userRef = Reference.builder()
|
||||
.href(URI.create(endpoint + "/admin/user/b37223f3-8792-477a-820f-334998f61cd6"))
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void testCreateUser() {
|
||||
VCloudDirectorClient client = requestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
.apiCommand("POST", "/admin/org/6f312e42-cd2b-488d-a2bb-97519cd57ed0/catalogs")
|
||||
.xmlFilePayload("/user/createUserSource.xml", VCloudDirectorMediaType.USER)
|
||||
.acceptMedia(VCloudDirectorMediaType.USER)
|
||||
.httpRequestBuilder().build(),
|
||||
new VcloudHttpResponsePrimer()
|
||||
.xmlFilePayload("/user/createUser.xml", VCloudDirectorMediaType.USER)
|
||||
.httpResponseBuilder().build());
|
||||
|
||||
User source = createUserSource();
|
||||
User expected = createUser();
|
||||
|
||||
assertEquals(client.getUserClient().createUser(orgRef.getHref(), source), expected);
|
||||
}
|
||||
|
||||
public static final User createUserSource() {
|
||||
return User.builder()
|
||||
.name("test")
|
||||
.fullName("testFullName")
|
||||
.emailAddress("test@test.com")
|
||||
.telephone("555-1234")
|
||||
.isEnabled(false)
|
||||
.im("testIM")
|
||||
.isAlertEnabled(false)
|
||||
.alertEmailPrefix("testPrefix")
|
||||
.alertEmail("testAlert@test.com")
|
||||
.isExternal(false)
|
||||
.isGroupRole(false)
|
||||
.role(Reference.builder()
|
||||
.type("application/vnd.vmware.admin.role+xml")
|
||||
.name("vApp User")
|
||||
.href(URI.create("https://vcloudbeta.bluelock.com/api/admin/role/ff1e0c91-1288-3664-82b7-a6fa303af4d1"))
|
||||
.build())
|
||||
.password("password")
|
||||
.groups(Collections.<Reference>emptyList())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static final User createUser() {
|
||||
return createUserSource().toBuilder()
|
||||
.id("urn:vcloud:user:b37223f3-8792-477a-820f-334998f61cd6")
|
||||
.type("application/vnd.vmware.admin.user+xml")
|
||||
.href(URI.create("https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"))
|
||||
.link(Link.builder()
|
||||
.rel("edit")
|
||||
.type("application/vnd.vmware.admin.user+xml")
|
||||
.href(URI.create("https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"))
|
||||
.build())
|
||||
.link(Link.builder()
|
||||
.rel("remove")
|
||||
.href(URI.create("https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"))
|
||||
.build())
|
||||
.isLocked(false)
|
||||
.isDefaultCached(false)
|
||||
.storedVmQuota(0)
|
||||
.deployedVmQuota(0)
|
||||
.password(null)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUser() {
|
||||
VCloudDirectorClient client = requestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
.apiCommand("GET", "/admin/user/b37223f3-8792-477a-820f-334998f61cd6")
|
||||
.acceptAnyMedia()
|
||||
.httpRequestBuilder().build(),
|
||||
new VcloudHttpResponsePrimer()
|
||||
.xmlFilePayload("/user/user.xml", VCloudDirectorMediaType.USER)
|
||||
.httpResponseBuilder().build());
|
||||
|
||||
User expected = user();
|
||||
|
||||
assertEquals(client.getUserClient().getUser(userRef.getHref()), expected);
|
||||
}
|
||||
|
||||
public static final User user() {
|
||||
return createUser().toBuilder()
|
||||
.nameInSource("test")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUser() {
|
||||
VCloudDirectorClient client = requestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
.apiCommand("PUT", "/admin/user/b37223f3-8792-477a-820f-334998f61cd6")
|
||||
.xmlFilePayload("/user/updateUserSource.xml", VCloudDirectorMediaType.USER)
|
||||
.acceptMedia(VCloudDirectorMediaType.USER)
|
||||
.httpRequestBuilder().build(),
|
||||
new VcloudHttpResponsePrimer()
|
||||
.xmlFilePayload("/user/updateUser.xml", VCloudDirectorMediaType.USER)
|
||||
.httpResponseBuilder().build());
|
||||
|
||||
User source = updateUserSource();
|
||||
User expected = updateUser();
|
||||
|
||||
assertEquals(client.getUserClient().updateUser(userRef.getHref(), source), expected);
|
||||
}
|
||||
|
||||
public static final User updateUserSource() {
|
||||
return user().toBuilder()
|
||||
.fullName("new"+user().getFullName())
|
||||
.emailAddress("new"+user().getEmailAddress())
|
||||
.telephone("1-"+user().getTelephone())
|
||||
.isEnabled(true)
|
||||
.im("new"+user().getIM())
|
||||
.isAlertEnabled(true)
|
||||
.alertEmailPrefix("new"+user().getAlertEmailPrefix())
|
||||
.alertEmail("new"+user().getAlertEmail())
|
||||
.storedVmQuota(1)
|
||||
.deployedVmQuota(1)
|
||||
.password("newPassword")
|
||||
.build();
|
||||
}
|
||||
|
||||
public static final User updateUser() {
|
||||
return updateUserSource().toBuilder()
|
||||
.password(null)
|
||||
.build();
|
||||
}
|
||||
|
||||
// POST /admin/user/{id}/action/unlock
|
||||
|
||||
@Test
|
||||
public void testDeleteUser() {
|
||||
VCloudDirectorClient client = requestsSendResponses(loginRequest, sessionResponse,
|
||||
new VcloudHttpRequestPrimer()
|
||||
.apiCommand("DELETE", "/admin/user/b37223f3-8792-477a-820f-334998f61cd6")
|
||||
.acceptAnyMedia()
|
||||
.httpRequestBuilder().build(),
|
||||
new VcloudHttpResponsePrimer()
|
||||
.httpResponseBuilder().statusCode(204).build());
|
||||
|
||||
client.getUserClient().deleteUser(userRef.getHref());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* 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.vcloud.director.v1_5.features;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_DEL;
|
||||
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_UPDATABLE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorException;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Checks;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Error;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Owner;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Reference;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.ReferenceType;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.User;
|
||||
import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorClientLiveTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Tests live behavior of {@link AdminGroupClient}.
|
||||
*
|
||||
* @author danikov
|
||||
*/
|
||||
@Test(groups = { "live", "admin", "adminUser" }, singleThreaded = true, testName = "UserClientLiveTest")
|
||||
public class UserClientLiveTest extends BaseVCloudDirectorClientLiveTest {
|
||||
|
||||
public static final String USER = "admin user";
|
||||
|
||||
/*
|
||||
* Convenience references to API clients.
|
||||
*/
|
||||
UserClient userClient;
|
||||
|
||||
/*
|
||||
* Shared state between dependant tests.
|
||||
*/
|
||||
private ReferenceType<?> orgRef;
|
||||
private User user;
|
||||
|
||||
@Override
|
||||
@BeforeClass(inheritGroups = true)
|
||||
public void setupRequiredClients() {
|
||||
userClient = context.getApi().getUserClient();
|
||||
orgRef = Iterables.getFirst(context.getApi().getOrgClient().getOrgList().getOrgs(), null).toAdminReference(endpoint);
|
||||
}
|
||||
|
||||
@Test(testName = "POST /admin/org/{id}/users")
|
||||
public void testCreateUser() {
|
||||
User newUser = User.builder()
|
||||
.name("test")
|
||||
.fullName("testFullName")
|
||||
.emailAddress("test@test.com")
|
||||
.telephone("555-1234")
|
||||
.isEnabled(false)
|
||||
.im("testIM")
|
||||
.isAlertEnabled(false)
|
||||
.alertEmailPrefix("testPrefix")
|
||||
.alertEmail("testAlert@test.com")
|
||||
.isExternal(false)
|
||||
.isGroupRole(false)
|
||||
.role(Reference.builder() // FIXME: auto-fetch a role? or inject
|
||||
.name("vApp User")
|
||||
.href(URI.create("https://vcloudbeta.bluelock.com/api/admin/role/ff1e0c91-1288-3664-82b7-a6fa303af4d1"))
|
||||
.build())
|
||||
.password("password")
|
||||
// .group()
|
||||
.build();
|
||||
user = userClient.createUser(orgRef.getHref(), newUser);
|
||||
|
||||
Checks.checkUser(user);
|
||||
}
|
||||
|
||||
@Test(testName = "GET /admin/user/{id}",
|
||||
dependsOnMethods = { "testCreateUser" })
|
||||
public void testGetUser() {
|
||||
user = userClient.getUser(user.getHref());
|
||||
|
||||
Checks.checkUser(user);
|
||||
}
|
||||
|
||||
@Test(testName = "PUT /admin/user/{id}",
|
||||
dependsOnMethods = { "testGetUser" })
|
||||
public void testUpdateUser() {
|
||||
User oldUser = user.toBuilder().build();
|
||||
User newUser = user.toBuilder()
|
||||
// .name("new"+oldUser.getName())
|
||||
.fullName("new"+oldUser.getFullName())
|
||||
.emailAddress("new"+oldUser.getEmailAddress())
|
||||
.telephone("1-"+oldUser.getTelephone())
|
||||
.isEnabled(true)
|
||||
.im("new"+oldUser.getIM())
|
||||
.isAlertEnabled(true)
|
||||
.alertEmailPrefix("new"+oldUser.getAlertEmailPrefix())
|
||||
.alertEmail("new"+oldUser.getAlertEmail())
|
||||
// .role(Reference.builder() // FIXME: auto-fetch a role? or inject
|
||||
// .name("vApp Author")
|
||||
// .href(URI.create("https://vcloudbeta.bluelock.com/api/admin/role/1bf4457f-a253-3cf1-b163-f319f1a31802"))
|
||||
// .build())
|
||||
.storedVmQuota(1)
|
||||
.deployedVmQuota(1)
|
||||
.password("newPassword")
|
||||
.build();
|
||||
|
||||
try {
|
||||
userClient.updateUser(user.getHref(), newUser);
|
||||
user = userClient.getUser(user.getHref());
|
||||
Checks.checkUser(user);
|
||||
// assertTrue(equal(user.getName(), newUser.getName()),
|
||||
// String.format(OBJ_FIELD_UPDATABLE, USER, "name"));
|
||||
assertTrue(equal(user.getFullName(), newUser.getFullName()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "fullName"));
|
||||
assertTrue(equal(user.getEmailAddress(), newUser.getEmailAddress()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "emailAddress"));
|
||||
assertTrue(equal(user.getTelephone(), newUser.getTelephone()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "telephone"));
|
||||
assertTrue(equal(user.isEnabled(), newUser.isEnabled()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "isEnabled"));
|
||||
assertTrue(equal(user.getIM(), newUser.getIM()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "im"));
|
||||
assertTrue(equal(user.isAlertEnabled(), newUser.isAlertEnabled()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "isAlertEnabled"));
|
||||
assertTrue(equal(user.getAlertEmailPrefix(), newUser.getAlertEmailPrefix()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "alertEmailPrefix"));
|
||||
assertTrue(equal(user.getAlertEmail(), newUser.getAlertEmail()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "alertEmail"));
|
||||
// assertTrue(equal(user.getRole(), newUser.getRole()),
|
||||
// String.format(OBJ_FIELD_UPDATABLE, USER, "role"));
|
||||
assertTrue(equal(user.getStoredVmQuota(), newUser.getStoredVmQuota()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "storedVmQuota"));
|
||||
assertTrue(equal(user.getDeployedVmQuota(), newUser.getDeployedVmQuota()),
|
||||
String.format(OBJ_FIELD_UPDATABLE, USER, "deployedVmQuota"));
|
||||
|
||||
// FIXME: assert password is changed with session client?
|
||||
} finally {
|
||||
userClient.updateUser(user.getHref(), oldUser);
|
||||
user = userClient.getUser(user.getHref());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
|
||||
@Test(testName = "POST /admin/user/{id}/action/unlock",
|
||||
dependsOnMethods = { "testUpdateUser" } )
|
||||
public void testUnlockUser() {
|
||||
//TODO: check previous tests a) enabled lockout, b) set password
|
||||
//TODO: attempt too many times with the wrong password
|
||||
//TODO: verify access is denied
|
||||
//TODO: unlock user
|
||||
//TODO: verify access is renewed
|
||||
}
|
||||
|
||||
@Test(testName = "DELETE /admin/user/{id}",
|
||||
dependsOnMethods = { "testUnlockUser" } )
|
||||
public void testDeleteUser() {
|
||||
userClient.deleteUser(user.getHref());
|
||||
|
||||
Error expected = Error.builder()
|
||||
.message("No access to entity \"(com.vmware.vcloud.entity.user:"+
|
||||
user.getId().substring("urn:vcloud:user:".length())+")\".")
|
||||
.majorErrorCode(403)
|
||||
.minorErrorCode("ACCESS_TO_RESOURCE_IS_FORBIDDEN")
|
||||
.build();
|
||||
|
||||
try {
|
||||
user = userClient.getUser(user.getHref());
|
||||
fail("Should give HTTP 403 error");
|
||||
} catch (VCloudDirectorException vde) {
|
||||
assertEquals(vde.getError(), expected);
|
||||
user = null;
|
||||
} catch (Exception e) {
|
||||
fail("Should have thrown a VCloudDirectorException");
|
||||
}
|
||||
|
||||
if (user != null) { // guard against NPE on the .toStrings
|
||||
assertNull(user, String.format(OBJ_DEL, USER, user.toString()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@ import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
|||
import org.jclouds.vcloud.director.v1_5.domain.Link;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Org;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Reference;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.ReferenceType;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Session;
|
||||
import org.jclouds.vcloud.director.v1_5.domain.Task;
|
||||
import org.jclouds.vcloud.director.v1_5.predicates.ReferenceTypePredicates;
|
||||
|
@ -135,4 +136,12 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ
|
|||
if (context != null)
|
||||
context.close();
|
||||
}
|
||||
|
||||
public URI toAdminUri(ReferenceType<?> ref) {
|
||||
return toAdminUri(ref.getHref());
|
||||
}
|
||||
|
||||
public URI toAdminUri(URI uri) {
|
||||
return Reference.builder().href(uri).build().toAdminReference(endpoint).getHref();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<User xmlns="http://www.vmware.com/vcloud/v1.5" name="test" id="urn:vcloud:user:b37223f3-8792-477a-820f-334998f61cd6" type="application/vnd.vmware.admin.user+xml" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://vcloudbeta.bluelock.com/api/v1.5/schema/master.xsd">
|
||||
<Link rel="edit" type="application/vnd.vmware.admin.user+xml" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"/>
|
||||
<Link rel="remove" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"/>
|
||||
<FullName>testFullName</FullName>
|
||||
<EmailAddress>test@test.com</EmailAddress>
|
||||
<Telephone>555-1234</Telephone>
|
||||
<IsEnabled>false</IsEnabled>
|
||||
<IsLocked>false</IsLocked>
|
||||
<IM>testIM</IM>
|
||||
<IsAlertEnabled>false</IsAlertEnabled>
|
||||
<AlertEmailPrefix>testPrefix</AlertEmailPrefix>
|
||||
<AlertEmail>testAlert@test.com</AlertEmail>
|
||||
<IsExternal>false</IsExternal>
|
||||
<IsDefaultCached>false</IsDefaultCached>
|
||||
<IsGroupRole>false</IsGroupRole>
|
||||
<StoredVmQuota>0</StoredVmQuota>
|
||||
<DeployedVmQuota>0</DeployedVmQuota>
|
||||
<Role type="application/vnd.vmware.admin.role+xml" name="vApp User" href="https://vcloudbeta.bluelock.com/api/admin/role/ff1e0c91-1288-3664-82b7-a6fa303af4d1"/>
|
||||
<GroupReferences/>
|
||||
</User>
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<User name="test" xmlns="http://www.vmware.com/vcloud/v1.5">
|
||||
<FullName>testFullName</FullName>
|
||||
<EmailAddress>test@test.com</EmailAddress>
|
||||
<Telephone>555-1234</Telephone>
|
||||
<IsEnabled>false</IsEnabled>
|
||||
<IM>testIM</IM>
|
||||
<IsAlertEnabled>false</IsAlertEnabled>
|
||||
<AlertEmailPrefix>testPrefix</AlertEmailPrefix>
|
||||
<AlertEmail>testAlert@test.com</AlertEmail>
|
||||
<IsExternal>false</IsExternal>
|
||||
<IsGroupRole>false</IsGroupRole>
|
||||
<Role type="application/vnd.vmware.admin.role+xml" name="vApp User" href="https://vcloudbeta.bluelock.com/api/admin/role/ff1e0c91-1288-3664-82b7-a6fa303af4d1"/>
|
||||
<Password>password</Password>
|
||||
<GroupReferences/>
|
||||
</User>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<User xmlns="http://www.vmware.com/vcloud/v1.5" name="test" id="urn:vcloud:user:b37223f3-8792-477a-820f-334998f61cd6" type="application/vnd.vmware.admin.user+xml" href="https://vcloudbeta.bluelock.com/api/admin/user/5fc76423-0380-4a6d-9f52-dffb4ffaa46a" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://vcloudbeta.bluelock.com/api/v1.5/schema/master.xsd">
|
||||
<Link rel="edit" type="application/vnd.vmware.admin.user+xml" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"/>
|
||||
<FullName>newtestFullName</FullName>
|
||||
<EmailAddress>newtest@test.com</EmailAddress>
|
||||
<Telephone>1-555-1234</Telephone>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<IsLocked>false</IsLocked>
|
||||
<IM>newtestIM</IM>
|
||||
<NameInSource>test</NameInSource>
|
||||
<IsAlertEnabled>true</IsAlertEnabled>
|
||||
<AlertEmailPrefix>newtestPrefix</AlertEmailPrefix>
|
||||
<AlertEmail>newtestAlert@test.com</AlertEmail>
|
||||
<IsExternal>false</IsExternal>
|
||||
<IsDefaultCached>false</IsDefaultCached>
|
||||
<IsGroupRole>false</IsGroupRole>
|
||||
<StoredVmQuota>1</StoredVmQuota>
|
||||
<DeployedVmQuota>1</DeployedVmQuota>
|
||||
<Role type="application/vnd.vmware.admin.role+xml" name="vApp User" href="https://vcloudbeta.bluelock.com/api/admin/role/ff1e0c91-1288-3664-82b7-a6fa303af4d1"/>
|
||||
<GroupReferences/>
|
||||
</User>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<User name="test" id="urn:vcloud:user:b37223f3-8792-477a-820f-334998f61cd6" type="application/vnd.vmware.admin.user+xml" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6" xmlns="http://www.vmware.com/vcloud/v1.5">
|
||||
<Link rel="edit" type="application/vnd.vmware.admin.user+xml" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"/>
|
||||
<Link rel="remove" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"/>
|
||||
<FullName>newtestFullName</FullName>
|
||||
<EmailAddress>newtest@test.com</EmailAddress>
|
||||
<Telephone>1-555-1234</Telephone>
|
||||
<IsEnabled>true</IsEnabled>
|
||||
<IsLocked>false</IsLocked>
|
||||
<IM>newtestIM</IM>
|
||||
<NameInSource>test</NameInSource>
|
||||
<IsAlertEnabled>true</IsAlertEnabled>
|
||||
<AlertEmailPrefix>newtestPrefix</AlertEmailPrefix>
|
||||
<AlertEmail>newtestAlert@test.com</AlertEmail>
|
||||
<IsExternal>false</IsExternal>
|
||||
<IsDefaultCached>false</IsDefaultCached>
|
||||
<IsGroupRole>false</IsGroupRole>
|
||||
<StoredVmQuota>1</StoredVmQuota>
|
||||
<DeployedVmQuota>1</DeployedVmQuota>
|
||||
<Role type="application/vnd.vmware.admin.role+xml" name="vApp User" href="https://vcloudbeta.bluelock.com/api/admin/role/ff1e0c91-1288-3664-82b7-a6fa303af4d1"/>
|
||||
<Password>newPassword</Password>
|
||||
<GroupReferences/>
|
||||
</User>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<User xmlns="http://www.vmware.com/vcloud/v1.5" name="test" id="urn:vcloud:user:b37223f3-8792-477a-820f-334998f61cd6" type="application/vnd.vmware.admin.user+xml" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://vcloudbeta.bluelock.com/api/v1.5/schema/master.xsd">
|
||||
<Link rel="edit" type="application/vnd.vmware.admin.user+xml" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"/>
|
||||
<Link rel="remove" href="https://vcloudbeta.bluelock.com/api/admin/user/b37223f3-8792-477a-820f-334998f61cd6"/>
|
||||
<FullName>testFullName</FullName>
|
||||
<EmailAddress>test@test.com</EmailAddress>
|
||||
<Telephone>555-1234</Telephone>
|
||||
<IsEnabled>false</IsEnabled>
|
||||
<IsLocked>false</IsLocked>
|
||||
<IM>testIM</IM>
|
||||
<NameInSource>test</NameInSource>
|
||||
<IsAlertEnabled>false</IsAlertEnabled>
|
||||
<AlertEmailPrefix>testPrefix</AlertEmailPrefix>
|
||||
<AlertEmail>testAlert@test.com</AlertEmail>
|
||||
<IsExternal>false</IsExternal>
|
||||
<IsDefaultCached>false</IsDefaultCached>
|
||||
<IsGroupRole>false</IsGroupRole>
|
||||
<StoredVmQuota>0</StoredVmQuota>
|
||||
<DeployedVmQuota>0</DeployedVmQuota>
|
||||
<Role type="application/vnd.vmware.admin.role+xml" name="vApp User" href="https://vcloudbeta.bluelock.com/api/admin/role/ff1e0c91-1288-3664-82b7-a6fa303af4d1"/>
|
||||
<GroupReferences/>
|
||||
</User>
|
|
@ -19,18 +19,16 @@
|
|||
|
||||
package org.jclouds.virtualbox;
|
||||
|
||||
import static org.jclouds.Constants.*;
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.Constants.PROPERTY_IDENTITY;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_IMAGE_AUTHENTICATE_SUDO;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_IMAGE_LOGIN_USER;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_DIR;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.*;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
|
@ -60,11 +58,9 @@ public class VirtualBoxPropertiesBuilder extends PropertiesBuilder {
|
|||
properties.put(PROPERTY_API_VERSION, "4.1.4");
|
||||
|
||||
properties.put(PROPERTY_BUILD_VERSION, "4.1.8r75467");
|
||||
properties.put(PROPERTY_IDENTITY, "toor");
|
||||
properties.put(PROPERTY_CREDENTIAL, "password");
|
||||
|
||||
properties.put(PROPERTY_IMAGE_LOGIN_USER, "toor:password");
|
||||
properties.put(PROPERTY_IMAGE_AUTHENTICATE_SUDO, "true");
|
||||
|
||||
|
||||
properties.put(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, "<Esc><Esc><Enter> "
|
||||
+ "/install/vmlinuz noapic preseed/url=PRECONFIGURATION_URL "
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/**
|
||||
* 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.virtualbox.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Name: en1: Wi-Fi (AirPort) GUID: 00316e65-0000-4000-8000-28cfdaf2917a Dhcp:
|
||||
* Disabled IPAddress: 192.168.57.1 NetworkMask: 255.255.255.0 IPV6Address:
|
||||
* IPV6NetworkMaskPrefixLength: 0 HardwareAddress: 28:cf:da:f2:91:7a MediumType:
|
||||
* Ethernet Status: Up VBoxNetworkName: HostInterfaceNetworking-en1: Wi-Fi
|
||||
* (AirPort)
|
||||
*
|
||||
* @author Andrea Turli
|
||||
*
|
||||
*/
|
||||
public class BridgedIf {
|
||||
|
||||
private final String name;
|
||||
private final String guid;
|
||||
private final String dhcp;
|
||||
private final String ipAddress;
|
||||
private final String networkMask;
|
||||
private final String ipv6Address;
|
||||
private final String ipv6NetworkMask;
|
||||
private final String mediumType;
|
||||
private final String status;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private String name;
|
||||
private String guid;
|
||||
private String dhcp;
|
||||
private String ipAddress;
|
||||
private String networkMask;
|
||||
private String ipv6Address;
|
||||
private String iv6NetworkMask;
|
||||
private String mediumType;
|
||||
private String status;
|
||||
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder guid(String guid) {
|
||||
this.guid = guid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder dhcp(String dhcp) {
|
||||
this.dhcp = dhcp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder ip(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder networkMask(String networkMask) {
|
||||
this.networkMask = networkMask;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder ipv6(String ipv6Address) {
|
||||
this.ipv6Address = ipv6Address;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder ipv6networkMask(String iv6NetworkMask) {
|
||||
this.iv6NetworkMask = iv6NetworkMask;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder mediumType(String mediumType) {
|
||||
this.mediumType = mediumType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder status(String status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BridgedIf build() {
|
||||
return new BridgedIf(name, guid, dhcp, ipAddress, networkMask,
|
||||
ipv6Address, iv6NetworkMask, mediumType, status);
|
||||
}
|
||||
}
|
||||
|
||||
public BridgedIf(String name, String guid, String dhcp, String ipAddress,
|
||||
String networkMask, String ipv6Address, String iv6NetworkMask,
|
||||
String mediumType, String status) {
|
||||
this.name = checkNotNull(name, "bridgedIf name");
|
||||
this.guid = guid;
|
||||
this.dhcp = dhcp;
|
||||
this.ipAddress = checkNotNull(ipAddress, "bridgedIf ipAddress");
|
||||
this.networkMask = networkMask;
|
||||
this.ipv6Address = ipv6Address;
|
||||
this.ipv6NetworkMask = iv6NetworkMask;
|
||||
this.mediumType = mediumType;
|
||||
this.status = checkNotNull(status, "bridgedIf status");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getGuid() {
|
||||
return guid;
|
||||
}
|
||||
|
||||
public String getDhcp() {
|
||||
return dhcp;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public String getNetworkMask() {
|
||||
return networkMask;
|
||||
}
|
||||
|
||||
public String getIpv6Address() {
|
||||
return ipv6Address;
|
||||
}
|
||||
|
||||
public String getIpv6NetworkMask() {
|
||||
return ipv6NetworkMask;
|
||||
}
|
||||
|
||||
public String getMediumType() {
|
||||
return mediumType;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o instanceof VmSpec) {
|
||||
BridgedIf other = (BridgedIf) o;
|
||||
return Objects.equal(name, other.name)
|
||||
&& Objects.equal(guid, other.guid)
|
||||
&& Objects.equal(dhcp, other.dhcp)
|
||||
&& Objects.equal(ipAddress, other.ipAddress)
|
||||
&& Objects.equal(networkMask, other.networkMask)
|
||||
&& Objects.equal(ipv6Address, other.ipv6Address)
|
||||
&& Objects.equal(ipv6NetworkMask, other.ipv6NetworkMask)
|
||||
&& Objects.equal(mediumType, other.mediumType)
|
||||
&& Objects.equal(status, other.status);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(name, guid, dhcp, ipAddress, networkMask, ipv6Address, ipv6NetworkMask, mediumType, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BridgedIf{" +
|
||||
"name=" + name +
|
||||
", dhcp=" + dhcp +
|
||||
", ipAddress=" + ipAddress +
|
||||
", networkMask=" + networkMask +
|
||||
", ipv6Address=" + ipv6Address +
|
||||
", ipv6NetworkMask=" + ipv6NetworkMask +
|
||||
", mediumType=" + mediumType +
|
||||
", status=" + status +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
|
@ -117,6 +117,6 @@ public class CloneSpec {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IMachineSpec{" + "vmSpec= " + vmSpec + ", networkSpec= " + networkSpec + '}';
|
||||
return "CloneSpec{" + "vmSpec= " + vmSpec + ", networkSpec= " + networkSpec + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* 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.virtualbox.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
@Singleton
|
||||
public class BridgedIfStringToBridgedIf implements Function<String, BridgedIf> {
|
||||
|
||||
private static final String BRIDGED_IF_STATUS = "Status";
|
||||
private static final String BRIDGED_IF_MEDIUM_TYPE = "MediumType";
|
||||
private static final String BRIDGED_IF_NETWORK_MASK = "NetworkMask";
|
||||
private static final String BRIDGED_IF_IP_ADDRESS = "IPAddress";
|
||||
private static final String BRIDGED_IF_GUID = "GUID";
|
||||
private static final String BRIDGED_IF_NAME = "Name";
|
||||
|
||||
@Inject
|
||||
public BridgedIfStringToBridgedIf() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BridgedIf apply(String rawBridgedIf) {
|
||||
checkNotNull(rawBridgedIf, "rawBridgedIf");
|
||||
|
||||
String transformedBridgedIf = transformRawBridgedIf(rawBridgedIf);
|
||||
Map<String, String> bridegedIfMap = Splitter.on("\n")
|
||||
.omitEmptyStrings().withKeyValueSeparator("=")
|
||||
.split(transformedBridgedIf);
|
||||
|
||||
return BridgedIf
|
||||
.builder()
|
||||
.name(getValueFromMap(bridegedIfMap, BRIDGED_IF_NAME))
|
||||
.guid(getValueFromMap(bridegedIfMap, BRIDGED_IF_GUID))
|
||||
.ip(getValueFromMap(bridegedIfMap, BRIDGED_IF_IP_ADDRESS))
|
||||
.networkMask(getValueFromMap(bridegedIfMap, BRIDGED_IF_NETWORK_MASK))
|
||||
.mediumType(getValueFromMap(bridegedIfMap, BRIDGED_IF_MEDIUM_TYPE))
|
||||
.status(getValueFromMap(bridegedIfMap, BRIDGED_IF_STATUS))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String getValueFromMap(Map<String, String> map, String key) {
|
||||
return map.get(key).trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an helper to simplify the split step of the raw bridgedIf
|
||||
* Substitute first ':' with '='
|
||||
*
|
||||
* @param rawBridgedIf
|
||||
* @return
|
||||
*/
|
||||
private String transformRawBridgedIf(String rawBridgedIf) {
|
||||
Iterable<String> transformedLines = Iterables.transform(
|
||||
Splitter.on("\n").split(rawBridgedIf),
|
||||
new Function<String, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(String line) {
|
||||
return line.replaceFirst(":", "=");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
for (String line : transformedLines) {
|
||||
stringBuilder.append(line + "\n");
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -33,18 +33,15 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.virtualbox.Preconfiguration;
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.jclouds.virtualbox.domain.IsoSpec;
|
||||
import org.jclouds.virtualbox.domain.MasterSpec;
|
||||
import org.jclouds.virtualbox.domain.VmSpec;
|
||||
import org.jclouds.virtualbox.predicates.GuestAdditionsInstaller;
|
||||
import org.jclouds.virtualbox.util.MachineController;
|
||||
import org.jclouds.virtualbox.util.MachineUtils;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.LockType;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
import org.virtualbox_4_1.jaxws.MachineState;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -56,124 +53,99 @@ import com.google.inject.Inject;
|
|||
@Singleton
|
||||
public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||
private final GuestAdditionsInstaller guestAdditionsInstaller;
|
||||
private final Predicate<SshClient> sshResponds;
|
||||
private final ExecutionType executionType;
|
||||
private LoadingCache<IsoSpec, URI> preConfiguration;
|
||||
private final Function<IMachine, SshClient> sshClientForIMachine;
|
||||
private final MachineUtils machineUtils;
|
||||
private final IMachineToNodeMetadata imachineToNodeMetadata;
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||
private final GuestAdditionsInstaller guestAdditionsInstaller;
|
||||
private final Predicate<SshClient> sshResponds;
|
||||
private LoadingCache<IsoSpec, URI> preConfiguration;
|
||||
private final Function<IMachine, SshClient> sshClientForIMachine;
|
||||
private final MachineUtils machineUtils;
|
||||
private final IMachineToNodeMetadata imachineToNodeMetadata;
|
||||
private final MachineController machineController;
|
||||
|
||||
|
||||
@Inject
|
||||
public CreateAndInstallVm(Supplier<VirtualBoxManager> manager,
|
||||
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
|
||||
GuestAdditionsInstaller guestAdditionsInstaller, IMachineToNodeMetadata imachineToNodeMetadata,
|
||||
Predicate<SshClient> sshResponds, Function<IMachine, SshClient> sshClientForIMachine,
|
||||
ExecutionType executionType, MachineUtils machineUtils,
|
||||
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration) {
|
||||
this.manager = manager;
|
||||
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||
this.sshResponds = sshResponds;
|
||||
this.sshClientForIMachine = sshClientForIMachine;
|
||||
this.executionType = executionType;
|
||||
this.machineUtils = machineUtils;
|
||||
this.preConfiguration = preConfiguration;
|
||||
this.guestAdditionsInstaller = guestAdditionsInstaller;
|
||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
||||
}
|
||||
@Inject
|
||||
public CreateAndInstallVm(
|
||||
Supplier<VirtualBoxManager> manager,
|
||||
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
|
||||
GuestAdditionsInstaller guestAdditionsInstaller,
|
||||
IMachineToNodeMetadata imachineToNodeMetadata,
|
||||
Predicate<SshClient> sshResponds,
|
||||
Function<IMachine, SshClient> sshClientForIMachine,
|
||||
MachineUtils machineUtils,
|
||||
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration, MachineController machineController) {
|
||||
this.manager = manager;
|
||||
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||
this.sshResponds = sshResponds;
|
||||
this.sshClientForIMachine = sshClientForIMachine;
|
||||
this.machineUtils = machineUtils;
|
||||
this.preConfiguration = preConfiguration;
|
||||
this.guestAdditionsInstaller = guestAdditionsInstaller;
|
||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
||||
this.machineController = machineController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMachine apply(MasterSpec masterSpec) {
|
||||
@Override
|
||||
public IMachine apply(MasterSpec masterSpec) {
|
||||
|
||||
VmSpec vmSpec = masterSpec.getVmSpec();
|
||||
IsoSpec isoSpec = masterSpec.getIsoSpec();
|
||||
String vmName = vmSpec.getVmName();
|
||||
VmSpec vmSpec = masterSpec.getVmSpec();
|
||||
IsoSpec isoSpec = masterSpec.getIsoSpec();
|
||||
String vmName = vmSpec.getVmName();
|
||||
|
||||
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec);
|
||||
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists
|
||||
.apply(masterSpec);
|
||||
|
||||
// Launch machine and wait for it to come online
|
||||
ensureMachineIsLaunched(vmName);
|
||||
// Launch machine and wait for it to come online
|
||||
machineController.ensureMachineIsLaunched(vmName);
|
||||
|
||||
URI uri = preConfiguration.getUnchecked(isoSpec);
|
||||
String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL",
|
||||
uri.toASCIIString());
|
||||
URI uri = preConfiguration.getUnchecked(isoSpec);
|
||||
String installationKeySequence = isoSpec.getInstallationKeySequence()
|
||||
.replace("PRECONFIGURATION_URL", uri.toASCIIString());
|
||||
|
||||
configureOsInstallationWithKeyboardSequence(vmName, installationKeySequence);
|
||||
SshClient client = sshClientForIMachine.apply(vm);
|
||||
|
||||
logger.debug(">> awaiting installation to finish node(%s)", vmName);
|
||||
configureOsInstallationWithKeyboardSequence(vmName,
|
||||
installationKeySequence);
|
||||
SshClient client = sshClientForIMachine.apply(vm);
|
||||
|
||||
checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh", vmName);
|
||||
logger.debug(">> awaiting installation to finish node(%s)", vmName);
|
||||
|
||||
logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
|
||||
checkState(sshResponds.apply(client),
|
||||
"timed out waiting for guest %s to be accessible via ssh",
|
||||
vmName);
|
||||
|
||||
checkState(guestAdditionsInstaller.apply(vm));
|
||||
//logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
|
||||
//checkState(guestAdditionsInstaller.apply(vm));
|
||||
|
||||
logger.debug(">> awaiting post-installation actions on vm: %s", vmName);
|
||||
logger.debug(">> awaiting post-installation actions on vm: %s", vmName);
|
||||
|
||||
NodeMetadata vmMetadata = imachineToNodeMetadata.apply(vm);
|
||||
|
||||
// TODO for now this is executed on installModuleAssistantIfNeeded as a workaround to some transient execution issue.
|
||||
// ListenableFuture<ExecResponse> execFuture = machineUtils.runScriptOnNode(vmMetadata, call("cleanupUdevIfNeeded"),
|
||||
// RunScriptOptions.NONE);
|
||||
|
||||
// ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
||||
// checkState(execResponse.getExitCode() == 0);
|
||||
NodeMetadata vmMetadata = imachineToNodeMetadata.apply(vm);
|
||||
|
||||
logger.debug("<< installation of image complete. Powering down node(%s)", vmName);
|
||||
ListenableFuture<ExecResponse> execFuture =
|
||||
machineUtils.runScriptOnNode(vmMetadata, call("cleanupUdevIfNeeded"), RunScriptOptions.NONE);
|
||||
|
||||
ensureMachineHasPowerDown(vmName);
|
||||
return vm;
|
||||
}
|
||||
ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
||||
checkState(execResponse.getExitStatus() == 0);
|
||||
|
||||
private void configureOsInstallationWithKeyboardSequence(String vmName, String installationKeySequence) {
|
||||
Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ").split(installationKeySequence),
|
||||
new StringToKeyCode());
|
||||
logger.debug(
|
||||
"<< installation of image complete. Powering down node(%s)",
|
||||
vmName);
|
||||
|
||||
for (List<Integer> scancodes : scancodelist) {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new SendScancodes(scancodes));
|
||||
}
|
||||
}
|
||||
machineController.ensureMachineHasPowerDown(vmName);
|
||||
return vm;
|
||||
}
|
||||
|
||||
/**
|
||||
* ensureMachineHasPowerDown needs to have this delay just to ensure that the machine is
|
||||
* completely powered off
|
||||
*
|
||||
* @param vmName
|
||||
*/
|
||||
private void ensureMachineHasPowerDown(String vmName) {
|
||||
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
|
||||
try {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole().powerDown();
|
||||
powerDownProgress.waitForCompletion(-1);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
// sometimes the machine might be powered of between the while test and the call to
|
||||
// lockSessionOnMachineAndApply
|
||||
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
|
||||
return;
|
||||
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
|
||||
continue;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void configureOsInstallationWithKeyboardSequence(String vmName,
|
||||
String installationKeySequence) {
|
||||
Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ")
|
||||
.split(installationKeySequence), new StringToKeyCode());
|
||||
|
||||
private void ensureMachineIsLaunched(String vmName) {
|
||||
machineUtils.applyForMachine(vmName, new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType, ""));
|
||||
}
|
||||
for (List<Integer> scancodes : scancodelist) {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared,
|
||||
new SendScancodes(scancodes));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,58 +19,123 @@
|
|||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||
import org.jclouds.virtualbox.statements.GetIPAddressFromMAC;
|
||||
import org.jclouds.virtualbox.statements.ScanNetworkWithPing;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.INetworkAdapter;
|
||||
import org.virtualbox_4_1.NetworkAttachmentType;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
@Singleton
|
||||
public class IMachineToSshClient implements Function<IMachine, SshClient> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final SshClient.Factory sshClientFactory;
|
||||
private final SshClient.Factory sshClientFactory;
|
||||
private final RunScriptOnNode.Factory scriptRunnerFactory;
|
||||
private final Supplier<NodeMetadata> hostSupplier;
|
||||
|
||||
@Inject
|
||||
public IMachineToSshClient(SshClient.Factory sshClientFactory) {
|
||||
this.sshClientFactory = sshClientFactory;
|
||||
}
|
||||
@Inject
|
||||
public IMachineToSshClient(SshClient.Factory sshClientFactory,
|
||||
RunScriptOnNode.Factory scriptRunnerFactory,
|
||||
Supplier<NodeMetadata> hostSupplier) {
|
||||
this.sshClientFactory = sshClientFactory;
|
||||
this.scriptRunnerFactory = scriptRunnerFactory;
|
||||
this.hostSupplier = hostSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SshClient apply(final IMachine vm) {
|
||||
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L);
|
||||
@Override
|
||||
public SshClient apply(final IMachine vm) {
|
||||
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L);
|
||||
|
||||
SshClient client = null;
|
||||
checkNotNull(networkAdapter);
|
||||
for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter.getNatDriver().getRedirects()) {
|
||||
Iterable<String> stuff = Splitter.on(',').split(nameProtocolnumberAddressInboudportGuestTargetport);
|
||||
String protocolNumber = Iterables.get(stuff, 1);
|
||||
String hostAddress = Iterables.get(stuff, 2);
|
||||
String inboundPort = Iterables.get(stuff, 3);
|
||||
String targetPort = Iterables.get(stuff, 5);
|
||||
// TODO: we need a way to align the default login credentials from the iso with the
|
||||
// vmspec
|
||||
if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
|
||||
client = sshClientFactory.create(new IPSocket(hostAddress, Integer.parseInt(inboundPort)), LoginCredentials
|
||||
.builder().user("toor").password("password").authenticateSudo(true).build());
|
||||
}
|
||||
}
|
||||
checkNotNull(client);
|
||||
return client;
|
||||
}
|
||||
SshClient client = null;
|
||||
checkNotNull(networkAdapter);
|
||||
|
||||
String clientIpAddress = null;
|
||||
String sshPort = "22";
|
||||
|
||||
// TODO: we need a way to align the default login credentials
|
||||
// from the iso with the vmspec -> IMachineToNodeMetadata using YamlImage ?
|
||||
LoginCredentials loginCredentials = LoginCredentials.builder()
|
||||
.user("toor").password("password").authenticateSudo(true)
|
||||
.build();
|
||||
|
||||
if (networkAdapter.getAttachmentType()
|
||||
.equals(NetworkAttachmentType.NAT)) {
|
||||
for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter
|
||||
.getNatDriver().getRedirects()) {
|
||||
Iterable<String> stuff = Splitter.on(',').split(
|
||||
nameProtocolnumberAddressInboudportGuestTargetport);
|
||||
String protocolNumber = Iterables.get(stuff, 1);
|
||||
String hostAddress = Iterables.get(stuff, 2);
|
||||
String inboundPort = Iterables.get(stuff, 3);
|
||||
String targetPort = Iterables.get(stuff, 5);
|
||||
if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
|
||||
clientIpAddress = hostAddress;
|
||||
sshPort = inboundPort;
|
||||
}
|
||||
}
|
||||
} else if (networkAdapter.getAttachmentType().equals(
|
||||
NetworkAttachmentType.Bridged)) {
|
||||
String network = "1.1.1.1";
|
||||
clientIpAddress = getIpAddressFromBridgedNIC(networkAdapter, network);
|
||||
}
|
||||
|
||||
checkNotNull(clientIpAddress, "clientIpAddress");
|
||||
client = sshClientFactory.create(
|
||||
new IPSocket(clientIpAddress, Integer.parseInt(sshPort)),
|
||||
loginCredentials);
|
||||
checkNotNull(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
private String getIpAddressFromBridgedNIC(INetworkAdapter networkAdapter,
|
||||
String network) {
|
||||
// RetrieveActiveBridgedInterfaces
|
||||
List<BridgedIf> activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(scriptRunnerFactory).apply(hostSupplier.get());
|
||||
BridgedIf activeBrigedIf = checkNotNull(Iterables.get(activeBridgedInterfaces, 0), "activeBridgrdIf");
|
||||
network = activeBrigedIf.getIpAddress();
|
||||
|
||||
// scan ip
|
||||
RunScriptOnNode ipScanRunScript = scriptRunnerFactory.create(
|
||||
hostSupplier.get(), new ScanNetworkWithPing(network),
|
||||
RunScriptOptions.NONE);
|
||||
ExecResponse execResponse = ipScanRunScript.init().call();
|
||||
checkState(execResponse.getExitStatus() == 0);
|
||||
|
||||
// retrieve ip from mac
|
||||
RunScriptOnNode getIpFromMACAddressRunScript = scriptRunnerFactory
|
||||
.create(hostSupplier.get(), new GetIPAddressFromMAC(
|
||||
networkAdapter.getMACAddress()),
|
||||
RunScriptOptions.NONE);
|
||||
ExecResponse ipExecResponse = getIpFromMACAddressRunScript.init()
|
||||
.call();
|
||||
checkState(ipExecResponse.getExitStatus() == 0);
|
||||
return checkNotNull(ipExecResponse.getOutput(), "ipAddress");
|
||||
}
|
||||
}
|
|
@ -23,15 +23,18 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||
import org.jclouds.virtualbox.domain.CloneSpec;
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.jclouds.virtualbox.domain.Master;
|
||||
|
@ -65,33 +68,34 @@ public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials
|
|||
|
||||
// TODO parameterize
|
||||
public static final boolean USE_LINKED = true;
|
||||
|
||||
// TODO parameterize
|
||||
public static final ExecutionType executionType = ExecutionType.GUI;
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final Function<CloneSpec, IMachine> cloner;
|
||||
private final AtomicInteger nodes;
|
||||
private final AtomicInteger nodePorts;
|
||||
private final AtomicInteger nodeIps;
|
||||
private MachineUtils machineUtils;
|
||||
private Function<IMachine, NodeMetadata> imachineToNodeMetadata;
|
||||
|
||||
private final RunScriptOnNode.Factory scriptRunnerFactory;
|
||||
private final Supplier<NodeMetadata> hostSupplier;
|
||||
|
||||
@Inject
|
||||
public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner,
|
||||
MachineUtils machineUtils, Function<IMachine, NodeMetadata> imachineToNodeMetadata) {
|
||||
MachineUtils machineUtils, Function<IMachine, NodeMetadata> imachineToNodeMetadata,
|
||||
RunScriptOnNode.Factory scriptRunnerFactory, Supplier<NodeMetadata> hostSupplier) {
|
||||
this.manager = manager;
|
||||
this.cloner = cloner;
|
||||
this.nodes = new AtomicInteger(0);
|
||||
this.nodePorts = new AtomicInteger(NODE_PORT_INIT);
|
||||
this.nodeIps = new AtomicInteger(1);
|
||||
this.machineUtils = machineUtils;
|
||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
||||
this.scriptRunnerFactory = scriptRunnerFactory;
|
||||
this.hostSupplier = hostSupplier;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a clone based on the {@link NodeSpec}. It is synchronized because it needs sole access
|
||||
* to the master. Could be improved by locking on a master basis (would allow concurrent cloning
|
||||
* as long as form different masters."
|
||||
*/
|
||||
@Override
|
||||
public synchronized NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
|
||||
public NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
|
||||
|
||||
checkNotNull(nodeSpec, "NodeSpec");
|
||||
|
||||
|
@ -108,7 +112,6 @@ public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials
|
|||
session.getConsole().deleteSnapshot(master.getMachine().getCurrentSnapshot().getId());
|
||||
session.unlockMachine();
|
||||
}
|
||||
|
||||
String masterNameWithoutPrefix = master.getSpec().getVmSpec().getVmName().replace(VIRTUALBOX_IMAGE_PREFIX, "");
|
||||
|
||||
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix + "-" + nodeSpec.getTag() + "-"
|
||||
|
@ -117,33 +120,59 @@ public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials
|
|||
VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full)
|
||||
.forceOverwrite(true).build();
|
||||
|
||||
// CASE NAT + HOST-ONLY
|
||||
NetworkAdapter natAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
|
||||
.tcpRedirectRule("127.0.0.1", NODE_PORT_INIT + this.nodes.getAndIncrement(), "", 22).build();
|
||||
|
||||
.tcpRedirectRule("127.0.0.1", this.nodePorts.getAndIncrement(), "", 22).build();
|
||||
NetworkInterfaceCard natIfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(natAdapter).slot(0L).build();
|
||||
|
||||
NetworkAdapter hostOnlyAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.HostOnly)
|
||||
.staticIp(VMS_NETWORK + this.nodes.getAndIncrement()).build();
|
||||
.staticIp(VMS_NETWORK + this.nodeIps.getAndIncrement()).build();
|
||||
|
||||
NetworkInterfaceCard hostOnlyIfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(hostOnlyAdapter)
|
||||
.addHostInterfaceName(HOST_ONLY_IFACE_NAME).slot(1L).build();
|
||||
|
||||
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(natIfaceCard).addNIC(hostOnlyIfaceCard).build();
|
||||
NetworkSpec networkSpec = createNetworkSpecForHostOnlyNATNICs(natIfaceCard, hostOnlyIfaceCard);
|
||||
// //
|
||||
|
||||
// CASE BRIDGED
|
||||
// NetworkSpec networkSpec = createNetworkSpecForBridgedNIC();
|
||||
|
||||
CloneSpec cloneSpec = CloneSpec.builder().linked(USE_LINKED).master(master.getMachine()).network(networkSpec)
|
||||
.vm(cloneVmSpec).build();
|
||||
|
||||
IMachine cloned = cloner.apply(cloneSpec);
|
||||
|
||||
new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType, "").apply(cloned);
|
||||
new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, "").apply(cloned);
|
||||
|
||||
// CASE NAT + HOST-ONLY
|
||||
machineUtils.runScriptOnNode(imachineToNodeMetadata.apply(cloned), new SetIpAddress(hostOnlyIfaceCard),
|
||||
RunScriptOptions.NONE);
|
||||
// //
|
||||
|
||||
// TODO get credentials from somewhere else (they are also HC in IMachineToSshClient)
|
||||
// TODO get credentials from somewhere else (they are also HC in
|
||||
// IMachineToSshClient)
|
||||
NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(cloned,
|
||||
cloneName, LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build());
|
||||
|
||||
return nodeAndInitialCredentials;
|
||||
}
|
||||
|
||||
private NetworkSpec createNetworkSpecForHostOnlyNATNICs(NetworkInterfaceCard natIfaceCard,
|
||||
NetworkInterfaceCard hostOnlyIfaceCard) {
|
||||
return NetworkSpec.builder().addNIC(natIfaceCard).addNIC(hostOnlyIfaceCard).build();
|
||||
}
|
||||
|
||||
private NetworkSpec createNetworkSpecForBridgedNIC() {
|
||||
List<BridgedIf> activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(scriptRunnerFactory)
|
||||
.apply(hostSupplier.get());
|
||||
BridgedIf bridgedActiveInterface = checkNotNull(activeBridgedInterfaces.get(0), "activeBridgedIf");
|
||||
|
||||
NetworkAdapter bridgedAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.Bridged)
|
||||
.build();
|
||||
NetworkInterfaceCard bridgedNIC = NetworkInterfaceCard.builder().addNetworkAdapter(bridgedAdapter)
|
||||
.addHostInterfaceName(bridgedActiveInterface.getName()).slot(0L).build();
|
||||
|
||||
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(bridgedNIC).build();
|
||||
return networkSpec;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -50,67 +51,56 @@ import com.google.inject.name.Named;
|
|||
/**
|
||||
* @author Andrea Turli
|
||||
*/
|
||||
public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, List<String>> {
|
||||
public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, List<BridgedIf>> {
|
||||
|
||||
@Resource
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Factory runScriptOnNodeFactory;
|
||||
|
||||
@Inject
|
||||
public RetrieveActiveBridgedInterfaces(Factory runScriptOnNodeFactory) {
|
||||
public RetrieveActiveBridgedInterfaces(Factory runScriptOnNodeFactory) {
|
||||
this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> apply(NodeMetadata host) {
|
||||
public List<BridgedIf> apply(NodeMetadata host) {
|
||||
// Bridged Network
|
||||
Statement command = Statements.exec("VBoxManage list bridgedifs");
|
||||
String bridgedIfBlocks = runScriptOnNodeFactory.create(host, command, runAsRoot(false).wrapInInitScript(false))
|
||||
.init().call().getOutput();
|
||||
|
||||
List<String> bridgedInterfaces = retrieveBridgedInterfaceNames(bridgedIfBlocks);
|
||||
List<BridgedIf> bridgedInterfaces = retrieveBridgedInterfaceNames(bridgedIfBlocks);
|
||||
checkNotNull(bridgedInterfaces);
|
||||
|
||||
// union of bridgedNetwork with inet up and !loopback
|
||||
List<String> activeNetworkInterfaceNames = Lists.newArrayList();
|
||||
List<BridgedIf> activeNetworkInterfaces = Lists.newArrayList();
|
||||
try {
|
||||
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
|
||||
for (NetworkInterface inet : Collections.list(nets)) {
|
||||
Iterable<String> filteredBridgedInterface = filter(bridgedInterfaces, new IsActiveBridgedInterface(inet));
|
||||
Iterables.addAll(activeNetworkInterfaceNames, filteredBridgedInterface);
|
||||
Iterable<BridgedIf> filteredBridgedInterface = filter(bridgedInterfaces, new IsActiveBridgedInterface(inet));
|
||||
Iterables.addAll(activeNetworkInterfaces, filteredBridgedInterface);
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
logger.error(e, "Problem in listing network interfaces.");
|
||||
Throwables.propagate(e);
|
||||
assert false;
|
||||
}
|
||||
return activeNetworkInterfaceNames;
|
||||
return activeNetworkInterfaces;
|
||||
}
|
||||
|
||||
protected static List<String> retrieveBridgedInterfaceNames(String bridgedIfBlocks) {
|
||||
List<String> bridgedInterfaceNames = Lists.newArrayList();
|
||||
protected static List<BridgedIf> retrieveBridgedInterfaceNames(String bridgedIfBlocks) {
|
||||
List<BridgedIf> bridgedInterfaces = Lists.newArrayList();
|
||||
// separate the different bridge block
|
||||
for (String bridgedIfBlock : Splitter.on(Pattern.compile("(?m)^[ \t]*\r?\n")).split(bridgedIfBlocks)) {
|
||||
|
||||
Iterable<String> bridgedIfName = filter(Splitter.on("\n").split(bridgedIfBlock), new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String arg0) {
|
||||
return arg0.startsWith("Name:");
|
||||
}
|
||||
});
|
||||
for (String bridgedInterfaceName : bridgedIfName) {
|
||||
for (String string : Splitter.on("Name:").split(bridgedInterfaceName)) {
|
||||
if (!string.isEmpty())
|
||||
bridgedInterfaceNames.add(string.trim());
|
||||
}
|
||||
}
|
||||
if(!bridgedIfBlock.isEmpty())
|
||||
bridgedInterfaces.add(new BridgedIfStringToBridgedIf().apply(bridgedIfBlock));
|
||||
}
|
||||
return bridgedInterfaceNames;
|
||||
return bridgedInterfaces;
|
||||
}
|
||||
|
||||
private class IsActiveBridgedInterface implements Predicate<String> {
|
||||
private class IsActiveBridgedInterface implements Predicate<BridgedIf> {
|
||||
|
||||
private NetworkInterface networkInterface;
|
||||
|
||||
|
@ -119,10 +109,12 @@ public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, L
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(String bridgedInterfaceName) {
|
||||
public boolean apply(BridgedIf bridgedInterface) {
|
||||
try {
|
||||
return (bridgedInterfaceName.startsWith(networkInterface.getDisplayName()) && networkInterface.isUp() && !networkInterface
|
||||
.isLoopback());
|
||||
return (bridgedInterface.getName().startsWith(networkInterface.getDisplayName()) &&
|
||||
bridgedInterface.getStatus().equals("Up") &&
|
||||
networkInterface.isUp() &&
|
||||
!networkInterface.isLoopback());
|
||||
} catch (SocketException e) {
|
||||
logger.error(e, "Problem in listing network interfaces.");
|
||||
Throwables.propagate(e);
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -58,8 +59,8 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
|
|||
private final RetryIfSocketNotYetOpen socketTester;
|
||||
private final Supplier<NodeMetadata> host;
|
||||
private final Supplier<URI> providerSupplier;
|
||||
private final String identity;
|
||||
private final String credential;
|
||||
// private final String identity;
|
||||
// private final String credential;
|
||||
private final Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode;
|
||||
private transient VirtualBoxManager manager;
|
||||
|
||||
|
@ -67,14 +68,15 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
|
|||
@Inject
|
||||
public StartVBoxIfNotAlreadyRunning(Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode,
|
||||
Factory runScriptOnNodeFactory, RetryIfSocketNotYetOpen socketTester, Supplier<NodeMetadata> host,
|
||||
@Provider Supplier<URI> providerSupplier, @Identity String identity, @Credential String credential) {
|
||||
@Provider Supplier<URI> providerSupplier, @Nullable @Identity String identity,
|
||||
@Nullable @Credential String credential) {
|
||||
this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
|
||||
this.socketTester = checkNotNull(socketTester, "socketTester");
|
||||
this.socketTester.seconds(3L);
|
||||
this.host = checkNotNull(host, "host");
|
||||
this.providerSupplier = checkNotNull(providerSupplier, "endpoint to virtualbox websrvd is needed");
|
||||
this.identity = checkNotNull(identity, "identity");
|
||||
this.credential = checkNotNull(credential, "credential");
|
||||
// this.identity = checkNotNull(identity, "identity");
|
||||
// this.credential = checkNotNull(credential, "credential");
|
||||
this.managerForNode = checkNotNull(managerForNode, "managerForNode");
|
||||
}
|
||||
|
||||
|
@ -99,7 +101,7 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
|
|||
}
|
||||
}
|
||||
manager = managerForNode.apply(host);
|
||||
manager.connect(provider.toASCIIString(), identity, credential);
|
||||
manager.connect(provider.toASCIIString(), "", "");
|
||||
if (logger.isDebugEnabled())
|
||||
if (manager.getSessionObject().getState() != SessionState.Unlocked)
|
||||
logger.warn("manager is not in unlocked state " + manager.getSessionObject().getState());
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/**
|
||||
* 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.virtualbox.predicates;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* 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.virtualbox.util;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.jclouds.virtualbox.functions.LaunchMachineIfNotAlreadyRunning;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.LockType;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
import org.virtualbox_4_1.jaxws.MachineState;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Utilities to manage VirtualBox machine life cycle.
|
||||
*
|
||||
* @author Adrian Cole, Mattias Holmqvist, Andrea Turli
|
||||
*/
|
||||
|
||||
@Singleton
|
||||
public class MachineController {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final MachineUtils machineUtils;
|
||||
private final ExecutionType executionType;
|
||||
|
||||
|
||||
@Inject
|
||||
public MachineController(Supplier<VirtualBoxManager> manager, MachineUtils machineUtils, ExecutionType executionType) {
|
||||
this.manager = manager;
|
||||
this.machineUtils = machineUtils;
|
||||
this.executionType = executionType;
|
||||
}
|
||||
|
||||
public void ensureMachineIsLaunched(String vmName) {
|
||||
machineUtils.applyForMachine(vmName, new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType, ""));
|
||||
}
|
||||
|
||||
public void ensureMachineHasPowerDown(String vmName) {
|
||||
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
|
||||
try {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole().powerDown();
|
||||
powerDownProgress.waitForCompletion(-1);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
// sometimes the machine might be powered of between the while test and the call to
|
||||
// lockSessionOnMachineAndApply
|
||||
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
|
||||
return;
|
||||
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
|
||||
continue;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
function cleanupUdevIfNeeded {
|
||||
unset OSNAME;
|
||||
local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
|
||||
if [ $OSNAME = 'Ubuntu' ]
|
||||
# unset OSNAME;
|
||||
# local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
|
||||
# if [ $OSNAME = 'Ubuntu' ]
|
||||
if [ -f '/etc/udev/rules.d/70-persistent-net.rules']
|
||||
then
|
||||
echo "OS is Ubuntu"
|
||||
rm /etc/udev/rules.d/70-persistent-net.rules;
|
||||
mkdir /etc/udev/rules.d/70-persistent-net.rules;
|
||||
rm -rf /dev/.udev/;
|
||||
|
|
|
@ -30,14 +30,11 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.byon.Node;
|
||||
import org.jclouds.byon.config.CacheNodeStoreModule;
|
||||
import org.jclouds.compute.BaseVersionedServiceLiveTest;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
||||
import org.jclouds.concurrent.MoreExecutors;
|
||||
|
@ -49,21 +46,16 @@ import org.jclouds.virtualbox.domain.IsoSpec;
|
|||
import org.jclouds.virtualbox.domain.Master;
|
||||
import org.jclouds.virtualbox.domain.VmSpec;
|
||||
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
|
||||
import org.jclouds.virtualbox.util.MachineController;
|
||||
import org.jclouds.virtualbox.util.MachineUtils;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.LockType;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
import org.virtualbox_4_1.jaxws.MachineState;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Module;
|
||||
|
@ -80,6 +72,9 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||
}
|
||||
|
||||
protected ComputeServiceContext context;
|
||||
|
||||
@Inject
|
||||
protected MachineController machineController;
|
||||
|
||||
@Inject
|
||||
protected Supplier<VirtualBoxManager> manager;
|
||||
|
@ -160,30 +155,7 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||
new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
|
||||
}
|
||||
|
||||
protected void ensureMachineHasPowerDown(String vmName) {
|
||||
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
|
||||
try {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole().powerDown();
|
||||
powerDownProgress.waitForCompletion(-1);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
// sometimes the machine might be powered of between the while test and the call to
|
||||
// lockSessionOnMachineAndApply
|
||||
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
|
||||
return;
|
||||
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
|
||||
continue;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String adminDisk(String vmName) {
|
||||
return workingDir + File.separator + vmName + ".vdi";
|
||||
|
|
|
@ -58,13 +58,13 @@ public class VirtualBoxExperimentLiveTest {
|
|||
|
||||
@BeforeClass
|
||||
public void setUp() {
|
||||
context = new ComputeServiceContextFactory().createContext("virtualbox", "toor", "password",
|
||||
context = new ComputeServiceContextFactory().createContext("virtualbox", "", "",
|
||||
ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchCluster() throws RunNodesException {
|
||||
int numNodes = 4;
|
||||
int numNodes = 1;
|
||||
final String clusterName = "test-launch-cluster";
|
||||
Set<? extends NodeMetadata> nodes = context.getComputeService().createNodesInGroup(clusterName, numNodes);
|
||||
assertEquals(numNodes, nodes.size(), "wrong number of nodes");
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test(groups = "live", singleThreaded = true, testName = "BridgedIfStringToBridgedIfTest")
|
||||
public class BridgedIfStringToBridgedIfTest {
|
||||
|
||||
private static final String en0 = "Name: en0: Ethernet\n" +
|
||||
"GUID: 00306e65-0000-4000-8000-3c0754205d2f\n" +
|
||||
"Dhcp: Disabled\n" +
|
||||
"IPAddress: 192.168.56.1\n" +
|
||||
"NetworkMask: 255.255.255.0\n" +
|
||||
"IPV6Address: \n" +
|
||||
"IPV6NetworkMaskPrefixLength: 0\n" +
|
||||
"HardwareAddress: 3c:07:54:20:5d:2f\n" +
|
||||
"MediumType: Ethernet\n" +
|
||||
"Status: Up\n" +
|
||||
"VBoxNetworkName: HostInterfaceNetworking-en0: Ethernet\n";
|
||||
|
||||
private static final String en1 = "Name: en1: Wi-Fi (AirPort)\n" +
|
||||
"GUID: 00316e65-0000-4000-8000-28cfdaf2917a\n" +
|
||||
"Dhcp: Disabled\n" +
|
||||
"IPAddress: 192.168.57.1\n" +
|
||||
"NetworkMask: 255.255.255.0\n" +
|
||||
"IPV6Address: \n" +
|
||||
"IPV6NetworkMaskPrefixLength: 0\n" +
|
||||
"HardwareAddress: 28:cf:da:f2:91:7a\n" +
|
||||
"MediumType: Ethernet\n" +
|
||||
"Status: Up\n" +
|
||||
"VBoxNetworkName: HostInterfaceNetworking-en1: Wi-Fi (AirPort)\n";
|
||||
|
||||
private static final String p2p0 = "Name: p2p0\n" +
|
||||
"GUID: 30703270-0000-4000-8000-0acfdaf2917a\n" +
|
||||
"Dhcp: Disabled\n" +
|
||||
"IPAddress: 192.168.58.1\n" +
|
||||
"NetworkMask: 255.255.255.0\n" +
|
||||
"IPV6Address: \n" +
|
||||
"IPV6NetworkMaskPrefixLength: 0\n" +
|
||||
"HardwareAddress: 0a:cf:da:f2:91:7a\n" +
|
||||
"MediumType: Ethernet\n" +
|
||||
"Status: Down\n" +
|
||||
"VBoxNetworkName: HostInterfaceNetworking-p2p0\n";
|
||||
|
||||
@Test
|
||||
public void transformRawBridgedifToBridgedIf() {
|
||||
BridgedIf bridgedIfEn1 = new BridgedIfStringToBridgedIf().apply(en1);
|
||||
assertEquals(bridgedIfEn1.getName(), "en1: Wi-Fi (AirPort)");
|
||||
}
|
||||
}
|
|
@ -26,8 +26,6 @@ import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTA
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
|
@ -153,21 +151,11 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
|
|||
}));
|
||||
} finally {
|
||||
for (VmSpec spec : ImmutableSet.of(vmSpecification)) {
|
||||
ensureMachineHasPowerDown(spec.getVmName());
|
||||
machineController.ensureMachineHasPowerDown(spec.getVmName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Function<Image, String> extractId() {
|
||||
return new Function<Image, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(@Nullable Image input) {
|
||||
return input.getId();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IMachine getVmWithGuestAdditionsInstalled() {
|
||||
try {
|
||||
Injector injector = context.utils().injector();
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.testng.Assert.assertFalse;
|
|||
import java.util.List;
|
||||
|
||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -51,13 +52,13 @@ public class RetrieveActiveBridgedInterfacesLiveTest extends BaseVirtualBoxClien
|
|||
|
||||
@Test
|
||||
public void retrieveBridgedInterfaceNamesTest() {
|
||||
List<String> activeBridgedInterfaceNames = retrieveBridgedInterfaceNames(TEST1);
|
||||
assertEquals(activeBridgedInterfaceNames, expectedBridgedInterfaces);
|
||||
List<BridgedIf> activeBridgedInterfaces = retrieveBridgedInterfaceNames(TEST1);
|
||||
assertEquals(activeBridgedInterfaces, expectedBridgedInterfaces);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveAvailableBridgedInterfaceInfoTest() {
|
||||
List<String> bridgedInterface = context.utils().injector().getInstance(RetrieveActiveBridgedInterfaces.class)
|
||||
List<BridgedIf> bridgedInterface = context.utils().injector().getInstance(RetrieveActiveBridgedInterfaces.class)
|
||||
.apply(host.get());
|
||||
assertFalse(bridgedInterface.isEmpty());
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.testng.annotations.BeforeClass;
|
|||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.LockType;
|
||||
import org.virtualbox_4_1.NetworkAttachmentType;
|
||||
|
@ -123,7 +122,7 @@ public class GuestAdditionsInstallerLiveTest extends
|
|||
}));
|
||||
} finally {
|
||||
for (VmSpec spec : ImmutableSet.of(sourceMachineSpec.getVmSpec())) {
|
||||
ensureMachineHasPowerDown(spec.getVmName());
|
||||
machineController.ensureMachineHasPowerDown(spec.getVmName());
|
||||
undoVm(spec);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ public class AWSEC2TemplateBuilderLiveTest extends EC2TemplateBuilderLiveTest {
|
|||
|
||||
Template defaultTemplate = context.getComputeService().templateBuilder().build();
|
||||
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "2011.09.2");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "pv-2012.03.rc-0");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
|
||||
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");
|
||||
|
@ -183,7 +183,7 @@ public class AWSEC2TemplateBuilderLiveTest extends EC2TemplateBuilderLiveTest {
|
|||
Template defaultTemplate = context.getComputeService().templateBuilder().osFamily(OsFamily.AMZN_LINUX)
|
||||
.imageMatches(EC2ImagePredicates.rootDeviceType(RootDeviceType.INSTANCE_STORE)).build();
|
||||
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "2011.09.2");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "pv-2012.03.rc-0");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
|
||||
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
|
||||
|
|
|
@ -53,14 +53,15 @@ public class CloudSigmaLasVegasTemplateBuilderLiveTest extends BaseTemplateBuild
|
|||
switch (input.family) {
|
||||
case UBUNTU:
|
||||
return (input.version.equals("11.04") && input.is64Bit)
|
||||
|| (input.version.equals("10.04") && !input.is64Bit) || input.version.equals("");
|
||||
|| (input.version.equals("11.10") && !input.is64Bit) || input.version.equals("")
|
||||
|| input.version.equals("10.04");
|
||||
case SOLARIS:
|
||||
return input.version.equals("") && input.is64Bit;
|
||||
case DEBIAN:
|
||||
return false;
|
||||
case CENTOS:
|
||||
return (input.version.equals("") || input.version.equals("6.0"))
|
||||
|| (input.version.matches("5.[57]") && input.is64Bit);
|
||||
return (input.version.equals("") || input.version.equals("5.7") || input.version.equals("6.0"))
|
||||
&& input.is64Bit;
|
||||
case WINDOWS:
|
||||
return (input.version.equals("2008 R2") || (input.version.equals("2003") || input.version.equals(""))
|
||||
&& input.is64Bit)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue