implemented add/delete firewall rule for savvis-symphonyvpdc

This commit is contained in:
Kedar Dave 2011-04-27 18:01:41 -05:00
parent 7ab57d3a1f
commit f22ac3bffa
7 changed files with 316 additions and 4 deletions

View File

@ -0,0 +1,121 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.savvis.vpdc.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Map;
import java.util.Properties;
import javax.inject.Singleton;
import javax.ws.rs.core.MediaType;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.savvis.vpdc.domain.FirewallRule;
import com.jamesmurty.utils.XMLBuilder;
/**
*
* @author Kedar Dave
*
*/
@Singleton
public class BindFirewallRuleToXmlPayload extends BindToStringPayload implements MapBinder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
throw new IllegalStateException("BindFirewallRuleToXmlPayload needs parameters");
}
protected FirewallRule findRuleInArgsOrNull(GeneratedHttpRequest<?> gRequest) {
for (Object arg : gRequest.getArgs()) {
if (arg instanceof FirewallRule) {
return (FirewallRule) arg;
} else if (arg instanceof FirewallRule[]) {
FirewallRule[] rules = (FirewallRule[]) arg;
return (rules.length > 0) ? rules[0] : null;
}
}
return null;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest<?>,
"this binder is only valid for GeneratedHttpRequests!");
GeneratedHttpRequest<?> gRequest = (GeneratedHttpRequest<?>) request;
checkState(gRequest.getArgs() != null, "args should be initialized at this point");
request = super.bindToRequest(request,
generateXml(findRuleInArgsOrNull(gRequest)));
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_XML);
return request;
}
public String generateXml(FirewallRule firewallRule) {
checkNotNull(firewallRule, "FirewallRule");
try {
XMLBuilder rootBuilder = buildRoot();
addFirewallRuleSection(rootBuilder, firewallRule);
Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
return rootBuilder.asString(outputProperties);
} catch (Exception e) {
return null;
}
}
void addFirewallRuleSection(XMLBuilder rootBuilder, FirewallRule firewallRule) {
XMLBuilder firewallRuleBuilder = rootBuilder.e("svvs:FirewallRule");
firewallRuleBuilder.e("svvs:IsEnabled").t(firewallRule.isEnabled() ? "true" : "false");
firewallRuleBuilder.e("svvs:Description").t("Server Tier Firewall Rule");
firewallRuleBuilder.e("svvs:Type").t(firewallRule.getFirewallType());
firewallRuleBuilder.e("svvs:Log").t(firewallRule.isLogged() ? "yes" : "no");
firewallRuleBuilder.e("svvs:Policy").t(firewallRule.getPolicy());
firewallRuleBuilder.e("svvs:Protocols").e("svvs:"+firewallRule.getProtocol()).t("true").up().up();
firewallRuleBuilder.e("svvs:Port").t(firewallRule.getPort());
firewallRuleBuilder.e("svvs:Destination").t(firewallRule.getDestination());
firewallRuleBuilder.e("svvs:Source").t(firewallRule.getSource());
}
protected XMLBuilder buildRoot() throws ParserConfigurationException, FactoryConfigurationError {
XMLBuilder rootBuilder = XMLBuilder.create("svvs:FirewallService")
.a("xmlns:common", "http://schemas.dmtf.org/wbem/wscim/1/common")
.a("xmlns:vApp", "http://www.vmware.com/vcloud/v0.8")
.a("xmlns:rasd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
.a("xmlns:vssd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData")
.a("xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1")
.a("xmlns:svvs", "http://schemas.api.sandbox.symphonyVPDC.savvis.net/vpdci");
return rootBuilder;
}
protected String ifNullDefaultTo(String value, String defaultValue) {
return value != null ? value : checkNotNull(defaultValue, "defaultValue");
}
}

View File

