WIP: XML control of VNMC

Signed-off-by: Chiradeep Vittal <chiradeep@apache.org>
This commit is contained in:
Chiradeep Vittal 2013-01-16 15:29:54 -08:00
parent a69e7f9bf6
commit 11b804a894
18 changed files with 1463 additions and 0 deletions

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project name="Cloud Stack VNMC network element" default="help" basedir=".">
<description>
Cloud Stack ant build file
</description>
<dirname property="vnmc.base.dir" file="${ant.file.Cloud Stack VNMC network element}/"/>
<!-- This directory must be set -->
<property name="top.dir" location="${vnmc.base.dir}/../../.."/>
<property name="build.dir" location="${top.dir}/build"/>
<echo message="build.dir=${build.dir}; top.dir=${top.dir}; vnmc.base.dir=${vnmc.base.dir}"/>
<!-- Import anything that the user wants to set-->
<!-- Import properties files and environment variables here -->
<property environment="env" />
<condition property="build-cloud.properties.file" value="${build.dir}/override/build-cloud.properties" else="${build.dir}/build-cloud.properties">
<available file="${build.dir}/override/build-cloud.properties" />
</condition>
<condition property="cloud.properties.file" value="${build.dir}/override/cloud.properties" else="${build.dir}/cloud.properties">
<available file="${build.dir}/override/cloud.properties" />
</condition>
<condition property="override.file" value="${build.dir}/override/replace.properties" else="${build.dir}/replace.properties">
<available file="${build.dir}/override/replace.properties" />
</condition>
<echo message="Using build parameters from ${build-cloud.properties.file}" />
<property file="${build-cloud.properties.file}" />
<echo message="Using company info from ${cloud.properties.file}" />
<property file="${cloud.properties.file}" />
<echo message="Using override file from ${override.file}" />
<property file="${override.file}" />
<property file="${build.dir}/build.number" />
<!-- In case these didn't get defined in the build-cloud.properties -->
<property name="branding.name" value="default" />
<property name="deprecation" value="off" />
<property name="target.compat.version" value="1.6" />
<property name="source.compat.version" value="1.6" />
<property name="debug" value="true" />
<property name="debuglevel" value="lines,source"/>
<echo message="target.dir=${target.dir}; top.dir=${top.dir}"/>
<!-- directories for build and distribution -->
<property name="target.dir" location="${top.dir}/target" />
<property name="classes.dir" location="${target.dir}/classes" />
<property name="jar.dir" location="${target.dir}/jar" />
<property name="dep.cache.dir" location="${target.dir}/dep-cache" />
<property name="build.log" location="${target.dir}/ant_verbose.txt" />
<property name="deps.dir" location="${top.dir}/deps" />
<property name="cloud-plugin-vnmc.jar" value="cloud-plugin-vnmc.jar" />
<import file="${build.dir}/build-common.xml"/>
<echo message="target.dir=${target.dir}; top.dir=${top.dir}"/>
<!-- This section needs to be replaced by some kind of dependency library-->
<path id="deps.classpath">
<!--filelist files="${deps.classpath}" /-->
<fileset dir="${deps.dir}" erroronmissingdir="false">
<include name="*.jar" />
</fileset>
</path>
<path id="cloudstack.classpath">
<fileset dir="${jar.dir}">
<include name="*.jar"/>
</fileset>
</path>
<path id="vnmc.classpath">
<path refid="deps.classpath"/>
<path refid="cloudstack.classpath"/>
</path>
<!-- This section needs to be replaced by some kind of dependency library-->
<target name="deploy-vnmc" >
</target>
<target name="init" description="Initialize binaries directory">
<mkdir dir="${classes.dir}/${cloud-plugin-vnmc.jar}"/>
<mkdir dir="${jar.dir}"/>
</target>
<target name="compile-vnmc" depends="init" description="Compile Cisco VNMC">
<compile-java jar.name="${cloud-plugin-vnmc.jar}" top.dir="${vnmc.base.dir}" classpath="vnmc.classpath" />
</target>
<target name="clean-vnmc">
<delete dir="${classes.dir}/${cloud-plugin-vnmc.jar}"/>
</target>
<target name="build" depends="compile-vnmc"/>
<target name="clean" depends="clean-vnmc"/>
<target name="help" description="help">
<echo level="info" message="This is the build file for Cisco VNMC element plugin"/>
<echo level="info" message="You can do a build by doing ant build or clean by doing ant clean" />
</target>
</project>

