From: Brent Salisbury Date: Sat, 24 May 2014 23:52:44 +0000 (-0400) Subject: Neutron API v2.0 bindings and APIs for security groups/rules. X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~25^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=e21c4dbc23761ee73360dabbd196428167388c05 Neutron API v2.0 bindings and APIs for security groups/rules. -This is to enhance the ODL/OpenStack ML2 integration work to include port security services. https://wiki.openstack.org/wiki/Neutron/APIv2-specification Change-Id: Ice5c2fd12381732ab1cbb2394fd67ffed1dcf62c Signed-off-by: Brent Salisbury --- diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java index c30f659032..f101538196 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java @@ -22,6 +22,8 @@ import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD; import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase; public class Activator extends ComponentActivatorAbstractBase { @@ -163,5 +165,37 @@ public class Activator extends ComponentActivatorAbstractBase { "setConfigurationContainerService", "unsetConfigurationContainerService").setRequired(true)); } + if (imp.equals(NeutronSecurityGroupInterface.class)) { + // export the service + c.setInterface( + new String[] { INeutronSecurityGroupCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); + Dictionary props = new Hashtable(); + props.put("salListenerName", "neutron"); + c.add(createContainerServiceDependency(containerName) + .setService(IClusterContainerServices.class) + .setCallbacks("setClusterContainerService", + "unsetClusterContainerService").setRequired(true)); + c.add(createContainerServiceDependency(containerName).setService( + IConfigurationContainerService.class).setCallbacks( + "setConfigurationContainerService", + "unsetConfigurationContainerService").setRequired(true)); + } + if (imp.equals(NeutronSecurityRuleInterface.class)) { + // export the service + c.setInterface( + new String[] { INeutronSecurityRuleCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); + Dictionary props = new Hashtable(); + props.put("salListenerName", "neutron"); + c.add(createContainerServiceDependency(containerName) + .setService(IClusterContainerServices.class) + .setCallbacks("setClusterContainerService", + "unsetClusterContainerService").setRequired(true)); + c.add(createContainerServiceDependency(containerName).setService( + IConfigurationContainerService.class).setCallbacks( + "setConfigurationContainerService", + "unsetConfigurationContainerService").setRequired(true)); + } } } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java new file mode 100644 index 0000000000..a991f61fcb --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron.implementation; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import org.apache.felix.dm.Component; +import org.opendaylight.controller.clustering.services.CacheConfigException; +import org.opendaylight.controller.clustering.services.CacheExistException; +import org.opendaylight.controller.clustering.services.IClusterContainerServices; +import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.ConfigurationObject; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; +import org.opendaylight.controller.configuration.IConfigurationContainerService; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class NeutronSecurityGroupInterface implements INeutronSecurityGroupCRUD, IConfigurationContainerAware, IObjectReader { + private static final Logger logger = LoggerFactory.getLogger(NeutronSecurityGroupInterface.class); + private static final String FILE_NAME ="neutron.securitygroup.conf"; + private String containerName = null; + + private IClusterContainerServices clusterContainerService = null; + private IConfigurationContainerService configurationService; + private ConcurrentMap securityGroupDB; + + // methods needed for creating caches + void setClusterContainerService(IClusterContainerServices s) { + logger.debug("Cluster Service set"); + clusterContainerService = s; + } + + void unsetClusterContainerService(IClusterContainerServices s) { + if (clusterContainerService == s) { + logger.debug("Cluster Service removed!"); + clusterContainerService = null; + } + } + + public void setConfigurationContainerService(IConfigurationContainerService service) { + logger.trace("Configuration service set: {}", service); + configurationService = service; + } + + public void unsetConfigurationContainerService(IConfigurationContainerService service) { + logger.trace("Configuration service removed: {}", service); + configurationService = null; + } + + private void allocateCache() { + if (this.clusterContainerService == null) { + logger.error("un-initialized clusterContainerService, can't create cache"); + return; + } + logger.debug("Creating Cache for Neutron Security Groups"); + try { + // neutron caches + this.clusterContainerService.createCache("neutronSecurityGroups", + EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL)); + } catch (CacheConfigException cce) { + logger.error("Cache couldn't be created for Neutron Security Groups - check cache mode"); + } catch (CacheExistException cce) { + logger.error("Cache for Neutron Security Groups already exists, destroy and recreate"); + } + logger.debug("Cache successfully created for Neutron Security Groups"); + } + + @SuppressWarnings({ "unchecked" }) + private void retrieveCache() { + if (clusterContainerService == null) { + logger.error("un-initialized clusterContainerService, can't retrieve cache"); + return; + } + + logger.debug("Retrieving cache for Neutron Security Groups"); + securityGroupDB = (ConcurrentMap) clusterContainerService + .getCache("neutronSecurityGroups"); + if (securityGroupDB == null) { + logger.error("Cache couldn't be retrieved for Neutron Security Groups"); + } + logger.debug("Cache was successfully retrieved for Neutron Security Groups"); + } + + private void destroyCache() { + if (clusterContainerService == null) { + logger.error("un-initialized clusterMger, can't destroy cache"); + return; + } + logger.debug("Destroying Cache for Neutron Security Groups"); + clusterContainerService.destroyCache("neutronSecurityGroups"); + } + + private void startUp() { + allocateCache(); + retrieveCache(); + loadConfiguration(); + } + + /** + * Function called by the dependency manager when all the required + * dependencies are satisfied + * + */ + void init(Component c) { + Dictionary props = c.getServiceProperties(); + if (props != null) { + this.containerName = (String) props.get("containerName"); + logger.debug("Running containerName: {}", this.containerName); + } else { + // In the Global instance case the containerName is empty + this.containerName = ""; + } + startUp(); + } + + /** + * Function called by the dependency manager when at least one dependency + * become unsatisfied or when the component is shutting down because for + * example bundle is being stopped. + * + */ + void destroy() { + destroyCache(); + } + + /** + * Function called by dependency manager after "init ()" is called and after + * the services provided by the class are registered in the service registry + * + */ + void start() { + } + + /** + * Function called by the dependency manager before the services exported by + * the component are unregistered, this will be followed by a "destroy ()" + * calls + * + */ + void stop() { + } + + // this method uses reflection to update an object from it's delta. + + private boolean overwrite(Object target, Object delta) { + Method[] methods = target.getClass().getMethods(); + + for(Method toMethod: methods){ + if(toMethod.getDeclaringClass().equals(target.getClass()) + && toMethod.getName().startsWith("set")){ + + String toName = toMethod.getName(); + String fromName = toName.replace("set", "get"); + + try { + Method fromMethod = delta.getClass().getMethod(fromName); + Object value = fromMethod.invoke(delta, (Object[])null); + if(value != null){ + toMethod.invoke(target, value); + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + } + return true; + } + + @Override + public boolean neutronSecurityGroupExists(String uuid) { + return securityGroupDB.containsKey(uuid); + } + + @Override + public NeutronSecurityGroup getNeutronSecurityGroup(String uuid) { + if (!neutronSecurityGroupExists(uuid)) { + logger.debug("No Security Groups Have Been Defined"); + return null; + } + return securityGroupDB.get(uuid); + } + + @Override + public List getAllNeutronSecurityGroups() { + Set allSecurityGroups = new HashSet(); + for (Entry entry : securityGroupDB.entrySet()) { + NeutronSecurityGroup securityGroup = entry.getValue(); + allSecurityGroups.add(securityGroup); + } + logger.debug("Exiting getSecurityGroups, Found {} OpenStackSecurityGroup", allSecurityGroups.size()); + List ans = new ArrayList(); + ans.addAll(allSecurityGroups); + return ans; + } + + @Override + public boolean addNeutronSecurityGroup(NeutronSecurityGroup input) { + if (neutronSecurityGroupExists(input.getSecurityGroupUUID())) { + return false; + } + securityGroupDB.putIfAbsent(input.getSecurityGroupUUID(), input); + return true; + } + + @Override + public boolean removeNeutronSecurityGroup(String uuid) { + if (!neutronSecurityGroupExists(uuid)) { + return false; + } + securityGroupDB.remove(uuid); + return true; + } + + @Override + public boolean updateNeutronSecurityGroup(String uuid, NeutronSecurityGroup delta) { + if (!neutronSecurityGroupExists(uuid)) { + return false; + } + NeutronSecurityGroup target = securityGroupDB.get(uuid); + return overwrite(target, delta); + } + + @Override + public boolean neutronSecurityGroupInUse(String securityGroupUUID) { + return !neutronSecurityGroupExists(securityGroupUUID); + } + + private void loadConfiguration() { + for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, FILE_NAME)) { + NeutronSecurityGroup nn = (NeutronSecurityGroup) conf; + securityGroupDB.put(nn.getSecurityGroupUUID(), nn); + } + } + + @Override + public Status saveConfiguration() { + return configurationService.persistConfiguration(new ArrayList(securityGroupDB.values()), + FILE_NAME); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + +} \ No newline at end of file diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java new file mode 100644 index 0000000000..5ca907b2b3 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron.implementation; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; + +import org.apache.felix.dm.Component; +import org.opendaylight.controller.clustering.services.CacheConfigException; +import org.opendaylight.controller.clustering.services.CacheExistException; +import org.opendaylight.controller.clustering.services.IClusterContainerServices; +import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.ConfigurationObject; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; +import org.opendaylight.controller.configuration.IConfigurationContainerService; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class NeutronSecurityRuleInterface implements INeutronSecurityRuleCRUD, IConfigurationContainerAware, IObjectReader { + private static final Logger logger = LoggerFactory.getLogger(NeutronSecurityRuleInterface.class); + private static final String FILE_NAME = "neutron.securityrule.conf"; + private String containerName = null; + + private IClusterContainerServices clusterContainerService = null; + private IConfigurationContainerService configurationService; + private ConcurrentMap securityRuleDB; + + // methods needed for creating caches + void setClusterContainerService(IClusterContainerServices s) { + logger.debug("Cluster Service set"); + clusterContainerService = s; + } + + void unsetClusterContainerService(IClusterContainerServices s) { + if (clusterContainerService == s) { + logger.debug("Cluster Service removed!"); + clusterContainerService = null; + } + } + + public void setConfigurationContainerService(IConfigurationContainerService service) { + logger.trace("Configuration service set: {}", service); + configurationService = service; + } + + public void unsetConfigurationContainerService(IConfigurationContainerService service) { + logger.trace("Configuration service removed: {}", service); + configurationService = null; + } + + private void allocateCache() { + if (this.clusterContainerService == null) { + logger.error("un-initialized clusterContainerService, can't create cache"); + return; + } + logger.debug("Creating Cache for Neutron Security Rules"); + try { + // neutron caches + this.clusterContainerService.createCache("neutronSecurityRules", + EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL)); + } catch (CacheConfigException cce) { + logger.error("Cache couldn't be created for Neutron Security Rules - check cache mode"); + } catch (CacheExistException cce) { + logger.error("Cache for Neutron Security Rules already exists, destroy and recreate"); + } + logger.debug("Cache successfully created for Neutron Security Rules"); + } + + @SuppressWarnings({"unchecked"}) + private void retrieveCache() { + if (clusterContainerService == null) { + logger.error("un-initialized clusterContainerService, can't retrieve cache"); + return; + } + + logger.debug("Retrieving cache for Neutron Security Rules"); + securityRuleDB = (ConcurrentMap) clusterContainerService + .getCache("neutronSecurityRules"); + if (securityRuleDB == null) { + logger.error("Cache couldn't be retrieved for Neutron Security Rules"); + } + logger.debug("Cache was successfully retrieved for Neutron Security Rules"); + } + + private void destroyCache() { + if (clusterContainerService == null) { + logger.error("un-initialized clusterMger, can't destroy cache"); + return; + } + logger.debug("Destroying Cache for Neutron Security Rules"); + clusterContainerService.destroyCache("neutronSecurityRules"); + } + + private void startUp() { + allocateCache(); + retrieveCache(); + loadConfiguration(); + } + + /** + * Function called by the dependency manager when all the required + * dependencies are satisfied + */ + void init(Component c) { + Dictionary props = c.getServiceProperties(); + if (props != null) { + this.containerName = (String) props.get("containerName"); + logger.debug("Running containerName: {}", this.containerName); + } else { + // In the Global instance case the containerName is empty + this.containerName = ""; + } + startUp(); + } + + /** + * Function called by the dependency manager when at least one dependency + * become unsatisfied or when the component is shutting down because for + * example bundle is being stopped. + */ + void destroy() { + destroyCache(); + } + + /** + * Function called by dependency manager after "init ()" is called and after + * the services provided by the class are registered in the service registry + */ + void start() { + } + + /** + * Function called by the dependency manager before the services exported by + * the component are unregistered, this will be followed by a "destroy ()" + * calls + */ + void stop() { + } + + // this method uses reflection to update an object from it's delta. + private boolean overwrite(Object target, Object delta) { + Method[] methods = target.getClass().getMethods(); + + for (Method toMethod : methods) { + if (toMethod.getDeclaringClass().equals(target.getClass()) + && toMethod.getName().startsWith("set")) { + + String toName = toMethod.getName(); + String fromName = toName.replace("set", "get"); + + try { + Method fromMethod = delta.getClass().getMethod(fromName); + Object value = fromMethod.invoke(delta, (Object[]) null); + if (value != null) { + toMethod.invoke(target, value); + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + } + return true; + } + + @Override + public boolean neutronSecurityRuleExists(String uuid) { + return securityRuleDB.containsKey(uuid); + } + + @Override + public NeutronSecurityRule getNeutronSecurityRule(String uuid) { + if (!neutronSecurityRuleExists(uuid)) { + logger.debug("No Security Rules Have Been Defined"); + return null; + } + return securityRuleDB.get(uuid); + } + + @Override + public List getAllNeutronSecurityRules() { + Set allSecurityRules = new HashSet(); + for (Entry entry : securityRuleDB.entrySet()) { + NeutronSecurityRule securityRule = entry.getValue(); + allSecurityRules.add(securityRule); + } + logger.debug("Exiting getSecurityRule, Found {} OpenStackSecurityRule", allSecurityRules.size()); + List ans = new ArrayList(); + ans.addAll(allSecurityRules); + return ans; + } + + @Override + public boolean addNeutronSecurityRule(NeutronSecurityRule input) { + if (neutronSecurityRuleExists(input.getSecurityRuleUUID())) { + return false; + } + securityRuleDB.putIfAbsent(input.getSecurityRuleUUID(), input); + return true; + } + + @Override + public boolean removeNeutronSecurityRule(String uuid) { + if (!neutronSecurityRuleExists(uuid)) { + return false; + } + securityRuleDB.remove(uuid); + return true; + } + + @Override + public boolean updateNeutronSecurityRule(String uuid, NeutronSecurityRule delta) { + if (!neutronSecurityRuleExists(uuid)) { + return false; + } + NeutronSecurityRule target = securityRuleDB.get(uuid); + return overwrite(target, delta); + } + + @Override + public boolean neutronSecurityRuleInUse(String securityRuleUUID) { + return !neutronSecurityRuleExists(securityRuleUUID); + } + + private void loadConfiguration() { + for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, FILE_NAME)) { + NeutronSecurityRule nn = (NeutronSecurityRule) conf; + securityRuleDB.put(nn.getSecurityRuleUUID(), nn); + } + } + + @Override + public Status saveConfiguration() { + return configurationService.persistConfiguration(new ArrayList(securityRuleDB.values()), + FILE_NAME); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + +} \ No newline at end of file diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java new file mode 100644 index 0000000000..0fdf77f968 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron; + +/** + * This interface defines the methods a service that wishes to be aware of Neutron Security Groups needs to implement + */ + +public interface INeutronSecurityGroupAware { + + /** + * Services provide this interface method to indicate if the specified security group can be created + * + * @param securityGroup instance of proposed new Neutron Security Group object + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the create operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canCreateNeutronSecurityGroup(NeutronSecurityGroup securityGroup); + + /** + * Services provide this interface method for taking action after a security group has been created + * + * @param securityGroup instance of new Neutron Security Group object + * @return void + */ + public void neutronSecurityGroupCreated(NeutronSecurityGroup securityGroup); + + /** + * Services provide this interface method to indicate if the specified security group can be changed using the specified + * delta + * + * @param delta updates to the security group object using patch semantics + * @param original instance of the Neutron Security Group object to be updated + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the update operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canUpdateNeutronSecurityGroup(NeutronSecurityGroup delta, NeutronSecurityGroup original); + + /** + * Services provide this interface method for taking action after a security group has been updated + * + * @param securityGroup instance of modified Neutron Security Group object + * @return void + */ + public void neutronSecurityGroupUpdated(NeutronSecurityGroup securityGroup); + + /** + * Services provide this interface method to indicate if the specified security group can be deleted + * + * @param securityGroup instance of the Neutron Security Group object to be deleted + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the delete operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canDeleteNeutronSecurityGroup(NeutronSecurityGroup securityGroup); + + /** + * Services provide this interface method for taking action after a security group has been deleted + * + * @param securityGroup instance of deleted Neutron Security Group object + * @return void + */ + public void neutronSecurityGroupDeleted(NeutronSecurityGroup securityGroup); +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java new file mode 100644 index 0000000000..a408ef92a7 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron; + +import java.util.List; + +/** + * This interface defines the methods for CRUD of NB OpenStack Security Group objects + */ + +public interface INeutronSecurityGroupCRUD { + /** + * Applications call this interface method to determine if a particular + * Security Group object exists + * + * @param uuid UUID of the Security Group object + * @return boolean + */ + + public boolean neutronSecurityGroupExists(String uuid); + + /** + * Applications call this interface method to return if a particular + * Security Group object exists + * + * @param uuid UUID of the Security Group object + * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup.OpenStackSecurity Groups} + * OpenStack Security Group class + */ + + public NeutronSecurityGroup getNeutronSecurityGroup(String uuid); + + /** + * Applications call this interface method to return all Security Group objects + * + * @return List of OpenStackSecurity Groups objects + */ + + public List getAllNeutronSecurityGroups(); + + /** + * Applications call this interface method to add a Security Group object to the + * concurrent map + * + * @param input OpenStackSecurity Group object + * @return boolean on whether the object was added or not + */ + + public boolean addNeutronSecurityGroup(NeutronSecurityGroup input); + + /** + * Applications call this interface method to remove a Neutron Security Group object to the + * concurrent map + * + * @param uuid identifier for the security group object + * @return boolean on whether the object was removed or not + */ + + public boolean removeNeutronSecurityGroup(String uuid); + + /** + * Applications call this interface method to edit a Security Group object + * + * @param uuid identifier of the security group object + * @param delta OpenStackSecurity Group object containing changes to apply + * @return boolean on whether the object was updated or not + */ + + public boolean updateNeutronSecurityGroup(String uuid, NeutronSecurityGroup delta); + + /** + * Applications call this interface method to see if a MAC address is in use + * + * @param uuid identifier of the security group object + * @return boolean on whether the Security Groups is already in use + */ + + public boolean neutronSecurityGroupInUse(String uuid); + +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java new file mode 100644 index 0000000000..ff2a1c4978 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron; + +/** + * This interface defines the methods required to be aware of Neutron Security Rules + */ + +public interface INeutronSecurityRuleAware { + + /** + * Services provide this interface method to indicate if the specified security rule can be created + * + * @param securityRule instance of proposed new Neutron Security Rule object + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the create operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canCreateNeutronSecurityRule(NeutronSecurityRule securityRule); + + /** + * Services provide this interface method for taking action after a security rule has been created + * + * @param securityRule instance of new Neutron Security Rule object + * @return void + */ + public void neutronSecurityRuleCreated(NeutronSecurityRule securityRule); + + /** + * Services provide this interface method to indicate if the specified security rule can be changed using the specified + * delta + * + * @param delta updates to the security rule object using patch semantics + * @param original instance of the Neutron Security Rule object to be updated + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the update operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canUpdateNeutronSecurityRule(NeutronSecurityRule delta, NeutronSecurityRule original); + + /** + * Services provide this interface method for taking action after a security rule has been updated + * + * @param securityRule instance of modified Neutron Security Rule object + * @return void + */ + public void neutronSecurityRuleUpdated(NeutronSecurityRule securityRule); + + /** + * Services provide this interface method to indicate if the specified security rule can be deleted + * + * @param securityRule instance of the Neutron Security Rule object to be deleted + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the delete operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canDeleteNeutronSecurityRule(NeutronSecurityRule securityRule); + + /** + * Services provide this interface method for taking action after a security rule has been deleted + * + * @param securityRule instance of deleted Neutron Security Rule object + * @return void + */ + public void neutronSecurityRuleDeleted(NeutronSecurityRule securityRule); +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java new file mode 100644 index 0000000000..73b41c71a4 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron; + +import java.util.List; + +/** + * This interface defines the methods for CRUD of NB OpenStack Security Rule objects + */ + +public interface INeutronSecurityRuleCRUD { + /** + * Applications call this interface method to determine if a particular + * Security Rule object exists + * + * @param uuid UUID of theSecurity Rule object + * @return boolean + */ + + public boolean neutronSecurityRuleExists(String uuid); + + /** + * Applications call this interface method to return if a particular + * Security Rule object exists + * + * @param uuid UUID of the security rule object + * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule.OpenStackNetworks} + * OpenStackSecurity Rule class + */ + + public NeutronSecurityRule getNeutronSecurityRule(String uuid); + + /** + * Applications call this interface method to return all Security Rule objects + * + * @return List of OpenStack SecurityRules objects + */ + + public List getAllNeutronSecurityRules(); + + /** + * Applications call this interface method to add a Security Rule object to the + * concurrent map + * + * @param input OpenStack security rule object + * @return boolean on whether the object was added or not + */ + + public boolean addNeutronSecurityRule(NeutronSecurityRule input); + + /** + * Applications call this interface method to remove a Neutron Security Rule object to the + * concurrent map + * + * @param uuid identifier for the security rule object + * @return boolean on whether the object was removed or not + */ + + public boolean removeNeutronSecurityRule(String uuid); + + /** + * Applications call this interface method to edit aSecurity Rule object + * + * @param uuid identifier of the security rule object + * @param delta OpenStackSecurity Rule object containing changes to apply + * @return boolean on whether the object was updated or not + */ + + public boolean updateNeutronSecurityRule(String uuid, NeutronSecurityRule delta); + + /** + * Applications call this interface method to see if a MAC address is in use + * + * @param uuid identifier of the security rule object + * @return boolean on whether the macAddress is already associated with a + * port or not + */ + + public boolean neutronSecurityRuleInUse(String uuid); + +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java index aebecfa93e..21cfdb1305 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java @@ -36,4 +36,14 @@ public class NeutronCRUDInterfaces { INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getGlobalInstance(INeutronFloatingIPCRUD.class, o); return answer; } -} + + public static INeutronSecurityGroupCRUD getINeutronSecurityGroupCRUD(Object o) { + INeutronSecurityGroupCRUD answer = (INeutronSecurityGroupCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityGroupCRUD.class, o); + return answer; + } + + public static INeutronSecurityRuleCRUD getINeutronSecurityRuleCRUD(Object o) { + INeutronSecurityRuleCRUD answer = (INeutronSecurityRuleCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityRuleCRUD.class, o); + return answer; + } +} \ No newline at end of file diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java index c8ee4e8ccc..680a07453b 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java @@ -61,9 +61,8 @@ public class NeutronPort extends ConfigurationObject implements Serializable { @XmlElement (name="tenant_id") String tenantID; - // TODO: add security groups - // @XmlElement (name="security_groups") - // List securityGroups; + @XmlElement (name="security_groups") + List securityGroups; /* this attribute stores the floating IP address assigned to * each fixed IP address @@ -162,6 +161,14 @@ public class NeutronPort extends ConfigurationObject implements Serializable { this.tenantID = tenantID; } + public List getSecurityGroups() { + return securityGroups; + } + + public void setSecurityGroups(List securityGroups) { + this.securityGroups = securityGroups; + } + public NeutronFloatingIP getFloatingIP(String key) { if (!floatingIPMap.containsKey(key)) { return null; @@ -259,6 +266,6 @@ public class NeutronPort extends ConfigurationObject implements Serializable { return "NeutronPort [portUUID=" + portUUID + ", networkUUID=" + networkUUID + ", name=" + name + ", adminStateUp=" + adminStateUp + ", status=" + status + ", macAddress=" + macAddress + ", fixedIPs=" + fixedIPs + ", deviceID=" + deviceID + ", deviceOwner=" + deviceOwner + ", tenantID=" - + tenantID + ", floatingIPMap=" + floatingIPMap + "]"; + + tenantID + ", floatingIPMap=" + floatingIPMap + ", securityGroups=" + securityGroups + "]"; } } diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java new file mode 100644 index 0000000000..0f0a14ca58 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron; + +import org.opendaylight.controller.configuration.ConfigurationObject; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * OpenStack Neutron v2.0 Security Group bindings. + * See OpenStack Network API v2.0 Reference for description of + * annotated attributes. The current fields are as follows: + *