@ -18,10 +18,27 @@
*/ */
package org.jclouds.savvis.vpdc.features; package org.jclouds.savvis.vpdc.features;
import javax.annotation.Nullable;
import javax.ws.rs.DELETE;
import javax.ws.rs.PUT;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.savvis.vpdc.binders.BindFirewallRuleToXmlPayload;
import org.jclouds.savvis.vpdc.domain.FirewallRule;
import org.jclouds.savvis.vpdc.domain.Task;
import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie; import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie;
import org.jclouds.savvis.vpdc.functions.DefaultOrgIfNull;
import org.jclouds.savvis.vpdc.xml.TaskHandler;
import com.google.common.util.concurrent.ListenableFuture;
/** /**
* Provides access to Symphony VPDC resources via their REST API. * Provides access to Symphony VPDC resources via their REST API.
@ -31,8 +48,29 @@ import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie;
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(SetVCloudTokenCookie.class) @RequestFilters(SetVCloudTokenCookie.class)
@Path("v{jclouds.api-version}")
public interface FirewallAsyncClient { public interface FirewallAsyncClient {
/**
* @see FirewallClient#addFirewallRule
*/
@PUT
@XMLResponseParser(TaskHandler.class)
@Path("v{jclouds.api-version}/org/{billingSiteId}/vdc/{vpdcId}/FirewallService/")
@MapBinder(BindFirewallRuleToXmlPayload.class)
ListenableFuture<Task> addFirewallRule(
@PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId,
@PathParam("vpdcId") String vpdcId, @PayloadParam("firewallRule") FirewallRule firewallRule);
/**
* @see FirewallClient#deleteFirewallRule
*/
@DELETE
@XMLResponseParser(TaskHandler.class)
@Path("v{jclouds.api-version}/org/{billingSiteId}/vdc/{vpdcId}/FirewallService/")
@MapBinder(BindFirewallRuleToXmlPayload.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Task> deleteFirewallRule(
@PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId,
@PathParam("vpdcId") String vpdcId, @PayloadParam("firewallRule") FirewallRule firewallRule);
} }

View File

@ -21,6 +21,8 @@ package org.jclouds.savvis.vpdc.features;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.savvis.vpdc.domain.FirewallRule;
import org.jclouds.savvis.vpdc.domain.Task;
/** /**
* Provides access to Symphony VPDC resources via their REST API. * Provides access to Symphony VPDC resources via their REST API.
@ -31,5 +33,30 @@ import org.jclouds.concurrent.Timeout;
*/ */
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface FirewallClient { public interface FirewallClient {
/**
* Add a new firewall rule
*
* @param billingSiteId
* billing site Id, or null for default
* @param vpdcId
* vpdc Id
* @param firewallRule
* firewall rule to be added
* @return
*/
Task addFirewallRule(String billingSiteId, String vpdcId, FirewallRule firewallRule);
/**
* Delete a firewall rule
*
* @param billingSiteId
* billing site Id, or null for default
* @param vpdcId
* vpdc Id
* @param firewallRule
* firewall rule to be deleted
* @return
*/
Task deleteFirewallRule(String billingSiteId, String vpdcId, FirewallRule firewallRule);
} }

View File

@ -0,0 +1,45 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.savvis.vpdc.binders;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import org.jclouds.savvis.vpdc.domain.FirewallRule;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code BindVMSpecToXmlPayload}
*
* @author Kedar Dave
*/
@Test(groups = "unit")
public class BindFirewallRuleToXmlPayloadTest {
public void test() throws IOException {
String expected = Strings2.toStringAndClose(getClass().getResourceAsStream("/firewallService-default.xml"));
FirewallRule firewallRule = FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet")
.destination("VM Tier01").port("22").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build();
assertEquals(new BindFirewallRuleToXmlPayload().generateXml(firewallRule), expected);
}
}

View File

@ -89,7 +89,7 @@ public class BaseVPDCClientLiveTest {
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.<Module> of( context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.<Module> of(
new Log4JLoggingModule(), new JschSshClientModule()), overrides); new Log4JLoggingModule(), new JschSshClientModule()), overrides);
restContext = context.getProviderSpecificContext(); restContext = context.getProviderSpecificContext();
taskTester = new RetryablePredicate<String>(new TaskSuccess(restContext.getApi()), 650, 10, TimeUnit.SECONDS); taskTester = new RetryablePredicate<String>(new TaskSuccess(restContext.getApi()), 1200, 10, TimeUnit.SECONDS);
} }
@AfterGroups(groups = "live") @AfterGroups(groups = "live")

