blob: 3f343f2f9c827c9eae5081e913fa3f7b29e6a2b4 [file] [log] [blame]
psnehab7109092018-10-10 08:26:02 -04001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.onosproject.dhcprelay.rest;
19
20import org.onlab.packet.IpAddress;
21import org.onlab.packet.IpPrefix;
anjalikk072e7912018-11-02 08:25:20 -040022import org.onlab.util.Tools;
23import com.fasterxml.jackson.databind.ObjectMapper;
24import com.fasterxml.jackson.databind.node.ArrayNode;
25import com.fasterxml.jackson.databind.node.ObjectNode;
psnehab7109092018-10-10 08:26:02 -040026import org.onosproject.dhcprelay.api.DhcpRelayService;
anjalikk072e7912018-11-02 08:25:20 -040027import org.onosproject.dhcprelay.api.DhcpServerInfo;
28import org.onosproject.dhcprelay.cli.DhcpRelayCommand;
29import org.onosproject.dhcprelay.store.DhcpRecord;
30import org.onosproject.dhcprelay.store.DhcpRelayCounters;
psnehab7109092018-10-10 08:26:02 -040031import org.onosproject.rest.AbstractWebResource;
32import org.onosproject.routeservice.Route;
33import org.onosproject.routeservice.RouteStore;
34import org.onosproject.routing.fpm.api.FpmRecord;
35import org.slf4j.Logger;
36
37import javax.ws.rs.DELETE;
anjalikk072e7912018-11-02 08:25:20 -040038import javax.ws.rs.GET;
39import javax.ws.rs.PUT;
psnehab7109092018-10-10 08:26:02 -040040import javax.ws.rs.Path;
41import javax.ws.rs.PathParam;
anjalikk072e7912018-11-02 08:25:20 -040042import javax.ws.rs.Produces;
43import javax.ws.rs.core.MediaType;
psnehab7109092018-10-10 08:26:02 -040044import javax.ws.rs.core.Response;
45
anjalikk072e7912018-11-02 08:25:20 -040046import java.util.Collection;
47import java.util.Map;
48import java.util.List;
psnehab7109092018-10-10 08:26:02 -040049import java.util.Optional;
50
51import static org.slf4j.LoggerFactory.getLogger;
52
53/**
54 * DHCP Relay agent REST API.
55 */
56@Path("fpm-delete")
57public class DhcpRelayWebResource extends AbstractWebResource {
58 private static final Logger LOG = getLogger(DhcpRelayWebResource.class);
anjalikk072e7912018-11-02 08:25:20 -040059 private final ObjectMapper mapper = new ObjectMapper();
60 private final DhcpRelayService dhcpDelayService = get(DhcpRelayService.class);
61 private static final String NA = "N/A";
62 List<DhcpServerInfo> defaultDhcpServerInfoList = dhcpDelayService.getDefaultDhcpServerInfoList();
63 List<DhcpServerInfo> indirectDhcpServerInfoList = dhcpDelayService.getIndirectDhcpServerInfoList();
64 Collection<DhcpRecord> records = dhcpDelayService.getDhcpRecords();
65
psnehab7109092018-10-10 08:26:02 -040066
67 /**
68 * Deletes the fpm route from fpm record.
69 * Corresponding route from the route store
70 *
71 * @param prefix IpPrefix
pierc9539e62018-12-12 19:00:29 +010072 * @return 204 NO CONTENT, 404; 401
psnehab7109092018-10-10 08:26:02 -040073 */
74 @DELETE
75 @Path("{prefix}")
76 public Response dhcpFpmDelete(@PathParam("prefix") String prefix) {
77 DhcpRelayService dhcpRelayService = get(DhcpRelayService.class);
78 RouteStore routeStore = get(RouteStore.class);
79
80 try {
81 // removes fpm route from fpm record
82 Optional<FpmRecord> fpmRecord = dhcpRelayService.removeFpmRecord(IpPrefix.valueOf(prefix));
83 if (fpmRecord.isPresent()) {
84 IpAddress nextHop = fpmRecord.get().nextHop();
85 Route route = new Route(Route.Source.DHCP, IpPrefix.valueOf(prefix), nextHop);
86 // removes DHCP route from route store
87 routeStore.removeRoute(route);
88 } else {
89 LOG.warn("fpmRecord is not present");
90 }
91 } catch (IllegalArgumentException ex) {
92 throw new IllegalArgumentException(ex);
93 }
94
95 return Response.noContent().build();
96 }
anjalikk072e7912018-11-02 08:25:20 -040097 /**
98 * Returns the response object with list of dhcp servers without counters.
99 *
100 * @return 200 OK with component properties of given component and variable
101 */
102 @GET
103 @Produces(MediaType.APPLICATION_JSON)
104 @Path("dhcp-relay")
105 public Response getDhcpServers() {
106 ObjectNode node = getdhcpRelayJsonOutput(null, null);
107 return Response.status(200).entity(node).build();
108 }
109
110 /**
111 * Returns dhcp servers details with counters.
112 *
113 * @param counter source ip identifier
114 * @return 200 OK with component properties of given component and variable
115 */
116 @GET
117 @Produces(MediaType.APPLICATION_JSON)
118 @Path("dhcp-relay/{counter}")
119 public Response getDhcpRelayCounter(@PathParam("counter") String counter) {
120 ObjectNode node = getdhcpRelayJsonOutput(counter, null);
121 return Response.status(200).entity(node).build();
122 }
123
124 /**
125 * To reset the dhcp relay counters.
126 *
127 * @param counter type String
128 * @param reset type String
129 * @return 200 OK with component properties of given component and variable
130 */
131 @PUT
132 @Produces(MediaType.APPLICATION_JSON)
133 @Path("dhcp-relay/{counter}/{reset}")
134 public Response resetDhcpRelayCounter(@PathParam("counter") String counter, @PathParam("reset") String reset) {
135 ObjectNode node = getdhcpRelayJsonOutput(counter, reset);
136 return Response.status(200).entity(node).build();
137 }
138
139
140 /**
141 * To create json output.
142 *
143 * @param counter type String
144 * @param reset type String
145 * @return node type ObjectNode.
146 */
147 private ObjectNode getdhcpRelayJsonOutput(String counter, String reset) {
148 ObjectNode node = mapper.createObjectNode();
149 ObjectNode dhcpRelayServerNode = mapper.createObjectNode();
150 if (!defaultDhcpServerInfoList.isEmpty()) {
151 ArrayNode defaultDhcpServers = listServers(defaultDhcpServerInfoList);
152 dhcpRelayServerNode.put("Default-DHCP-Server", defaultDhcpServers);
153 }
154 if (!indirectDhcpServerInfoList.isEmpty()) {
155 ArrayNode indirectDhcpServers = listServers(indirectDhcpServerInfoList);
156 dhcpRelayServerNode.put("Indirect-DHCP-Server", indirectDhcpServers);
157 }
158
159 ArrayNode dhcpRecords = dhcpRelayRecords(records);
160 dhcpRelayServerNode.put("DHCP-Relay-Records([D]:Directly-Connected)", dhcpRecords);
161 if (counter != null && !counter.equals("counter")) {
162 ArrayNode counterArray = dhcpRelayCounters(reset);
163 dhcpRelayServerNode.put("DHCP-Relay-Counter", counterArray);
164 }
165 node.put("Default-DHCP-Servers", dhcpRelayServerNode);
166
167 return node;
168
169 }
170 /**
171 * To get the liset of dhcp servers.
172 *
173 * @param dhcpServerInfoList type List
174 * @return servers type ArrayNode.
175 */
176 private ArrayNode listServers(List<DhcpServerInfo> dhcpServerInfoList) {
177 ArrayNode servers = mapper.createArrayNode();
178 dhcpServerInfoList.forEach(dhcpServerInfo -> {
179 ObjectNode serverNode = mapper.createObjectNode();
180 String connectPoint = dhcpServerInfo.getDhcpServerConnectPoint()
181 .map(cp -> cp.toString()).orElse(NA);
182 String serverMac = dhcpServerInfo.getDhcpConnectMac()
183 .map(mac -> mac.toString()).orElse(NA);
184 String gatewayAddress;
185 String serverIp;
186
187 switch (dhcpServerInfo.getVersion()) {
188 case DHCP_V4:
189 gatewayAddress = dhcpServerInfo.getDhcpGatewayIp4()
190 .map(gw -> gw.toString()).orElse(null);
191 serverIp = dhcpServerInfo.getDhcpServerIp4()
192 .map(ip -> ip.toString()).orElse(NA);
193 break;
194 case DHCP_V6:
195 gatewayAddress = dhcpServerInfo.getDhcpGatewayIp6()
196 .map(gw -> gw.toString()).orElse(null);
197 serverIp = dhcpServerInfo.getDhcpServerIp6()
198 .map(ip -> ip.toString()).orElse(NA);
199 break;
200 default:
201 return;
202 }
203
204 serverNode.put("connectPoint", connectPoint);
205 if (gatewayAddress != null) {
206 serverNode.put("server", serverIp.concat(" via ").concat(gatewayAddress));
207 } else {
208 serverNode.put("server", serverIp);
209 }
210 serverNode.put("mac", serverMac);
211 servers.add(serverNode);
212 });
213 return servers;
214}
215
216 /**
217 * To get the list of dhcp relay records.
218 *
219 * @param records type Collections
220 * @return dhcpRelayRecords type ArrayNode.
221 */
222 private ArrayNode dhcpRelayRecords(Collection<DhcpRecord> records) {
223 DhcpRelayCommand dhcpRelayCommand = new DhcpRelayCommand();
224 ArrayNode dhcpRelayRecords = mapper.createArrayNode();
225 records.forEach(record -> {
226 ObjectNode dhcpRecord = mapper.createObjectNode();
227 dhcpRecord.put("id", record.macAddress() + "/" + record.vlanId());
228 dhcpRecord.put("locations", record.locations().toString());
229 dhcpRecord.put("last-seen", Tools.timeAgo(record.lastSeen()));
230 dhcpRecord.put("IPv4", dhcpRelayCommand.ip4State(record));
231 dhcpRecord.put("IPv6", dhcpRelayCommand.ip6State(record));
232 dhcpRelayRecords.add(dhcpRecord);
233 });
234 return dhcpRelayRecords;
235 }
236
237 /**
238 * To get the details of dhcp relay counters.
239 *
240 * @param reset type String
241 * @return counterArray type ArrayNode.
242 */
243 private ArrayNode dhcpRelayCounters(String reset) {
244 ObjectNode counters = mapper.createObjectNode();
245 ObjectNode counterPackets = mapper.createObjectNode();
246 ArrayNode counterArray = mapper.createArrayNode();
247 records.forEach(record -> {
248 DhcpRelayCounters v6Counters = record.getV6Counters();
249 if (reset != null && reset.equals("reset")) {
250 v6Counters.resetCounters();
251 }
252 Map<String, Integer> countersMap = v6Counters.getCounters();
253 countersMap.forEach((name, value) -> {
254 counterPackets.put(name, value);
255
256 });
257 counters.put(record.locations().toString(), counterPackets);
258 counterArray.add(counters);
259 });
260 return counterArray;
261 }
psnehab7109092018-10-10 08:26:02 -0400262
263}