View Javadoc

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  import java.net.HttpURLConnection;
12  import java.util.List;
13  import java.util.concurrent.Future;
14  
15  import org.apache.commons.lang3.exception.ExceptionUtils;
16  import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
17  import org.opendaylight.neutron.spi.INeutronPortAware;
18  import org.opendaylight.neutron.spi.NeutronPort;
19  import org.opendaylight.neutron.spi.Neutron_IPs;
20  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
21  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
22  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
23  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingInput;
24  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingOutput;
25  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.OdlMappingserviceService;
26  import org.opendaylight.yangtools.yang.common.RpcResult;
27  
28  /**
29   * Lisp Service implementation of NeutronPortAware API Creation of a new port
30   * results adding the mapping for the port's IP addresses to the port's host_ip
31   * in the mapping service. Currently the NetronPort object does not carry the
32   * required information to achieve the port's host_ip. Once such extension is
33   * available this class shall be updated.
34   *
35   * @author Vina Ermagan
36   *
37   */
38  
39  public class LispNeutronPortHandler extends LispNeutronService implements
40          INeutronPortAware {
41  
42      // The implementation for each of these services is resolved by the OSGi
43      // Service Manager
44      private volatile ILispNeutronService lispNeutronService;
45  
46      @Override
47      public int canCreatePort(NeutronPort port) {
48          LOG.info("Neutron canCreatePort : Port name: " + port.getName());
49  
50          return HttpURLConnection.HTTP_OK;
51      }
52  
53      @Override
54      public void neutronPortCreated(NeutronPort port) {
55  
56          // TODO Consider adding Port MAC -> Port fixed IP in MS
57          // TODO Add Port fixed ip -> host ip , if Port.host_id mapping to
58          // host_ip exists in MS
59  
60          LOG.debug("Neutron Port Created : " + port.toString());
61  
62          // Check if port.hostID is in map-server, if it is, get host eidtoloc
63          // record?
64          if (port.getBindinghostID() == null) {
65              LOG.error("Adding new Neutron port to lisp service mapping service failed. Port does not have Host_ID. Port : "
66                      + port.toString());
67              return;
68          }
69          Eid hostAddress = LispAddressUtil.asDistinguishedNameEid(port.getBindinghostID());
70  
71          MappingRecord eidRecord;
72          List<LocatorRecord> hostLocRecords;
73          GetMappingInput input = LispUtil.buildGetMappingInput(hostAddress);
74          try {
75              OdlMappingserviceService lfmdb = lispNeutronService.getMappingDbService();
76              if (lfmdb == null) {
77                  LOG.debug("lfmdb is null!!!");
78                  return;
79              }
80              Future<RpcResult<GetMappingOutput>> result = lfmdb.getMapping(input);
81              GetMappingOutput output = result.get().getResult();
82              if (output == null) {
83                  LOG.debug("No mapping found to Host Id {}", port.getBindinghostID());
84                  return;
85              }
86  
87              // TODO for now only selecting the first EidToLocatorRecord from the
88              // Host_ID mapping
89  
90              eidRecord = output.getMappingRecord();
91              hostLocRecords = eidRecord.getLocatorRecord();
92              LOG.debug("hostLocRecords is : {}",hostLocRecords);
93  
94  
95          } catch (Exception e) {
96              LOG.warn("Failed to GET mapping for EID {}: , mappingInput: {} , Exception: {}", hostAddress, input,
97                      ExceptionUtils.getStackTrace(e));
98              return;
99          }
100 
101         List<Neutron_IPs> fixedIPs = port.getFixedIPs();
102         if (fixedIPs != null && fixedIPs.size() > 0) {
103           Eid eidAddress;
104             for (Neutron_IPs ip : fixedIPs) {
105 
106                 // TODO Add check/support for IPv6.
107                 // Get subnet for this port, based on v4 or v6 decide address
108                 // iana code.
109 
110                 eidAddress = LispAddressUtil.asIpv4PrefixEid(ip.getIpAddress() + "/32");
111                 lispNeutronService.getMappingDbService().addMapping(LispUtil.buildAddMappingInput(eidAddress, hostLocRecords));
112             }
113         }
114 
115         LOG.info("Neutron Port Created: Port name: "
116                     + port.getName()
117                     + " Port Fixed IP: "
118                     + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
119                             : "No Fixed IP assigned"));
120 
121     }
122 
123     @Override
124     public int canUpdatePort(NeutronPort delta, NeutronPort original) {
125         // TODO Change of Fixed IPs are not allowed as we are storing ports by
126         // fixed IPs for now
127 
128         if (original.getFixedIPs().equals(original.getFixedIPs())) {
129             LOG.info("Neutron canUpdatePort : Port name: "
130                     + original.getName()
131                     + " Port Fixed IP: "
132                     + (original.getFixedIPs() != null ? original.getFixedIPs()
133                             .get(0) : "No Fixed IP assigned")
134                     + "New Port Fixed IP: "
135                     + (delta.getFixedIPs() != null ? delta.getFixedIPs().get(0)
136                             : "No Fixed IP assigned"));
137             LOG.debug("Neutron canUpdatePort : original" + original.toString()
138                     + " delta : " + delta.toString());
139 
140             return HttpURLConnection.HTTP_OK;
141         }
142         return HttpURLConnection.HTTP_NOT_IMPLEMENTED;
143     }
144 
145     @Override
146     public void neutronPortUpdated(NeutronPort port) {
147         // TODO Port IP and port's host ip is stored by Lisp Neutron Service. If
148         // there is change to these fields, the update needs to be processed.
149 
150         LOG.info("Neutron Port updated: Port name: "
151                 + port.getName()
152                 + " Port Fixed IP: "
153                 + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
154                         : "No Fixed IP assigned"));
155         LOG.debug("Neutron Port Updated : " + port.toString());
156 
157     }
158 
159     @Override
160     public int canDeletePort(NeutronPort port) {
161         // TODO Check if Port IPs are stored by Lisp Neutron Service. if not
162         // return error code.
163 
164         LOG.info("Neutron canDeletePort : Port name: "
165                 + port.getName()
166                 + " Port Fixed IP: "
167                 + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
168                         : "No Fixed IP assigned"));
169         LOG.debug("Neutron canDeltePort: " + port.toString());
170 
171         return HttpURLConnection.HTTP_OK;
172     }
173 
174     @Override
175     public void neutronPortDeleted(NeutronPort port) {
176         // TODO if port ips existed in MapServer, delete them. Else, log error.
177 
178         LOG.info("Neutron Port Deleted: Port name: "
179                 + port.getName()
180                 + " Port Fixed IP: "
181                 + (port.getFixedIPs() != null ? port.getFixedIPs().get(0)
182                         : "No Fixed IP assigned"));
183         LOG.debug("Neutron Port Deleted : " + port.toString());
184 
185         List<Neutron_IPs> fixedIPs = port.getFixedIPs();
186         if (fixedIPs != null && fixedIPs.size() > 0) {
187             Eid eidAddress;
188 
189             for (Neutron_IPs ip : fixedIPs) {
190 
191                 // TODO Add check/support for IPv6.
192                 // Get subnet for this port, based on v4 or v6 decide address
193                 // iana code.
194 
195                 eidAddress = LispAddressUtil.asIpv4PrefixEid(ip.getIpAddress() + "/32");
196                 lispNeutronService.getMappingDbService().removeMapping(LispUtil.buildRemoveMappingInput(eidAddress));
197 
198                 LOG.info("Neutron Port mapping deleted from lisp: "
199                         + " Port Fixed IP: " + ip + "Port host IP: ");
200 
201             }
202         }
203 
204     }
205 
206 }