View File

@ -18,14 +18,25 @@
*/ */
package org.jclouds.savvis.vpdc.features; package org.jclouds.savvis.vpdc.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.savvis.vpdc.domain.FirewallRule;
import org.jclouds.savvis.vpdc.domain.Resource;
import org.jclouds.savvis.vpdc.domain.Task;
import org.jclouds.savvis.vpdc.predicates.TaskSuccess;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@Test(groups = "live") import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
public class FirewallClientLiveTest extends BaseVPDCClientLiveTest { public class FirewallClientLiveTest extends BaseVPDCClientLiveTest {
private FirewallClient client; private FirewallClient client;
private String billingSiteId;
private String vpdcId;
@Override @Override
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
@ -33,7 +44,76 @@ public class FirewallClientLiveTest extends BaseVPDCClientLiveTest {
super.setupClient(); super.setupClient();
client = restContext.getApi().getFirewallClient(); client = restContext.getApi().getFirewallClient();
} }
@Test(groups = "live")
public void testAddFirewallRule() throws Exception {
billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default
vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(),
new Predicate<Resource>() {
// try to find the first VDC owned by the current user
// check here for what the email property might be, or in
// the jclouds-wire.log
@Override
public boolean apply(Resource arg0) {
String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId,
arg0.getId()).getDescription();
return description.indexOf(email) != -1;
}
}).getId();
String networkTierName = Iterables.get(
restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId).getAvailableNetworks(), 0)
.getName();
FirewallRule firewallRule = FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet")
.destination(networkTierName).port("10000").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build();
System.out.printf("adding firewall rule:%s %n", firewallRule.toString());
Task task = client.addFirewallRule(billingSiteId, vpdcId, firewallRule);
// make sure there's no error
assert task.getId() != null && task.getError() == null : task;
taskTester = new RetryablePredicate<String>(new TaskSuccess(restContext.getApi()), 30, 10, TimeUnit.MINUTES);
assert this.taskTester.apply(task.getId());
}
@Test(groups = "live", dependsOnMethods = {"testAddFirewallRule"})
public void testDeleteFirewallRule() throws Exception {
billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default
vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(),
new Predicate<Resource>() {
// try to find the first VDC owned by the current user
// check here for what the email property might be, or in
// the jclouds-wire.log
@Override
public boolean apply(Resource arg0) {
String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId,
arg0.getId()).getDescription();
return description.indexOf(email) != -1;
}
}).getId();
String networkTierName = Iterables.get(
restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId).getAvailableNetworks(), 0)
.getName();
FirewallRule firewallRule = FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet")
.destination(networkTierName).port("10000").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build();
System.out.printf("deleting firewall rule:%s %n", firewallRule.toString());
Task task = client.deleteFirewallRule(billingSiteId, vpdcId, firewallRule);
// make sure there's no error
assert task.getId() != null && task.getError() == null : task;
taskTester = new RetryablePredicate<String>(new TaskSuccess(restContext.getApi()), 30, 10, TimeUnit.MINUTES);
assert this.taskTester.apply(task.getId());
}
@AfterGroups(groups = "live") @AfterGroups(groups = "live")
protected void tearDown() { protected void tearDown() {

View File

@ -0,0 +1 @@
<svvs:FirewallService xmlns:svvs="http://schemas.api.sandbox.symphonyVPDC.savvis.net/vpdci" xmlns:common="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vApp="http://www.vmware.com/vcloud/v0.8" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"><svvs:FirewallRule><svvs:IsEnabled>true</svvs:IsEnabled><svvs:Description>Server Tier Firewall Rule</svvs:Description><svvs:Type>SERVER_TIER_FIREWALL</svvs:Type><svvs:Log>no</svvs:Log><svvs:Policy>allow</svvs:Policy><svvs:Protocols><svvs:Tcp>true</svvs:Tcp></svvs:Protocols><svvs:Port>22</svvs:Port><svvs:Destination>VM Tier01</svvs:Destination><svvs:Source>internet</svvs:Source></svvs:FirewallRule></svvs:FirewallService>