http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/loaders/CreateUniqueKeyPairTest.java
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/loaders/CreateUniqueKeyPairTest.java
 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/loaders/CreateUniqueKeyPairTest.java
new file mode 100644
index 0000000..1bb09e6
--- /dev/null
+++ 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/loaders/CreateUniqueKeyPairTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.compute.loaders;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.testng.Assert.assertEquals;
+
+import java.net.UnknownHostException;
+
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.SshKeyPair;
+import org.jclouds.cloudstack.features.SSHKeyPairClient;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.TypeLiteral;
+
+/**
+ * @author Adam Lowe
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "CreateUniqueKeyPairTest")
+public class CreateUniqueKeyPairTest {
+
+   @Test
+   public void testLoad() throws UnknownHostException {
+      final CloudStackClient client = createMock(CloudStackClient.class);
+      SSHKeyPairClient keyClient = createMock(SSHKeyPairClient.class);
+
+      SshKeyPair pair = createMock(SshKeyPair.class);
+
+      expect(client.getSSHKeyPairClient()).andReturn(keyClient);
+      expect(keyClient.createSSHKeyPair("group-1")).andReturn(pair);
+
+      replay(client, keyClient);
+
+      CreateUniqueKeyPair parser = Guice.createInjector(new AbstractModule() {
+
+         @Override
+         protected void configure() {
+            bind(new TypeLiteral<Supplier<String>>() {
+            }).toInstance(Suppliers.ofInstance("1"));
+            bind(CloudStackClient.class).toInstance(client);
+         }
+
+      }).getInstance(CreateUniqueKeyPair.class);
+
+      assertEquals(parser.load("group-1"), pair);
+
+      verify(client, keyClient);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/loaders/FindSecurityGroupOrCreateTest.java
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/loaders/FindSecurityGroupOrCreateTest.java
 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/loaders/FindSecurityGroupOrCreateTest.java
new file mode 100644
index 0000000..fa6b749
--- /dev/null
+++ 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/loaders/FindSecurityGroupOrCreateTest.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.compute.loaders;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+import static org.jclouds.util.Predicates2.retry;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.testng.Assert.assertEquals;
+
+import java.net.UnknownHostException;
+import javax.inject.Singleton;
+
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.IngressRule;
+import org.jclouds.cloudstack.domain.SecurityGroup;
+import org.jclouds.cloudstack.domain.Zone;
+import org.jclouds.cloudstack.domain.ZoneAndName;
+import org.jclouds.cloudstack.domain.ZoneSecurityGroupNamePortsCidrs;
+import org.jclouds.cloudstack.features.AsyncJobClient;
+import org.jclouds.cloudstack.features.SecurityGroupClient;
+import org.jclouds.cloudstack.features.ZoneClient;
+import org.jclouds.cloudstack.functions.CreateSecurityGroupIfNeeded;
+import org.jclouds.cloudstack.functions.ZoneIdToZone;
+import org.jclouds.cloudstack.predicates.JobComplete;
+import org.jclouds.cloudstack.suppliers.ZoneIdToZoneSupplier;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+
+/**
+ * @author Adam Lowe
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "FindSecurityGroupOrCreateTest")
+public class FindSecurityGroupOrCreateTest {
+
+   @Test
+   public void testLoad() throws UnknownHostException {
+      final CloudStackClient client = createMock(CloudStackClient.class);
+      SecurityGroupClient secClient = createMock(SecurityGroupClient.class);
+      ZoneClient zoneClient = createMock(ZoneClient.class);
+      AsyncJobClient jobClient = createMock(AsyncJobClient.class);
+      
+      SecurityGroup group = createMock(SecurityGroup.class);
+      
+      Zone zone = createMock(Zone.class);
+
+      expect(group.getIngressRules()).andReturn(ImmutableSet.<IngressRule> 
of());
+      expect(group.getId()).andReturn("sec-1234").anyTimes();
+      expect(zone.isSecurityGroupsEnabled()).andReturn(true);
+      
+      expect(client.getSecurityGroupClient()).andReturn(secClient)
+         .anyTimes();
+      expect(client.getZoneClient()).andReturn(zoneClient);
+      expect(client.getAsyncJobClient()).andReturn(jobClient).anyTimes();
+
+      expect(zoneClient.getZone("zone-1")).andReturn(zone);
+      expect(secClient.getSecurityGroupByName("group-1")).andReturn(null);
+      expect(secClient.createSecurityGroup("group-1")).andReturn(group);
+      expect(secClient.authorizeIngressPortsToCIDRs("sec-1234",
+                                                    "TCP",
+                                                    22,
+                                                    22,
+                                                    
ImmutableSet.of("0.0.0.0/0"))).andReturn("job-1234");
+
+      replay(client, secClient, zoneClient, zone, group);
+
+      ZoneSecurityGroupNamePortsCidrs input = 
ZoneSecurityGroupNamePortsCidrs.builder()
+         .zone("zone-1")
+         .name("group-1")
+         .ports(ImmutableSet.of(22))
+         .cidrs(ImmutableSet.<String> of()).build();
+      
+      FindSecurityGroupOrCreate parser = Guice.createInjector(new 
AbstractModule() {
+            
+            @Override
+            protected void configure() {
+               bind(new TypeLiteral<Supplier<String>>() {
+                  }).toInstance(Suppliers.ofInstance("1"));
+               bind(CloudStackClient.class).toInstance(client);
+               bind(new TypeLiteral<CacheLoader<String, Zone>>() {}).
+                  to(ZoneIdToZone.class);
+               bind(new TypeLiteral<Supplier<LoadingCache<String, Zone>>>() 
{}).
+                  to(ZoneIdToZoneSupplier.class);
+               
bind(String.class).annotatedWith(Names.named(PROPERTY_SESSION_INTERVAL)).toInstance("60");
+
+               bind(new TypeLiteral<Function<ZoneSecurityGroupNamePortsCidrs, 
SecurityGroup>>() {
+                  }).to(CreateSecurityGroupIfNeeded.class);
+               
+               bind(new TypeLiteral<CacheLoader<ZoneAndName, SecurityGroup>>() 
{
+                  }).to(FindSecurityGroupOrCreate.class);
+            }
+            
+            @Provides
+            @Singleton
+            protected Predicate<String> jobComplete(JobComplete jobComplete) {
+               return retry(jobComplete, 1200, 1, 5, SECONDS);
+            }
+
+      }).getInstance(FindSecurityGroupOrCreate.class);
+
+      assertEquals(parser.load(input), group);
+
+      verify(client, secClient, zoneClient, zone, group);
+   }
+
+   
+   @Test
+   public void testLoadAlreadyExists() throws UnknownHostException {
+      final CloudStackClient client = createMock(CloudStackClient.class);
+      SecurityGroupClient secClient = createMock(SecurityGroupClient.class);
+      ZoneClient zoneClient = createMock(ZoneClient.class);
+      AsyncJobClient jobClient = createMock(AsyncJobClient.class);
+      
+      SecurityGroup group = createMock(SecurityGroup.class);
+      
+      Zone zone = createMock(Zone.class);
+
+      expect(group.getId()).andReturn("sec-1234").anyTimes();
+      
+      expect(client.getSecurityGroupClient()).andReturn(secClient)
+         .anyTimes();
+      expect(client.getZoneClient()).andReturn(zoneClient);
+      expect(client.getAsyncJobClient()).andReturn(jobClient).anyTimes();
+
+      expect(secClient.getSecurityGroupByName("group-1")).andReturn(group);
+
+      replay(client, secClient, zoneClient, zone, group);
+
+      ZoneSecurityGroupNamePortsCidrs input = 
ZoneSecurityGroupNamePortsCidrs.builder()
+         .zone("zone-1")
+         .name("group-1")
+         .ports(ImmutableSet.of(22))
+         .cidrs(ImmutableSet.<String> of()).build();
+      
+      FindSecurityGroupOrCreate parser = Guice.createInjector(new 
AbstractModule() {
+            
+            @Override
+            protected void configure() {
+               bind(new TypeLiteral<Supplier<String>>() {
+                  }).toInstance(Suppliers.ofInstance("1"));
+               bind(CloudStackClient.class).toInstance(client);
+               bind(new TypeLiteral<CacheLoader<String, Zone>>() {}).
+                  to(ZoneIdToZone.class);
+               bind(new TypeLiteral<Supplier<LoadingCache<String, Zone>>>() 
{}).
+                  to(ZoneIdToZoneSupplier.class);
+               
bind(String.class).annotatedWith(Names.named(PROPERTY_SESSION_INTERVAL)).toInstance("60");
+
+               bind(new TypeLiteral<Function<ZoneSecurityGroupNamePortsCidrs, 
SecurityGroup>>() {
+                  }).to(CreateSecurityGroupIfNeeded.class);
+               
+               bind(new TypeLiteral<CacheLoader<ZoneAndName, SecurityGroup>>() 
{
+                  }).to(FindSecurityGroupOrCreate.class);
+            }
+            
+            @Provides
+            @Singleton
+            protected Predicate<String> jobComplete(JobComplete jobComplete) {
+               return retry(jobComplete, 1200, 1, 5, SECONDS);
+            }
+
+      }).getInstance(FindSecurityGroupOrCreate.class);
+
+      assertEquals(parser.load(input), group);
+
+      verify(client, secClient, zoneClient, zone, group);
+   }
+
+   @Test(expectedExceptions = IllegalArgumentException.class)
+   public void testLoadZoneNoSecurityGroups() throws UnknownHostException {
+      final CloudStackClient client = createMock(CloudStackClient.class);
+      SecurityGroupClient secClient = createMock(SecurityGroupClient.class);
+      ZoneClient zoneClient = createMock(ZoneClient.class);
+      AsyncJobClient jobClient = createMock(AsyncJobClient.class);
+      
+      SecurityGroup group = createMock(SecurityGroup.class);
+      
+      Zone zone = createMock(Zone.class);
+
+      expect(zone.isSecurityGroupsEnabled()).andReturn(false);
+      
+      expect(client.getSecurityGroupClient()).andReturn(secClient)
+         .anyTimes();
+      expect(client.getZoneClient()).andReturn(zoneClient);
+      expect(client.getAsyncJobClient()).andReturn(jobClient).anyTimes();
+
+      expect(zoneClient.getZone("zone-1")).andReturn(zone);
+      expect(secClient.getSecurityGroupByName("group-1")).andReturn(null);
+
+      replay(client, secClient, zoneClient, zone, group);
+
+      ZoneSecurityGroupNamePortsCidrs input = 
ZoneSecurityGroupNamePortsCidrs.builder()
+         .zone("zone-1")
+         .name("group-1")
+         .ports(ImmutableSet.of(22))
+         .cidrs(ImmutableSet.<String> of()).build();
+      
+      FindSecurityGroupOrCreate parser = Guice.createInjector(new 
AbstractModule() {
+            
+            @Override
+            protected void configure() {
+               bind(new TypeLiteral<Supplier<String>>() {
+                  }).toInstance(Suppliers.ofInstance("1"));
+               bind(CloudStackClient.class).toInstance(client);
+               bind(new TypeLiteral<CacheLoader<String, Zone>>() {}).
+                  to(ZoneIdToZone.class);
+               bind(new TypeLiteral<Supplier<LoadingCache<String, Zone>>>() 
{}).
+                  to(ZoneIdToZoneSupplier.class);
+               
bind(String.class).annotatedWith(Names.named(PROPERTY_SESSION_INTERVAL)).toInstance("60");
+
+               bind(new TypeLiteral<Function<ZoneSecurityGroupNamePortsCidrs, 
SecurityGroup>>() {
+                  }).to(CreateSecurityGroupIfNeeded.class);
+               
+               bind(new TypeLiteral<CacheLoader<ZoneAndName, SecurityGroup>>() 
{
+                  }).to(FindSecurityGroupOrCreate.class);
+            }
+            
+            @Provides
+            @Singleton
+            protected Predicate<String> jobComplete(JobComplete jobComplete) {
+               return retry(jobComplete, 1200, 1, 5, SECONDS);
+            }
+
+      }).getInstance(FindSecurityGroupOrCreate.class);
+
+      assertEquals(parser.load(input), group);
+
+      verify(client, secClient, zoneClient, zone, group);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/options/CloudStackTemplateOptionsTest.java
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/options/CloudStackTemplateOptionsTest.java
 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/options/CloudStackTemplateOptionsTest.java
index 33a66fc..7bb81f5 100644
--- 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/options/CloudStackTemplateOptionsTest.java
+++ 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/options/CloudStackTemplateOptionsTest.java
@@ -18,6 +18,8 @@ package org.jclouds.cloudstack.compute.options;
 
 import static 
org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.account;
 import static 
org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.domainId;
+import static 
org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.generateKeyPair;
+import static 
org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.generateSecurityGroup;
 import static 
org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.ipOnDefaultNetwork;
 import static 
org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.ipsToNetworks;
 import static 
org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.keyPair;
@@ -88,6 +90,27 @@ public class CloudStackTemplateOptionsTest {
    }
 
    @Test
+   public void testGenerateSecurityGroupDefaultsFalse() {
+      TemplateOptions options = new CloudStackTemplateOptions();
+      assertFalse(options.as(CloudStackTemplateOptions.class)
+         .shouldGenerateSecurityGroup());
+   }
+
+   @Test
+   public void testGenerateSecurityGroup() {
+      TemplateOptions options = new 
CloudStackTemplateOptions().generateSecurityGroup(true);
+      assertTrue(options.as(CloudStackTemplateOptions.class)
+         .shouldGenerateSecurityGroup());
+   }
+
+   @Test
+   public void testGenerateSecurityGroupStatic() {
+      TemplateOptions options = generateSecurityGroup(true);
+      assertTrue(options.as(CloudStackTemplateOptions.class)
+         .shouldGenerateSecurityGroup());
+   }
+
+   @Test
    public void testDefaultNetworkIds() {
       TemplateOptions options = new CloudStackTemplateOptions();
       
assertEquals(options.as(CloudStackTemplateOptions.class).getNetworkIds(), 
ImmutableSet.of());
@@ -171,6 +194,27 @@ public class CloudStackTemplateOptionsTest {
    }
 
    @Test
+   public void testGenerateKeyPairDefaultsFalse() {
+      TemplateOptions options = new CloudStackTemplateOptions();
+      assertFalse(options.as(CloudStackTemplateOptions.class)
+         .shouldGenerateKeyPair());
+   }
+
+   @Test
+   public void testGenerateKeyPair() {
+      TemplateOptions options = new 
CloudStackTemplateOptions().generateKeyPair(true);
+      assertTrue(options.as(CloudStackTemplateOptions.class)
+         .shouldGenerateKeyPair());
+   }
+
+   @Test
+   public void testGenerateKeyPairStatic() {
+      TemplateOptions options = generateKeyPair(true);
+      assertTrue(options.as(CloudStackTemplateOptions.class)
+         .shouldGenerateKeyPair());
+   }
+
+   @Test
    public void testKeyPair() {
       TemplateOptions options = keyPair("test");
       assertEquals(options.as(CloudStackTemplateOptions.class).getKeyPair(), 
"test");

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupAsyncClientTest.java
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupAsyncClientTest.java
 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupAsyncClientTest.java
index 516d8f1..4240530 100644
--- 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupAsyncClientTest.java
+++ 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupAsyncClientTest.java
@@ -104,6 +104,24 @@ public class SecurityGroupAsyncClientTest extends 
BaseCloudStackAsyncClientTest<
 
    }
 
+   public void testGetSecurityGroupByName() throws SecurityException, 
NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(SecurityGroupAsyncClient.class, 
"getSecurityGroupByName", String.class);
+      GeneratedHttpRequest httpRequest = processor.createRequest(method, 
ImmutableList.<Object> of("some-name"));
+
+      assertRequestLineEquals(httpRequest,
+            "GET 
http://localhost:8080/client/api?response=json&command=listSecurityGroups&listAll=true&securitygroupname=some-name
 HTTP/1.1");
+      assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
+      assertPayloadEquals(httpRequest, null, null, false);
+
+      assertResponseParserClassEquals(method, httpRequest,
+            Functions.compose(IdentityFunction.INSTANCE, 
IdentityFunction.INSTANCE).getClass());
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, NullOnNotFoundOr404.class);
+
+      checkFilters(httpRequest);
+
+   }
+
    public void testCreateSecurityGroup() throws SecurityException, 
NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(SecurityGroupAsyncClient.class, 
"createSecurityGroup", String.class);
       GeneratedHttpRequest httpRequest = processor.createRequest(method, 
ImmutableList.<Object> of("goo"));

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java
 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java
index f2d9d3f..f5cb8ed 100644
--- 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java
+++ 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java
@@ -190,8 +190,10 @@ public class SecurityGroupClientLiveTest extends 
BaseCloudStackClientLiveTest {
 
    protected void checkGroup(SecurityGroup group) {
       // http://bugs.cloud.com/show_bug.cgi?id=8968
-      if (group.getIngressRules().size() <= 1)
+      if (group.getIngressRules().size() <= 1) {
          assertEquals(group, 
client.getSecurityGroupClient().getSecurityGroup(group.getId()));
+         assertEquals(group, 
client.getSecurityGroupClient().getSecurityGroupByName(group.getName()));
+      }
       assert group.getId() != null : group;
       assert group.getName() != null : group;
       assert group.getAccount() != null : group;

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/java/org/jclouds/cloudstack/functions/CreateSecurityGroupIfNeededTest.java
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/functions/CreateSecurityGroupIfNeededTest.java
 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/functions/CreateSecurityGroupIfNeededTest.java
new file mode 100644
index 0000000..e131911
--- /dev/null
+++ 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/functions/CreateSecurityGroupIfNeededTest.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.functions;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+import static org.jclouds.util.Predicates2.retry;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.testng.Assert.assertEquals;
+
+import java.net.UnknownHostException;
+import javax.inject.Singleton;
+
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.IngressRule;
+import org.jclouds.cloudstack.domain.SecurityGroup;
+import org.jclouds.cloudstack.domain.Zone;
+import org.jclouds.cloudstack.domain.ZoneSecurityGroupNamePortsCidrs;
+import org.jclouds.cloudstack.features.AsyncJobClient;
+import org.jclouds.cloudstack.features.SecurityGroupClient;
+import org.jclouds.cloudstack.features.ZoneClient;
+import org.jclouds.cloudstack.functions.ZoneIdToZone;
+import org.jclouds.cloudstack.predicates.JobComplete;
+import org.jclouds.cloudstack.suppliers.ZoneIdToZoneSupplier;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+
+/**
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit", testName = "CreateSecurityGroupIfNeededTest")
+public class CreateSecurityGroupIfNeededTest {
+
+   @Test
+   public void testApply() throws UnknownHostException {
+      final CloudStackClient client = createMock(CloudStackClient.class);
+      SecurityGroupClient secClient = createMock(SecurityGroupClient.class);
+      ZoneClient zoneClient = createMock(ZoneClient.class);
+      AsyncJobClient jobClient = createMock(AsyncJobClient.class);
+      
+      SecurityGroup group = createMock(SecurityGroup.class);
+      
+      Zone zone = createMock(Zone.class);
+
+      expect(group.getIngressRules()).andReturn(ImmutableSet.<IngressRule> 
of());
+      expect(group.getId()).andReturn("sec-1234").anyTimes();
+      expect(zone.isSecurityGroupsEnabled()).andReturn(true);
+      
+      expect(client.getSecurityGroupClient()).andReturn(secClient)
+         .anyTimes();
+      expect(client.getZoneClient()).andReturn(zoneClient);
+      expect(client.getAsyncJobClient()).andReturn(jobClient).anyTimes();
+
+      expect(zoneClient.getZone("zone-abc1")).andReturn(zone);
+      expect(secClient.createSecurityGroup("group-1")).andReturn(group);
+      expect(secClient.authorizeIngressPortsToCIDRs("sec-1234",
+                                                    "TCP",
+                                                    22,
+                                                    22,
+                                                    
ImmutableSet.of("0.0.0.0/0"))).andReturn("job-1234");
+
+      replay(client, secClient, zoneClient, zone, group);
+
+      ZoneSecurityGroupNamePortsCidrs input = 
ZoneSecurityGroupNamePortsCidrs.builder()
+         .zone("zone-abc1")
+         .name("group-1")
+         .ports(ImmutableSet.of(22))
+         .cidrs(ImmutableSet.<String> of()).build();
+      
+      CreateSecurityGroupIfNeeded parser = Guice.createInjector(new 
AbstractModule() {
+
+            @Override
+            protected void configure() {
+               bind(new TypeLiteral<Supplier<String>>() {
+                  }).toInstance(Suppliers.ofInstance("1"));
+               bind(CloudStackClient.class).toInstance(client);
+               bind(new TypeLiteral<CacheLoader<String, Zone>>() {}).
+                  to(ZoneIdToZone.class);
+               bind(new TypeLiteral<Supplier<LoadingCache<String, Zone>>>() 
{}).
+                  to(ZoneIdToZoneSupplier.class);
+               
bind(String.class).annotatedWith(Names.named(PROPERTY_SESSION_INTERVAL)).toInstance("60");
+            }
+            
+            @Provides
+            @Singleton
+            protected Predicate<String> jobComplete(JobComplete jobComplete) {
+               return retry(jobComplete, 1200, 1, 5, SECONDS);
+            }
+            
+         }).getInstance(CreateSecurityGroupIfNeeded.class);
+      
+      assertEquals(parser.apply(input), group);
+
+      verify(client, secClient, zoneClient, zone, group);
+   }
+
+   
+   @Test
+   public void testApplyGroupAlreadyExists() throws UnknownHostException {
+      final CloudStackClient client = createMock(CloudStackClient.class);
+      SecurityGroupClient secClient = createMock(SecurityGroupClient.class);
+      ZoneClient zoneClient = createMock(ZoneClient.class);
+      AsyncJobClient jobClient = createMock(AsyncJobClient.class);
+      
+      SecurityGroup group = createMock(SecurityGroup.class);
+      
+      Zone zone = createMock(Zone.class);
+
+      expect(group.getId()).andReturn("sec-1234").anyTimes();
+      expect(zone.isSecurityGroupsEnabled()).andReturn(true);
+      
+      expect(client.getSecurityGroupClient()).andReturn(secClient)
+         .anyTimes();
+      expect(client.getZoneClient()).andReturn(zoneClient);
+      expect(client.getAsyncJobClient()).andReturn(jobClient).anyTimes();
+
+      expect(zoneClient.getZone("zone-abc2")).andReturn(zone);
+      expect(secClient.createSecurityGroup("group-1")).andThrow(new 
IllegalStateException());
+      expect(secClient.getSecurityGroupByName("group-1")).andReturn(group);
+
+      replay(client, secClient, zoneClient, zone, group);
+
+      ZoneSecurityGroupNamePortsCidrs input = 
ZoneSecurityGroupNamePortsCidrs.builder()
+         .zone("zone-abc2")
+         .name("group-1")
+         .ports(ImmutableSet.of(22))
+         .cidrs(ImmutableSet.<String> of()).build();
+      
+      CreateSecurityGroupIfNeeded parser = Guice.createInjector(new 
AbstractModule() {
+
+            @Override
+            protected void configure() {
+               bind(new TypeLiteral<Supplier<String>>() {
+                  }).toInstance(Suppliers.ofInstance("1"));
+               bind(CloudStackClient.class).toInstance(client);
+               bind(new TypeLiteral<CacheLoader<String, Zone>>() {}).
+                  to(ZoneIdToZone.class);
+               bind(new TypeLiteral<Supplier<LoadingCache<String, Zone>>>() 
{}).
+                  to(ZoneIdToZoneSupplier.class);
+               
bind(String.class).annotatedWith(Names.named(PROPERTY_SESSION_INTERVAL)).toInstance("60");
+            }
+            
+            @Provides
+            @Singleton
+            protected Predicate<String> jobComplete(JobComplete jobComplete) {
+               return retry(jobComplete, 1200, 1, 5, SECONDS);
+            }
+            
+         }).getInstance(CreateSecurityGroupIfNeeded.class);
+      
+      assertEquals(parser.apply(input), group);
+
+      verify(client, secClient, zoneClient, zone, group);
+   }
+
+   @Test(expectedExceptions = IllegalArgumentException.class)
+   public void testApplyZoneNoSecurityGroups() throws UnknownHostException {
+      final CloudStackClient client = createMock(CloudStackClient.class);
+      SecurityGroupClient secClient = createMock(SecurityGroupClient.class);
+      ZoneClient zoneClient = createMock(ZoneClient.class);
+      AsyncJobClient jobClient = createMock(AsyncJobClient.class);
+      
+      SecurityGroup group = createMock(SecurityGroup.class);
+      
+      Zone zone = createMock(Zone.class);
+
+      expect(zone.isSecurityGroupsEnabled()).andReturn(false);
+      
+      expect(client.getZoneClient()).andReturn(zoneClient);
+
+      expect(zoneClient.getZone("zone-abc3")).andReturn(zone);
+
+      replay(client, zoneClient, zone);
+
+      ZoneSecurityGroupNamePortsCidrs input = 
ZoneSecurityGroupNamePortsCidrs.builder()
+         .zone("zone-abc3")
+         .name("group-1")
+         .ports(ImmutableSet.of(22))
+         .cidrs(ImmutableSet.<String> of()).build();
+      
+      CreateSecurityGroupIfNeeded parser = Guice.createInjector(new 
AbstractModule() {
+
+            @Override
+            protected void configure() {
+               bind(new TypeLiteral<Supplier<String>>() {
+                  }).toInstance(Suppliers.ofInstance("1"));
+               bind(CloudStackClient.class).toInstance(client);
+               bind(new TypeLiteral<CacheLoader<String, Zone>>() {}).
+                  to(ZoneIdToZone.class);
+               bind(new TypeLiteral<Supplier<LoadingCache<String, Zone>>>() 
{}).
+                  to(ZoneIdToZoneSupplier.class);
+               
bind(String.class).annotatedWith(Names.named(PROPERTY_SESSION_INTERVAL)).toInstance("60");
+            }
+            
+            @Provides
+            @Singleton
+            protected Predicate<String> jobComplete(JobComplete jobComplete) {
+               return retry(jobComplete, 1200, 1, 5, SECONDS);
+            }
+            
+         }).getInstance(CreateSecurityGroupIfNeeded.class);
+
+      assertEquals(parser.apply(input), group);
+
+      verify(client, zoneClient, zone);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java
 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java
index 9d24257..8b8d01d 100644
--- 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java
+++ 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/internal/BaseCloudStackComputeServiceContextExpectTest.java
@@ -134,6 +134,10 @@ public abstract class 
BaseCloudStackComputeServiceContextExpectTest<T> extends B
       .payload(payloadFromResource("/listnetworksresponse.json"))
       .build();   
    
+   protected final HttpResponse listNetworksWithSecurityGroupsResponse = 
HttpResponse.builder().statusCode(200)
+      .payload(payloadFromResource("/listnetworksresponse-2.json"))
+      .build();   
+
    protected final HttpRequest getZone = HttpRequest.builder().method("GET")
       .endpoint("http://localhost:8080/client/api";)
       .addQueryParam("response", "json")
@@ -148,6 +152,21 @@ public abstract class 
BaseCloudStackComputeServiceContextExpectTest<T> extends B
    protected final HttpResponse getZoneResponse = 
HttpResponse.builder().statusCode(200)
       .payload(payloadFromResource("/getzoneresponse.json"))
       .build();
+
+   protected final HttpRequest getZoneWithSecurityGroups = 
HttpRequest.builder().method("GET")
+      .endpoint("http://localhost:8080/client/api";)
+      .addQueryParam("response", "json")
+      .addQueryParam("command", "listZones")
+      .addQueryParam("listAll", "true")
+      .addQueryParam("id", "2")
+      .addQueryParam("apiKey", "APIKEY")
+      .addQueryParam("signature", "FnYX25207fVLLRz5GhOfRrWuUek%3D")
+      .addHeader("Accept", "application/json")
+      .build();
+
+   protected final HttpResponse getZoneWithSecurityGroupsResponse = 
HttpResponse.builder().statusCode(200)
+      .payload(payloadFromResource("/getzoneresponse-2.json"))
+      .build();
    
    protected final HttpRequest listCapabilities = 
HttpRequest.builder().method("GET")
       .endpoint("http://localhost:8080/client/api";)
@@ -163,4 +182,64 @@ public abstract class 
BaseCloudStackComputeServiceContextExpectTest<T> extends B
       .payload(payloadFromResource("/listcapabilitiesresponse.json"))
       .build();   
          
+   protected final HttpRequest getSecurityGroup = 
HttpRequest.builder().method("GET")
+      .endpoint("http://localhost:8080/client/api";)
+      .addQueryParam("response", "json")
+      .addQueryParam("command", "listSecurityGroups")
+      .addQueryParam("listAll", "true")      
+      .addQueryParam("securitygroupname", "jclouds-test")      
+      .addQueryParam("apiKey", "APIKEY")      
+      .addQueryParam("signature", "zGp2rfHY6fBIGkgODRxyNzFfPFI%3D")
+      .addHeader("Accept", "application/json")
+      .build();
+
+   protected final HttpResponse getSecurityGroupResponse = 
HttpResponse.builder().statusCode(200)
+      .payload(payloadFromResource("/getsecuritygroupresponse.json"))
+      .build();   
+
+   protected final HttpRequest createSecurityGroup = 
HttpRequest.builder().method("GET")
+      .endpoint("http://localhost:8080/client/api";)
+      .addQueryParam("response", "json")
+      .addQueryParam("command", "createSecurityGroup")
+      .addQueryParam("name", "jclouds-test")      
+      .addQueryParam("apiKey", "APIKEY")      
+      .addQueryParam("signature", "BdgmqGsvjPmP4PxsEKEpq6buwuA%3D")
+      .addHeader("Accept", "application/json")
+      .build();
+
+   protected final HttpResponse createSecurityGroupResponse = 
HttpResponse.builder().statusCode(200)
+      .payload(payloadFromResource("/createsecuritygroupresponse.json"))
+      .build();   
+
+   protected final HttpRequest authorizeIngress = 
HttpRequest.builder().method("GET")
+      .endpoint("http://localhost:8080/client/api";)
+      .addQueryParam("response", "json")
+      .addQueryParam("command", "authorizeSecurityGroupIngress")
+      .addQueryParam("securitygroupid", "30")      
+      .addQueryParam("protocol", "TCP")
+      .addQueryParam("startport", "22")
+      .addQueryParam("endport", "22")
+      .addQueryParam("cidrlist", "0.0.0.0/0")
+      .addQueryParam("apiKey", "APIKEY")      
+      .addQueryParam("signature", "GVtXzAl/Q7z4wnvKEHtdV0lxv2o%3D")
+      .addHeader("Accept", "application/json")
+      .build();
+
+   protected final HttpResponse authorizeIngressResponse = 
HttpResponse.builder().statusCode(200)
+      
.payload(payloadFromResource("/authorizesecuritygroupingressresponse.json"))
+      .build();   
+
+   protected final HttpRequest createSSHKeyPair = 
HttpRequest.builder().method("GET")
+      .endpoint("http://localhost:8080/client/api";)
+      .addQueryParam("response", "json")
+      .addQueryParam("command", "createSSHKeyPair")
+      .addQueryParam("name", "jclouds-test")      
+      .addQueryParam("apiKey", "APIKEY")      
+      .addQueryParam("signature", "er6YjvUjPFwxy/x/aAVNW9Z8yo8%3D")
+      .addHeader("Accept", "application/json")
+      .build();
+
+   protected final HttpResponse createSSHKeyPairResponse = 
HttpResponse.builder().statusCode(200)
+      .payload(payloadFromResource("/createsshkeypairresponse-2.json"))
+      .build();   
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/SecurityGroupPredicatesTest.java
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/SecurityGroupPredicatesTest.java
 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/SecurityGroupPredicatesTest.java
new file mode 100644
index 0000000..16e473a
--- /dev/null
+++ 
b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/SecurityGroupPredicatesTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.cloudstack.predicates;
+
+import static 
org.jclouds.cloudstack.predicates.SecurityGroupPredicates.portInRange;
+import static 
org.jclouds.cloudstack.predicates.SecurityGroupPredicates.hasCidr;
+import static 
org.jclouds.cloudstack.predicates.SecurityGroupPredicates.portInRangeForCidr;
+import static 
org.jclouds.cloudstack.predicates.SecurityGroupPredicates.nameEquals;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.cloudstack.domain.IngressRule;
+import org.jclouds.cloudstack.domain.SecurityGroup;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author Andrew Bayer
+ */
+@Test(groups = "unit")
+public class SecurityGroupPredicatesTest {
+
+   public SecurityGroup group() {
+      return SecurityGroup
+         .builder()
+         .id("13")
+         .name("default")
+         .description("description")
+         .account("adrian")
+         .domainId("1")
+         .domain("ROOT")
+         .ingressRules(
+                       ImmutableSet.of(
+                                       
+                                       
IngressRule.builder().id("5").protocol("tcp").startPort(22).endPort(22)
+                                       
.securityGroupName("adriancole").account("adrian").build(),
+                                       
IngressRule.builder().id("6").protocol("udp").startPort(11).endPort(11).CIDR("1.1.1.1/24").build(),
+                                       
IngressRule.builder().id("7").protocol("tcp").startPort(40).endPort(50).CIDR("1.1.1.1/24").build(),
+                                       
IngressRule.builder().id("8").protocol("tcp").startPort(60).endPort(60).CIDR("2.2.2.2/16").build()
+                                       )).build();
+   }
+
+   @Test
+   public void testPortInRange() {
+      assertTrue(portInRange(22).apply(group()));
+      assertTrue(portInRange(45).apply(group()));
+      assertFalse(portInRange(100).apply(group()));
+   }
+
+   @Test
+   public void testHasCidr() {
+      assertTrue(hasCidr("1.1.1.1/24").apply(group()));
+      assertFalse(hasCidr("3.3.3.3/25").apply(group()));
+   }
+
+   @Test
+   public void testPortInRangeForCidr() {
+      assertTrue(portInRangeForCidr(11, "1.1.1.1/24").apply(group()));
+      assertTrue(portInRangeForCidr(45, "1.1.1.1/24").apply(group()));
+      assertFalse(portInRangeForCidr(45, "2.2.2.2/16").apply(group()));
+      assertFalse(portInRangeForCidr(11, "2.2.2.2/16").apply(group()));
+      assertFalse(portInRangeForCidr(11, "3.3.3.3/25").apply(group()));
+   }
+   
+   @Test
+   public void testNameEquals() {
+      assertTrue(nameEquals("default").apply(group()));
+      assertFalse(nameEquals("not-default").apply(group()));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/resources/authorizesecuritygroupingressresponse.json
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/resources/authorizesecuritygroupingressresponse.json 
b/apis/cloudstack/src/test/resources/authorizesecuritygroupingressresponse.json
new file mode 100644
index 0000000..e0280e4
--- /dev/null
+++ 
b/apis/cloudstack/src/test/resources/authorizesecuritygroupingressresponse.json
@@ -0,0 +1,2 @@
+ { "authorizesecuritygroupingressresponse" :
+ {"jobid":"13330fc9-8b3e-4582-aa3e-90883c041010"} }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/resources/createsecuritygroupresponse.json
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/resources/createsecuritygroupresponse.json 
b/apis/cloudstack/src/test/resources/createsecuritygroupresponse.json
new file mode 100644
index 0000000..99a2ad2
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/createsecuritygroupresponse.json
@@ -0,0 +1,3 @@
+{ "listsecuritygroupsresponse" : { "securitygroup" : 
+{"id":30,"name":"jclouds-test","account":"adrian","domainid":1,"domain":"ROOT"}
+ } }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/resources/createsshkeypairresponse-2.json
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/resources/createsshkeypairresponse-2.json 
b/apis/cloudstack/src/test/resources/createsshkeypairresponse-2.json
new file mode 100644
index 0000000..3dfb3b4
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/createsshkeypairresponse-2.json
@@ -0,0 +1,4 @@
+{ "createsshkeypairresponse" :  { "keypair" : {
+   "name":"jclouds-test",
+   "fingerprint":"1c:06:74:52:3b:99:1c:95:5c:04:c2:f4:ba:77:6e:7b",
+   "privatekey":"-----BEGIN RSA PRIVATE 
KEY-----\nMIICXgIBAAKBgQDZo/EF4Ew1uEW0raz7vCs28lBwy0UKV2Xr606gaEgxO7h9mSXZ\n4x2K/KQ1NMnrbjppxGycLh9EKPWAO3ezFULAyuOZW4Fy+xRS8+3MAijxBJY/KBgl\nx5rJm2ILumRkTNkMlLGCSBb9SOqYRN1VpOy7kn3StzU9LdJ/snKVE2JLHQIDAQAB\nAoGBAMnL5okKRd9xcsBqYIAxIuiZmNhcwTErhEdRMOAukPGFbDSYsa3rldLvGdpz\njd2LoQG8rO/LHBZ429kASqZzyiV+NvcgH+tFNJSVAigjSICfhEKF9PY2TiAkrg7S\nGyJgAjpPWQc2sQh0dE8EPEtBiq4ibXfMTDmbs1d/vnfdwtQJAkEA+AX5Y+xgWj74\ndYETmNLyLhNZpftLizEfIYj7lCVhsbFwVb8jbM1m8n8bxwGjls1w/ico1CWcQna+\nUnAfA8kJvwJBAOCj0YgDKpYd0OLQhvI3212J9QcQpJEkDOTYiMwXNHCNMKRpoF47\nMPPX+GG8YzUiQAi9/OG4pDKCjzQWE/ebiiMCQQCssnQ5WICqtggIwYykr9VDseON\nSFIMpHJ5xkjumazRrqx6eDGxc8BH/6uWwRRoT7pqrVeniFyqhsX03u8pkpU/AkBj\nWfCcwBHArNUqy2EzlWKuvwogosq16oTNXbs60HR/5uIBhTnJE1K2NemDiGc0I77A\nXw6N4jS0piuhtLYGB8OTAkEA50abdbduXWcr62Z6E8G/6LNFaNg0uBuVgwSHtJMd\ndNeUtVDHQCHSf3tvxXTAtaB9PCnGOfgm/dyYWEMf3rMoHQ==\n-----END
 RSA PRIVATE KEY-----\n"} }  }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/resources/getsecuritygroupresponse.json
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/resources/getsecuritygroupresponse.json 
b/apis/cloudstack/src/test/resources/getsecuritygroupresponse.json
new file mode 100644
index 0000000..27743ed
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/getsecuritygroupresponse.json
@@ -0,0 +1 @@
+{ "listsecuritygroupsresponse" : { count: 0, "securitygroup" : [ { } ] } }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/resources/getzoneresponse-2.json
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/resources/getzoneresponse-2.json 
b/apis/cloudstack/src/test/resources/getzoneresponse-2.json
new file mode 100644
index 0000000..7261716
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/getzoneresponse-2.json
@@ -0,0 +1 @@
+{ "listzonesresponse" : { "zone" : [  
{"id":2,"name":"Chicago","networktype":"Advanced","securitygroupsenabled":true} 
] } }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/resources/listnetworksresponse-2.json
----------------------------------------------------------------------
diff --git a/apis/cloudstack/src/test/resources/listnetworksresponse-2.json 
b/apis/cloudstack/src/test/resources/listnetworksresponse-2.json
new file mode 100644
index 0000000..2f10824
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/listnetworksresponse-2.json
@@ -0,0 +1 @@
+{ "listnetworksresponse" : { "network" : [  {"id":204,"name":"Virtual 
Network","displaytext":"A dedicated virtualized network for your account.  The 
broadcast domain is contained within a VLAN and all public network access is 
routed out by a virtual 
router.","broadcastdomaintype":"Vlan","traffictype":"Guest","zoneid":2,"networkofferingid":6,"networkofferingname":"DefaultVirtualizedNetworkOffering","networkofferingdisplaytext":"Virtual
 
Vlan","networkofferingavailability":"Required","isshared":false,"issystem":false,"state":"Implemented","related":204,"broadcasturi":"vlan://240","dns1":"8.8.8.8","type":"Virtual","account":"adrian","domainid":1,"domain":"ROOT","isdefault":true,"service":[{"name":"Vpn","capability":[{"name":"SupportedVpnTypes","value":"pptp,l2tp,ipsec"}]},{"name":"Gateway"},{"name":"UserData"},{"name":"Dhcp"},{"name":"Firewall","capability":[{"name":"SupportedSourceNatTypes","value":"per
 
account"},{"name":"StaticNat","value":"true"},{"name":"TrafficStatistics","value":"
 per public 
ip"},{"name":"PortForwarding","value":"true"},{"name":"MultipleIps","value":"true"},{"name":"SupportedProtocols","value":"tcp,udp"}]},{"name":"Dns"},{"name":"Lb","capability":[{"name":"SupportedLbAlgorithms","value":"roundrobin,leastconn,source"},{"name":"SupportedProtocols","value":"tcp,
 udp"}]}],"networkdomain":"cs3cloud.internal"} ] } }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-authorizeingress.json
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-authorizeingress.json
 
b/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-authorizeingress.json
new file mode 100644
index 0000000..7ee489d
--- /dev/null
+++ 
b/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-authorizeingress.json
@@ -0,0 +1,34 @@
+{
+    "queryasyncjobresultresponse": {
+        "accountid": 3,
+        "userid": 3,
+        "cmd": "com.cloud.api.commands.AuthorizeSecurityGroupIngressCmd",
+        "jobstatus": 1,
+        "jobprocstatus": 0,
+        "jobresultcode": 0,
+        "jobresulttype": "object",
+        "jobresult": {
+            "securitygroup": {
+                "id": "30",
+                "name": "jclouds-test",
+                "account": "adrian",
+                "domainid": "1",
+                "domain": "ROOT",
+                "ingressrule": [
+                    {
+                        "ruleid": "35bb2ad4-e0cb-48a0-9534-fc4a067b5665",
+                        "protocol": "tcp",
+                        "startport": 22,
+                        "endport": 22,
+                        "cidr": "0.0.0.0/0"
+                    }
+                ],
+                "egressrule": [
+                    
+                ]
+            }
+        },
+        "jobid": "13330fc9-8b3e-4582-aa3e-90883c041010",
+        "created": "2013-06-04T14:37:26-0700"
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/fbe637c8/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-virtualmachine-securitygroup.json
----------------------------------------------------------------------
diff --git 
a/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-virtualmachine-securitygroup.json
 
b/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-virtualmachine-securitygroup.json
new file mode 100644
index 0000000..cc75e11
--- /dev/null
+++ 
b/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-virtualmachine-securitygroup.json
@@ -0,0 +1,73 @@
+{
+    "queryasyncjobresultresponse": {
+            "jobid": 50006,
+            "accountid": 3,
+            "userid": 3,
+            "cmd": "com.cloud.api.commands.DeployVMCmd",
+            "jobstatus": 1,
+            "jobprocstatus": 0,
+            "jobresultcode": 0,
+            "jobresult": {
+                "virtualmachine": {
+                    "id": 1234,
+                    "name": "i-3-218-VM",
+                    "displayname": "i-3-218-VM",
+                    "account": "adrian",
+                    "domainid": 1,
+                    "domain": "ROOT",
+                    "created": "2011-02-27T08:39:10-0800",
+                    "state": "Running",
+                    "haenable": false,
+                    "zoneid": 1,
+                    "zonename": "San Jose 1",
+                    "templateid": 203,
+                    "templatename": "Centos 5.3 Password Managed",
+                    "templatedisplaytext": "Centos 5.3 Password Managed",
+                    "passwordenabled": true,
+                    "serviceofferingid": 1,
+                    "serviceofferingname": "Small Instance",
+                    "cpunumber": 1,
+                    "cpuspeed": 500,
+                    "memory": 512,
+                    "guestosid": 12,
+                    "rootdeviceid": 0,
+                    "rootdevicetype": "NetworkFilesystem",
+                    "securitygroup": [
+                        {
+                            "id": "30",
+                            "name": "jclouds-test",
+                            "account": "adrian",
+                            "domainid": "1",
+                            "domain": "ROOT",
+                            "ingressrule": [
+                                {
+                                    "ruleid": 
"35bb2ad4-e0cb-48a0-9534-fc4a067b5665",
+                                    "protocol": "tcp",
+                                    "startport": 22,
+                                    "endport": 22,
+                                    "cidr": "0.0.0.0/0"
+                                }
+                            ],
+                            "egressrule": [
+                                
+                            ]
+                        }
+                    ],
+                    "password": "dD7jwajkh",
+                    "nic": [{
+                        "id": 250,
+                        "networkid": 204,
+                        "netmask": "255.255.255.0",
+                        "gateway": "10.1.1.1",
+                        "ipaddress": "10.1.1.195",
+                        "traffictype": "Guest",
+                        "type": "Virtual",
+                        "isdefault": true
+                    }],
+                    "hypervisor": "XenServer"
+                }
+            },
+            "created": "2011-02-27T08:39:10-0800"
+        }
+    
+}

Reply via email to