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
10 package org.opendaylight.neutron.northbound.api;
12 import java.net.HttpURLConnection;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 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.INeutronSecurityRuleAware;
34 import org.opendaylight.neutron.spi.INeutronSecurityRuleCRUD;
35 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
36 import org.opendaylight.neutron.spi.NeutronSecurityRule;
39 * Neutron Northbound REST APIs for Security Rule.<br>
40 * This class provides REST APIs for managing neutron Security 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 ("/security-group-rules")
56 public class NeutronSecurityRulesNorthbound {
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 = "Security Rule CRUD Interface";
60 private static final String UUID_NO_EXIST = "Security Rule UUID does not exist.";
61 private static final String UUID_EXISTS = "Security 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";
65 private NeutronSecurityRule extractFields(NeutronSecurityRule o, List<String> fields) {
66 return o.extractFields(fields);
69 private NeutronCRUDInterfaces getNeutronInterfaces() {
70 NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronSecurityRuleCRUD(this);
71 if (answer.getSecurityRuleInterface() == null) {
72 throw new ServiceUnavailableException(INTERFACE_NAME
73 + RestMessages.SERVICEUNAVAILABLE.toString());
79 * Returns a list of all Security Rules
82 @Produces ({MediaType.APPLICATION_JSON})
84 @ResponseCode (code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
85 @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
86 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
87 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
88 public Response listRules(
90 @QueryParam ("fields") List<String> fields,
91 // OpenStack security rule attributes
92 @QueryParam ("id") String querySecurityRuleUUID,
93 @QueryParam ("direction") String querySecurityRuleDirection,
94 @QueryParam ("protocol") String querySecurityRuleProtocol,
95 @QueryParam ("port_range_min") Integer querySecurityRulePortMin,
96 @QueryParam ("port_range_max") Integer querySecurityRulePortMax,
97 @QueryParam ("ethertype") String querySecurityRuleEthertype,
98 @QueryParam ("remote_ip_prefix") String querySecurityRuleIpPrefix,
99 @QueryParam ("remote_group_id") String querySecurityRemoteGroupID,
100 @QueryParam ("security_group_id") String querySecurityRuleGroupID,
101 @QueryParam ("tenant_id") String querySecurityRuleTenantID,
102 @QueryParam ("limit") String limit,
103 @QueryParam ("marker") String marker,
104 @QueryParam ("page_reverse") String pageReverse
106 INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
107 List<NeutronSecurityRule> allSecurityRules = securityRuleInterface.getAllNeutronSecurityRules();
108 List<NeutronSecurityRule> ans = new ArrayList<NeutronSecurityRule>();
109 Iterator<NeutronSecurityRule> i = allSecurityRules.iterator();
110 while (i.hasNext()) {
111 NeutronSecurityRule nsr = i.next();
112 if ((querySecurityRuleUUID == null ||
113 querySecurityRuleUUID.equals(nsr.getSecurityRuleUUID())) &&
114 (querySecurityRuleDirection == null ||
115 querySecurityRuleDirection.equals(nsr.getSecurityRuleDirection())) &&
116 (querySecurityRuleProtocol == null ||
117 querySecurityRuleProtocol.equals(nsr.getSecurityRuleProtocol())) &&
118 (querySecurityRulePortMin == null ||
119 querySecurityRulePortMin.equals(nsr.getSecurityRulePortMin())) &&
120 (querySecurityRulePortMax == null ||
121 querySecurityRulePortMax.equals(nsr.getSecurityRulePortMax())) &&
122 (querySecurityRuleEthertype == null ||
123 querySecurityRuleEthertype.equals(nsr.getSecurityRuleEthertype())) &&
124 (querySecurityRuleIpPrefix == null ||
125 querySecurityRuleIpPrefix.equals(nsr.getSecurityRuleRemoteIpPrefix())) &&
126 (querySecurityRuleGroupID == null ||
127 querySecurityRuleGroupID.equals(nsr.getSecurityRuleGroupID())) &&
128 (querySecurityRemoteGroupID == null ||
129 querySecurityRemoteGroupID.equals(nsr.getSecurityRemoteGroupID())) &&
130 (querySecurityRuleTenantID == null ||
131 querySecurityRuleTenantID.equals(nsr.getSecurityRuleTenantID()))) {
132 if (fields.size() > 0) {
133 ans.add(extractFields(nsr, fields));
139 return Response.status(HttpURLConnection.HTTP_OK).entity(
140 new NeutronSecurityRuleRequest(ans)).build();
144 * Returns a specific Security Rule
147 @Path ("{securityRuleUUID}")
149 @Produces ({MediaType.APPLICATION_JSON})
151 @ResponseCode (code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
152 @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
153 @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
154 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
155 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
156 public Response showSecurityRule(@PathParam ("securityRuleUUID") String securityRuleUUID,
158 @QueryParam ("fields") List<String> fields) {
159 INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
160 if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
161 throw new ResourceNotFoundException(UUID_NO_EXIST);
163 if (!fields.isEmpty()) {
164 NeutronSecurityRule ans = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
165 return Response.status(HttpURLConnection.HTTP_OK).entity(
166 new NeutronSecurityRuleRequest(extractFields(ans, fields))).build();
168 return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build();
173 * Creates new Security Rule
177 @Produces ({MediaType.APPLICATION_JSON})
178 @Consumes ({MediaType.APPLICATION_JSON})
180 @ResponseCode (code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
181 @ResponseCode (code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
182 @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
183 @ResponseCode (code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
184 @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
185 @ResponseCode (code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
186 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
187 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
188 public Response createSecurityRules(final NeutronSecurityRuleRequest input) {
189 INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
192 * Existing entry checks
195 if (input.isSingleton()) {
196 NeutronSecurityRule singleton = input.getSingleton();
198 if (securityRuleInterface.neutronSecurityRuleExists(singleton.getSecurityRuleUUID())) {
199 throw new BadRequestException(UUID_EXISTS);
201 Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
202 if (instances != null) {
203 if (instances.length > 0) {
204 for (Object instance : instances) {
205 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
206 int status = service.canCreateNeutronSecurityRule(singleton);
207 if ((status < HTTP_OK_BOTTOM) || (status > HTTP_OK_TOP)) {
208 return Response.status(status).build();
212 throw new ServiceUnavailableException(NO_PROVIDERS);
215 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
219 singleton.initDefaults();
220 securityRuleInterface.addNeutronSecurityRule(singleton);
221 if (instances != null) {
222 for (Object instance : instances) {
223 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
224 service.neutronSecurityRuleCreated(singleton);
228 List<NeutronSecurityRule> bulk = input.getBulk();
229 Iterator<NeutronSecurityRule> i = bulk.iterator();
230 HashMap<String, NeutronSecurityRule> testMap = new HashMap<String, NeutronSecurityRule>();
231 Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
232 while (i.hasNext()) {
233 NeutronSecurityRule test = i.next();
236 * Verify that the security rule doesn't already exist
239 if (securityRuleInterface.neutronSecurityRuleExists(test.getSecurityRuleUUID())) {
240 throw new BadRequestException(UUID_EXISTS);
242 if (testMap.containsKey(test.getSecurityRuleUUID())) {
243 throw new BadRequestException(UUID_EXISTS);
245 if (instances != null) {
246 if (instances.length > 0) {
247 for (Object instance : instances) {
248 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
249 int status = service.canCreateNeutronSecurityRule(test);
250 if ((status < HTTP_OK_BOTTOM) || (status > HTTP_OK_TOP)) {
251 return Response.status(status).build();
255 throw new ServiceUnavailableException(NO_PROVIDERS);
258 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
263 * now, each element of the bulk request can be added to the cache
266 while (i.hasNext()) {
267 NeutronSecurityRule test = i.next();
268 securityRuleInterface.addNeutronSecurityRule(test);
269 if (instances != null) {
270 for (Object instance : instances) {
271 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
272 service.neutronSecurityRuleCreated(test);
277 return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
281 * Updates a Security Rule
284 @Path ("{securityRuleUUID}")
286 @Produces ({MediaType.APPLICATION_JSON})
287 @Consumes ({MediaType.APPLICATION_JSON})
289 @ResponseCode (code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
290 @ResponseCode (code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
291 @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
292 @ResponseCode (code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
293 @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
294 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
295 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
296 public Response updateSecurityRule(
297 @PathParam ("securityRuleUUID") String securityRuleUUID, final NeutronSecurityRuleRequest input) {
298 INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
301 * verify the Security Rule exists and there is only one delta provided
303 if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
304 throw new ResourceNotFoundException(UUID_NO_EXIST);
306 if (!input.isSingleton()) {
307 throw new BadRequestException("Only singleton edit supported");
309 NeutronSecurityRule delta = input.getSingleton();
310 NeutronSecurityRule original = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
313 * updates restricted by Neutron
316 if (delta.getSecurityRuleUUID() != null ||
317 delta.getSecurityRuleDirection() != null ||
318 delta.getSecurityRuleProtocol() != null ||
319 delta.getSecurityRulePortMin() != null ||
320 delta.getSecurityRulePortMax() != null ||
321 delta.getSecurityRuleEthertype() != null ||
322 delta.getSecurityRuleRemoteIpPrefix() != null ||
323 delta.getSecurityRuleGroupID() != null ||
324 delta.getSecurityRemoteGroupID() != null ||
325 delta.getSecurityRuleTenantID() != null) {
326 throw new BadRequestException("Attribute edit blocked by Neutron");
329 Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
330 if (instances != null) {
331 if (instances.length > 0) {
332 for (Object instance : instances) {
333 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
334 int status = service.canUpdateNeutronSecurityRule(delta, original);
335 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
336 return Response.status(status).build();
340 throw new ServiceUnavailableException(NO_PROVIDERS);
343 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
347 * update the object and return it
349 securityRuleInterface.updateNeutronSecurityRule(securityRuleUUID, delta);
350 NeutronSecurityRule updatedSecurityRule = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
351 if (instances != null) {
352 for (Object instance : instances) {
353 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
354 service.neutronSecurityRuleUpdated(updatedSecurityRule);
357 return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build();
361 * Deletes a Security Rule
364 @Path ("{securityRuleUUID}")
367 @ResponseCode (code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
368 @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
369 @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
370 @ResponseCode (code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
371 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
372 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
373 public Response deleteSecurityRule(
374 @PathParam ("securityRuleUUID") String securityRuleUUID) {
375 INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
378 * verify the Security Rule exists and it isn't currently in use
380 if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
381 throw new ResourceNotFoundException(UUID_NO_EXIST);
383 if (securityRuleInterface.neutronSecurityRuleInUse(securityRuleUUID)) {
384 return Response.status(HttpURLConnection.HTTP_CONFLICT).build();
386 NeutronSecurityRule singleton = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
387 Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
388 if (instances != null) {
389 if (instances.length > 0) {
390 for (Object instance : instances) {
391 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
392 int status = service.canDeleteNeutronSecurityRule(singleton);
393 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
394 return Response.status(status).build();
398 throw new ServiceUnavailableException(NO_PROVIDERS);
401 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
406 * remove it and return 204 status
408 securityRuleInterface.removeNeutronSecurityRule(securityRuleUUID);
409 if (instances != null) {
410 for (Object instance : instances) {
411 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
412 service.neutronSecurityRuleDeleted(singleton);
415 return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();