00cc1e6dcfdf04709d7e0d7ba543dd5a1b0da118
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / confighelpers / OvsdbTepRemoveConfigHelper.java
1 /*
2  * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  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 package org.opendaylight.genius.itm.confighelpers;
9
10 import java.math.BigInteger;
11 import java.util.List;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.genius.itm.globals.ITMConstants;
16 import org.opendaylight.genius.itm.impl.ItmUtils;
17 import org.opendaylight.genius.mdsalutil.MDSALUtil;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZone;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TepsNotHostedInTransportZoneKey;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.tepsnothostedintransportzone.UnknownVteps;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.tepsnothostedintransportzone.UnknownVtepsKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsKey;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 public final class OvsdbTepRemoveConfigHelper {
36
37     private static final Logger LOG = LoggerFactory.getLogger(OvsdbTepRemoveConfigHelper.class);
38
39     private OvsdbTepRemoveConfigHelper() { }
40
41     /**
42      * Removes the TEP from ITM configuration Datastore in one of the following cases.
43      * 1) default transport zone
44      * 2) Configured transport zone
45      * 3) Unhosted transport zone
46      * Function checks for above three cases and calls other sub-function to remove the TEP
47      *
48      * @param tepIp TEP-IP address in string
49      * @param strDpnId bridge datapath ID in string
50      * @param tzName transport zone name in string
51      * @param dataBroker data broker handle to perform operations on config datastore
52      * @param wrTx WriteTransaction object
53      */
54
55     public static void removeTepReceivedFromOvsdb(String tepIp, String strDpnId, String tzName,
56                                                   DataBroker dataBroker, WriteTransaction wrTx) {
57         BigInteger dpnId = BigInteger.valueOf(0);
58
59         LOG.trace("Remove TEP: TEP-IP: {}, TZ name: {}, DPID: {}", tepIp, tzName, strDpnId);
60
61         if (strDpnId != null && !strDpnId.isEmpty()) {
62             dpnId = MDSALUtil.getDpnId(strDpnId);
63         }
64
65         // Get tep IP
66         IpAddress tepIpAddress = new IpAddress(tepIp.toCharArray());
67         TransportZone transportZone = null;
68
69         // Case: TZ name is not given from OVS's other_config parameters.
70         if (tzName == null) {
71             tzName = ITMConstants.DEFAULT_TRANSPORT_ZONE;
72             // add TEP into default-TZ
73             transportZone = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
74             if (transportZone == null) {
75                 LOG.error("Error: default-transport-zone is not yet created.");
76                 return;
77             }
78             LOG.trace("Remove TEP from default-transport-zone.");
79         } else {
80             // Case: Add TEP into corresponding TZ created from Northbound.
81             transportZone = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
82             if (transportZone == null) {
83                 // Case: TZ is not configured from Northbound, then add TEP into
84                 // "teps-not-hosted-in-transport-zone"
85                 LOG.trace("Removing TEP from unknown TZ into teps-not-hosted-in-transport-zone.");
86                 removeUnknownTzTepFromTepsNotHosted(tzName, tepIpAddress, dpnId, dataBroker, wrTx);
87                 return;
88             } else {
89                 LOG.trace("Remove TEP from transport-zone already configured by Northbound.");
90             }
91         }
92
93         // Remove TEP from (default transport-zone) OR (transport-zone already configured by Northbound)
94
95         // Get subnet list of corresponding TZ created from Northbound.
96         List<Subnets> subnetList = transportZone.getSubnets();
97
98         if (subnetList == null || subnetList.isEmpty()) {
99             LOG.trace("No subnet list in transport-zone. Nothing to do.");
100         } else {
101             IpPrefix subnetMaskObj = ItmUtils.getDummySubnet();
102
103             List<Vteps> vtepList = null;
104
105             // subnet list already exists case; check for dummy-subnet
106             for (Subnets subnet : subnetList) {
107                 if (subnet.getKey().getPrefix().equals(subnetMaskObj)) {
108                     LOG.trace("Subnet exists in the subnet list of transport-zone {}.", tzName);
109                     // get vtep list of existing subnet
110                     vtepList = subnet.getVteps();
111                     break;
112                 }
113             }
114
115             if (vtepList == null || vtepList.isEmpty()) {
116                 //  case: vtep list does not exist or it has no elements
117                 LOG.trace("No vtep list in subnet list of transport-zone. Nothing to do.");
118             } else {
119                 //  case: vtep list has elements
120                 boolean vtepFound = false;
121                 Vteps oldVtep = null;
122
123                 for (Vteps vtep : vtepList) {
124                     if (vtep.getDpnId().equals(dpnId)) {
125                         vtepFound = true;
126                         oldVtep = vtep;
127                         break;
128                     }
129                 }
130                 if (vtepFound) {
131                     // vtep is found, update it with tep-ip
132                     LOG.trace("Remove TEP from vtep list in subnet list of transport-zone.");
133                     dpnId = oldVtep.getDpnId();
134                     String portName = oldVtep.getPortname();
135                     removeVtepFromTZConfig(subnetMaskObj, tzName, dpnId, portName, wrTx);
136                 } else {
137                     LOG.trace(
138                         "TEP is not found in the vtep list in subnet list of transport-zone. Nothing to do.");
139                 }
140             }
141         }
142     }
143
144     /**
145      * Removes the TEP from subnet list in the transport zone list
146      * from ITM configuration Datastore by delete operation with write transaction.
147      *
148      * @param subnetMaskObj subnet mask in IpPrefix object
149      * @param dpnId bridge datapath ID in BigInteger
150      * @param tzName transport zone name in string
151      * @param portName port name as a part of VtepsKey
152      * @param wrTx WriteTransaction object
153      */
154     private static void removeVtepFromTZConfig(IpPrefix subnetMaskObj, String tzName, BigInteger dpnId,
155         String portName, WriteTransaction wrTx) {
156         SubnetsKey subnetsKey = new SubnetsKey(subnetMaskObj);
157         VtepsKey vtepkey = new VtepsKey(dpnId, portName);
158
159         InstanceIdentifier<Vteps> vtepPath = InstanceIdentifier.builder(TransportZones.class)
160             .child(TransportZone.class, new TransportZoneKey(tzName))
161             .child(Subnets.class, subnetsKey).child(Vteps.class, vtepkey).build();
162
163         LOG.trace("Removing TEP (TZ: {} Subnet: {} DPN-ID: {}) in ITM Config DS.", tzName, subnetMaskObj, dpnId);
164         // remove vtep
165         wrTx.delete(LogicalDatastoreType.CONFIGURATION, vtepPath);
166     }
167
168     /**
169      * Removes the TEP from the not-hosted transport zone in the TepsNotHosted list
170      * from ITM configuration Datastore.
171      *
172      * @param tzName transport zone name in string
173      * @param tepIpAddress TEP IP address in IpAddress object
174      * @param dpnId bridge datapath ID in BigInteger
175      * @param dataBroker data broker handle to perform operations on config datastore
176      * @param wrTx WriteTransaction object
177      */
178     public static void removeUnknownTzTepFromTepsNotHosted(String tzName, IpAddress tepIpAddress,
179                                                            BigInteger dpnId, DataBroker dataBroker,
180                                                            WriteTransaction wrTx) {
181         List<UnknownVteps> vtepList = null;
182
183         TepsNotHostedInTransportZone unknownTz =
184             ItmUtils.getUnknownTransportZoneFromITMConfigDS(tzName, dataBroker);
185         if (unknownTz == null) {
186             LOG.trace("Unhosted TransportZone does not exist. Nothing to do for TEP removal.");
187             return;
188         } else {
189             vtepList = unknownTz.getUnknownVteps();
190             if (vtepList == null || vtepList.isEmpty()) {
191                 //  case: vtep list does not exist or it has no elements
192                 LOG.trace(
193                     "Remove TEP in unhosted TZ ({}) when no vtep-list in the TZ. Nothing to do.",
194                     tzName);
195             } else {
196                 //  case: vtep list has elements
197                 boolean vtepFound = false;
198                 UnknownVteps foundVtep = null;
199
200                 for (UnknownVteps vtep : vtepList) {
201                     if (vtep.getDpnId().equals(dpnId)) {
202                         vtepFound = true;
203                         foundVtep = vtep;
204                         break;
205                     }
206                 }
207                 if (vtepFound) {
208                     // vtep is found, update it with tep-ip
209                     LOG.trace(
210                         "Remove TEP with IP ({}) from unhosted TZ ({}) in TepsNotHosted list.",
211                         tepIpAddress, tzName);
212                     if (vtepList.size() == 1) {
213                         removeTzFromTepsNotHosted(tzName, wrTx);
214                     } else {
215                         removeVtepFromTepsNotHosted(tzName, dpnId, wrTx);
216                     }
217                     vtepList.remove(foundVtep);
218                 }
219             }
220         }
221     }
222
223     /**
224      * Removes the TEP from unknown vtep list under the transport zone in the TepsNotHosted list
225      * from ITM configuration Datastore by delete operation with write transaction.
226      *
227      * @param tzName transport zone name in string
228      * @param dpnId bridge datapath ID in BigInteger
229      * @param wrTx WriteTransaction object
230      */
231     private static void removeVtepFromTepsNotHosted(String tzName, BigInteger dpnId,
232                                                       WriteTransaction wrTx) {
233
234         UnknownVtepsKey unknownVtepkey = new UnknownVtepsKey(dpnId);
235         InstanceIdentifier<UnknownVteps> vtepPath = InstanceIdentifier.builder(TransportZones.class)
236             .child(TepsNotHostedInTransportZone.class, new TepsNotHostedInTransportZoneKey(tzName))
237             .child(UnknownVteps.class, unknownVtepkey).build();
238
239         LOG.trace("Removing TEP from unhosted (TZ: {}, DPID: {}) from ITM Config DS.",
240                 tzName, dpnId);
241         // remove vtep
242         wrTx.delete(LogicalDatastoreType.CONFIGURATION, vtepPath);
243     }
244
245     /**
246      * Removes the transport zone in the TepsNotHosted list
247      * from ITM configuration Datastore by delete operation with write transaction.
248      *
249      * @param tzName transport zone name in string
250      * @param wrTx WriteTransaction object
251      */
252     private static void removeTzFromTepsNotHosted(String tzName, WriteTransaction wrTx) {
253         InstanceIdentifier<TepsNotHostedInTransportZone> tzTepsNotHostedTepPath =
254                 InstanceIdentifier.builder(TransportZones.class)
255                 .child(TepsNotHostedInTransportZone.class,
256                     new TepsNotHostedInTransportZoneKey(tzName)).build();
257
258         LOG.trace("Removing TZ ({})from TepsNotHosted list  from ITM Config DS.", tzName);
259         // remove TZ from TepsNotHosted list
260         wrTx.delete(LogicalDatastoreType.CONFIGURATION, tzTepsNotHostedTepPath);
261     }
262 }