View File

@ -0,0 +1,32 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-network-cisco-vnmc</artifactId>
<name>Apache CloudStack Plugin - Cisco VNMC</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
<configConfMo
cookie="%cookie%"
inHierarchical="false">
<inConfig>
<policyEdgeDeviceServiceProfile
addrTranslationTimeout="10800"
descr="%descr%"
dn="%dn%"
name="%name%"
status="created"
vpn=""/>
</inConfig>
</configConfMo>
<!--dn="org-root/org-TestTenant3/org-Tenant3-VDC/edsp-Tenant3-Edge-Device-Profile" -->

View File

@ -0,0 +1,12 @@
<configConfMo
dn=""
cookie="%cookie%"
inHierarchical="false">
<inConfig>
<routeRoutingPolicy
descr="%descr%"
dn="%routepolicydn%"
name="%name%"
status="created"/>
</inConfig>
</configConfMo>

View File

@ -0,0 +1,17 @@
<configConfMos
cookie="%cookie%"
inHierarchical="false">
<inConfigs>
<pair key="%routedn%" >
<routeStaticRoute
dn="%routedn%"
id="%id%"
ipAddress="%destination%"
ipSubnet="%netmask%"
nextHopGWIp="%nexthop%"
nextHopIntf="%nexthopintf%"
routeMetric="1"
status="created"/>
</pair>
</inConfigs>
</configConfMos>

View File

@ -0,0 +1,9 @@
<configConfMo cookie="%cookie%" inHierarchical="false">
<inConfig>
<orgTenant
descr="%descr%"
dn="%dn%"
name="%name%"
status="created"/>
</inConfig>
</configConfMo>

View File

@ -0,0 +1,12 @@
<configConfMo
dn=""
cookie="%cookie%"
inHierarchical="false">
<inConfig>
<orgDatacenter
descr="%descr%"
dn="%dn%"
name="%name%"
status="created"/>
</inConfig>
</configConfMo>

View File

@ -0,0 +1,8 @@
<configResolveChildren
cookie="%cookie%"
classId="orgTenant"
inDn="org-root"
inHierarchical="false">
<inFilter>
</inFilter>
</configResolveChildren>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="us-ascii"?>
<!--
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.
-->
<aaaLogin inName="%username%" inPassword="%password%" />

View File

@ -0,0 +1,7 @@
<configResolveChildren cookie="1349183392/5c1d1ceb-9a5d-433b-aab2-0760b90f31f8" commCookie="2/12/0/eab" srcExtSys="10.223.56.5" destExtSys="10.223.56.5" srcSvc="sam_extXMLApi" destSvc="service-reg_dme" response="yes" classId="orgTenant">
<outConfigs>
<orgTenant descr="Test Tenant 2" dn="org-root/org-TestTenant2" fltAggr="0" level="1" name="TestTenant2"/>
<orgTenant descr="First test" dn="org-root/org-TestTenant1" fltAggr="0" level="1" name="TestTenant1"/>
</outConfigs>
</configResolveChildren>

View File

@ -0,0 +1 @@
<aaaLogin cookie="testCookie" commCookie="" srcExtSys="0.0.0.0" destExtSys="0.0.0.0" srcSvc="" destSvc="" response="yes" errorCode="539" invocationResult="unidentified-fail" errorDescr="Authentication failed"/>

View File

@ -0,0 +1,2 @@
<aaaLogin cookie="testCookie" commCookie="" srcExtSys="0.0.0.0" destExtSys="0.0.0.0" srcSvc="" destSvc="" response="yes" outCookie="1349183392/5c1d1ceb-9a5d-433b-aab2-0760b90f31f8" outRefreshPeriod="600" outPriv="admin,read-only" outDomains="" outChannel="fullssl" outEvtChannel="fullssl" outSessionId="web_36667" outVersion="2.0(3f)"/>

View File