+ * id uuid-str unique ID for the security group. + * name String name of the security group. + * description String name of the security group. + * tenant_id uuid-str Owner of security rule.. + * security_group_rules List nested RO in the sec group. + */ + +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) + +public class NeutronSecurityGroup extends ConfigurationObject implements Serializable { + private static final long serialVersionUID = 1L; + + @XmlElement(name = "id") + String securityGroupUUID; + + @XmlElement(name = "name") + String securityGroupName; + + @XmlElement(name = "description") + String securityGroupDescription; + + @XmlElement(name = "tenant_id") + String securityGroupTenantID; + + @XmlElement(name = "security_group_rules") + List neutronSecurityRule; + + List neutronPorts; + + public NeutronSecurityGroup() { + neutronPorts = new ArrayList (); + List securityRules; + + } + + public String getSecurityGroupUUID() { + return securityGroupUUID; + } + + public void setSecurityGroupUUID(String securityGroupUUID) { + this.securityGroupUUID = securityGroupUUID; + } + + public String getSecurityGroupName() { + return securityGroupName; + } + + public void setSecurityGroupName(String securityGroupName) { + this.securityGroupName = securityGroupName; + } + + public String getSecurityGroupDescription() { + return securityGroupDescription; + } + + public void setSecurityGroupDescription(String securityGroupDescription) { + this.securityGroupDescription = securityGroupDescription; + } + + public String getSecurityGroupTenantID() { + return securityGroupTenantID; + } + + public void setSecurityGroupTenantID(String securityGroupTenantID) { + this.securityGroupTenantID = securityGroupTenantID; + } + + // Rules In Group + public List getSecurityRules() { + return neutronSecurityRule; + } + + public void setSecurityRules(NeutronSecurityRule neutronSecurityRule) { + this.neutronSecurityRule = (List) neutronSecurityRule; + } + + public NeutronSecurityGroup extractFields(List fields) { + NeutronSecurityGroup ans = new NeutronSecurityGroup (); + Iterator i = fields.iterator (); + while (i.hasNext ()) { + String s = i.next (); + if (s.equals ("id")) { + ans.setSecurityGroupUUID (this.getSecurityGroupUUID ()); + } + if (s.equals ("name")) { + ans.setSecurityGroupName (this.getSecurityGroupName ()); + } + if (s.equals ("description")) { + ans.setSecurityGroupDescription (this.getSecurityGroupDescription ()); + } + if (s.equals ("tenant_id")) { + ans.setSecurityGroupTenantID (this.getSecurityGroupTenantID ()); + } + if (s.equals ("security_group_rules")) { + ans.setSecurityRules ((NeutronSecurityRule) this.getSecurityRules ()); + } + } + return ans; + } + + @Override + public String toString() { + return "NeutronSecurityGroup{" + + "securityGroupUUID='" + securityGroupUUID + '\'' + + ", securityGroupName='" + securityGroupName + '\'' + + ", securityGroupDescription='" + securityGroupDescription + '\'' + + ", securityGroupTenantID='" + securityGroupTenantID + '\'' + + ", securityRules=" + neutronSecurityRule + "]"; + } + + public void initDefaults() { + //TODO verify no defaults values are nessecary required. + } +} \ No newline at end of file diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java new file mode 100644 index 0000000000..3fad4fe626 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron; + +import org.opendaylight.controller.configuration.ConfigurationObject; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; + +/** + * See OpenStack Network API v2.0 Reference for description of + * annotated attributes. The current fields are as follows: + *

+ * id uuid (String) UUID for the security group rule. + * security_rule_id uuid (String) The security group to associate rule. + * direction String Direction the VM traffic (ingress/egress). + * security_group_id The security group to associate rule with. + * protocol String IP Protocol (icmp, tcp, udp, etc). + * port_range_min Integer Port at start of range + * port_range_max Integer Port at end of range + * ethertype String ethertype in L2 packet (IPv4, IPv6, etc) + * remote_ip_prefix String (IP cidr) CIDR for address range. + * remote_group_id uuid-str Source security group to apply to rule. + * tenant_id uuid-str Owner of security rule. Admin only outside tenant. + */ + +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) + +public class NeutronSecurityRule extends ConfigurationObject implements Serializable { + private static final long serialVersionUID = 1L; + + @XmlElement(name = "id") + String securityRuleUUID; + + @XmlElement(name = "direction") + String securityRuleDirection; + + @XmlElement(name = "protocol") + String securityRuleProtocol; + + @XmlElement(name = "port_range_min") + Integer securityRulePortMin; + + @XmlElement(name = " port_range_max") + Integer securityRulePortMax; + + @XmlElement(name = "ethertype") + String securityRuleEthertype; + + @XmlElement(name = "remote_ip_prefix") + String securityRuleRemoteIpPrefix; + + @XmlElement(name = "remote_group_id") + String securityRemoteGroupID; + + @XmlElement(name = "security_group_id") + String securityRuleGroupID; + + @XmlElement(name = "tenant_id") + String securityRuleTenantID; + + public NeutronSecurityRule() { + List securityRules; + } + + public String getSecurityRuleUUID() { + return securityRuleUUID; + } + + public void setSecurityRuleUUID(String securityRuleUUID) { + this.securityRuleUUID = securityRuleUUID; + } + + public String getSecurityRuleDirection() { + return securityRuleDirection; + } + + public void setSecurityRuleDirection(String securityRuleDirection) { + this.securityRuleDirection = securityRuleDirection; + } + + public String getSecurityRuleProtocol() { + return securityRuleProtocol; + } + + public void setSecurityRuleProtocol(String securityRuleProtocol) { + this.securityRuleProtocol = securityRuleProtocol; + } + + public Integer getSecurityRulePortMin() { + return securityRulePortMin; + } + + public void setSecurityRulePortMin(Integer securityRulePortMin) { + this.securityRulePortMin = securityRulePortMin; + } + + public Integer getSecurityRulePortMax() { + return securityRulePortMax; + } + + public void setSecurityRulePortMax(Integer securityRulePortMax) { + this.securityRulePortMax = securityRulePortMax; + } + + public String getSecurityRuleEthertype() { + return securityRuleEthertype; + } + + public void setSecurityRuleEthertype(String securityRuleEthertype) { + this.securityRuleEthertype = securityRuleEthertype; + } + + public String getSecurityRuleRemoteIpPrefix() { + return securityRuleRemoteIpPrefix; + } + + public void setSecurityRuleRemoteIpPrefix(String securityRuleRemoteIpPrefix) { + this.securityRuleRemoteIpPrefix = securityRuleRemoteIpPrefix; + } + + public String getSecurityRemoteGroupID() { + return securityRemoteGroupID; + } + + public void setSecurityRemoteGroupID(String securityRemoteGroupID) { + this.securityRemoteGroupID = securityRemoteGroupID; + } + + public String getSecurityRuleGroupID() { + return securityRuleGroupID; + } + + public void setSecurityRuleGroupID(String securityRuleGroupID) { + this.securityRuleGroupID = securityRuleGroupID; + } + + public String getSecurityRuleTenantID() { + return securityRuleTenantID; + } + + public void setSecurityRuleTenantID(String securityRuleTenantID) { + this.securityRuleTenantID = securityRuleTenantID; + } + + public NeutronSecurityRule extractFields(List fields) { + NeutronSecurityRule ans = new NeutronSecurityRule(); + Iterator i = fields.iterator(); + while (i.hasNext()) { + String s = i.next(); + if (s.equals("id")) { + ans.setSecurityRuleUUID(this.getSecurityRuleUUID()); + } + if (s.equals("direction")) { + ans.setSecurityRuleDirection(this.getSecurityRuleDirection()); + } + if (s.equals("protocol")) { + ans.setSecurityRuleProtocol(this.getSecurityRuleProtocol()); + } + if (s.equals("port_range_min")) { + ans.setSecurityRulePortMin(this.getSecurityRulePortMin()); + } + if (s.equals("port_range_max")) { + ans.setSecurityRulePortMax(this.getSecurityRulePortMax()); + } + if (s.equals("ethertype")) { + ans.setSecurityRuleEthertype(this.getSecurityRuleEthertype()); + } + if (s.equals("remote_ip_prefix")) { + ans.setSecurityRuleRemoteIpPrefix(this.getSecurityRuleRemoteIpPrefix()); + } + if (s.equals("remote_group_id")) { + ans.setSecurityRemoteGroupID(this.getSecurityRemoteGroupID()); + } + if (s.equals("security_group_id")) { + ans.setSecurityRuleGroupID(this.getSecurityRuleGroupID()); + } + if (s.equals("tenant_id")) { + ans.setSecurityRuleTenantID(this.getSecurityRuleTenantID()); + } + } + return ans; + } + + @Override + public String toString() { + return "NeutronSecurityRule{" + + "securityRuleUUID='" + securityRuleUUID + '\'' + + ", securityRuleDirection='" + securityRuleDirection + '\'' + + ", securityRuleProtocol='" + securityRuleProtocol + '\'' + + ", securityRulePortMin=" + securityRulePortMin + + ", securityRulePortMax=" + securityRulePortMax + + ", securityRuleEthertype='" + securityRuleEthertype + '\'' + + ", securityRuleRemoteIpPrefix='" + securityRuleRemoteIpPrefix + '\'' + + ", securityRemoteGroupID=" + securityRemoteGroupID + + ", securityRuleGroupID='" + securityRuleGroupID + '\'' + + ", securityRuleTenantID='" + securityRuleTenantID + '\'' + + '}'; + } + + public void initDefaults() { + //TODO verify no defaults values are nessecary required. + } +} \ No newline at end of file diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java index 76c39e4294..3fe03a2dac 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java @@ -32,6 +32,8 @@ public class NeutronNorthboundRSApplication extends Application { classes.add(NeutronPortsNorthbound.class); classes.add(NeutronRoutersNorthbound.class); classes.add(NeutronFloatingIPsNorthbound.class); + classes.add(NeutronSecurityGroupsNorthbound.class); + classes.add(NeutronSecurityRulesNorthbound.class); return classes; } diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java new file mode 100644 index 0000000000..6e779d64e2 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron.northbound; + +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + + +@XmlRootElement +@XmlAccessorType (XmlAccessType.NONE) + +public class NeutronSecurityGroupRequest { + /** + * See OpenStack Network API v2.0 Reference for a + * description of annotated attributes and operations + */ + + @XmlElement (name = "security_group") + NeutronSecurityGroup singletonSecurityGroup; + + @XmlElement (name = "security_groups") + List bulkRequest; + + NeutronSecurityGroupRequest() { + } + + NeutronSecurityGroupRequest(List bulk) { + bulkRequest = bulk; + singletonSecurityGroup = null; + } + + NeutronSecurityGroupRequest(NeutronSecurityGroup group) { + singletonSecurityGroup = group; + } + + public List getBulk() { + return bulkRequest; + } + + public NeutronSecurityGroup getSingleton() { + return singletonSecurityGroup; + } + + public boolean isSingleton() { + return (singletonSecurityGroup != null); + } +} \ No newline at end of file diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java new file mode 100644 index 0000000000..5e9a3318b9 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron.northbound; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.codehaus.enunciate.jaxrs.ResponseCode; +import org.codehaus.enunciate.jaxrs.StatusCodes; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupAware; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces; +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup; +import org.opendaylight.controller.northbound.commons.RestMessages; +import org.opendaylight.controller.northbound.commons.exception.BadRequestException; +import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException; +import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException; +import org.opendaylight.controller.sal.utils.ServiceHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Neutron Northbound REST APIs for Security Group.
+ * This class provides REST APIs for managing neutron Security Group + *

+ *
+ *
+ * Authentication scheme : HTTP Basic
+ * Authentication realm : opendaylight
+ * Transport : HTTP and HTTPS
+ *
+ * HTTPS Authentication is disabled by default. Administrator can enable it in + * tomcat-server.xml after adding a proper keystore / SSL certificate from a + * trusted authority.
+ * More info : + * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration + */ +@Path ("/security-groups") +public class NeutronSecurityGroupsNorthbound { + static final Logger logger = LoggerFactory.getLogger(NeutronSecurityGroupsNorthbound.class); + + private NeutronSecurityGroup extractFields(NeutronSecurityGroup o, List fields) { + return o.extractFields(fields); + } + + /** + * Returns a list of all Security Groups + */ + @GET + @Produces ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + + public Response listGroups( + // return fields + @QueryParam ("fields") List fields, + // OpenStack security group attributes + @QueryParam ("id") String querySecurityGroupUUID, + @QueryParam ("name") String querySecurityGroupName, + @QueryParam ("description") String querySecurityDescription, + @QueryParam ("tenant_id") String querySecurityTenantID, + @QueryParam ("limit") String limit, + @QueryParam ("marker") String marker, + @QueryParam ("page_reverse") String pageReverse + ) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + List allSecurityGroups = securityGroupInterface.getAllNeutronSecurityGroups(); + List ans = new ArrayList(); + Iterator i = allSecurityGroups.iterator(); + while (i.hasNext()) { + NeutronSecurityGroup nsg = i.next(); + if ((querySecurityGroupUUID == null || + querySecurityGroupUUID.equals(nsg.getSecurityGroupUUID())) && + (querySecurityGroupName == null || + querySecurityGroupName.equals(nsg.getSecurityGroupName())) && + (querySecurityDescription == null || + querySecurityDescription.equals(nsg.getSecurityGroupDescription())) && + (querySecurityTenantID == null || + querySecurityTenantID.equals(nsg.getSecurityGroupTenantID()))) { + if (fields.size() > 0) { + ans.add(extractFields(nsg, fields)); + } else { + ans.add(nsg); + } + } + } + return Response.status(200).entity( + new NeutronSecurityGroupRequest(ans)).build(); + } + + /** + * Returns a specific Security Group + */ + + @Path ("{securityGroupUUID}") + @GET + @Produces ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response showSecurityGroup(@PathParam ("securityGroupUUID") String securityGroupUUID, + // return fields + @QueryParam ("fields") List fields) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) { + throw new ResourceNotFoundException("Security Group UUID does not exist."); + } + if (!fields.isEmpty()) { + NeutronSecurityGroup ans = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID); + return Response.status(200).entity( + new NeutronSecurityGroupRequest(extractFields(ans, fields))).build(); + } else { + return Response.status(200).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build(); + } + } + + /** + * Creates new Security Group + */ + + @POST + @Produces ({MediaType.APPLICATION_JSON}) + @Consumes ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 201, condition = "Created"), + @ResponseCode (code = 400, condition = "Bad Request"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 403, condition = "Forbidden"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 409, condition = "Conflict"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response createSecurityGroups(final NeutronSecurityGroupRequest input) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + if (input.isSingleton()) { + NeutronSecurityGroup singleton = input.getSingleton(); + + /* + * Verify that the Security Group doesn't already exist. + */ + if (securityGroupInterface.neutronSecurityGroupExists(singleton.getSecurityGroupUUID())) { + throw new BadRequestException("Security Group UUID already exists"); + } + + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + int status = service.canCreateNeutronSecurityGroup(singleton); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + // Add to Neutron cache + securityGroupInterface.addNeutronSecurityGroup(singleton); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + service.neutronSecurityGroupCreated(singleton); + } + } + } else { + List bulk = input.getBulk(); + Iterator i = bulk.iterator(); + HashMap testMap = new HashMap(); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null); + while (i.hasNext()) { + NeutronSecurityGroup test = i.next(); + + /* + * Verify that the security group doesn't already exist + */ + + if (securityGroupInterface.neutronSecurityGroupExists(test.getSecurityGroupUUID())) { + throw new BadRequestException("Security Group UUID already is already created"); + } + if (instances != null) for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + int status = service.canCreateNeutronSecurityGroup(test); + if ((status < 200) || (status > 299)) return Response.status(status).build(); + } + } + + /* + * now, each element of the bulk request can be added to the cache + */ + i = bulk.iterator(); + while (i.hasNext()) { + NeutronSecurityGroup test = i.next(); + securityGroupInterface.addNeutronSecurityGroup(test); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + service.neutronSecurityGroupCreated(test); + } + } + } + } + return Response.status(201).entity(input).build(); + } + + /** + * Updates a Security Group + */ + + @Path ("{securityGroupUUID}") + @PUT + @Produces ({MediaType.APPLICATION_JSON}) + @Consumes ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 400, condition = "Bad Request"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 403, condition = "Forbidden"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response updateSecurityGroup( + @PathParam ("securityGroupUUID") String securityGroupUUID, final NeutronSecurityGroupRequest input) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * verify the Security Group exists and there is only one delta provided + */ + if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) { + throw new ResourceNotFoundException("Security Group UUID does not exist."); + } + if (!input.isSingleton()) { + throw new BadRequestException("Only singleton edit supported"); + } + NeutronSecurityGroup delta = input.getSingleton(); + NeutronSecurityGroup original = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID); + + if (delta.getSecurityGroupUUID() != null || + delta.getSecurityGroupTenantID() != null || + delta.getSecurityGroupName() != null || + delta.getSecurityGroupDescription() != null) { + throw new BadRequestException("Attribute edit blocked by Neutron"); + } + + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + int status = service.canUpdateNeutronSecurityGroup(delta, original); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + + /* + * update the object and return it + */ + securityGroupInterface.updateNeutronSecurityGroup(securityGroupUUID, delta); + NeutronSecurityGroup updatedSecurityGroup = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + service.neutronSecurityGroupUpdated(updatedSecurityGroup); + } + } + return Response.status(200).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build(); + } + + /** + * Deletes a Security Group + */ + + @Path ("{securityGroupUUID}") + @DELETE + @StatusCodes ({ + @ResponseCode (code = 204, condition = "No Content"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 409, condition = "Conflict"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response deleteSecurityGroup( + @PathParam ("securityGroupUUID") String securityGroupUUID) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * verify the Security Group exists and it isn't currently in use + */ + if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) { + throw new ResourceNotFoundException("Security Group UUID does not exist."); + } + if (securityGroupInterface.neutronSecurityGroupInUse(securityGroupUUID)) { + return Response.status(409).build(); + } + NeutronSecurityGroup singleton = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + int status = service.canDeleteNeutronSecurityGroup(singleton); + if ((status < 200) || (status > 299)) { + return Response.status(status).build(); + } + } + } + + /* + * remove it and return 204 status + */ + securityGroupInterface.removeNeutronSecurityGroup(securityGroupUUID); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + service.neutronSecurityGroupDeleted(singleton); + } + } + return Response.status(204).build(); + } +} \ No newline at end of file diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java new file mode 100644 index 0000000000..b805bd63bc --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron.northbound; + +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + + +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) + +public class NeutronSecurityRuleRequest { + /** + * See OpenStack Network API v2.0 Reference for a + * description of annotated attributes and operations + */ + + @XmlElement(name="security_group_rule") + NeutronSecurityRule singletonSecurityRule; + + @XmlElement(name="security_group_rules") + List bulkRequest; + + NeutronSecurityRuleRequest() { + } + + NeutronSecurityRuleRequest(List bulk) { + bulkRequest = bulk; + singletonSecurityRule = null; + } + + NeutronSecurityRuleRequest(NeutronSecurityRule rule) { + singletonSecurityRule = rule; + } + + public NeutronSecurityRule getSingleton() { + return singletonSecurityRule; + } + + public boolean isSingleton() { + return (singletonSecurityRule != null); + } + public List getBulk() { + return bulkRequest; + } + +} \ No newline at end of file diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java new file mode 100644 index 0000000000..b2c05e0071 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.controller.networkconfig.neutron.northbound; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.codehaus.enunciate.jaxrs.ResponseCode; +import org.codehaus.enunciate.jaxrs.StatusCodes; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleAware; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces; +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule; +import org.opendaylight.controller.northbound.commons.RestMessages; +import org.opendaylight.controller.northbound.commons.exception.BadRequestException; +import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException; +import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException; +import org.opendaylight.controller.sal.utils.ServiceHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Neutron Northbound REST APIs for Security Rule.
+ * This class provides REST APIs for managing neutron Security Rule + *

+ *
+ *
+ * Authentication scheme : HTTP Basic
+ * Authentication realm : opendaylight
+ * Transport : HTTP and HTTPS
+ *
+ * HTTPS Authentication is disabled by default. Administrator can enable it in + * tomcat-server.xml after adding a proper keystore / SSL certificate from a + * trusted authority.
+ * More info : + * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration + */ + +@Path ("/security-group-rules") +public class NeutronSecurityRulesNorthbound { + static final Logger logger = LoggerFactory.getLogger(NeutronSecurityRulesNorthbound.class); + + private NeutronSecurityRule extractFields(NeutronSecurityRule o, List fields) { + return o.extractFields(fields); + } + + /** + * Returns a list of all Security Rules + */ + @GET + @Produces ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response listRules( + // return fields + @QueryParam ("fields") List fields, + // OpenStack security rule attributes + @QueryParam ("id") String querySecurityRuleUUID, + @QueryParam ("direction") String querySecurityRuleDirection, + @QueryParam ("protocol") String querySecurityRuleProtocol, + @QueryParam ("port_range_min") Integer querySecurityRulePortMin, + @QueryParam ("port_range_max") Integer querySecurityRulePortMax, + @QueryParam ("ethertype") String querySecurityRuleEthertype, + @QueryParam ("remote_ip_prefix") String querySecurityRuleIpPrefix, + @QueryParam ("remote_group_id") String querySecurityRemoteGroupID, + @QueryParam ("security_group_id") String querySecurityRuleGroupID, + @QueryParam ("tenant_id") String querySecurityRuleTenantID, + @QueryParam ("limit") String limit, + @QueryParam ("marker") String marker, + @QueryParam ("page_reverse") String pageReverse + ) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + List allSecurityRules = securityRuleInterface.getAllNeutronSecurityRules(); + List ans = new ArrayList(); + Iterator i = allSecurityRules.iterator(); + while (i.hasNext()) { + NeutronSecurityRule nsr = i.next(); + if ((querySecurityRuleUUID == null || + querySecurityRuleUUID.equals(nsr.getSecurityRuleUUID())) && + (querySecurityRuleDirection == null || + querySecurityRuleDirection.equals(nsr.getSecurityRuleDirection())) && + (querySecurityRuleProtocol == null || + querySecurityRuleProtocol.equals(nsr.getSecurityRuleProtocol())) && + (querySecurityRulePortMin == null || + querySecurityRulePortMin.equals(nsr.getSecurityRulePortMin())) && + (querySecurityRulePortMax == null || + querySecurityRulePortMax.equals(nsr.getSecurityRulePortMax())) && + (querySecurityRuleEthertype == null || + querySecurityRuleEthertype.equals(nsr.getSecurityRuleEthertype())) && + (querySecurityRuleIpPrefix == null || + querySecurityRuleIpPrefix.equals(nsr.getSecurityRuleRemoteIpPrefix())) && + (querySecurityRuleGroupID == null || + querySecurityRuleGroupID.equals(nsr.getSecurityRuleGroupID())) && + (querySecurityRemoteGroupID == null || + querySecurityRemoteGroupID.equals(nsr.getSecurityRemoteGroupID())) && + (querySecurityRuleTenantID == null || + querySecurityRuleTenantID.equals(nsr.getSecurityRuleTenantID()))) { + if (fields.size() > 0) { + ans.add(extractFields(nsr, fields)); + } else { + ans.add(nsr); + } + } + } + return Response.status(200).entity( + new NeutronSecurityRuleRequest(ans)).build(); + } + + /** + * Returns a specific Security Rule + */ + + @Path ("{securityRuleUUID}") + @GET + @Produces ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response showSecurityRule(@PathParam ("securityRuleUUID") String securityRuleUUID, + // return fields + @QueryParam ("fields") List fields) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) { + throw new ResourceNotFoundException("Security Rule UUID does not exist."); + } + if (!fields.isEmpty()) { + NeutronSecurityRule ans = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID); + return Response.status(200).entity( + new NeutronSecurityRuleRequest(extractFields(ans, fields))).build(); + } else { + return Response.status(200).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build(); + } + } + + /** + * Creates new Security Rule + */ + + @POST + @Produces ({MediaType.APPLICATION_JSON}) + @Consumes ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 201, condition = "Created"), + @ResponseCode (code = 400, condition = "Bad Request"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 403, condition = "Forbidden"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 409, condition = "Conflict"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response createSecurityRules(final NeutronSecurityRuleRequest input) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * Existing entry checks + */ + + if (input.isSingleton()) { + NeutronSecurityRule singleton = input.getSingleton(); + + if (securityRuleInterface.neutronSecurityRuleExists(singleton.getSecurityRuleUUID())) { + throw new BadRequestException("Security Rule UUID already exists"); + } + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + int status = service.canCreateNeutronSecurityRule(singleton); + if ((status < 200) || (status > 299)) { + return Response.status(status).build(); + } + } + } + + // add rule to cache + singleton.initDefaults(); + securityRuleInterface.addNeutronSecurityRule(singleton); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleCreated(singleton); + } + } + + securityRuleInterface.addNeutronSecurityRule(singleton); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleCreated(singleton); + } + } + } else { + List bulk = input.getBulk(); + Iterator i = bulk.iterator(); + HashMap testMap = new HashMap(); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null); + while (i.hasNext()) { + NeutronSecurityRule test = i.next(); + + /* + * Verify that the security rule doesn't already exist + */ + + if (securityRuleInterface.neutronSecurityRuleExists(test.getSecurityRuleUUID())) { + throw new BadRequestException("Security Rule UUID already exists"); + } + if (testMap.containsKey(test.getSecurityRuleUUID())) { + throw new BadRequestException("Security Rule UUID already exists"); + } + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + int status = service.canCreateNeutronSecurityRule(test); + if ((status < 200) || (status > 299)) { + return Response.status(status).build(); + } + } + } + } + + /* + * now, each element of the bulk request can be added to the cache + */ + i = bulk.iterator(); + while (i.hasNext()) { + NeutronSecurityRule test = i.next(); + securityRuleInterface.addNeutronSecurityRule(test); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleCreated(test); + } + } + } + } + return Response.status(201).entity(input).build(); + } + + /** + * Updates a Security Rule + */ + + @Path ("{securityRuleUUID}") + @PUT + @Produces ({MediaType.APPLICATION_JSON}) + @Consumes ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 400, condition = "Bad Request"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 403, condition = "Forbidden"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response updateSecurityRule( + @PathParam ("securityRuleUUID") String securityRuleUUID, final NeutronSecurityRuleRequest input) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * verify the Security Rule exists and there is only one delta provided + */ + if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) { + throw new ResourceNotFoundException("Security Rule UUID does not exist."); + } + if (!input.isSingleton()) { + throw new BadRequestException("Only singleton edit supported"); + } + NeutronSecurityRule delta = input.getSingleton(); + NeutronSecurityRule original = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID); + + /* + * updates restricted by Neutron + * + */ + if (delta.getSecurityRuleUUID() != null || + delta.getSecurityRuleDirection() != null || + delta.getSecurityRuleProtocol() != null || + delta.getSecurityRulePortMin() != null || + delta.getSecurityRulePortMax() != null || + delta.getSecurityRuleEthertype() != null || + delta.getSecurityRuleRemoteIpPrefix() != null || + delta.getSecurityRuleGroupID() != null || + delta.getSecurityRemoteGroupID() != null || + delta.getSecurityRuleTenantID() != null) { + throw new BadRequestException("Attribute edit blocked by Neutron"); + } + + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + int status = service.canUpdateNeutronSecurityRule(delta, original); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + + /* + * update the object and return it + */ + securityRuleInterface.updateNeutronSecurityRule(securityRuleUUID, delta); + NeutronSecurityRule updatedSecurityRule = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleUpdated(updatedSecurityRule); + } + } + return Response.status(200).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build(); + } + + /** + * Deletes a Security Rule + */ + + @Path ("{securityRuleUUID}") + @DELETE + @StatusCodes ({ + @ResponseCode (code = 204, condition = "No Content"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 409, condition = "Conflict"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response deleteSecurityRule( + @PathParam ("securityRuleUUID") String securityRuleUUID) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * verify the Security Rule exists and it isn't currently in use + */ + if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) { + throw new ResourceNotFoundException("Security Rule UUID does not exist."); + } + if (securityRuleInterface.neutronSecurityRuleInUse(securityRuleUUID)) { + return Response.status(409).build(); + } + NeutronSecurityRule singleton = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + int status = service.canDeleteNeutronSecurityRule(singleton); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + + /* + * remove it and return 204 status + */ + securityRuleInterface.removeNeutronSecurityRule(securityRuleUUID); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleDeleted(singleton); + } + } + return Response.status(204).build(); + } +} \ No newline at end of file