blob: 1a48ea51dbf0ea64297ac7bd24ff1fbf7b296093 [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
46import java.io.IOException;
anjalikk072e7912018-11-02 08:25:20 -040047import java.util.Collection;
48import java.util.Map;
49import java.util.List;
psnehab7109092018-10-10 08:26:02 -040050import java.util.Optional;
51
52import static org.slf4j.LoggerFactory.getLogger;
53
54/**
55 * DHCP Relay agent REST API.
56 */
57@Path("fpm-delete")
58public class DhcpRelayWebResource extends AbstractWebResource {
59 private static final Logger LOG = getLogger(DhcpRelayWebResource.class);
anjalikk072e7912018-11-02 08:25:20 -040060 private final ObjectMapper mapper = new ObjectMapper();
61 private final DhcpRelayService dhcpDelayService = get(DhcpRelayService.class);
62 private static final String NA = "N/A";
63 List<DhcpServerInfo> defaultDhcpServerInfoList = dhcpDelayService.getDefaultDhcpServerInfoList();
64 List<DhcpServerInfo> indirectDhcpServerInfoList = dhcpDelayService.getIndirectDhcpServerInfoList();
65 Collection<DhcpRecord> records = dhcpDelayService.getDhcpRecords();
66
psnehab7109092018-10-10 08:26:02 -040067
68 /**
69 * Deletes the fpm route from fpm record.
70 * Corresponding route from the route store
71 *
72 * @param prefix IpPrefix
73 * @return 204 NO CONTENT
74 * @throws IOException to signify bad request
75 */
76 @DELETE
77 @Path("{prefix}")
78 public Response dhcpFpmDelete(@PathParam("prefix") String prefix) {
79 DhcpRelayService dhcpRelayService = get(DhcpRelayService.class);
80 RouteStore routeStore = get(RouteStore.class);
81
82 try {
83 // removes fpm route from fpm record
84 Optional<FpmRecord> fpmRecord = dhcpRelayService.removeFpmRecord(IpPrefix.valueOf(prefix));
85 if (fpmRecord.isPresent()) {
86 IpAddress nextHop = fpmRecord.get().nextHop();
87 Route route = new Route(Route.Source.DHCP, IpPrefix.valueOf(prefix), nextHop);
88 // removes DHCP route from route store
89 routeStore.removeRoute(route);
90 } else {
91 LOG.warn("fpmRecord is not present");
92 }
93 } catch (IllegalArgumentException ex) {
94 throw new IllegalArgumentException(ex);
95 }
96
97 return Response.noContent().build();
98 }
anjalikk072e7912018-11-02 08:25:20 -040099 /**
100 * Returns the response object with list of dhcp servers without counters.
101 *
102 * @return 200 OK with component properties of given component and variable
103 */
104 @GET
105 @Produces(MediaType.APPLICATION_JSON)
106 @Path("dhcp-relay")
107 public Response getDhcpServers() {
108 ObjectNode node = getdhcpRelayJsonOutput(null, null);
109 return Response.status(200).entity(node).build();
110 }
111
112 /**
113 * Returns dhcp servers details with counters.
114 *
115 * @param counter source ip identifier
116 * @return 200 OK with component properties of given component and variable
117 */
118 @GET
119 @Produces(MediaType.APPLICATION_JSON)
120 @Path("dhcp-relay/{counter}")
121 public Response getDhcpRelayCounter(@PathParam("counter") String counter) {
122 ObjectNode node = getdhcpRelayJsonOutput(counter, null);
123 return Response.status(200).entity(node).build();
124 }
125
126 /**
127 * To reset the dhcp relay counters.
128 *
129 * @param counter type String
130 * @param reset type String
131 * @return 200 OK with component properties of given component and variable
132 */
133 @PUT
134 @Produces(MediaType.APPLICATION_JSON)
135 @Path("dhcp-relay/{counter}/{reset}")
136 public Response resetDhcpRelayCounter(@PathParam("counter") String counter, @PathParam("reset") String reset) {
137 ObjectNode node = getdhcpRelayJsonOutput(counter, reset);
138 return Response.status(200).entity(node).build();
139 }
140
141
142 /**
143 * To create json output.
144 *
145 * @param counter type String
146 * @param reset type String
147 * @return node type ObjectNode.
148 */
149 private ObjectNode getdhcpRelayJsonOutput(String counter, String reset) {
150 ObjectNode node = mapper.createObjectNode();
151 ObjectNode dhcpRelayServerNode = mapper.createObjectNode();
152 if (!defaultDhcpServerInfoList.isEmpty()) {
153 ArrayNode defaultDhcpServers = listServers(defaultDhcpServerInfoList);
154 dhcpRelayServerNode.put("Default-DHCP-Server", defaultDhcpServers);
155 }
156 if (!indirectDhcpServerInfoList.isEmpty()) {
157 ArrayNode indirectDhcpServers = listServers(indirectDhcpServerInfoList);
158 dhcpRelayServerNode.put("Indirect-DHCP-Server", indirectDhcpServers);
159 }
160
161 ArrayNode dhcpRecords = dhcpRelayRecords(records);
162 dhcpRelayServerNode.put("DHCP-Relay-Records([D]:Directly-Connected)", dhcpRecords);
163 if (counter != null && !counter.equals("counter")) {
164 ArrayNode counterArray = dhcpRelayCounters(reset);
165 dhcpRelayServerNode.put("DHCP-Relay-Counter", counterArray);
166 }
167 node.put("Default-DHCP-Servers", dhcpRelayServerNode);
168
169 return node;
170
171 }
172 /**
173 * To get the liset of dhcp servers.
174 *
175 * @param dhcpServerInfoList type List
176 * @return servers type ArrayNode.
177 */
178 private ArrayNode listServers(List<DhcpServerInfo> dhcpServerInfoList) {
179 ArrayNode servers = mapper.createArrayNode();
180 dhcpServerInfoList.forEach(dhcpServerInfo -> {
181 ObjectNode serverNode = mapper.createObjectNode();
182 String connectPoint = dhcpServerInfo.getDhcpServerConnectPoint()
183 .map(cp -> cp.toString()).orElse(NA);
184 String serverMac = dhcpServerInfo.getDhcpConnectMac()
185 .map(mac -> mac.toString()).orElse(NA);
186 String gatewayAddress;
187 String serverIp;
188
189 switch (dhcpServerInfo.getVersion()) {
190 case DHCP_V4:
191 gatewayAddress = dhcpServerInfo.getDhcpGatewayIp4()
192 .map(gw -> gw.toString()).orElse(null);
193 serverIp = dhcpServerInfo.getDhcpServerIp4()
194 .map(ip -> ip.toString()).orElse(NA);
195 break;
196 case DHCP_V6:
197 gatewayAddress = dhcpServerInfo.getDhcpGatewayIp6()
198 .map(gw -> gw.toString()).orElse(null);
199 serverIp = dhcpServerInfo.getDhcpServerIp6()
200 .map(ip -> ip.toString()).orElse(NA);
201 break;
202 default:
203 return;
204 }
205
206 serverNode.put("connectPoint", connectPoint);
207 if (gatewayAddress != null) {
208 serverNode.put("server", serverIp.concat(" via ").concat(gatewayAddress));
209 } else {
210 serverNode.put("server", serverIp);
211 }
212 serverNode.put("mac", serverMac);
213 servers.add(serverNode);
214 });
215 return servers;
216}
217
218 /**
219 * To get the list of dhcp relay records.
220 *
221 * @param records type Collections
222 * @return dhcpRelayRecords type ArrayNode.
223 */
224 private ArrayNode dhcpRelayRecords(Collection<DhcpRecord> records) {
225 DhcpRelayCommand dhcpRelayCommand = new DhcpRelayCommand();
226 ArrayNode dhcpRelayRecords = mapper.createArrayNode();
227 records.forEach(record -> {
228 ObjectNode dhcpRecord = mapper.createObjectNode();
229 dhcpRecord.put("id", record.macAddress() + "/" + record.vlanId());
230 dhcpRecord.put("locations", record.locations().toString());
231 dhcpRecord.put("last-seen", Tools.timeAgo(record.lastSeen()));
232 dhcpRecord.put("IPv4", dhcpRelayCommand.ip4State(record));
233 dhcpRecord.put("IPv6", dhcpRelayCommand.ip6State(record));
234 dhcpRelayRecords.add(dhcpRecord);
235 });
236 return dhcpRelayRecords;
237 }
238
239 /**
240 * To get the details of dhcp relay counters.
241 *
242 * @param reset type String
243 * @return counterArray type ArrayNode.
244 */
245 private ArrayNode dhcpRelayCounters(String reset) {
246 ObjectNode counters = mapper.createObjectNode();
247 ObjectNode counterPackets = mapper.createObjectNode();
248 ArrayNode counterArray = mapper.createArrayNode();
249 records.forEach(record -> {
250 DhcpRelayCounters v6Counters = record.getV6Counters();
251 if (reset != null && reset.equals("reset")) {
252 v6Counters.resetCounters();
253 }
254 Map<String, Integer> countersMap = v6Counters.getCounters();
255 countersMap.forEach((name, value) -> {
256 counterPackets.put(name, value);
257
258 });
259 counters.put(record.locations().toString(), counterPackets);
260 counterArray.add(counters);
261 });
262 return counterArray;
263 }
psnehab7109092018-10-10 08:26:02 -0400264
265}