@ -0,0 +1,96 @@
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.cloud.network.resource.CiscoVnmcResource;
import com.cloud.utils.exception.ExecutionException;
public class CiscoVnmcResourceTest {
static CiscoVnmcResource resource;
@BeforeClass
public static void setUpClass() throws Exception {
resource = new CiscoVnmcResource("10.223.56.5", "admin", "C1sco123");
try {
boolean response = resource.login();
assertTrue(response);
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testLogin() {
//fail("Not yet implemented");
try {
boolean response = resource.login();
assertTrue(response);
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testCreateTenant() {
//fail("Not yet implemented");
try {
boolean response = resource.createTenant("TenantA");
assertTrue(response);
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testCreateTenantVDC() {
//fail("Not yet implemented");
try {
boolean response = resource.createTenantVDC("TenantA");
assertTrue(response);
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testCreateTenantVDCEdgeDeviceProfile() {
//fail("Not yet implemented");
try {
boolean response = resource.createTenantVDCEdgeDeviceProfile("TenantA");
assertTrue(response);
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testCreateTenantVDCEdgeDeviceRoutePolicy() {
try {
boolean response = resource.createTenantVDCEdgeStaticRoutePolicy("TenantA");
assertTrue(response);
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testCreateTenantVDCEdgeDeviceRoute() {
try {
boolean response = resource.createTenantVDCEdgeStaticRoute("TenantA",
"10.223.136.1", "Edge_Outside", "0.0.0.0", "0.0.0.0");
assertTrue(response);
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,109 @@
// 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 com.cloud.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseCmd;
import com.cloud.api.IdentityMapper;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.PlugService;
import com.cloud.api.ServerApiException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.host.Host;
import com.cloud.server.api.response.ExternalFirewallResponse;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
@Implementation(description="Adds an external firewall appliance", responseObject = ExternalFirewallResponse.class)
public class AddExternalFirewallCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(AddExternalFirewallCmd.class.getName());
private static final String s_name = "addexternalfirewallresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@IdentityMapper(entityTableName="data_center")
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required = true, description="Zone in which to add the external firewall appliance.")
private Long zoneId;
@Parameter(name=ApiConstants.URL, type=CommandType.STRING, required = true, description="URL of the external firewall appliance.")
private String url;
@Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required = true, description="Username of the external firewall appliance.")
private String username;
@Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required = true, description="Password of the external firewall appliance.")
private String password;
///////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getZoneId() {
return zoneId;
}
public String getUrl() {
return url;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
//@PlugService JuniperSRXFirewallElementService _srxElementService;
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@SuppressWarnings("deprecation")
@Override
public void execute(){
try {
// Host externalFirewall = _srxElementService.addExternalFirewall(this);
// ExternalFirewallResponse response = _srxElementService.createExternalFirewallResponse(externalFirewall);
// response.setObjectName("externalfirewall");
// response.setResponseName(getCommandName());
// this.setResponseObject(response);
} catch (InvalidParameterValueException ipve) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, ipve.getMessage());
} catch (CloudRuntimeException cre) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, cre.getMessage());
}
}
}

View File

@ -0,0 +1,647 @@
// 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 com.cloud.network.resource;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupExternalFirewallCommand;
import com.cloud.agent.api.routing.IpAssocAnswer;
import com.cloud.agent.api.routing.IpAssocCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.host.Host;
import com.cloud.resource.ServerResource;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.script.Script;
public class CiscoVnmcResource implements ServerResource {
private String _name;
private String _zoneId;
private String _physicalNetworkId;
private String _ip;
private String _username;
private String _password;
private String _guid;
private String _objectNameWordSep;
private Integer _numRetries;
private String _publicZone;
private String _privateZone;
private String _publicInterface;
private String _privateInterface;
private String _cookie;
private String _primaryDnsAddress;
private final Logger s_logger = Logger.getLogger(CiscoVnmcResource.class);
private enum VnmcXml {
LOGIN("login.xml", "mgmt-controller"),
CREATE_TENANT("create-tenant.xml", "service-reg"),
CREATE_VDC("create-vdc.xml", "service-reg"),
CREATE_EDGE_DEVICE_PROFILE("create-edge-device-profile.xml", "policy-mgr"),
CREATE_EDGE_ROUTE_POLICY("create-edge-device-route-policy.xml", "policy-mgr"),
CREATE_EDGE_ROUTE("create-edge-device-route.xml", "policy-mgr");
private String scriptsDir = "scripts/network/cisco";
private String xml;
private String service;
private final Logger s_logger = Logger.getLogger(CiscoVnmcResource.class);
private VnmcXml(String filename, String service) {
this.xml = getXml(filename);
this.service = service;
}
public String getXml() {
return xml;
}
private String getXml(String filename) {
try {
String xmlFilePath = Script.findScript(scriptsDir, filename);
if (xmlFilePath == null) {
throw new Exception("Failed to find Cisco VNMC XML file: " + filename);
}
FileReader fr = new FileReader(xmlFilePath);
BufferedReader br = new BufferedReader(fr);
String xml = "";
String line;
while ((line = br.readLine()) != null) {
xml += line.replaceAll("\n"," ");
}
return xml;
} catch (Exception e) {
s_logger.debug(e);
return null;
}
}
public String getService() {
return service;
}
}
public CiscoVnmcResource(String ip, String username, String password) {
_ip = ip;
_username = username;
_password = password;
}
public Answer executeRequest(Command cmd) {
if (cmd instanceof ReadyCommand) {
return execute((ReadyCommand) cmd);
} else if (cmd instanceof MaintainCommand) {
return execute((MaintainCommand) cmd);
} else if (cmd instanceof IpAssocCommand) {
return execute((IpAssocCommand) cmd);
} else if (cmd instanceof SetStaticNatRulesCommand) {
return execute((SetStaticNatRulesCommand) cmd);
} else if (cmd instanceof SetPortForwardingRulesCommand) {
return execute((SetPortForwardingRulesCommand) cmd);
} else if (cmd instanceof ExternalNetworkResourceUsageCommand) {
return execute((ExternalNetworkResourceUsageCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
}
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
try {
_name = (String) params.get("name");
if (_name == null) {
throw new ConfigurationException("Unable to find name");
}
_zoneId = (String) params.get("zoneId");
if (_zoneId == null) {
throw new ConfigurationException("Unable to find zone");
}
_physicalNetworkId = (String) params.get("physicalNetworkId");
if (_physicalNetworkId == null) {
throw new ConfigurationException("Unable to find physical network id in the configuration parameters");
}
_ip = (String) params.get("ip");
if (_ip == null) {
throw new ConfigurationException("Unable to find IP");
}
_username = (String) params.get("username");
if (_username == null) {
throw new ConfigurationException("Unable to find username");
}
_password = (String) params.get("password");
if (_password == null) {
throw new ConfigurationException("Unable to find password");
}
_publicInterface = (String) params.get("publicinterface");
if (_publicInterface == null) {
throw new ConfigurationException("Unable to find public interface.");
}
_privateInterface = (String) params.get("privateinterface");
if (_privateInterface == null) {
throw new ConfigurationException("Unable to find private interface.");
}
_publicZone = (String) params.get("publiczone");
if (_publicZone == null) {
_publicZone = "untrust";
}
_privateZone = (String) params.get("privatezone");
if (_privateZone == null) {
_privateZone = "trust";
}
_guid = (String)params.get("guid");
if (_guid == null) {
throw new ConfigurationException("Unable to find the guid");
}
_numRetries = NumbersUtil.parseInt((String) params.get("numretries"), 1);
NumbersUtil.parseInt((String) params.get("timeout"), 300);
_objectNameWordSep = "-";
_primaryDnsAddress = "4.2.2.2";
// Open a socket and login
if (!refreshVnmcConnection()) {
throw new ConfigurationException("Unable to open a connection to the VNMC.");
}
return true;
} catch (Exception e) {
throw new ConfigurationException(e.getMessage());
}
}
public StartupCommand[] initialize() {
StartupExternalFirewallCommand cmd = new StartupExternalFirewallCommand();
cmd.setName(_name);
cmd.setDataCenter(_zoneId);
cmd.setPod("");
cmd.setPrivateIpAddress(_ip);
cmd.setStorageIpAddress("");
cmd.setVersion("");
cmd.setGuid(_guid);
return new StartupCommand[]{cmd};
}
public Host.Type getType() {
return Host.Type.ExternalFirewall;
}
@Override
public String getName() {
return _name;
}
@Override
public boolean start() {
return true;
}
@Override
public boolean stop() {
return true;
}
@Override
public PingCommand getCurrentStatus(final long id) {
return new PingCommand(Host.Type.ExternalFirewall, id);
}
@Override
public void disconnected() {
}
public IAgentControl getAgentControl() {
return null;
}
public void setAgentControl(IAgentControl agentControl) {
return;
}
private Answer execute(ReadyCommand cmd) {
return new ReadyAnswer(cmd);
}
private Answer execute(MaintainCommand cmd) {
return new MaintainAnswer(cmd);
}
private ExternalNetworkResourceUsageAnswer execute(ExternalNetworkResourceUsageCommand cmd) {
return new ExternalNetworkResourceUsageAnswer(cmd);
}
/*
* Login
*/
private boolean refreshVnmcConnection() {
return true;
}
public boolean login() throws ExecutionException {
String xml = VnmcXml.LOGIN.getXml();
String service = VnmcXml.LOGIN.getService();
xml = replaceXmlValue(xml, "username", _username);
xml = replaceXmlValue(xml, "password", _password);
String response = sendRequest(service, xml);
Map<String, String> checked = checkResponse(response, "outCookie", "errorCode", "response");
if (checked.get("errorCode") != null)
return false;
_cookie = checked.get("outCookie");
if (_cookie == null) {
return false;
}
return true;
}
private String getDnForTenant(String tenantName) {
return "org-root/org-" + tenantName;
}
private String getDnForTenantVDC(String tenantName) {
return getDnForTenant(tenantName) + "/org-VDC-" + tenantName;
}
private String getDnForTenantVDCEdgeDeviceProfile(String tenantName) {
return getDnForTenantVDC(tenantName) + "/edsp-" + tenantName + "-Edge-Device-Profile";
}
private String getDnForEdgeDeviceRoutingPolicy(String tenantName) {
return getDnForTenantVDC(tenantName) + "/routing-policy-EDSP-" + tenantName + "-Routes";
//FIXME: any other construct is unreliable. why?
}
private String getDnForEdgeDeviceRoute(String tenantName, int id) {
return getDnForEdgeDeviceRoutingPolicy(tenantName) + "/sroute-" + id ;
}
public boolean createTenant(String tenantName) throws ExecutionException {
String xml = VnmcXml.CREATE_TENANT.getXml();
String service = VnmcXml.CREATE_TENANT.getService();
xml = replaceXmlValue(xml, "cookie", _cookie);
xml = replaceXmlValue(xml, "descr", "Tenant for account " + tenantName);
xml = replaceXmlValue(xml, "name", tenantName);
xml = replaceXmlValue(xml, "dn", getDnForTenant(tenantName));
String response = sendRequest(service, xml);
Map<String, String> checked = checkResponse(response, "errorCode", "response");
if (checked.get("errorCode") != null) {
String errorCode = checked.get("errorCode");
if (errorCode.equals("103")) {
//tenant already exists
return true;
}
return false;
}
return true;
}
public boolean createTenantVDC(String tenantName) throws ExecutionException {
String xml = VnmcXml.CREATE_VDC.getXml();
String service = VnmcXml.CREATE_VDC.getService();
xml = replaceXmlValue(xml, "cookie", _cookie);
xml = replaceXmlValue(xml, "descr", "VDC for Tenant" + tenantName);
xml = replaceXmlValue(xml, "name", "VDC-" + tenantName);
xml = replaceXmlValue(xml, "dn", getDnForTenantVDC(tenantName));
String response = sendRequest(service, xml);
Map<String, String> checked = checkResponse(response, "errorCode", "response");
if (checked.get("errorCode") != null) {
String errorCode = checked.get("errorCode");
if (errorCode.equals("103")) {
//tenant already exists
return true;
}
return false;
}
return true;
}
public boolean createTenantVDCEdgeDeviceProfile(String tenantName) throws ExecutionException {
String xml = VnmcXml.CREATE_EDGE_DEVICE_PROFILE.getXml();
String service = VnmcXml.CREATE_EDGE_DEVICE_PROFILE.getService();
xml = replaceXmlValue(xml, "cookie", _cookie);
xml = replaceXmlValue(xml, "descr", "Edge Device Profile for Tenant VDC" + tenantName);
xml = replaceXmlValue(xml, "name", "EDSP-" + tenantName);
xml = replaceXmlValue(xml, "dn", getDnForTenantVDCEdgeDeviceProfile(tenantName));
String response = sendRequest(service, xml);
Map<String, String> checked = checkResponse(response, "errorCode", "response");
if (checked.get("errorCode") != null) {
String errorCode = checked.get("errorCode");
if (errorCode.equals("103")) {
//tenant already exists
return true;
}
return false;
}
return true;
}
public boolean createTenantVDCEdgeStaticRoutePolicy(String tenantName) throws ExecutionException {
String xml = VnmcXml.CREATE_EDGE_ROUTE_POLICY.getXml();
String service = VnmcXml.CREATE_EDGE_ROUTE_POLICY.getService();
xml = replaceXmlValue(xml, "cookie", _cookie);
xml = replaceXmlValue(xml, "name", "EDSP-" + tenantName + "-Routes");//FIXME: this has to match DN somehow?
xml = replaceXmlValue(xml, "routepolicydn", getDnForEdgeDeviceRoutingPolicy(tenantName));
xml = replaceXmlValue(xml, "descr", "Routing Policy for Edge Device for Tenant " + tenantName);
String response = sendRequest(service, xml);
Map<String, String> checked = checkResponse(response, "errorCode", "response");
if (checked.get("errorCode") != null) {
String errorCode = checked.get("errorCode");
if (errorCode.equals("103")) {
//already exists
return true;
}
return false;
}
return true;
}
public boolean createTenantVDCEdgeStaticRoute(String tenantName,
String nextHopIp, String outsideIntf,
String destination, String netmask) throws ExecutionException {
String xml = VnmcXml.CREATE_EDGE_ROUTE.getXml();
String service = VnmcXml.CREATE_EDGE_ROUTE.getService();
xml = replaceXmlValue(xml, "cookie", _cookie);
xml = replaceXmlValue(xml, "routedn", getDnForEdgeDeviceRoute(tenantName, 2));//TODO: why 2?
xml = replaceXmlValue(xml, "id", "2"); // TODO:2?
xml = replaceXmlValue(xml, "nexthop", nextHopIp);
xml = replaceXmlValue(xml, "nexthopintf", outsideIntf);
xml = replaceXmlValue(xml, "destination", destination);
xml = replaceXmlValue(xml, "netmask", netmask);
//TODO: this adds default route, make it more generic
String response = sendRequest(service, xml);
Map<String, String> checked = checkResponse(response, "errorCode", "response");
if (checked.get("errorCode") != null) {
String errorCode = checked.get("errorCode");
if (errorCode.equals("103")) {
//tenant already exists
return true;
}
return false;
}
return true;
}
private String sendRequest(String service, String xmlRequest) throws ExecutionException {
org.apache.commons.httpclient.protocol.Protocol myhttps =
new org.apache.commons.httpclient.protocol.Protocol("https", new EasySSLProtocolSocketFactory(), 443);
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost(_ip, 443, myhttps);
byte[] response = null;
PostMethod method = new PostMethod("/xmlIM/" + service);
method.setRequestBody(xmlRequest);
try{
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
throw new Exception("Error code : " + statusCode);
}
response = method.getResponseBody();
}catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println(new String(response));
return new String(response);
}
private synchronized Answer execute(IpAssocCommand cmd) {
refreshVnmcConnection();
return execute(cmd, _numRetries);
}
private Answer execute(IpAssocCommand cmd, int numRetries) {
String[] results = new String[cmd.getIpAddresses().length];
return new IpAssocAnswer(cmd, results);
}
/*
* Static NAT
*/
private synchronized Answer execute(SetStaticNatRulesCommand cmd) {
refreshVnmcConnection();
return execute(cmd, _numRetries);
}
private Answer execute(SetStaticNatRulesCommand cmd, int numRetries) {
return new Answer(cmd);
}
/*
* Destination NAT
*/
private synchronized Answer execute (SetPortForwardingRulesCommand cmd) {
refreshVnmcConnection();
return execute(cmd, _numRetries);
}
private Answer execute(SetPortForwardingRulesCommand cmd, int numRetries) {
return new Answer(cmd);
}
/*
* XML API commands
*/
private Map<String, String> checkResponse(String xmlResponse, String... keys) throws ExecutionException {
Document xmlDoc = getDocument(xmlResponse);
Map<String, String> result = new HashMap<String, String>();
Node topElement = xmlDoc.getChildNodes().item(0);
if (topElement != null) {
for (String key: keys){
Node valueNode = topElement.getAttributes().getNamedItem(key);
result.put(key, valueNode==null?null:valueNode.getNodeValue());
}
}
return result;
}
/*
* XML utils
*/
private String replaceXmlTag(String xml, String oldTag, String newTag) {
return xml.replaceAll(oldTag, newTag);
}
private String replaceXmlValue(String xml, String marker, String value) {
marker = "\\s*%" + marker + "%\\s*";
if (value == null) {
value = "";
}
return xml.replaceAll(marker, value);
}
private String extractXml(String xml, String marker) {
String startMarker = "<" + marker + ">";
String endMarker = "</" + marker + ">";
if (xml.contains(startMarker) && xml.contains(endMarker)) {
return xml.substring(xml.indexOf(startMarker) + startMarker.length(), xml.indexOf(endMarker));
} else {
return null;
}
}
/*
* Misc
*/
private Long getVlanTag(String vlan) throws ExecutionException {
Long publicVlanTag = null;
if (!vlan.equals("untagged")) {
try {
publicVlanTag = Long.parseLong(vlan);
} catch (Exception e) {
throw new ExecutionException("Unable to parse VLAN tag: " + vlan);
}
}
return publicVlanTag;
}
private String genObjectName(String... args) {
String objectName = "";
for (int i = 0; i < args.length; i++) {
objectName += args[i];
if (i != args.length -1) {
objectName += _objectNameWordSep;
}
}
return objectName;
}
private Document getDocument(String xml) throws ExecutionException {
StringReader xmlReader = new StringReader("<?xml version=\"1.0\"?> \n" + xml.trim());
InputSource xmlSource = new InputSource(xmlReader);
Document doc = null;
try {
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlSource);
} catch (Exception e) {
s_logger.error(e);
throw new ExecutionException(e.getMessage());
}
if (doc == null) {
throw new ExecutionException("Failed to parse xml " + xml);
} else {
return doc;
}
}
}

View File

@ -0,0 +1,2 @@
org-root/org-TenantA/org-VDC-TenantA/routing-policy-EDSP-TenantA-Routes/sroute-2
org-root/org-TenantA/org-VDC-TenantA/routing-policy-EDSP-TenantA-Routes/sroute-2

View File

@ -0,0 +1,232 @@
/*
* $HeadURL$
* $Revision$
* $Date$
*
* ====================================================================
*
* 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.httpclient.contrib.ssl;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* <p>
* EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s
* that accept self-signed certificates.
* </p>
* <p>
* This socket factory SHOULD NOT be used for productive systems
* due to security reasons, unless it is a concious decision and
* you are perfectly aware of security implications of accepting
* self-signed certificates
* </p>
*
* <p>
* Example of using custom protocol socket factory for a specific host:
* <pre>
* Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
*
* URI uri = new URI("https://localhost/", true);
* // use relative url only
* GetMethod httpget = new GetMethod(uri.getPathQuery());
* HostConfiguration hc = new HostConfiguration();
* hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
* HttpClient client = new HttpClient();
* client.executeMethod(hc, httpget);
* </pre>
* </p>
* <p>
* Example of using custom protocol socket factory per default instead of the standard one:
* <pre>
* Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
* Protocol.registerProtocol("https", easyhttps);
*
* HttpClient client = new HttpClient();
* GetMethod httpget = new GetMethod("https://localhost/");
* client.executeMethod(httpget);
* </pre>
* </p>
*
* @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
*
* <p>
* DISCLAIMER: HttpClient developers DO NOT actively support this component.
* The component is provided as a reference material, which may be inappropriate
* for use without additional customization.
* </p>
*/
public class EasySSLProtocolSocketFactory implements SecureProtocolSocketFactory {
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(EasySSLProtocolSocketFactory.class);
private SSLContext sslcontext = null;
/**
* Constructor for EasySSLProtocolSocketFactory.
*/
public EasySSLProtocolSocketFactory() {
super();
}
private static SSLContext createEasySSLContext() {
try {
SSLContext context = SSLContext.getInstance("SSL");
context.init(
null,
new TrustManager[] {new EasyX509TrustManager(null)},
null);
return context;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new HttpClientError(e.toString());
}
}
private SSLContext getSSLContext() {
if (this.sslcontext == null) {
this.sslcontext = createEasySSLContext();
}
return this.sslcontext;
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
*/
public Socket createSocket(
String host,
int port,
InetAddress clientHost,
int clientPort)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
host,
port,
clientHost,
clientPort
);
}
/**
* Attempts to get a new socket connection to the given host within the given time limit.
* <p>
* To circumvent the limitations of older JREs that do not support connect timeout a
* controller thread is executed. The controller thread attempts to create a new socket
* within the given limit of time. If socket constructor does not return until the
* timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
* </p>
*
* @param host the host name/IP
* @param port the port on the host
* @param clientHost the local host name/IP to bind the socket to
* @param clientPort the port on the local machine
* @param params {@link HttpConnectionParams Http connection parameters}
*
* @return Socket a new socket
*
* @throws IOException if an I/O error occurs while creating the socket
* @throws UnknownHostException if the IP address of the host cannot be
* determined
*/
public Socket createSocket(
final String host,
final int port,
final InetAddress localAddress,
final int localPort,
final HttpConnectionParams params
) throws IOException, UnknownHostException, ConnectTimeoutException {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketfactory = getSSLContext().getSocketFactory();
if (timeout == 0) {
return socketfactory.createSocket(host, port, localAddress, localPort);
} else {
Socket socket = socketfactory.createSocket();
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteaddr = new InetSocketAddress(host, port);
socket.bind(localaddr);
socket.connect(remoteaddr, timeout);
return socket;
}
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
*/
public Socket createSocket(String host, int port)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
host,
port
);
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
*/
public Socket createSocket(
Socket socket,
String host,
int port,
boolean autoClose)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
socket,
host,
port,
autoClose
);
}
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(EasySSLProtocolSocketFactory.class));
}
public int hashCode() {
return EasySSLProtocolSocketFactory.class.hashCode();
}
}

View File

@ -0,0 +1,114 @@
/*
* ====================================================================
*
* 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.httpclient.contrib.ssl;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* <p>
* EasyX509TrustManager unlike default {@link X509TrustManager} accepts
* self-signed certificates.
* </p>
* <p>
* This trust manager SHOULD NOT be used for productive systems
* due to security reasons, unless it is a concious decision and
* you are perfectly aware of security implications of accepting
* self-signed certificates
* </p>
*
* @author <a href="mailto:adrian.sutton@ephox.com">Adrian Sutton</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* <p>
* DISCLAIMER: HttpClient developers DO NOT actively support this component.
* The component is provided as a reference material, which may be inappropriate
* for use without additional customization.
* </p>
*/
public class EasyX509TrustManager implements X509TrustManager
{
private X509TrustManager standardTrustManager = null;
/** Log object for this class. */
private static final Log LOG = LogFactory.getLog(EasyX509TrustManager.class);
/**
* Constructor for EasyX509TrustManager.
*/
public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
super();
TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
factory.init(keystore);
TrustManager[] trustmanagers = factory.getTrustManagers();
if (trustmanagers.length == 0) {
throw new NoSuchAlgorithmException("no trust manager found");
}
this.standardTrustManager = (X509TrustManager)trustmanagers[0];
}
/**
* @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
*/
public void checkClientTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
standardTrustManager.checkClientTrusted(certificates,authType);
}
/**
* @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
*/
public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
if ((certificates != null) && LOG.isDebugEnabled()) {
LOG.debug("Server certificate chain:");
for (int i = 0; i < certificates.length; i++) {
LOG.debug("X509Certificate[" + i + "]=" + certificates[i]);
}
}
if ((certificates != null) && (certificates.length == 1)) {
certificates[0].checkValidity();
} else {
standardTrustManager.checkServerTrusted(certificates,authType);
}
}
/**
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
public X509Certificate[] getAcceptedIssuers() {
return this.standardTrustManager.getAcceptedIssuers();
}
}