2 * Copyright (C) 2014 Red Hat, Inc.
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
9 package org.opendaylight.neutron.northbound.api;
11 import java.net.HttpURLConnection;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
19 import javax.ws.rs.Consumes;
20 import javax.ws.rs.DELETE;
21 import javax.ws.rs.GET;
22 import javax.ws.rs.POST;
23 import javax.ws.rs.PUT;
24 import javax.ws.rs.Path;
25 import javax.ws.rs.PathParam;
26 import javax.ws.rs.Produces;
27 import javax.ws.rs.QueryParam;
28 import javax.ws.rs.core.MediaType;
29 import javax.ws.rs.core.Response;
31 import org.codehaus.enunciate.jaxrs.ResponseCode;
32 import org.codehaus.enunciate.jaxrs.StatusCodes;
33 import org.opendaylight.neutron.spi.INeutronFirewallRuleAware;
34 import org.opendaylight.neutron.spi.INeutronFirewallRuleCRUD;
35 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
36 import org.opendaylight.neutron.spi.NeutronFirewallRule;
39 * Neutron Northbound REST APIs for Firewall Rule.<br>
40 * This class provides REST APIs for managing neutron Firewall Rule
44 * Authentication scheme : <b>HTTP Basic</b><br>
45 * Authentication realm : <b>opendaylight</b><br>
46 * Transport : <b>HTTP and HTTPS</b><br>
48 * HTTPS Authentication is disabled by default. Administrator can enable it in
49 * tomcat-server.xml after adding a proper keystore / SSL certificate from a
50 * trusted authority.<br>
52 * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
55 @Path("fw/firewalls_rules")
56 public class NeutronFirewallRulesNorthbound {
57 private static final int HTTP_OK_BOTTOM = 200;
58 private static final int HTTP_OK_TOP = 299;
59 private static final String INTERFACE_NAME = "Firewall Rule CRUD Interface";
60 private static final String UUID_NO_EXIST = "Firewall Rule UUID does not exist.";
61 private static final String UUID_EXISTS = "Firewall Rule UUID already exists.";
62 private static final String NO_PROVIDERS = "No providers registered. Please try again later";
63 private static final String NO_PROVIDER_LIST = "Couldn't get providers list. Please try again later";
66 private NeutronFirewallRule extractFields(NeutronFirewallRule o, List<String> fields) {
67 return o.extractFields(fields);
70 private NeutronCRUDInterfaces getNeutronInterfaces() {
71 NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronFirewallRuleCRUD(this);
72 if (answer.getFirewallRuleInterface() == null) {
73 throw new ServiceUnavailableException(INTERFACE_NAME
74 + RestMessages.SERVICEUNAVAILABLE.toString());
80 * Returns a list of all Firewall Rules
83 @Produces({MediaType.APPLICATION_JSON})
85 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
86 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
87 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
88 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
89 public Response listRules(
91 @QueryParam("fields") List<String> fields,
92 // OpenStack firewall rule attributes
93 @QueryParam("id") String queryFirewallRuleUUID,
94 @QueryParam("tenant_id") String queryFirewallRuleTenantID,
95 @QueryParam("name") String queryFirewallRuleName,
96 @QueryParam("description") String queryFirewallRuleDescription,
97 @QueryParam("status") String queryFirewallRuleStatus,
98 @QueryParam("shared") Boolean queryFirewallRuleIsShared,
99 @QueryParam("firewall_policy_id") String queryFirewallRulePolicyID,
100 @QueryParam("protocol") String queryFirewallRuleProtocol,
101 @QueryParam("ip_version") Integer queryFirewallRuleIpVer,
102 @QueryParam("source_ip_address") String queryFirewallRuleSrcIpAddr,
103 @QueryParam("destination_ip_address") String queryFirewallRuleDstIpAddr,
104 @QueryParam("source_port") Integer queryFirewallRuleSrcPort,
105 @QueryParam("destination_port") Integer queryFirewallRuleDstPort,
106 @QueryParam("position") Integer queryFirewallRulePosition,
107 @QueryParam("action") String queryFirewallRuleAction,
108 @QueryParam("enabled") Boolean queryFirewallRuleIsEnabled,
110 @QueryParam("limit") String limit,
111 @QueryParam("marker") String marker,
112 @QueryParam("page_reverse") String pageReverse
113 // sorting not supported
115 INeutronFirewallRuleCRUD firewallRuleInterface = getNeutronInterfaces().getFirewallRuleInterface();
116 List<NeutronFirewallRule> allFirewallRules = firewallRuleInterface.getAllNeutronFirewallRules();
117 List<NeutronFirewallRule> ans = new ArrayList<NeutronFirewallRule>();
118 Iterator<NeutronFirewallRule> i = allFirewallRules.iterator();
119 while (i.hasNext()) {
120 NeutronFirewallRule nsr = i.next();
121 if ((queryFirewallRuleUUID == null ||
122 queryFirewallRuleUUID.equals(nsr.getFirewallRuleUUID())) &&
123 (queryFirewallRuleTenantID == null ||
124 queryFirewallRuleTenantID.equals(nsr.getFirewallRuleTenantID())) &&
125 (queryFirewallRuleName == null ||
126 queryFirewallRuleName.equals(nsr.getFirewallRuleName())) &&
127 (queryFirewallRuleDescription == null ||
128 queryFirewallRuleDescription.equals(nsr.getFirewallRuleDescription())) &&
129 (queryFirewallRuleStatus == null ||
130 queryFirewallRuleStatus.equals(nsr.getFirewallRuleStatus())) &&
131 (queryFirewallRuleIsShared == null ||
132 queryFirewallRuleIsShared.equals(nsr.getFirewallRuleIsShared())) &&
133 (queryFirewallRulePolicyID == null ||
134 queryFirewallRulePolicyID.equals(nsr.getFirewallRulePolicyID())) &&
135 (queryFirewallRuleProtocol == null ||
136 queryFirewallRuleProtocol.equals(nsr.getFirewallRuleProtocol())) &&
137 (queryFirewallRuleIpVer == null ||
138 queryFirewallRuleIpVer.equals(nsr.getFirewallRuleIpVer())) &&
139 (queryFirewallRuleSrcIpAddr == null ||
140 queryFirewallRuleSrcIpAddr.equals(nsr.getFirewallRuleSrcIpAddr())) &&
141 (queryFirewallRuleDstIpAddr == null ||
142 queryFirewallRuleDstIpAddr.equals(nsr.getFirewallRuleDstIpAddr())) &&
143 (queryFirewallRuleSrcPort == null ||
144 queryFirewallRuleSrcPort.equals(nsr.getFirewallRuleSrcPort())) &&
145 (queryFirewallRuleDstPort == null ||
146 queryFirewallRuleDstPort.equals(nsr.getFirewallRuleDstPort())) &&
147 (queryFirewallRulePosition == null ||
148 queryFirewallRulePosition.equals(nsr.getFirewallRulePosition())) &&
149 (queryFirewallRuleAction == null ||
150 queryFirewallRuleAction.equals(nsr.getFirewallRuleAction())) &&
151 (queryFirewallRuleIsEnabled == null ||
152 queryFirewallRuleIsEnabled.equals(nsr.getFirewallRuleIsEnabled()))) {
153 if (fields.size() > 0) {
154 ans.add(extractFields(nsr, fields));
160 //TODO: apply pagination to results
161 return Response.status(HttpURLConnection.HTTP_OK).entity(
162 new NeutronFirewallRuleRequest(ans)).build();
166 * Returns a specific Firewall Rule
169 @Path("{firewallRuleUUID}")
171 @Produces({MediaType.APPLICATION_JSON})
173 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
174 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
175 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
176 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
177 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
178 public Response showFirewallRule(@PathParam("firewallRuleUUID") String firewallRuleUUID,
180 @QueryParam("fields") List<String> fields) {
181 INeutronFirewallRuleCRUD firewallRuleInterface = getNeutronInterfaces().getFirewallRuleInterface();
182 if (!firewallRuleInterface.neutronFirewallRuleExists(firewallRuleUUID)) {
183 throw new ResourceNotFoundException(UUID_NO_EXIST);
185 if (fields.size() > 0) {
186 NeutronFirewallRule ans = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
187 return Response.status(HttpURLConnection.HTTP_OK).entity(
188 new NeutronFirewallRuleRequest(extractFields(ans, fields))).build();
190 return Response.status(HttpURLConnection.HTTP_OK)
191 .entity(new NeutronFirewallRuleRequest(
192 firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID)))
198 * Creates new Firewall Rule
202 @Produces({MediaType.APPLICATION_JSON})
203 @Consumes({MediaType.APPLICATION_JSON})
205 @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
206 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
207 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
208 @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
209 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
210 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
211 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
212 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
213 public Response createFirewallRules(final NeutronFirewallRuleRequest input) {
214 INeutronFirewallRuleCRUD firewallRuleInterface = getNeutronInterfaces().getFirewallRuleInterface();
216 if (input.isSingleton()) {
217 NeutronFirewallRule singleton = input.getSingleton();
218 if (firewallRuleInterface.neutronFirewallRuleExists(singleton.getFirewallRuleUUID())) {
219 throw new BadRequestException(UUID_EXISTS);
221 firewallRuleInterface.addNeutronFirewallRule(singleton);
222 Object[] instances = NeutronUtil.getInstances(INeutronFirewallRuleAware.class, this);
223 if (instances != null) {
224 if (instances.length > 0) {
225 for (Object instance : instances) {
226 INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
227 int status = service.canCreateNeutronFirewallRule(singleton);
228 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
229 return Response.status(status).build();
233 throw new ServiceUnavailableException(NO_PROVIDERS);
236 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
239 singleton.initDefaults();
240 firewallRuleInterface.addNeutronFirewallRule(singleton);
241 if (instances != null) {
242 for (Object instance : instances) {
243 INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
244 service.neutronFirewallRuleCreated(singleton);
248 List<NeutronFirewallRule> bulk = input.getBulk();
249 Iterator<NeutronFirewallRule> i = bulk.iterator();
250 Map<String, NeutronFirewallRule> testMap = new HashMap<String, NeutronFirewallRule>();
251 Object[] instances = NeutronUtil.getInstances(INeutronFirewallRuleAware.class, this);
252 while (i.hasNext()) {
253 NeutronFirewallRule test = i.next();
256 * Verify that the Firewall rule doesn't already exist
259 if (firewallRuleInterface.neutronFirewallRuleExists(test.getFirewallRuleUUID())) {
260 throw new BadRequestException(UUID_EXISTS);
262 if (testMap.containsKey(test.getFirewallRuleUUID())) {
263 throw new BadRequestException(UUID_EXISTS);
265 if (instances != null) {
266 if (instances.length > 0) {
267 for (Object instance : instances) {
268 INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
269 int status = service.canCreateNeutronFirewallRule(test);
270 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
271 return Response.status(status).build();
275 throw new ServiceUnavailableException(NO_PROVIDERS);
278 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
282 * now, each element of the bulk request can be added to the cache
285 while (i.hasNext()) {
286 NeutronFirewallRule test = i.next();
287 firewallRuleInterface.addNeutronFirewallRule(test);
288 if (instances != null) {
289 for (Object instance : instances) {
290 INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
291 service.neutronFirewallRuleCreated(test);
296 return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
300 * Updates a Firewall Rule
302 @Path("{firewallRuleUUID}")
304 @Produces({MediaType.APPLICATION_JSON})
305 @Consumes({MediaType.APPLICATION_JSON})
307 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
308 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
309 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
310 @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
311 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
312 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
313 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
314 public Response updateFirewallRule(
315 @PathParam("firewallRuleUUID") String firewallRuleUUID, final NeutronFirewallRuleRequest input) {
316 INeutronFirewallRuleCRUD firewallRuleInterface = getNeutronInterfaces().getFirewallRuleInterface();
318 * verify the Firewall Rule exists
320 if (!firewallRuleInterface.neutronFirewallRuleExists(firewallRuleUUID)) {
321 throw new ResourceNotFoundException(UUID_NO_EXIST);
323 if (!input.isSingleton()) {
324 throw new BadRequestException("Only singleton edit supported");
326 NeutronFirewallRule delta = input.getSingleton();
327 NeutronFirewallRule original = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
330 * updates restricted by Neutron
333 if (delta.getFirewallRuleUUID() != null ||
334 delta.getFirewallRuleTenantID() != null ||
335 delta.getFirewallRuleName() != null ||
336 delta.getFirewallRuleDescription() != null ||
337 delta.getFirewallRuleStatus() != null ||
338 delta.getFirewallRuleIsShared() != null ||
339 delta.getFirewallRulePolicyID() != null ||
340 delta.getFirewallRuleProtocol() != null ||
341 delta.getFirewallRuleIpVer() != null ||
342 delta.getFirewallRuleSrcIpAddr() != null ||
343 delta.getFirewallRuleDstIpAddr() != null ||
344 delta.getFirewallRuleSrcPort() != null ||
345 delta.getFirewallRuleDstPort() != null ||
346 delta.getFirewallRulePosition() != null ||
347 delta.getFirewallRuleAction() != null ||
348 delta.getFirewallRuleIsEnabled() != null) {
349 throw new BadRequestException("Attribute edit blocked by Neutron");
352 Object[] instances = NeutronUtil.getInstances(INeutronFirewallRuleAware.class, this);
353 if (instances != null) {
354 if (instances.length > 0) {
355 for (Object instance : instances) {
356 INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
357 int status = service.canUpdateNeutronFirewallRule(delta, original);
358 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
359 return Response.status(status).build();
363 throw new ServiceUnavailableException(NO_PROVIDERS);
366 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
370 * update the object and return it
372 firewallRuleInterface.updateNeutronFirewallRule(firewallRuleUUID, delta);
373 NeutronFirewallRule updatedFirewallRule = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
374 if (instances != null) {
375 for (Object instance : instances) {
376 INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
377 service.neutronFirewallRuleUpdated(updatedFirewallRule);
380 return Response.status(HttpURLConnection.HTTP_OK)
381 .entity(new NeutronFirewallRuleRequest(firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID)))
386 * Deletes a Firewall Rule
389 @Path("{firewallRuleUUID}")
392 @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
393 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
394 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
395 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
396 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
397 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
398 public Response deleteFirewallRule(
399 @PathParam("firewallRuleUUID") String firewallRuleUUID) {
400 INeutronFirewallRuleCRUD firewallRuleInterface = getNeutronInterfaces().getFirewallRuleInterface();
403 * verify the Firewall Rule exists and it isn't currently in use
405 if (!firewallRuleInterface.neutronFirewallRuleExists(firewallRuleUUID)) {
406 throw new ResourceNotFoundException(UUID_NO_EXIST);
408 if (firewallRuleInterface.neutronFirewallRuleInUse(firewallRuleUUID)) {
409 return Response.status(HttpURLConnection.HTTP_CONFLICT).build();
411 NeutronFirewallRule singleton = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
412 Object[] instances = NeutronUtil.getInstances(INeutronFirewallRuleAware.class, this);
413 if (instances != null) {
414 if (instances.length > 0) {
415 for (Object instance : instances) {
416 INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
417 int status = service.canDeleteNeutronFirewallRule(singleton);
418 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
419 return Response.status(status).build();
423 throw new ServiceUnavailableException(NO_PROVIDERS);
426 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
430 * remove it and return 204 status
432 firewallRuleInterface.removeNeutronFirewallRule(firewallRuleUUID);
433 if (instances != null) {
434 for (Object instance : instances) {
435 INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
436 service.neutronFirewallRuleDeleted(singleton);
439 return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();