From dad42494983bb2ada670d18cb25cdae4e3cec63b Mon Sep 17 00:00:00 2001 From: Antonio Fornie Date: Mon, 23 Dec 2013 13:07:06 +0100 Subject: [PATCH] SecurityProfile and ACL for NiciraNvpApi, including Unit and Integration tests Signed-off-by: Daan Hoogland --- plugins/network-elements/nicira-nvp/pom.xml | 35 +- .../network/nicira/AccessConfiguration.java | 129 ++++++ .../com/cloud/network/nicira/AccessRule.java | 55 +++ .../src/com/cloud/network/nicira/Acl.java | 21 + .../src/com/cloud/network/nicira/AclRule.java | 206 ++++++++++ .../cloud/network/nicira/NiciraNvpApi.java | 370 ++++++++++++++---- .../cloud/network/nicira/SecurityProfile.java | 21 + .../cloud/network/nicira/SecurityRule.java | 135 +++++++ .../cloud/network/nicira/NiciraNvpApiIT.java | 163 ++++++++ .../network/nicira/NiciraNvpApiTest.java | 196 +++++++++- .../test/resources/config.properties | 21 + 11 files changed, 1261 insertions(+), 91 deletions(-) create mode 100644 plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AccessConfiguration.java create mode 100644 plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AccessRule.java create mode 100644 plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Acl.java create mode 100644 plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AclRule.java create mode 100644 plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityProfile.java create mode 100644 plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityRule.java create mode 100644 plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiIT.java create mode 100644 plugins/network-elements/nicira-nvp/test/resources/config.properties diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 3bc8d141093..477b2955adc 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -26,8 +26,16 @@ 4.4.0-SNAPSHOT ../../pom.xml - + + + + + integration + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + + + + diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AccessConfiguration.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AccessConfiguration.java new file mode 100644 index 00000000000..74fe19d644e --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AccessConfiguration.java @@ -0,0 +1,129 @@ +// 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.nicira; + +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ReflectionToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +@SuppressWarnings("serial") +public abstract class AccessConfiguration implements Serializable { + + protected String displayName; + protected List logicalPortEgressRules; + protected List logicalPortIngressRules; + protected List tags; + protected String uuid; + protected String href; + protected String schema; + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(final String displayName) { + this.displayName = displayName; + } + + public List getLogicalPortEgressRules() { + return logicalPortEgressRules; + } + + public void setLogicalPortEgressRules(final List logicalPortEgressRules) { + this.logicalPortEgressRules = logicalPortEgressRules; + } + + public List getLogicalPortIngressRules() { + return logicalPortIngressRules; + } + + public void setLogicalPortIngressRules(final List logicalPortIngressRules) { + this.logicalPortIngressRules = logicalPortIngressRules; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(final String uuid) { + this.uuid = uuid; + } + + public String getHref() { + return href; + } + + public void setHref(final String href) { + this.href = href; + } + + public String getSchema() { + return schema; + } + + public void setSchema(final String schema) { + this.schema = schema; + } + + public List getTags() { + return tags; + } + + public void setTags(final List tags) { + this.tags = tags; + } + + @Override + public String toString() { + return ReflectionToStringBuilder.reflectionToString(this, ToStringStyle.DEFAULT_STYLE, false); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 31) + .append(displayName).append(logicalPortEgressRules) + .append(logicalPortIngressRules).append(tags) + .append(uuid).append(href).append(schema) + .toHashCode(); + } + + @Override + @SuppressWarnings("unchecked") + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(this.getClass().isInstance(obj))) { + return false; + } + final AccessConfiguration another = + (AccessConfiguration) obj; + return new EqualsBuilder() + .append(displayName, another.displayName) + .append(uuid, another.uuid) + .append(href, another.href) + .append(schema, another.schema) + .isEquals(); + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AccessRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AccessRule.java new file mode 100644 index 00000000000..cf02eb16a42 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AccessRule.java @@ -0,0 +1,55 @@ +// 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.nicira; + +import java.io.Serializable; + +import org.apache.commons.lang.builder.ReflectionToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +@SuppressWarnings("serial") +public abstract class AccessRule implements Serializable { + + public static final String ETHERTYPE_IPV4 = "IPv4"; + public static final String ETHERTYPE_IPV6 = "IPv6"; + + protected String ethertype = ETHERTYPE_IPV4; + + protected int protocol; + + + public String getEthertype() { + return ethertype; + } + + public void setEthertype(String ethertype) { + this.ethertype = ethertype; + } + + public int getProtocol() { + return protocol; + } + + public void setProtocol(int protocol) { + this.protocol = protocol; + } + + @Override + public String toString() { + return ReflectionToStringBuilder.reflectionToString(this, ToStringStyle.DEFAULT_STYLE, false); + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Acl.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Acl.java new file mode 100644 index 00000000000..3a9b387cd2c --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Acl.java @@ -0,0 +1,21 @@ +// 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.nicira; + +@SuppressWarnings("serial") +public class Acl extends AccessConfiguration { +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AclRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AclRule.java new file mode 100644 index 00000000000..aa4f637886b --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/AclRule.java @@ -0,0 +1,206 @@ +// 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.nicira; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +@SuppressWarnings("serial") +public class AclRule extends AccessRule { + + public static final String ETHERTYPE_ARP = "ARP"; + + /** + * @TODO Convert this String into Enum and check the JSON communication still works + */ + protected String action; + + protected String sourceIpPrefix; + + protected String destinationIpPrefix; + + protected String sourceMacAddress; + + protected String destinationMacAddress; + + protected Integer sourcePortRangeMin; + + protected Integer destinationPortRangeMin; + + protected Integer sourcePortRangeMax; + + protected Integer destinationPortRangeMax; + + protected Integer icmpProtocolCode; + + protected Integer icmpProtocolType; + + protected int order; + + + /** + * Default constructor + */ + public AclRule() { + } + + /** + * Fully parameterized constructor + */ + public AclRule(String ethertype, int protocol, String action, String sourceMacAddress, + String destinationMacAddress, String sourceIpPrefix, String destinationIpPrefix, + Integer sourcePortRangeMin, Integer sourcePortRangeMax, + Integer destinationPortRangeMin, Integer destinationPortRangeMax, + int order, Integer icmpProtocolCode, Integer icmpProtocolType) { + this.ethertype = ethertype; + this.protocol = protocol; + this.action = action; + this.sourceMacAddress = sourceMacAddress; + this.destinationMacAddress = destinationMacAddress; + this.sourceIpPrefix = sourceIpPrefix; + this.destinationIpPrefix = destinationIpPrefix; + this.sourcePortRangeMin = sourcePortRangeMin; + this.sourcePortRangeMax = sourcePortRangeMax; + this.destinationPortRangeMin = destinationPortRangeMin; + this.destinationPortRangeMax = destinationPortRangeMax; + this.order = order; + this.icmpProtocolCode = icmpProtocolCode; + this.icmpProtocolType = icmpProtocolType; + } + + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getSourceIpPrefix() { + return sourceIpPrefix; + } + + public void setSourceIpPrefix(String sourceIpPrefix) { + this.sourceIpPrefix = sourceIpPrefix; + } + + public String getDestinationIpPrefix() { + return destinationIpPrefix; + } + + public void setDestinationIpPrefix(String destinationIpPrefix) { + this.destinationIpPrefix = destinationIpPrefix; + } + + public String getSourceMacAddress() { + return sourceMacAddress; + } + + public void setSourceMacAddress(String sourceMacAddress) { + this.sourceMacAddress = sourceMacAddress; + } + + public String getDestinationMacAddress() { + return destinationMacAddress; + } + + public void setDestinationMacAddress(String destinationMacAddress) { + this.destinationMacAddress = destinationMacAddress; + } + + public Integer getSourcePortRangeMin() { + return sourcePortRangeMin; + } + + public void setSourcePortRangeMin(Integer sourcePortRangeMin) { + this.sourcePortRangeMin = sourcePortRangeMin; + } + + public Integer getDestinationPortRangeMin() { + return destinationPortRangeMin; + } + + public void setDestinationPortRangeMin(Integer destinationPortRangeMin) { + this.destinationPortRangeMin = destinationPortRangeMin; + } + + public Integer getSourcePortRangeMax() { + return sourcePortRangeMax; + } + + public void setSourcePortRangeMax(Integer sourcePortRangeMax) { + this.sourcePortRangeMax = sourcePortRangeMax; + } + + public Integer getDestinationPortRangeMax() { + return destinationPortRangeMax; + } + + public void setDestinationPortRangeMax(Integer destinationPortRangeMax) { + this.destinationPortRangeMax = destinationPortRangeMax; + } + + public Integer getIcmpProtocolCode() { + return icmpProtocolCode; + } + + public void setIcmpProtocolCode(Integer icmpProtocolCode) { + this.icmpProtocolCode = icmpProtocolCode; + } + + public Integer getIcmpProtocolType() { + return icmpProtocolType; + } + + public void setIcmpProtocolType(Integer icmpProtocolType) { + this.icmpProtocolType = icmpProtocolType; + } + + public int getOrder() { + return order; + } + + public void setOrder(int order) { + this.order = order; + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 31) + .append(ethertype).append(protocol) + .toHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof AclRule)) { + return false; + } + AclRule another = (AclRule) obj; + return new EqualsBuilder() + .append(ethertype, another.ethertype) + .append(protocol, another.protocol) + .isEquals(); + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java index 6f695ade9bd..92bbaab0067 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java @@ -72,10 +72,16 @@ import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; public class NiciraNvpApi { + protected static final String GET_METHOD_TYPE = "get"; + protected static final String DELETE_METHOD_TYPE = "delete"; + protected static final String PUT_METHOD_TYPE = "put"; + protected static final String POST_METHOD_TYPE = "post"; private static final String TEXT_HTML_CONTENT_TYPE = "text/html"; private static final String JSON_CONTENT_TYPE = "application/json"; private static final String CONTENT_TYPE = "Content-Type"; private static final int BODY_RESP_MAX_LEN = 1024; + protected static final String SEC_PROFILE_URI_PREFIX = "/ws.v1/security-profile"; + protected static final String ACL_URI_PREFIX = "/ws.v1/acl"; private static final String SWITCH_URI_PREFIX = "/ws.v1/lswitch"; private static final String ROUTER_URI_PREFIX = "/ws.v1/lrouter"; private static final int HTTPS_PORT = 443; @@ -83,7 +89,6 @@ public class NiciraNvpApi { private final static String protocol = "https"; private final static MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager(); - private String name; private String host; private String adminuser; private String adminpass; @@ -93,6 +98,14 @@ public class NiciraNvpApi { private final Gson gson; + @SuppressWarnings("rawtypes") + protected static Map prefixMap; + + @SuppressWarnings("rawtypes") + protected static Map listTypeMap; + + protected static Map defaultListParams; + /* This factory method is protected so we can extend this * in the unittests. */ @@ -104,18 +117,18 @@ public class NiciraNvpApi { String url; try { url = new URL(protocol, host, uri).toString(); - } catch (MalformedURLException e) { + } catch (final MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); } - if ("post".equalsIgnoreCase(type)) { + if (POST_METHOD_TYPE.equalsIgnoreCase(type)) { return new PostMethod(url); - } else if ("get".equalsIgnoreCase(type)) { + } else if (GET_METHOD_TYPE.equalsIgnoreCase(type)) { return new GetMethod(url); - } else if ("delete".equalsIgnoreCase(type)) { + } else if (DELETE_METHOD_TYPE.equalsIgnoreCase(type)) { return new DeleteMethod(url); - } else if ("put".equalsIgnoreCase(type)) { + } else if (PUT_METHOD_TYPE.equalsIgnoreCase(type)) { return new PutMethod(url); } else { throw new NiciraNvpApiException("Requesting unknown method type"); @@ -129,11 +142,28 @@ public class NiciraNvpApi { try { // Cast to ProtocolSocketFactory to avoid the deprecated constructor with the SecureProtocolSocketFactory parameter Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory)new TrustingProtocolSocketFactory(), HTTPS_PORT)); - } catch (IOException e) { + } catch (final IOException e) { s_logger.warn("Failed to register the TrustingProtocolSocketFactory, falling back to default SSLSocketFactory", e); } gson = new GsonBuilder().registerTypeAdapter(NatRule.class, new NatRuleAdapter()).setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); + buildTypeSpecificStructures(); + } + + @SuppressWarnings("rawtypes") + protected void buildTypeSpecificStructures() { + if (prefixMap == null || listTypeMap == null || defaultListParams == null) { + prefixMap = new HashMap(); + prefixMap.put(SecurityProfile.class, SEC_PROFILE_URI_PREFIX); + prefixMap.put(Acl.class, ACL_URI_PREFIX); + + listTypeMap = new HashMap(); + listTypeMap.put(SecurityProfile.class, new TypeToken>() {}.getType()); + listTypeMap.put(Acl.class, new TypeToken>() {}.getType()); + + defaultListParams = new HashMap(); + defaultListParams.put("fields", "*"); + } } public void setControllerAddress(final String address) { @@ -160,20 +190,20 @@ public class NiciraNvpApi { try { url = new URL(protocol, host, "/ws.v1/login").toString(); - } catch (MalformedURLException e) { + } catch (final MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); } - PostMethod pm = new PostMethod(url); + final PostMethod pm = new PostMethod(url); pm.addParameter("username", adminuser); pm.addParameter("password", adminpass); try { client.executeMethod(pm); - } catch (HttpException e) { + } catch (final HttpException e) { throw new NiciraNvpApiException("Nicira NVP API login failed ", e); - } catch (IOException e) { + } catch (final IOException e) { throw new NiciraNvpApiException("Nicira NVP API login failed ", e); } finally { pm.releaseConnection(); @@ -193,69 +223,263 @@ public class NiciraNvpApi { // Success; the cookie required for login is kept in _client } + /** + * POST {@link SecurityProfile} + * + * @param securityProfile + * @return + * @throws NiciraNvpApiException + */ + public SecurityProfile createSecurityProfile(final SecurityProfile securityProfile) throws NiciraNvpApiException { + return create(securityProfile); + } + + /** + * GET list of {@link SecurityProfile} + * + * @return + * @throws NiciraNvpApiException + */ + public NiciraNvpList findSecurityProfile() throws NiciraNvpApiException { + return findSecurityProfile(null); + } + + /** + * GET list of {@link SecurityProfile} filtered by UUID + * + * We could have invoked the service: + * SEC_PROFILE_URI_PREFIX + "/" + securityProfileUuid + * but it is not working currently + * + * @param uuid + * @return + * @throws NiciraNvpApiException + */ + public NiciraNvpList findSecurityProfile(final String uuid) throws NiciraNvpApiException { + return find(uuid, SecurityProfile.class); + } + + /** + * PUT {@link SecurityProfile} given a UUID as key and a {@link SecurityProfile} + * with the new data + * + * @param securityProfile + * @param securityProfileUuid + * @throws NiciraNvpApiException + */ + public void updateSecurityProfile(final SecurityProfile securityProfile, + final String securityProfileUuid) + throws NiciraNvpApiException { + update(securityProfile, securityProfileUuid); + } + + /** + * DELETE Security Profile given a UUID as key + * + * @param securityProfileUuid + * @throws NiciraNvpApiException + */ + public void deleteSecurityProfile(final String securityProfileUuid) + throws NiciraNvpApiException { + delete(securityProfileUuid, SecurityProfile.class); + } + + + /** + * POST {@link Acl} + * + * @param acl + * @return + * @throws NiciraNvpApiException + */ + public Acl createAcl(final Acl acl) throws NiciraNvpApiException { + return create(acl); + } + + /** + * GET list of {@link Acl} + * + * @return + * @throws NiciraNvpApiException + */ + public NiciraNvpList findAcl() throws NiciraNvpApiException { + return findAcl(null); + } + + /** + * GET list of {@link Acl} filtered by UUID + * + * @param uuid + * @return + * @throws NiciraNvpApiException + */ + public NiciraNvpList findAcl(final String uuid) throws NiciraNvpApiException { + return find(uuid, Acl.class); + } + + /** + * PUT {@link Acl} given a UUID as key and a {@link Acl} + * with the new data + * + * @param acl + * @param aclUuid + * @throws NiciraNvpApiException + */ + public void updateAcl(final Acl acl, + final String aclUuid) + throws NiciraNvpApiException { + update(acl, aclUuid); + } + + /** + * DELETE Acl given a UUID as key + * + * @param acl + * @throws NiciraNvpApiException + */ + public void deleteAcl(final String aclUuid) throws NiciraNvpApiException { + delete(aclUuid, Acl.class); + } + + /** + * POST + * + * @param entity + * @return + * @throws NiciraNvpApiException + */ + protected T create(final T entity) throws NiciraNvpApiException { + final String uri = prefixMap.get(entity.getClass()); + final T createdEntity = executeCreateObject(entity, new TypeToken() { + }.getType(), uri, Collections. emptyMap()); + + return createdEntity; + } + + /** + * GET list of items + * + * @return + * @throws NiciraNvpApiException + */ + protected NiciraNvpList find(final Class clazz) throws NiciraNvpApiException { + return find(null, clazz); + } + + /** + * GET list of items + * + * @param uuid + * @return + * @throws NiciraNvpApiException + */ + public NiciraNvpList find(final String uuid, final Class clazz) throws NiciraNvpApiException { + final String uri = prefixMap.get(clazz); + Map params = defaultListParams; + if (uuid != null) { + params = new HashMap(defaultListParams); + params.put("uuid", uuid); + } + + final NiciraNvpList entities = executeRetrieveObject(listTypeMap.get(clazz), uri, params); + + if (entities == null) { + throw new NiciraNvpApiException("Unexpected response from API"); + } + + return entities; + } + + /** + * PUT item given a UUID as key and an item object + * with the new data + * + * @param item + * @param uuid + * @throws NiciraNvpApiException + */ + public void update(final T item, + final String uuid) + throws NiciraNvpApiException { + final String uri = prefixMap.get(item.getClass()) + "/" + uuid; + executeUpdateObject(item, uri, Collections. emptyMap()); + } + + /** + * DELETE Security Profile given a UUID as key + * + * @param securityProfileUuid + * @throws NiciraNvpApiException + */ + public void delete(final String uuid, final Class clazz) + throws NiciraNvpApiException { + final String uri = prefixMap.get(clazz) + "/" + uuid; + executeDeleteObject(uri); + } + public LogicalSwitch createLogicalSwitch(final LogicalSwitch logicalSwitch) throws NiciraNvpApiException { - String uri = SWITCH_URI_PREFIX; - LogicalSwitch createdLogicalSwitch = executeCreateObject(logicalSwitch, new TypeToken() { + final String uri = SWITCH_URI_PREFIX; + final LogicalSwitch createdLogicalSwitch = executeCreateObject(logicalSwitch, new TypeToken() { }.getType(), uri, Collections. emptyMap()); return createdLogicalSwitch; } public void deleteLogicalSwitch(final String uuid) throws NiciraNvpApiException { - String uri = SWITCH_URI_PREFIX + uuid; + final String uri = SWITCH_URI_PREFIX + uuid; executeDeleteObject(uri); } public LogicalSwitchPort createLogicalSwitchPort(final String logicalSwitchUuid, final LogicalSwitchPort logicalSwitchPort) throws NiciraNvpApiException { - String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport"; - LogicalSwitchPort createdLogicalSwitchPort = executeCreateObject(logicalSwitchPort, new TypeToken() { + final String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport"; + final LogicalSwitchPort createdLogicalSwitchPort = executeCreateObject(logicalSwitchPort, new TypeToken() { }.getType(), uri, Collections. emptyMap()); return createdLogicalSwitchPort; } - public void modifyLogicalSwitchPortAttachment(final String logicalSwitchUuid, final String logicalSwitchPortUuid, Attachment attachment) throws NiciraNvpApiException { - String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport/" + logicalSwitchPortUuid + "/attachment"; + public void modifyLogicalSwitchPortAttachment(final String logicalSwitchUuid, final String logicalSwitchPortUuid, final Attachment attachment) throws NiciraNvpApiException { + final String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport/" + logicalSwitchPortUuid + "/attachment"; executeUpdateObject(attachment, uri, Collections. emptyMap()); } public void deleteLogicalSwitchPort(final String logicalSwitchUuid, final String logicalSwitchPortUuid) throws NiciraNvpApiException { - String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport/" + logicalSwitchPortUuid; + final String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport/" + logicalSwitchPortUuid; executeDeleteObject(uri); } public String findLogicalSwitchPortUuidByVifAttachmentUuid(final String logicalSwitchUuid, final String vifAttachmentUuid) throws NiciraNvpApiException { - String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport"; - Map params = new HashMap(); + final String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport"; + final Map params = new HashMap(); params.put("attachment_vif_uuid", vifAttachmentUuid); params.put("fields", "uuid"); - NiciraNvpList lspl = executeRetrieveObject(new TypeToken>() { + final NiciraNvpList lspl = executeRetrieveObject(new TypeToken>() { }.getType(), uri, params); if (lspl == null || lspl.getResultCount() != 1) { throw new NiciraNvpApiException("Unexpected response from API"); } - LogicalSwitchPort lsp = lspl.getResults().get(0); + final LogicalSwitchPort lsp = lspl.getResults().get(0); return lsp.getUuid(); } public ControlClusterStatus getControlClusterStatus() throws NiciraNvpApiException { - String uri = "/ws.v1/control-cluster/status"; - ControlClusterStatus ccs = executeRetrieveObject(new TypeToken() { + final String uri = "/ws.v1/control-cluster/status"; + final ControlClusterStatus ccs = executeRetrieveObject(new TypeToken() { }.getType(), uri, null); return ccs; } public NiciraNvpList findLogicalSwitchPortsByUuid(final String logicalSwitchUuid, final String logicalSwitchPortUuid) throws NiciraNvpApiException { - String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport"; - Map params = new HashMap(); + final String uri = SWITCH_URI_PREFIX + logicalSwitchUuid + "/lport"; + final Map params = new HashMap(); params.put("uuid", logicalSwitchPortUuid); params.put("fields", "uuid"); - NiciraNvpList lspl = executeRetrieveObject(new TypeToken>() { + final NiciraNvpList lspl = executeRetrieveObject(new TypeToken>() { }.getType(), uri, params); if (lspl == null) { @@ -266,69 +490,69 @@ public class NiciraNvpApi { } public LogicalRouterConfig createLogicalRouter(final LogicalRouterConfig logicalRouterConfig) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX; + final String uri = ROUTER_URI_PREFIX; - LogicalRouterConfig lrc = executeCreateObject(logicalRouterConfig, new TypeToken() { + final LogicalRouterConfig lrc = executeCreateObject(logicalRouterConfig, new TypeToken() { }.getType(), uri, Collections. emptyMap()); return lrc; } public void deleteLogicalRouter(final String logicalRouterUuid) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid; + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid; executeDeleteObject(uri); } public LogicalRouterPort createLogicalRouterPort(final String logicalRouterUuid, final LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport"; + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport"; - LogicalRouterPort lrp = executeCreateObject(logicalRouterPort, new TypeToken() { + final LogicalRouterPort lrp = executeCreateObject(logicalRouterPort, new TypeToken() { }.getType(), uri, Collections. emptyMap()); return lrp; } public void deleteLogicalRouterPort(final String logicalRouterUuid, final String logicalRouterPortUuid) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport/" + logicalRouterPortUuid; + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport/" + logicalRouterPortUuid; executeDeleteObject(uri); } public void modifyLogicalRouterPort(final String logicalRouterUuid, final LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport/" + logicalRouterPort.getUuid(); + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport/" + logicalRouterPort.getUuid(); executeUpdateObject(logicalRouterPort, uri, Collections. emptyMap()); } public void modifyLogicalRouterPortAttachment(final String logicalRouterUuid, final String logicalRouterPortUuid, final Attachment attachment) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport/" + logicalRouterPortUuid + "/attachment"; + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport/" + logicalRouterPortUuid + "/attachment"; executeUpdateObject(attachment, uri, Collections. emptyMap()); } public NatRule createLogicalRouterNatRule(final String logicalRouterUuid, final NatRule natRule) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/nat"; + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/nat"; return executeCreateObject(natRule, new TypeToken() { }.getType(), uri, Collections. emptyMap()); } public void modifyLogicalRouterNatRule(final String logicalRouterUuid, final NatRule natRule) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/nat/" + natRule.getUuid(); + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/nat/" + natRule.getUuid(); executeUpdateObject(natRule, uri, Collections. emptyMap()); } public void deleteLogicalRouterNatRule(final String logicalRouterUuid, final UUID natRuleUuid) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/nat/" + natRuleUuid.toString(); + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/nat/" + natRuleUuid.toString(); executeDeleteObject(uri); } public NiciraNvpList findLogicalRouterPortByGatewayServiceAndVlanId(final String logicalRouterUuid, final String gatewayServiceUuid, final long vlanId) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport"; - Map params = new HashMap(); + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport"; + final Map params = new HashMap(); params.put("attachment_gwsvc_uuid", gatewayServiceUuid); params.put("attachment_vlan", "0"); params.put("fields", "*"); @@ -338,21 +562,21 @@ public class NiciraNvpApi { } public LogicalRouterConfig findOneLogicalRouterByUuid(final String logicalRouterUuid) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid; + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid; return executeRetrieveObject(new TypeToken() { }.getType(), uri, Collections. emptyMap()); } public void updateLogicalRouterPortConfig(final String logicalRouterUuid, final LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport" + logicalRouterPort.getUuid(); + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport" + logicalRouterPort.getUuid(); executeUpdateObject(logicalRouterPort, uri, Collections. emptyMap()); } public NiciraNvpList findNatRulesByLogicalRouterUuid(final String logicalRouterUuid) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/nat"; - Map params = new HashMap(); + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/nat"; + final Map params = new HashMap(); params.put("fields", "*"); return executeRetrieveObject(new TypeToken>() { @@ -361,8 +585,8 @@ public class NiciraNvpApi { public NiciraNvpList findLogicalRouterPortByGatewayServiceUuid(final String logicalRouterUuid, final String l3GatewayServiceUuid) throws NiciraNvpApiException { - String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport"; - Map params = new HashMap(); + final String uri = ROUTER_URI_PREFIX + logicalRouterUuid + "/lport"; + final Map params = new HashMap(); params.put("fields", "*"); params.put("attachment_gwsvc_uuid", l3GatewayServiceUuid); @@ -375,18 +599,18 @@ public class NiciraNvpApi { throw new NiciraNvpApiException("Hostname/credentials are null or empty"); } - PutMethod pm = (PutMethod)createMethod("put", uri); + final PutMethod pm = (PutMethod)createMethod(PUT_METHOD_TYPE, uri); pm.setRequestHeader(CONTENT_TYPE, JSON_CONTENT_TYPE); try { pm.setRequestEntity(new StringRequestEntity(gson.toJson(newObject), JSON_CONTENT_TYPE, null)); - } catch (UnsupportedEncodingException e) { + } catch (final UnsupportedEncodingException e) { throw new NiciraNvpApiException("Failed to encode json request body", e); } executeMethod(pm); if (pm.getStatusCode() != HttpStatus.SC_OK) { - String errorMessage = responseToErrorMessage(pm); + final String errorMessage = responseToErrorMessage(pm); pm.releaseConnection(); s_logger.error("Failed to update object : " + errorMessage); throw new NiciraNvpApiException("Failed to update object : " + errorMessage); @@ -394,24 +618,25 @@ public class NiciraNvpApi { pm.releaseConnection(); } + @SuppressWarnings("unchecked") protected T executeCreateObject(final T newObject, final Type returnObjectType, final String uri, final Map parameters) throws NiciraNvpApiException { if (host == null || host.isEmpty() || adminuser == null || adminuser.isEmpty() || adminpass == null || adminpass.isEmpty()) { throw new NiciraNvpApiException("Hostname/credentials are null or empty"); } - PostMethod pm = (PostMethod)createMethod("post", uri); + final PostMethod pm = (PostMethod)createMethod(POST_METHOD_TYPE, uri); pm.setRequestHeader(CONTENT_TYPE, JSON_CONTENT_TYPE); try { pm.setRequestEntity(new StringRequestEntity(gson.toJson(newObject), JSON_CONTENT_TYPE, null)); - } catch (UnsupportedEncodingException e) { + } catch (final UnsupportedEncodingException e) { throw new NiciraNvpApiException("Failed to encode json request body", e); } executeMethod(pm); if (pm.getStatusCode() != HttpStatus.SC_CREATED) { - String errorMessage = responseToErrorMessage(pm); + final String errorMessage = responseToErrorMessage(pm); pm.releaseConnection(); s_logger.error("Failed to create object : " + errorMessage); throw new NiciraNvpApiException("Failed to create object : " + errorMessage); @@ -420,7 +645,7 @@ public class NiciraNvpApi { T result; try { result = (T)gson.fromJson(pm.getResponseBodyAsString(), TypeToken.get(newObject.getClass()).getType()); - } catch (IOException e) { + } catch (final IOException e) { throw new NiciraNvpApiException("Failed to decode json response body", e); } finally { pm.releaseConnection(); @@ -434,13 +659,13 @@ public class NiciraNvpApi { throw new NiciraNvpApiException("Hostname/credentials are null or empty"); } - DeleteMethod dm = (DeleteMethod)createMethod("delete", uri); + final DeleteMethod dm = (DeleteMethod)createMethod(DELETE_METHOD_TYPE, uri); dm.setRequestHeader(CONTENT_TYPE, JSON_CONTENT_TYPE); executeMethod(dm); if (dm.getStatusCode() != HttpStatus.SC_NO_CONTENT) { - String errorMessage = responseToErrorMessage(dm); + final String errorMessage = responseToErrorMessage(dm); dm.releaseConnection(); s_logger.error("Failed to delete object : " + errorMessage); throw new NiciraNvpApiException("Failed to delete object : " + errorMessage); @@ -448,16 +673,17 @@ public class NiciraNvpApi { dm.releaseConnection(); } + @SuppressWarnings("unchecked") protected T executeRetrieveObject(final Type returnObjectType, final String uri, final Map parameters) throws NiciraNvpApiException { if (host == null || host.isEmpty() || adminuser == null || adminuser.isEmpty() || adminpass == null || adminpass.isEmpty()) { throw new NiciraNvpApiException("Hostname/credentials are null or empty"); } - GetMethod gm = (GetMethod)createMethod("get", uri); + final GetMethod gm = (GetMethod)createMethod(GET_METHOD_TYPE, uri); gm.setRequestHeader(CONTENT_TYPE, JSON_CONTENT_TYPE); if (parameters != null && !parameters.isEmpty()) { - List nameValuePairs = new ArrayList(parameters.size()); - for (Entry e : parameters.entrySet()) { + final List nameValuePairs = new ArrayList(parameters.size()); + for (final Entry e : parameters.entrySet()) { nameValuePairs.add(new NameValuePair(e.getKey(), e.getValue())); } gm.setQueryString(nameValuePairs.toArray(new NameValuePair[0])); @@ -466,7 +692,7 @@ public class NiciraNvpApi { executeMethod(gm); if (gm.getStatusCode() != HttpStatus.SC_OK) { - String errorMessage = responseToErrorMessage(gm); + final String errorMessage = responseToErrorMessage(gm); gm.releaseConnection(); s_logger.error("Failed to retrieve object : " + errorMessage); throw new NiciraNvpApiException("Failed to retrieve object : " + errorMessage); @@ -475,7 +701,7 @@ public class NiciraNvpApi { T returnValue; try { returnValue = (T)gson.fromJson(gm.getResponseBodyAsString(), returnObjectType); - } catch (IOException e) { + } catch (final IOException e) { s_logger.error("IOException while retrieving response body", e); throw new NiciraNvpApiException(e); } finally { @@ -493,11 +719,11 @@ public class NiciraNvpApi { login(); client.executeMethod(method); } - } catch (HttpException e) { + } catch (final HttpException e) { s_logger.error("HttpException caught while trying to connect to the Nicira NVP Controller", e); method.releaseConnection(); throw new NiciraNvpApiException("API call to Nicira NVP Controller Failed", e); - } catch (IOException e) { + } catch (final IOException e) { s_logger.error("IOException caught while trying to connect to the Nicira NVP Controller", e); method.releaseConnection(); throw new NiciraNvpApiException("API call to Nicira NVP Controller Failed", e); @@ -513,7 +739,7 @@ public class NiciraNvpApi { // and will clutter the logs try { return method.getResponseBodyAsString(BODY_RESP_MAX_LEN); - } catch (IOException e) { + } catch (final IOException e) { s_logger.debug("Error while loading response body", e); } } @@ -533,7 +759,7 @@ public class NiciraNvpApi { public TrustingProtocolSocketFactory() throws IOException { // Create a trust manager that does not validate certificate chains - TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { + final TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; @@ -552,12 +778,12 @@ public class NiciraNvpApi { try { // Install the all-trusting trust manager - SSLContext sc = SSLContext.getInstance("SSL"); + final SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); ssf = sc.getSocketFactory(); - } catch (KeyManagementException e) { + } catch (final KeyManagementException e) { throw new IOException(e); - } catch (NoSuchAlgorithmException e) { + } catch (final NoSuchAlgorithmException e) { throw new IOException(e); } } @@ -580,11 +806,11 @@ public class NiciraNvpApi { @Override public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort, final HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { - int timeout = params.getConnectionTimeout(); + final int timeout = params.getConnectionTimeout(); if (timeout == 0) { return createSocket(host, port, localAddress, localPort); } else { - Socket s = ssf.createSocket(); + final Socket s = ssf.createSocket(); s.bind(new InetSocketAddress(localAddress, localPort)); s.connect(new InetSocketAddress(host, port), timeout); return s; @@ -596,13 +822,13 @@ public class NiciraNvpApi { @Override public NatRule deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) throws JsonParseException { - JsonObject jsonObject = jsonElement.getAsJsonObject(); + final JsonObject jsonObject = jsonElement.getAsJsonObject(); if (!jsonObject.has("type")) { throw new JsonParseException("Deserializing as a NatRule, but no type present in the json object"); } - String natRuleType = jsonObject.get("type").getAsString(); + final String natRuleType = jsonObject.get("type").getAsString(); if ("SourceNatRule".equals(natRuleType)) { return context.deserialize(jsonElement, SourceNatRule.class); } else if ("DestinationNatRule".equals(natRuleType)) { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityProfile.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityProfile.java new file mode 100644 index 00000000000..fb3f0743cd0 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityProfile.java @@ -0,0 +1,21 @@ +// 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.nicira; + +@SuppressWarnings("serial") +public class SecurityProfile extends AccessConfiguration { +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityRule.java new file mode 100644 index 00000000000..06181f0725d --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityRule.java @@ -0,0 +1,135 @@ +// 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.nicira; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +@SuppressWarnings("serial") +public class SecurityRule extends AccessRule { + + protected String ipPrefix; + + protected int portRangeMin; + + protected int portRangeMax; + + protected String profileUuid; + + + /** + * Default constructor + */ + public SecurityRule() { + } + + /** + * Fully parameterized constructor + */ + public SecurityRule(final String ethertype, final String ipPrefix, final String profileUuid, + final int portRangeMin, final int portRangeMax, final int protocol) { + this.ethertype = ethertype; + this.ipPrefix = ipPrefix; + this.portRangeMin = portRangeMin; + this.portRangeMax = portRangeMax; + this.profileUuid = profileUuid; + this.protocol = protocol; + } + + @Override + public String getEthertype() { + return ethertype; + } + + @Override + public void setEthertype(final String ethertype) { + this.ethertype = ethertype; + } + + public String getIpPrefix() { + return ipPrefix; + } + + public void setIpPrefix(final String ipPrefix) { + this.ipPrefix = ipPrefix; + } + + public int getPortRangeMin() { + return portRangeMin; + } + + public void setPortRangeMin(final int portRangeMin) { + this.portRangeMin = portRangeMin; + } + + public int getPortRangeMax() { + return portRangeMax; + } + + public void setPortRangeMax(final int portRangeMax) { + this.portRangeMax = portRangeMax; + } + + public String getProfileUuid() { + return profileUuid; + } + + public void setProfileUuid(final String profileUuid) { + this.profileUuid = profileUuid; + } + + @Override + public int getProtocol() { + return protocol; + } + + @Override + public void setProtocol(final int protocol) { + this.protocol = protocol; + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 31) + .append(ethertype).append(ipPrefix) + .append(portRangeMin).append(portRangeMax) + .append(profileUuid).append(protocol) + .toHashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof SecurityRule)) { + return false; + } + final SecurityRule another = (SecurityRule) obj; + return new EqualsBuilder() + .append(ethertype, another.ethertype) + .append(ipPrefix, another.ipPrefix) + .append(portRangeMin, another.portRangeMin) + .append(portRangeMax, another.portRangeMax) + .append(profileUuid, another.profileUuid) + .append(protocol, another.protocol) + .isEquals(); + } +} diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiIT.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiIT.java new file mode 100644 index 00000000000..c541d87cae3 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiIT.java @@ -0,0 +1,163 @@ +// 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.nicira; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.cloud.utils.PropertiesUtil; + +public class NiciraNvpApiIT { + + protected NiciraNvpApi api; + + protected long timestamp = System.currentTimeMillis(); + + @Before + public void setup() throws IOException { + final Properties properties = new Properties(); + PropertiesUtil.loadFromFile(properties, PropertiesUtil.findConfigFile("config.properties")); + api = new NiciraNvpApi(); + api.setControllerAddress(properties.getProperty("nvp.host")); + api.setAdminCredentials(properties.getProperty("nvp.admin.user"), + properties.getProperty("nvp.admin.pwd")); + } + + @Test + public void testCRUDSecurityProfile() throws NiciraNvpApiException { + SecurityProfile sProfile = new SecurityProfile(); + sProfile.setDisplayName("SecProfile"+timestamp); + + final List egressRules = new ArrayList(); + sProfile.setLogicalPortEgressRules(egressRules); + egressRules.add(new SecurityRule(SecurityRule.ETHERTYPE_IPV4, "1.10.10.0", null, 80, 88, 6)); + egressRules.add(new SecurityRule(SecurityRule.ETHERTYPE_IPV6, "2a80:34ac::1", null, 90, 98, 6)); + + final List ingressRules = new ArrayList(); + sProfile.setLogicalPortIngressRules(ingressRules); + ingressRules.add(new SecurityRule(SecurityRule.ETHERTYPE_IPV4, "1.10.10.0", null, 50, 58, 6)); + ingressRules.add(new SecurityRule(SecurityRule.ETHERTYPE_IPV6, "280a:3ac4::1", null, 60, 68, 6)); + + final List tags = new ArrayList(); + sProfile.setTags(tags); + tags.add(new NiciraNvpTag("nvp", "MyTag1")); + tags.add(new NiciraNvpTag("nicira", "MyTag2")); + // In the creation we don't get to specify UUID, href or schema: they don't exist yet + + try { + sProfile = api.createSecurityProfile(sProfile); + + // We can now update the new entity + sProfile.setDisplayName("UpdatedSecProfile"+timestamp); + api.updateSecurityProfile(sProfile, sProfile.getUuid()); + + // Read them all + NiciraNvpList profiles = api.findSecurityProfile(); + SecurityProfile scInList = null; + for(final SecurityProfile iProfile : profiles.getResults()) { + if (iProfile.getUuid().equalsIgnoreCase(sProfile.getUuid())) { + scInList = iProfile; + } + } + Assert.assertEquals("Read a Security Profile different from the one just created and updated", + sProfile, scInList); + + // Read them filtered by uuid (get one) + profiles = api.findSecurityProfile(sProfile.getUuid()); + Assert.assertEquals("Read a Security Profile different from the one just created and updated", + sProfile, + profiles.getResults().get(0)); + Assert.assertEquals("Read a Security Profile filtered by unique id (UUID) with more than one item", + 1, profiles.getResults().size()); + + // We can now delete the new entity + api.deleteSecurityProfile(sProfile.getUuid()); + } catch (final NiciraNvpApiException e) { + e.printStackTrace(); + assertTrue("Errors creating Security Profile", false); + } + } + + @Test + public void testCRUDAcl() throws NiciraNvpApiException { + Acl acl = new Acl(); + acl.setDisplayName("Acl"+timestamp); + + // Note that if the protocol is 6 (TCP) then you cannot put ICMP code and type + // Note that if the protocol is 1 (ICMP) then you cannot put ports + final List egressRules = new ArrayList(); + acl.setLogicalPortEgressRules(egressRules); + egressRules.add(new AclRule(AclRule.ETHERTYPE_IPV4, 1, "allow", null, null, + "1.10.10.0", "1.10.10.1", null, null, null, null, 0, 0, 5)); + egressRules.add(new AclRule(AclRule.ETHERTYPE_IPV4, 6, "allow", null, null, + "1.10.10.6", "1.10.10.7", 80, 80, 80, 80, 1, null, null)); + + final List ingressRules = new ArrayList(); + acl.setLogicalPortIngressRules(ingressRules); + ingressRules.add(new AclRule(AclRule.ETHERTYPE_IPV4, 1, "allow", null, null, + "1.10.10.0", "1.10.10.1", null, null, null, null, 0, 0, 5)); + ingressRules.add(new AclRule(AclRule.ETHERTYPE_IPV4, 6, "allow", null, null, + "1.10.10.6", "1.10.10.7", 80, 80, 80, 80, 1, null, null)); + + final List tags = new ArrayList(); + acl.setTags(tags); + tags.add(new NiciraNvpTag("nvp", "MyTag1")); + tags.add(new NiciraNvpTag("nicira", "MyTag2")); + // In the creation we don't get to specify UUID, href or schema: they don't exist yet + + try { + acl = api.createAcl(acl); + + // We can now update the new entity + acl.setDisplayName("UpdatedAcl"+timestamp); + api.updateAcl(acl, acl.getUuid()); + + // Read them all + NiciraNvpList acls = api.findAcl(); + Acl scInList = null; + for(final Acl iAcl : acls.getResults()) { + if (iAcl.getUuid().equalsIgnoreCase(acl.getUuid())) { + scInList = iAcl; + } + } + Assert.assertEquals("Read a ACL different from the one just created and updated", + acl, scInList); + + // Read them filtered by uuid (get one) + acls = api.findAcl(acl.getUuid()); + Assert.assertEquals("Read a ACL different from the one just created and updated", + acl, + acls.getResults().get(0)); + Assert.assertEquals("Read a ACL filtered by unique id (UUID) with more than one item", + 1, acls.getResults().size()); + + // We can now delete the new entity + api.deleteAcl(acl.getUuid()); + } catch (final NiciraNvpApiException e) { + e.printStackTrace(); + assertTrue("Errors creating ACL", false); + } + } +} diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiTest.java index 26517b5fb88..2e4cfaf1a05 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiTest.java @@ -17,6 +17,7 @@ package com.cloud.network.nicira; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -35,18 +36,46 @@ import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.params.HttpClientParams; +import org.apache.commons.httpclient.NameValuePair; import org.apache.http.HttpStatus; import org.junit.Before; import org.junit.Test; public class NiciraNvpApiTest { + protected static final String UUID = "aaaa"; + protected static final String UUID2 = "bbbb"; + protected static final String UUID_SEC_PROFILE_URI = NiciraNvpApi.SEC_PROFILE_URI_PREFIX + "/aaaa"; + protected static final String SCHEMA = "myTestSchema"; + protected static final String SCHEMA2 = "myTestSchema2"; + protected static final String HREF = "myTestHref"; + protected static final String HREF2 = "myTestHref2"; + protected static final String DISPLAY_NAME = "myTestName"; + protected static final String UUID_JSON_RESPONSE = "{\"uuid\" : \"aaaa\"}"; + protected static final String SEC_PROFILE_JSON_RESPONSE = + "{\"uuid\" : \"aaaa\"," + + "\"display_name\" : \"myTestName\"," + + "\"href\" : \"myTestHref\"," + + "\"schema\" : \"myTestSchema\"}"; + + protected static final String SEC_PROFILE_LIST_JSON_RESPONSE = "{\"results\" : [{\"uuid\" : \"aaaa\"," + + "\"display_name\" : \"myTestName\"," + + "\"href\" : \"myTestHref\"," + + "\"schema\" : \"myTestSchema\"}," + + "{ \"uuid\" : \"bbbb\"," + + "\"display_name\" : \"myTestName2\"," + + "\"href\" : \"myTestHref2\"," + + "\"schema\" : \"myTestSchema2\"}]," + + "\"result_count\": 2}"; + NiciraNvpApi api; HttpClient client = mock(HttpClient.class); HttpMethod method; + String type; + String uri; @Before public void setUp() { - HttpClientParams hmp = mock(HttpClientParams.class); + final HttpClientParams hmp = mock(HttpClientParams.class); when(client.getParams()).thenReturn(hmp); api = new NiciraNvpApi() { @Override @@ -55,7 +84,9 @@ public class NiciraNvpApiTest { } @Override - protected HttpMethod createMethod(String type, String uri) { + protected HttpMethod createMethod(final String newType, final String newUri) { + type = newType; + uri = newUri; return method; } }; @@ -125,7 +156,7 @@ public class NiciraNvpApiTest { @Test public void executeMethodTest() throws NiciraNvpApiException { - GetMethod gm = mock(GetMethod.class); + final GetMethod gm = mock(GetMethod.class); when(gm.getStatusCode()).thenReturn(HttpStatus.SC_OK); api.executeMethod(gm); @@ -137,7 +168,7 @@ public class NiciraNvpApiTest { */ @Test(expected = NiciraNvpApiException.class) public void executeMethodTestWithLogin() throws NiciraNvpApiException, HttpException, IOException { - GetMethod gm = mock(GetMethod.class); + final GetMethod gm = mock(GetMethod.class); when(client.executeMethod((HttpMethod)any())).thenThrow(new HttpException()); when(gm.getStatusCode()).thenReturn(HttpStatus.SC_UNAUTHORIZED).thenReturn(HttpStatus.SC_UNAUTHORIZED); api.executeMethod(gm); @@ -149,9 +180,9 @@ public class NiciraNvpApiTest { LogicalSwitch ls = new LogicalSwitch(); method = mock(PostMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_CREATED); - when(method.getResponseBodyAsString()).thenReturn("{ \"uuid\" : \"aaaa\" }"); + when(method.getResponseBodyAsString()).thenReturn(UUID_JSON_RESPONSE); ls = api.executeCreateObject(ls, LogicalSwitch.class, "/", Collections. emptyMap()); - assertTrue("aaaa".equals(ls.getUuid())); + assertTrue(UUID.equals(ls.getUuid())); verify(method, times(1)).releaseConnection(); } @@ -161,7 +192,7 @@ public class NiciraNvpApiTest { LogicalSwitch ls = new LogicalSwitch(); method = mock(PostMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); - Header header = mock(Header.class); + final Header header = mock(Header.class); when(header.getValue()).thenReturn("text/html"); when(method.getResponseHeader("Content-Type")).thenReturn(header); when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); @@ -179,7 +210,7 @@ public class NiciraNvpApiTest { when(client.executeMethod((HttpMethod)any())).thenThrow(new HttpException()); method = mock(PostMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); - Header header = mock(Header.class); + final Header header = mock(Header.class); when(header.getValue()).thenReturn("text/html"); when(method.getResponseHeader("Content-Type")).thenReturn(header); when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); @@ -192,7 +223,7 @@ public class NiciraNvpApiTest { @Test public void testExecuteUpdateObject() throws NiciraNvpApiException, IOException { - LogicalSwitch ls = new LogicalSwitch(); + final LogicalSwitch ls = new LogicalSwitch(); method = mock(PutMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); api.executeUpdateObject(ls, "/", Collections. emptyMap()); @@ -202,10 +233,10 @@ public class NiciraNvpApiTest { @Test(expected = NiciraNvpApiException.class) public void testExecuteUpdateObjectFailure() throws NiciraNvpApiException, IOException { - LogicalSwitch ls = new LogicalSwitch(); + final LogicalSwitch ls = new LogicalSwitch(); method = mock(PutMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); - Header header = mock(Header.class); + final Header header = mock(Header.class); when(header.getValue()).thenReturn("text/html"); when(method.getResponseHeader("Content-Type")).thenReturn(header); when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); @@ -219,7 +250,7 @@ public class NiciraNvpApiTest { @Test(expected = NiciraNvpApiException.class) public void testExecuteUpdateObjectException() throws NiciraNvpApiException, IOException { - LogicalSwitch ls = new LogicalSwitch(); + final LogicalSwitch ls = new LogicalSwitch(); method = mock(PutMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); when(client.executeMethod((HttpMethod)any())).thenThrow(new IOException()); @@ -243,7 +274,7 @@ public class NiciraNvpApiTest { public void testExecuteDeleteObjectFailure() throws NiciraNvpApiException, IOException { method = mock(DeleteMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); - Header header = mock(Header.class); + final Header header = mock(Header.class); when(header.getValue()).thenReturn("text/html"); when(method.getResponseHeader("Content-Type")).thenReturn(header); when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); @@ -271,7 +302,7 @@ public class NiciraNvpApiTest { public void testExecuteRetrieveObject() throws NiciraNvpApiException, IOException { method = mock(GetMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); - when(method.getResponseBodyAsString()).thenReturn("{ \"uuid\" : \"aaaa\" }"); + when(method.getResponseBodyAsString()).thenReturn(UUID_JSON_RESPONSE); api.executeRetrieveObject(LogicalSwitch.class, "/", Collections. emptyMap()); verify(method, times(1)).releaseConnection(); verify(client, times(1)).executeMethod(method); @@ -281,8 +312,8 @@ public class NiciraNvpApiTest { public void testExecuteRetrieveObjectFailure() throws NiciraNvpApiException, IOException { method = mock(GetMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); - when(method.getResponseBodyAsString()).thenReturn("{ \"uuid\" : \"aaaa\" }"); - Header header = mock(Header.class); + when(method.getResponseBodyAsString()).thenReturn(UUID_JSON_RESPONSE); + final Header header = mock(Header.class); when(header.getValue()).thenReturn("text/html"); when(method.getResponseHeader("Content-Type")).thenReturn(header); when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); @@ -298,7 +329,7 @@ public class NiciraNvpApiTest { public void testExecuteRetrieveObjectException() throws NiciraNvpApiException, IOException { method = mock(GetMethod.class); when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); - when(method.getResponseBodyAsString()).thenReturn("{ \"uuid\" : \"aaaa\" }"); + when(method.getResponseBodyAsString()).thenReturn(UUID_JSON_RESPONSE); when(client.executeMethod((HttpMethod)any())).thenThrow(new HttpException()); try { api.executeRetrieveObject(LogicalSwitch.class, "/", Collections. emptyMap()); @@ -307,4 +338,135 @@ public class NiciraNvpApiTest { } } + @Test + public void testFindSecurityProfile() throws NiciraNvpApiException, IOException { + // Prepare + method = mock(GetMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); + when(method.getResponseBodyAsString()).thenReturn(SEC_PROFILE_LIST_JSON_RESPONSE); + final NameValuePair[] queryString = new NameValuePair[]{ + new NameValuePair("fields","*")}; + + // Execute + final NiciraNvpList actualProfiles = api.findSecurityProfile(); + + // Assert + verify(method, times(1)).releaseConnection(); + verify(method, times(1)).setQueryString(queryString); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + UUID, actualProfiles.getResults().get(0).getUuid()); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + HREF, actualProfiles.getResults().get(0).getHref()); + assertEquals("Wrong Schema in the newly created SecurityProfile", + SCHEMA, actualProfiles.getResults().get(0).getSchema()); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + UUID2, actualProfiles.getResults().get(1).getUuid()); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + HREF2, actualProfiles.getResults().get(1).getHref()); + assertEquals("Wrong Schema in the newly created SecurityProfile", + SCHEMA2, actualProfiles.getResults().get(1).getSchema()); + assertEquals("Wrong Schema in the newly created SecurityProfile", + 2, actualProfiles.getResultCount()); + assertEquals("Wrong URI for SecurityProfile creation REST service", + NiciraNvpApi.SEC_PROFILE_URI_PREFIX, uri); + assertEquals("Wrong URI for SecurityProfile creation REST service", + NiciraNvpApi.GET_METHOD_TYPE, type); + } + + @Test + public void testFindSecurityProfileByUuid() throws NiciraNvpApiException, IOException { + // Prepare + method = mock(GetMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); + when(method.getResponseBodyAsString()).thenReturn(SEC_PROFILE_LIST_JSON_RESPONSE); + final NameValuePair[] queryString = new NameValuePair[]{ + new NameValuePair("uuid", UUID), + new NameValuePair("fields","*") + }; + + // Execute + final NiciraNvpList actualProfiles = api.findSecurityProfile(UUID); + + // Assert + verify(method, times(1)).releaseConnection(); + verify(method, times(1)).setQueryString(queryString); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + UUID, actualProfiles.getResults().get(0).getUuid()); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + HREF, actualProfiles.getResults().get(0).getHref()); + assertEquals("Wrong Schema in the newly created SecurityProfile", + SCHEMA, actualProfiles.getResults().get(0).getSchema()); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + UUID2, actualProfiles.getResults().get(1).getUuid()); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + HREF2, actualProfiles.getResults().get(1).getHref()); + assertEquals("Wrong Schema in the newly created SecurityProfile", + SCHEMA2, actualProfiles.getResults().get(1).getSchema()); + assertEquals("Wrong Schema in the newly created SecurityProfile", + 2, actualProfiles.getResultCount()); + assertEquals("Wrong URI for SecurityProfile creation REST service", + NiciraNvpApi.SEC_PROFILE_URI_PREFIX, uri); + assertEquals("Wrong HTTP method for SecurityProfile creation REST service", + NiciraNvpApi.GET_METHOD_TYPE, type); + } + + @Test + public void testCreateSecurityProfile() throws NiciraNvpApiException, IOException { + // Prepare + final SecurityProfile inputSecProfile = new SecurityProfile(); + method = mock(PostMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_CREATED); + when(method.getResponseBodyAsString()).thenReturn(SEC_PROFILE_JSON_RESPONSE); + + // Execute + final SecurityProfile actualSecProfile = api.createSecurityProfile(inputSecProfile); + + // Assert + verify(method, times(1)).releaseConnection(); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + UUID, actualSecProfile.getUuid()); + assertEquals("Wrong Uuid in the newly created SecurityProfile", + HREF, actualSecProfile.getHref()); + assertEquals("Wrong Schema in the newly created SecurityProfile", + SCHEMA, actualSecProfile.getSchema()); + assertEquals("Wrong URI for SecurityProfile creation REST service", + NiciraNvpApi.SEC_PROFILE_URI_PREFIX, uri); + assertEquals("Wrong HTTP method for SecurityProfile creation REST service", + NiciraNvpApi.POST_METHOD_TYPE, type); + } + + @Test + public void testUpdateSecurityProfile() throws NiciraNvpApiException, IOException { + // Prepare + final SecurityProfile inputSecProfile = new SecurityProfile(); + method = mock(PutMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); + + // Execute + api.updateSecurityProfile(inputSecProfile, UUID); + + // Assert + verify(method, times(1)).releaseConnection(); + assertEquals("Wrong URI for SecurityProfile creation REST service", + UUID_SEC_PROFILE_URI, uri); + assertEquals("Wrong HTTP method for SecurityProfile creation REST service", + NiciraNvpApi.PUT_METHOD_TYPE, type); + } + + @Test + public void testDeleteSecurityProfile() throws NiciraNvpApiException, IOException { + // Prepare + method = mock(DeleteMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + + // Execute + api.deleteSecurityProfile(UUID); + + // Assert + verify(method, times(1)).releaseConnection(); + assertEquals("Wrong URI for SecurityProfile deletion REST service", + UUID_SEC_PROFILE_URI, uri); + assertEquals("Wrong HTTP method for SecurityProfile deletion REST service", + NiciraNvpApi.DELETE_METHOD_TYPE, type); + } } diff --git a/plugins/network-elements/nicira-nvp/test/resources/config.properties b/plugins/network-elements/nicira-nvp/test/resources/config.properties new file mode 100644 index 00000000000..67576923823 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/test/resources/config.properties @@ -0,0 +1,21 @@ +# 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. + + +nvp.host=${nvp-host} +nvp.admin.user=${nvp-admin-user} +nvp.admin.pwd=${nvp-admin-pwd}