Initial push of Neutron interface
[controller.git] / opendaylight / networkconfiguration / neutron / src / main / java / org / opendaylight / controller / networkconfig / neutron / NeutronSubnet.java
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java
new file mode 100644 (file)
index 0000000..b1414c3
--- /dev/null
@@ -0,0 +1,403 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.controller.networkconfig.neutron;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+import org.apache.commons.net.util.SubnetUtils;\r
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronSubnet {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement (name="id")\r
+    String subnetUUID;\r
+\r
+    @XmlElement (name="network_id")\r
+    String networkUUID;\r
+\r
+    @XmlElement (name="name")\r
+    String name;\r
+\r
+    @XmlElement (defaultValue="4", name="ip_version")\r
+    Integer ipVersion;\r
+\r
+    @XmlElement (name="cidr")\r
+    String cidr;\r
+\r
+    @XmlElement (name="gateway_ip")\r
+    String gatewayIP;\r
+\r
+    @XmlElement (name="dns_nameservers")\r
+    List<String> dnsNameservers;\r
+\r
+    @XmlElement (name="allocation_pools")\r
+    List<NeutronSubnet_IPAllocationPool> allocationPools;\r
+\r
+    @XmlElement (name="host_routes")\r
+    List<NeutronSubnet_HostRoute> hostRoutes;\r
+\r
+    @XmlElement (defaultValue="true", name="enable_dhcp")\r
+    Boolean enableDHCP;\r
+\r
+    @XmlElement (name="tenant_id")\r
+    String tenantID;\r
+\r
+    /* stores the OpenStackPorts associated with an instance\r
+     * used to determine if that instance can be deleted.\r
+     */\r
+    List<NeutronPort> myPorts;\r
+\r
+    boolean gatewayIPAssigned;\r
+\r
+    public NeutronSubnet() {\r
+        myPorts = new ArrayList<NeutronPort>();\r
+    }\r
+\r
+    public String getID() { return subnetUUID; }\r
+\r
+    public String getSubnetUUID() {\r
+        return subnetUUID;\r
+    }\r
+\r
+    public void setSubnetUUID(String subnetUUID) {\r
+        this.subnetUUID = subnetUUID;\r
+    }\r
+\r
+    public String getNetworkUUID() {\r
+        return networkUUID;\r
+    }\r
+\r
+    public void setNetworkUUID(String networkUUID) {\r
+        this.networkUUID = networkUUID;\r
+    }\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public Integer getIpVersion() {\r
+        return ipVersion;\r
+    }\r
+\r
+    public void setIpVersion(Integer ipVersion) {\r
+        this.ipVersion = ipVersion;\r
+    }\r
+\r
+    public String getCidr() {\r
+        return cidr;\r
+    }\r
+\r
+    public void setCidr(String cidr) {\r
+        this.cidr = cidr;\r
+    }\r
+\r
+    public String getGatewayIP() {\r
+        return gatewayIP;\r
+    }\r
+\r
+    public void setGatewayIP(String gatewayIP) {\r
+        this.gatewayIP = gatewayIP;\r
+    }\r
+\r
+    public List<String> getDnsNameservers() {\r
+        return dnsNameservers;\r
+    }\r
+\r
+    public void setDnsNameservers(List<String> dnsNameservers) {\r
+        this.dnsNameservers = dnsNameservers;\r
+    }\r
+\r
+    public List<NeutronSubnet_IPAllocationPool> getAllocationPools() {\r
+        return allocationPools;\r
+    }\r
+\r
+    public void setAllocationPools(List<NeutronSubnet_IPAllocationPool> allocationPools) {\r
+        this.allocationPools = allocationPools;\r
+    }\r
+\r
+    public List<NeutronSubnet_HostRoute> getHostRoutes() {\r
+        return hostRoutes;\r
+    }\r
+\r
+    public void setHostRoutes(List<NeutronSubnet_HostRoute> hostRoutes) {\r
+        this.hostRoutes = hostRoutes;\r
+    }\r
+\r
+    public boolean isEnableDHCP() {\r
+        if (enableDHCP == null)\r
+            return true;\r
+        return enableDHCP;\r
+    }\r
+\r
+    public Boolean getEnableDHCP() { return enableDHCP; }\r
+\r
+    public void setEnableDHCP(Boolean newValue) {\r
+            this.enableDHCP = newValue;\r
+    }\r
+\r
+    public String getTenantID() {\r
+        return tenantID;\r
+    }\r
+\r
+    public void setTenantID(String tenantID) {\r
+        this.tenantID = tenantID;\r
+    }\r
+\r
+    /**\r
+     * This method copies selected fields from the object and returns them\r
+     * as a new object, suitable for marshaling.\r
+     *\r
+     * @param fields\r
+     *            List of attributes to be extracted\r
+     * @return an OpenStackSubnets object with only the selected fields\r
+     * populated\r
+     */\r
+\r
+    public NeutronSubnet extractFields(List<String> fields) {\r
+        NeutronSubnet ans = new NeutronSubnet();\r
+        Iterator<String> i = fields.iterator();\r
+        while (i.hasNext()) {\r
+            String s = i.next();\r
+            if (s.equals("id"))\r
+                ans.setSubnetUUID(this.getSubnetUUID());\r
+            if (s.equals("network_id"))\r
+                ans.setNetworkUUID(this.getNetworkUUID());\r
+            if (s.equals("name"))\r
+                ans.setName(this.getName());\r
+            if (s.equals("ip_version"))\r
+                ans.setIpVersion(this.getIpVersion());\r
+            if (s.equals("cidr"))\r
+                ans.setCidr(this.getCidr());\r
+            if (s.equals("gateway_ip"))\r
+                ans.setGatewayIP(this.getGatewayIP());\r
+            if (s.equals("dns_nameservers")) {\r
+                List<String> nsList = new ArrayList<String>();\r
+                nsList.addAll(this.getDnsNameservers());\r
+                ans.setDnsNameservers(nsList);\r
+            }\r
+            if (s.equals("allocation_pools")) {\r
+                List<NeutronSubnet_IPAllocationPool> aPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
+                aPools.addAll(this.getAllocationPools());\r
+                ans.setAllocationPools(aPools);\r
+            }\r
+            if (s.equals("host_routes")) {\r
+                List<NeutronSubnet_HostRoute> hRoutes = new ArrayList<NeutronSubnet_HostRoute>();\r
+                hRoutes.addAll(this.getHostRoutes());\r
+                ans.setHostRoutes(hRoutes);\r
+            }\r
+            if (s.equals("enable_dhcp"))\r
+                ans.setEnableDHCP(this.getEnableDHCP());\r
+            if (s.equals("tenant_id"))\r
+                ans.setTenantID(this.getTenantID());\r
+        }\r
+        return ans;\r
+    }\r
+\r
+    /* test to see if the cidr address used to define this subnet\r
+     * is a valid network address (an necessary condition when creating\r
+     * a new subnet)\r
+     */\r
+    public boolean isValidCIDR() {\r
+        try {\r
+            SubnetUtils util = new SubnetUtils(cidr);\r
+            SubnetInfo info = util.getInfo();\r
+            if (!info.getNetworkAddress().equals(info.getAddress()))\r
+                return false;\r
+        } catch (Exception e) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /* test to see if the gateway IP specified overlaps with specified\r
+     * allocation pools (an error condition when creating a new subnet\r
+     * or assigning a gateway IP)\r
+     */\r
+    public boolean gatewayIP_Pool_overlap() {\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            if (pool.contains(gatewayIP))\r
+                return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
+    public void initDefaults() {\r
+        if (enableDHCP == null)\r
+            enableDHCP = true;\r
+        if (ipVersion == null)\r
+            ipVersion = 4;\r
+        gatewayIPAssigned = false;\r
+        dnsNameservers = new ArrayList<String>();\r
+        allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
+        hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();\r
+        try {\r
+            SubnetUtils util = new SubnetUtils(cidr);\r
+            SubnetInfo info = util.getInfo();\r
+            if (gatewayIP == null)\r
+                gatewayIP = info.getLowAddress();\r
+            if (allocationPools.size() < 1) {\r
+                NeutronSubnet_IPAllocationPool source =\r
+                    new NeutronSubnet_IPAllocationPool(info.getLowAddress(),\r
+                            info.getHighAddress());\r
+                allocationPools = source.splitPool(gatewayIP);\r
+            }\r
+        } catch (Exception e) {\r
+            ;\r
+        }\r
+    }\r
+\r
+    public List<NeutronPort> getPortsInSubnet() {\r
+        return myPorts;\r
+    }\r
+\r
+    public void addPort(NeutronPort port) {\r
+        myPorts.add(port);\r
+    }\r
+\r
+    public void removePort(NeutronPort port) {\r
+        myPorts.remove(port);\r
+    }\r
+\r
+    /* this method tests to see if the supplied IPv4 address\r
+     * is valid for this subnet or not\r
+     */\r
+    public boolean isValidIP(String ipAddress) {\r
+        try {\r
+            SubnetUtils util = new SubnetUtils(cidr);\r
+            SubnetInfo info = util.getInfo();\r
+            return info.isInRange(ipAddress);\r
+        } catch (Exception e) {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    /* test to see if the supplied IPv4 address is part of one of the\r
+     * available allocation pools or not\r
+     */\r
+    public boolean isIPInUse(String ipAddress) {\r
+        if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned )\r
+            return false;\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            if (pool.contains(ipAddress))\r
+                return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /* method to get the lowest available address of the subnet.\r
+     * go through all the allocation pools and keep the lowest of their\r
+     * low addresses.\r
+     */\r
+    public String getLowAddr() {\r
+        String ans = null;\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            if (ans == null)\r
+                ans = pool.getPoolStart();\r
+            else\r
+                if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <\r
+                        NeutronSubnet_IPAllocationPool.convert(ans))\r
+                    ans = pool.getPoolStart();\r
+        }\r
+        return ans;\r
+    }\r
+\r
+    /*\r
+     * allocate the parameter address.  Because this uses an iterator to\r
+     * check the instance's list of allocation pools and we want to modify\r
+     * pools while the iterator is being used, it is necessary to\r
+     * build a new list of allocation pools and replace the list when\r
+     * finished (otherwise a split will cause undefined iterator behavior.\r
+     */\r
+    public void allocateIP(String ipAddress) {\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        List<NeutronSubnet_IPAllocationPool> newList = new ArrayList<NeutronSubnet_IPAllocationPool>();    // we have to modify a separate list\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            if (pool.getPoolEnd().equalsIgnoreCase(ipAddress) &&\r
+                    pool.getPoolStart().equalsIgnoreCase(ipAddress))\r
+                ; // do nothing, i.e. don't add the current pool to the new list\r
+            else\r
+                if (pool.contains(ipAddress)) {\r
+                    List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);\r
+                    newList.addAll(pools);\r
+                } else\r
+                    newList.add(pool);\r
+        }\r
+        allocationPools = newList;\r
+    }\r
+\r
+    /*\r
+     * release an IP address back to the subnet.  Although an iterator\r
+     * is used, the list is not modified until the iterator is complete, so\r
+     * an extra list is not necessary.\r
+     */\r
+    public void releaseIP(String ipAddress) {\r
+        NeutronSubnet_IPAllocationPool lPool = null;\r
+        NeutronSubnet_IPAllocationPool hPool = null;\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        long sIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);\r
+        //look for lPool where ipAddr - 1 is high address\r
+        //look for hPool where ipAddr + 1 is low address\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());\r
+            long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());\r
+            if (sIP+1 == lIP)\r
+                hPool = pool;\r
+            if (sIP-1 == hIP)\r
+                lPool = pool;\r
+        }\r
+        //if (lPool == NULL and hPool == NULL) create new pool where low = ip = high\r
+        if (lPool == null && hPool == null)\r
+            allocationPools.add(new NeutronSubnet_IPAllocationPool(ipAddress,ipAddress));\r
+        //if (lPool == NULL and hPool != NULL) change low address of hPool to ipAddr\r
+        if (lPool == null && hPool != null)\r
+            hPool.setPoolStart(ipAddress);\r
+        //if (lPool != NULL and hPool == NULL) change high address of lPool to ipAddr\r
+        if (lPool != null && hPool == null)\r
+            lPool.setPoolEnd(ipAddress);\r
+        //if (lPool != NULL and hPool != NULL) remove lPool and hPool and create new pool\r
+        //        where low address = lPool.low address and high address = hPool.high Address\r
+        if (lPool != null && hPool != null) {\r
+            allocationPools.remove(lPool);\r
+            allocationPools.remove(hPool);\r
+            allocationPools.add(new NeutronSubnet_IPAllocationPool(\r
+                    lPool.getPoolStart(), hPool.getPoolEnd()));\r
+        }\r
+    }\r
+\r
+    public void setGatewayIPAllocated() {\r
+        gatewayIPAssigned = true;\r
+    }\r
+\r
+    public void resetGatewayIPAllocated() {\r
+        gatewayIPAssigned = false;\r
+    }\r
+}\r