Prepare the YANG models for RESTCONF
[lispflowmapping.git] / mappingservice / neutron / src / main / java / org / opendaylight / lispflowmapping / neutron / LispNeutronSubnetHandler.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.lispflowmapping.neutron;
10
11
12 import java.net.HttpURLConnection;
13
14 import org.apache.commons.net.util.SubnetUtils;
15 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
16 import org.opendaylight.neutron.spi.INeutronSubnetAware;
17 import org.opendaylight.neutron.spi.NeutronSubnet;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.LispAFIAddress;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainer;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainerBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.Address;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.ipv4.Ipv4AddressBuilder;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
24
25 /**
26  * Lisp Service implementation of NeutronSubnetAware API
27  * Creation of a new Subnet results in defining the subnet as an EID prefix
28  * in the LISP Mapping System with subnet's network UUID as the key to use
29  * for registering mappings for the subnet.
30  *
31  */
32 public class LispNeutronSubnetHandler extends LispNeutronService implements INeutronSubnetAware {
33     private static final Integer SIX = Integer.valueOf(6);
34
35     // The implementation for each of these services is resolved by the OSGi Service Manager
36     private volatile ILispNeutronService lispNeutronService;
37
38         @Override
39         public int canCreateSubnet(NeutronSubnet subnet) {
40                 LOG.info("Neutron canCreateSubnet : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
41                         subnet.getCidr());
42         LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
43
44         return HttpURLConnection.HTTP_OK;
45         }
46
47         /**
48          * Method adds the newly created subnet as an EID prefix to the
49          * MappingService. The subnet's network UUID is used as the key
50          * for this EID prefix.
51          *
52          */
53         @Override
54         public void neutronSubnetCreated(NeutronSubnet subnet) {
55                 //TODO update for multi-tenancy
56
57                 LOG.info("Neutron Subnet Created request : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
58                         subnet.getCidr());
59         LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
60
61             int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
62             SubnetUtils util = new SubnetUtils(subnet.getCidr());
63         SubnetInfo info = util.getInfo();
64
65         // Determine the IANA code for the subnet IP version
66         // Default is set to IPv4 for neutron subnets
67
68         short ianaCode = 1;
69         if ( SIX.equals(subnet.getIpVersion()) )
70                 ianaCode = 2;
71
72         LispAFIAddress lispAddress = new Ipv4AddressBuilder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
73         LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
74
75         try{
76                 lispNeutronService.getMappingService().addAuthenticationKey(addressContainer, masklen, subnet.getNetworkUUID());
77
78                 LOG.debug("Neutron Subnet Added to MapServer : Subnet name: " + subnet.getName() + " EID Prefix: " +
79                         addressContainer.toString() + " Key: " + subnet.getNetworkUUID());
80         }
81         catch (Exception e){
82                 LOG.error("Adding new subnet to lisp service mapping service failed. Subnet : " + subnet.toString());
83         }
84
85         }
86
87         /**
88          * Method to check whether new Subnet can be created by LISP
89          * implementation of Neutron service API.
90          * Since we store the Cidr part of the subnet as the main key to the Lisp
91          * mapping service, we do not support updates to subnets that change it's cidr.
92          */
93         @Override
94         public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original) {
95                 if (delta == null || original == null){
96                 LOG.error("Neutron canUpdateSubnet rejected: subnet objects were null");
97                 return HttpURLConnection.HTTP_BAD_REQUEST;
98                 }
99                 LOG.info("Neutron canUpdateSubnet : Subnet name: " + original.getName() + " Subnet Cidr: " +
100                         original.getCidr());
101         LOG.debug("Lisp Neutron Subnet update: original : " + original.toString() + " delta : " + delta.toString());
102
103
104                 // We do not accept a Subnet update that changes the cidr. If cider or network UUID is changed, return error.
105                 if ( !(original.getCidr().equals(delta.getCidr())) ){
106                         LOG.error("Neutron canUpdateSubnet rejected: Subnet name: " + original.getName() + " Subnet Cidr: " +
107                                 original.getCidr());
108                         return HttpURLConnection.HTTP_CONFLICT;
109                 }
110         return HttpURLConnection.HTTP_OK;
111         }
112
113         @Override
114         public void neutronSubnetUpdated(NeutronSubnet subnet) {
115                 // Nothing to do here.
116         }
117
118         /**
119          * Method to check if subnet can be deleted.
120          * Returns error only if subnet does not exist
121          * in the lisp mapping service.
122          */
123         @Override
124         public int canDeleteSubnet(NeutronSubnet subnet) {
125         LOG.info("Neutron canDeleteSubnet : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
126                         subnet.getCidr() + "Key: " + subnet.getNetworkUUID());
127         LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
128
129         int result;
130             int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
131             SubnetUtils util = new SubnetUtils(subnet.getCidr());
132         SubnetInfo info = util.getInfo();
133
134         // Determine the IANA code for the subnet IP version
135         // Default is set to IPv4 for neutron subnets
136         short ianaCode = 1;
137         if ( SIX.equals(subnet.getIpVersion()) )
138                 ianaCode = 2;
139
140         LispAFIAddress lispAddress = new Ipv4AddressBuilder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
141         LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
142
143         // if subnet does not exist in MapServer, return error
144         try{
145                 if (lispNeutronService.getMappingService().getAuthenticationKey(addressContainer, masklen) == null){
146
147                         LOG.error("Neutron canDeleteSubnet rejected : Subnet does not exist: Subnet name: " +
148                                         subnet.getName() +
149                                         " Eid Prefix: " + addressContainer.toString() +
150                                         " Key: " + subnet.getNetworkUUID());
151                         return HttpURLConnection.HTTP_BAD_REQUEST;
152                 }
153                 result =  HttpURLConnection.HTTP_OK;
154         }
155         catch (Exception e){
156                 LOG.error("canDeleteSubnet request rejected. Subnet : " + subnet.toString());
157                 result =  HttpURLConnection.HTTP_BAD_REQUEST;
158         }
159         return result;
160         }
161
162         /**
163          * Method removes the EID prefix and key associated
164          * with the deleted subnet from Lisp mapping service.
165          */
166         @Override
167         public void neutronSubnetDeleted(NeutronSubnet subnet) {
168                 LOG.info("Neutron Subnet Deleted Request : Subnet name: " + subnet.getName() + " Subnet Cidr: " +
169                         subnet.getCidr() + "Key: " + subnet.getNetworkUUID());
170         LOG.debug("Lisp Neutron Subnet: " + subnet.toString());
171
172         int masklen = Integer.parseInt(subnet.getCidr().split("/")[1]);
173             SubnetUtils util = new SubnetUtils(subnet.getCidr());
174         SubnetInfo info = util.getInfo();
175
176         // Determine the IANA code for the subnet IP version
177         // Default is set to IPv4 for neutron subnets
178
179         short ianaCode = 1;
180         if ( SIX.equals(subnet.getIpVersion()) )
181                 ianaCode = 2;
182
183         LispAFIAddress lispAddress = new Ipv4AddressBuilder().setIpv4Address(new Ipv4Address(info.getNetworkAddress())).setAfi(ianaCode).build();
184         LispAddressContainer addressContainer = new LispAddressContainerBuilder().setAddress((Address) lispAddress).build();
185
186         try{
187                 // if subnet does not exist in MapServer, return error
188                 if (lispNeutronService.getMappingService().getAuthenticationKey(addressContainer,masklen) == null){
189                     LOG.error("Neutron Delete Subnet Failed: Subnet does not exist: Subnet name: " + subnet.getName() +
190                                 " Eid Prefix: " + addressContainer.toString() +
191                                 "Key: " + subnet.getNetworkUUID());
192                     return;
193                 }
194                 lispNeutronService.getMappingService().removeAuthenticationKey(addressContainer, masklen);
195
196                 LOG.debug("Neutron Subnet Deleted from MapServer : Subnet name: " + subnet.getName() +
197                                 " Eid Prefix: " + addressContainer.toString() +
198                                 " Key: " + subnet.getNetworkUUID());
199         }
200         catch (Exception e){
201                 LOG.error("Deleting subnet's EID prefix from mapping service failed + Subnet: " + subnet.toString());
202         }
203         }
204
205 }