/******************************************************************************* * Copyright (c) 2013 GigaSpaces Technologies Ltd. All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. ******************************************************************************/ package org.cloudifysource.esc.driver.provisioning.openstack; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.lang.StringUtils; import org.cloudifysource.esc.driver.provisioning.openstack.rest.FloatingIp; import org.cloudifysource.esc.driver.provisioning.openstack.rest.Network; import org.cloudifysource.esc.driver.provisioning.openstack.rest.Port; import org.cloudifysource.esc.driver.provisioning.openstack.rest.Quota; import org.cloudifysource.esc.driver.provisioning.openstack.rest.Router; import org.cloudifysource.esc.driver.provisioning.openstack.rest.RouterInterface; import org.cloudifysource.esc.driver.provisioning.openstack.rest.SecurityGroup; import org.cloudifysource.esc.driver.provisioning.openstack.rest.SecurityGroupRule; import org.cloudifysource.esc.driver.provisioning.openstack.rest.Subnet; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; /** * A client for Openstack Network API. * * @author victor * @since 2.7.0 * */ public class OpenStackNetworkClient extends OpenStackBaseClient { private static final Logger logger = Logger.getLogger(OpenStackNetworkClient.class.getName()); private static final byte[] MUTEX_CREATE_SECURITY_GROUPS = new byte[0]; private static final byte[] MUTEX_CREATE_NETWORK = new byte[0]; private final String serviceName; private final String networkApiVersion; /** Testing purpose. */ OpenStackNetworkClient() { this.serviceName = "neutron"; this.networkApiVersion = "v2.0"; } public OpenStackNetworkClient(final String endpoint, final String username, final String password, final String tenant, final String region) throws OpenstackJsonSerializationException { this(endpoint, username, password, tenant, region, null, null); } public OpenStackNetworkClient(final String endpoint, final String username, final String password, final String tenant, final String region, final String serviceName) throws OpenstackJsonSerializationException { this(endpoint, username, password, tenant, region, serviceName, null); } public OpenStackNetworkClient(final String endpoint, final String username, final String password, final String tenant, final String region, final String serviceName, final String networkApiVersion) throws OpenstackJsonSerializationException { super(endpoint, username, password, tenant, region); this.serviceName = serviceName; this.networkApiVersion = StringUtils.isEmpty(networkApiVersion) ? "v2.0" : networkApiVersion; } @Override protected WebResource getWebResource() throws OpenstackException { WebResource webResource = super.getWebResource(); if (this.networkApiVersion != null) { webResource = webResource.path(this.networkApiVersion); } return webResource; } @Override protected String getServiceType() { return "network"; } @Override protected String getServiceName() { return this.serviceName; } /** * Retrieve the floating ip address associated to a port. * * @param portId * The port id. * @return The floating ip address or <code>null</code> if no floating ip attached. * @throws OpenstackException * Thrown when something went wrong with the request. */ public FloatingIp getFloatingIpByPortId(final String portId) throws OpenstackException { final String response = this.doGet("floatingips", new String[] { "port_id", portId }); final List<FloatingIp> floatingips = JsonUtils.unwrapRootToList(FloatingIp.class, response); if (floatingips != null && !floatingips.isEmpty()) { return floatingips.get(0); } return null; } /** * Retrieve floating ip by its ip address. * * @param floatingIp * The ip address of the floating ip. * @return The floating ip object. * @throws OpenstackException * Thrown when something went wrong with the request. */ public FloatingIp getFloatingIpByIp(final String floatingIp) throws OpenstackException { final String response = this.doGet("floatingips", new String[] { "floating_ip_address", floatingIp }); final List<FloatingIp> floatingips = JsonUtils.unwrapRootToList(FloatingIp.class, response); if (floatingips != null && !floatingips.isEmpty()) { return floatingips.get(0); } return null; } /** * Retrieve floating IPs. * * @return The list of floating IPs * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<FloatingIp> getFloatingIps() throws OpenstackException { final String response = this.doGet("floatingips"); final List<FloatingIp> floatingips = JsonUtils.unwrapRootToList(FloatingIp.class, response); return floatingips; } /** * Allocation a floating ip for a network. * * @param extNetworkName * The network name. * @return The allocated floating ip. * @throws OpenstackException * Thrown when something went wrong with the request. */ public FloatingIp allocateFloatingIp(final String extNetworkName) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Allocate floatingIp from network=" + extNetworkName); } final Network extNetwork = this.getNetworkByName(extNetworkName); if (extNetwork == null) { throw new OpenstackException("External network not found: " + extNetworkName); } final String input = String.format("{\"floatingip\":{\"floating_network_id\":\"%s\"}}", extNetwork.getId()); final String response = doPost("floatingips", input); final FloatingIp floatingIp = JsonUtils.unwrapRootToObject(FloatingIp.class, response); return floatingIp; } /** * Release a floating ip to free a slot in the pool. * * @param floatingIpId * The id of the floating ip to free. * @throws OpenstackException * Thrown when something went wrong with the request. */ public void releaseFloatingIp(final String floatingIpId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Release floatingIp=" + floatingIpId); } this.doDelete("floatingips/" + floatingIpId, CODE_OK_204); } /** * Assign a floating ip to a port. * * @param floatingId * The floating ip to assign. * @param portId * The port. * @return The updated floating ip object. * @throws OpenstackException * Thrown when something went wrong with the request. */ public FloatingIp assignFloatingIp(final String floatingId, final String portId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Assign floating ip for floatingId=" + floatingId + " to portId=" + portId); } final String input = String.format("{\"floatingip\":{\"port_id\":\"%s\"}}", portId); final String response = this.doPut("floatingips/" + floatingId, input); final FloatingIp floatingIp = JsonUtils.unwrapRootToObject(FloatingIp.class, response); return floatingIp; } /** * Unassign a floating ip. * * @param floatingId * The id of the floating ip to unsassign. * @return The updated floating ip object. * @throws OpenstackException * Thrown when something went wrong with the request. */ public FloatingIp unassignFloatingIp(final String floatingId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Unassign floating ip for floatingId=" + floatingId); } final String input = String.format("{\"floatingip\":{\"port_id\":null}}"); final String response = this.doPut("floatingips/" + floatingId, input); final FloatingIp floatingIp = JsonUtils.unwrapRootToObject(FloatingIp.class, response); return floatingIp; } /** * Allocate a floating from the pool and associate it to the given instance and network. * * @param deviceId * The server id. * @param networkId * The network id. * @return The floating ip address. * @throws OpenstackException * Thrown when something went wrong with the request. */ public String createAndAssociateFloatingIp(final String deviceId, final String networkId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Create and associate floating ip for devideId=" + deviceId + "/networkId=" + networkId); } if (networkId == null) { throw new OpenstackException("Public network not found for deviceId=" + deviceId); } final String floatingNetworkId = this.getPublicNetworkId(); final Port port = this.getPort(deviceId, networkId); if (port == null) { throw new OpenstackException("Port not found for deviceId=" + deviceId); } try { final String input = String.format( "{\"floatingip\":{\"floating_network_id\":\"%s\"," + "\"port_id\":\"%s\", \"fixed_ip_address\":\"%s\"}}", floatingNetworkId, port.getId(), port.getFixedIps().get(0).getIpAddress()); final String response = this.doPost("floatingips", input); final FloatingIp floatingIp = JsonUtils.unwrapRootToObject(FloatingIp.class, response); return floatingIp.getFloatingIpAddress(); } catch (final UniformInterfaceException e) { throw this.createOpenstackServerException(e); } } /** * Add interface to a router. * * @param routerId * The router id. * * @param subnetId * The subnet id. * @return The response. * @throws OpenstackException * Thrown if something went wrong with the request. */ public RouterInterface addRouterInterface(final String routerId, final String subnetId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Add interface subnetId=" + subnetId + " from routerId=" + routerId); } final String path = "routers/" + routerId + "/add_router_interface"; final String input = "{\"subnet_id\":\"" + subnetId + "\"}"; final String response = this.doPut(path, input); final RouterInterface routerInterface = JsonUtils.mapJsonToObject(RouterInterface.class, response); return routerInterface; } /** * Remove an interface from a router. * * @param routerId * The router id. * @param subnetId * The subnet id. * @throws OpenstackException * Thrown if something went wrong with the request. */ public void deleteRouterInterface(final String routerId, final String subnetId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Remove interface subnetId=" + subnetId + " from routerId=" + routerId); } final String path = "routers/" + routerId + "/remove_router_interface"; final String input = "{\"subnet_id\":\"" + subnetId + "\"}"; this.doPut(path, input); } /** * Create a router. * * @param request * The request. * @return The created router. * @throws OpenstackException * Thrown if something went wrong with the request. */ public Router createRouter(final Router request) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Create router=" + request); } final String jsonRequest = JsonUtils.toJson(request); final String response = this.doPost("routers", jsonRequest); final Router router = JsonUtils.unwrapRootToObject(Router.class, response); return router; } /** * Delete a router. * * @param routerId * The if of the router to delete. * @throws OpenstackException * Thrown if something went wrong with the request. */ public void deleteRouter(final String routerId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Delete routerId=" + routerId); } this.doDelete("routers/" + routerId, CODE_OK_204); } /** * Retrieve a list of routers. * * @return The list of routers. * @throws OpenstackException * Thrown if something went wrong with the request. */ public List<Router> getRouters() throws OpenstackException { final String response = this.doGet("routers"); final List<Router> routers = JsonUtils.unwrapRootToList(Router.class, response); return routers; } /** * Retrieve a router by name. * * @param name * The name of the router. * @return The router matching the given name. * @throws OpenstackException * Thrown if something went wrong with the request. */ public Router getRouterByName(final String name) throws OpenstackException { final String response = this.doGet("routers", new String[] { "name", name }); final List<Router> routers = JsonUtils.unwrapRootToList(Router.class, response); if (routers == null || routers.isEmpty()) { return null; } return routers.get(0); } /** * Retrieve routers by tenant id. * * @param tenantId * The tenant's id. * @return The router matching the tenant id. * @throws OpenstackException * Thrown if something went wrong with the request. */ public List<Router> getRoutersByTenantId(final String tenantId) throws OpenstackException { final String response = this.doGet("routers", new String[] { "tenant_id", tenantId }); return JsonUtils.unwrapRootToList(Router.class, response); } /** * Create a network if its not already exists.<br /> * To know if a network exists, it will check the network's name. * * @param request * The request. * @return The created network. * @throws OpenstackException * Thrown if something went wrong with the request. */ public Network createNetworkIfNotExists(final Network request) throws OpenstackException { if (request.getName() == null) { throw new IllegalArgumentException("Network templates should have names."); } synchronized (MUTEX_CREATE_NETWORK) { final Network existingNetwork = this.getNetworkByName(request.getName()); if (existingNetwork != null) { logger.info("Network '" + request.getName() + "' already exists."); return existingNetwork; } if (logger.isLoggable(Level.FINE)) { logger.fine("Create network=" + request); } final String json = JsonUtils.toJson(request); final String response = this.doPost("networks", json); final Network network = JsonUtils.unwrapRootToObject(Network.class, response); return network; } } /** * Delete a network. * * @param networkId * The id of the network to delete. * @throws OpenstackException * Thrown if something went wrong with the request. */ public void deleteNetwork(final String networkId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Delete networkId=" + networkId); } final List<Port> ports = getPortsByNetworkId(networkId); for (final Port port : ports) { this.deletePort(port.getId()); } this.doDelete("networks/" + networkId, CODE_OK_204); } /** * Retrieve a network by name. * * @param networkName * The name of the network. * @throws OpenstackException * Thrown if something went wrong with the request. */ public void deleteNetworkByName(final String networkName) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Delete network=" + networkName); } final Network network = this.getNetworkByName(networkName); if (network != null) { this.deleteNetwork(network.getId()); } } /** * Retrieve a network id which is connected to the external world. * * @return The public network id or <code>null</code> if not found. * @throws OpenstackException * Thrown when something went wrong with the request. */ public String getPublicNetworkId() throws OpenstackException { final List<Network> networks = this.getPublicNetwork(); for (final Network network : networks) { return network.getId(); } return null; } /** * Retrieve a network which is connected to the external world. * * @return The public network. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<Network> getPublicNetwork() throws OpenstackException { final String response = this.doGet("networks", new String[] { "router:external", "true" }); final List<Network> networks = JsonUtils.unwrapRootToList(Network.class, response); return networks; } /** * Retrieve a network by id. * * @param networkId * The id of the network. * @return The network. * @throws OpenstackException * Thrown if something went wrong with the request. */ public Network getNetwork(final String networkId) throws OpenstackException { final String response = this.doGet("networks/" + networkId); final Network network = JsonUtils.unwrapRootToObject(Network.class, response); return network; } /** * Retrieve a network matching the given name. * * @param networkName * The name of the looking network. * @return The network. * @throws OpenstackException * Thrown if something went wrong with the request. */ public Network getNetworkByName(final String networkName) throws OpenstackException { final String response = this.doGet("networks", new String[] { "name", networkName }); final List<Network> networks = JsonUtils.unwrapRootToList(Network.class, response); if (networks != null) { for (final Network network : networks) { if (networkName.equals(network.getName())) { return network; } } } return null; } /** * Returns networks. * * @return networks * @throws OpenstackException * Thrown if something went wrong with the request. */ public List<Network> getNetworks() throws OpenstackException { final String response = this.doGet("networks"); return JsonUtils.unwrapRootToList(Network.class, response); } /** * Returns networks of the given tenant id. * @param tenantId The id of the tenant * @return a list of networks * @throws OpenstackException * Thrown if something went wrong with the request. */ public List<Network> getNetworksByTenantId(final String tenantId) throws OpenstackException { final String response = this.doGet("networks", new String[] { "tenant_id", tenantId }); return JsonUtils.unwrapRootToList(Network.class, response); } /** * Retrieve networks with a prefix name. * * @param prefix * The prefix name. * @return A list of networks matching the prefix. * @throws OpenstackException * Thrown if something went wrong with the request. */ public List<Network> getNetworkByPrefix(final String prefix) throws OpenstackException { final String response = this.doGet("networks"); final List<Network> list = JsonUtils.unwrapRootToList(Network.class, response); final List<Network> networksToReturn = new ArrayList<Network>(); for (Network network : list) { if (network.getName().startsWith(prefix)) { networksToReturn.add(network); } } return networksToReturn; } /** * Retrieve the port which connect a given server to a given network. * * @param serverId * The server id. * @param networkId * The network id. * @return The port or <code>null</code> if none. * @throws OpenstackException * Thrown if something went wrong with the request. */ public Port getPort(final String serverId, final String networkId) throws OpenstackException { final String[] params = new String[] { "device_id", serverId, "network_id", networkId }; final String response = this.doGet("ports", params); final List<Port> ports = JsonUtils.unwrapRootToList(Port.class, response); if (ports == null || ports.isEmpty()) { return null; } return ports.get(0); } /** * Retrieve all ports attached to a network. * * @param networkId * The network id. * @return All ports attached to a network. * @throws OpenstackException * Thrown if something went wrong with the request. */ private List<Port> getPortsByNetworkId(final String networkId) throws OpenstackException { final String[] params = new String[] { "network_id", networkId }; final String response = this.doGet("ports", params); final List<Port> ports = JsonUtils.unwrapRootToList(Port.class, response); return ports; } /** * Retrieve all ports attached to a device. * * @param deviceId * The server to request. * @return The list ports attached to the server. * @throws OpenstackException * Thrown if something went wrong with the request. */ public List<Port> getPortsByDeviceId(final String deviceId) throws OpenstackException { final String[] params = new String[] { "device_id", deviceId }; final String response = this.doGet("ports", params); final List<Port> ports = JsonUtils.unwrapRootToList(Port.class, response); return ports; } /** * Create a port. * * @param request * The request. * @return The created port. * @throws OpenstackException * Thrown if something went wrong with the request. */ public Port createPort(final Port request) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Create port=" + request); } final String jsonRequest = JsonUtils.toJson(request); final String response = this.doPost("ports", jsonRequest); final Port port = JsonUtils.unwrapRootToObject(Port.class, response); return port; } /** * Update a port (to add security groups for instance). * * @param request * The request. * @return The updated port. * @throws OpenstackException * Thrown when something went wrong with the request. */ public Port updatePort(final Port request) throws OpenstackException { final String portId = request.getId(); if (logger.isLoggable(Level.FINE)) { logger.fine("Update portId=" + portId); } try { // TODO Should handle the request properly without changing the request object. request.setId(null); final String jsonRequest = JsonUtils.toJson(request); final String response = this.doPut("ports/" + portId, jsonRequest); final Port port = JsonUtils.unwrapRootToObject(Port.class, response); return port; } finally { request.setId(portId); } } /** * Delete a port. * * @param portId * The id of the port to delete. * @throws OpenstackException * Thrown when something went wrong with the request. */ public void deletePort(final String portId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Delete portId=" + portId); } this.doDelete("ports/" + portId, CODE_OK_204); } /** * Disassociate and release a floating ip which was mapped to a fixed ip address. * * @param fixedIp * The fixed ip address. * @throws OpenstackException * Thrown when something went wrong with the request. */ public void deleteFloatingIPByFixedIp(final String fixedIp) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Delete floatingIp associated to fixedIp=" + fixedIp); } final String response = this.doGet("floatingips", new String[] { "fixed_ip_address", fixedIp }); final List<FloatingIp> floatingIPs = JsonUtils.unwrapRootToList(FloatingIp.class, response); if (floatingIPs != null && floatingIPs.size() != 0) { final String floatingIPId = floatingIPs.get(0).getId(); this.deleteFloatingIP(floatingIPId); } else { logger.warning("No Floating IP found for fixedIp=" + fixedIp); } } /** * Release a floating ip and return it to the pool. * * @param floatingIPId * The floating id to delete. * * @throws OpenstackException * Thrown when something went wrong with the request. */ public void deleteFloatingIP(final String floatingIPId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Delete floatingIp=" + floatingIPId); } this.doDelete("floatingips/" + floatingIPId, CODE_OK_204); } /** * Retrieve existing security groups by prefix name. * * @param prefix * The prefix. * @return A list of security groups that match the prefix. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<SecurityGroup> getSecurityGroupsByPrefix(final String prefix) throws OpenstackException { final String response = this.doGet("security-groups"); final List<SecurityGroup> securityGroupsResponse = JsonUtils.unwrapRootToList(SecurityGroup.class, response); final List<SecurityGroup> list = new ArrayList<SecurityGroup>(); if (securityGroupsResponse != null) { for (final SecurityGroup securityGroup : securityGroupsResponse) { if (securityGroup.getName().startsWith(prefix)) { list.add(securityGroup); } } } return list; } /** * Retrieve existing security groups by name. * * @param name * The name. * @return A list of security groups that match the exact given name. * @throws OpenstackException * Thrown when something went wrong with the request. */ public SecurityGroup getSecurityGroupsByName(final String name) throws OpenstackException { final String response = this.doGet("security-groups"); final List<SecurityGroup> securityGroups = JsonUtils.unwrapRootToList(SecurityGroup.class, response); if (securityGroups != null) { for (final SecurityGroup securityGroup : securityGroups) { if (securityGroup.getName().equals(name)) { return securityGroup; } } } return null; } /** * Retrieve existing security groups by tenant id. * * @param tenantId * The tenant's id. * @return A list of security groups that match the specified tenant id. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<SecurityGroup> getSecurityGroupsByTenantId(final String tenantId) throws OpenstackException { final String response = this.doGet("security-groups", new String[] { "tenant_id", tenantId }); return JsonUtils.unwrapRootToList(SecurityGroup.class, response); } /** * Returns existing security groups. * * @return Existing security groups. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<SecurityGroup> getSecurityGroups() throws OpenstackException { final String response = this.doGet("security-groups"); final List<SecurityGroup> securityGroups = JsonUtils.unwrapRootToList(SecurityGroup.class, response); return securityGroups; } /** * Retrieve security groups by id. * * @param securityGroupId * The security group id. * @return The security group. * @throws OpenstackException * Thrown when something went wrong with the request. */ public SecurityGroup getSecurityGroupsById(final String securityGroupId) throws OpenstackException { final String response = this.doGet("security-groups/" + securityGroupId); final SecurityGroup securityGroup = JsonUtils.unwrapRootToObject(SecurityGroup.class, response); return securityGroup; } /** * Create a security group if it does not already exists. * * @param request * The request. * @return The created security group or <code>null</code> if the security group already exists. * @throws OpenstackException * Thrown when something went wrong with the request. */ public SecurityGroup createSecurityGroupsIfNotExist(final SecurityGroup request) throws OpenstackException { // We can either use synchronize or handle exception to ensure that we create only one group. synchronized (MUTEX_CREATE_SECURITY_GROUPS) { try { final String jsonRequest = JsonUtils.toJson(request); final SecurityGroup securityGroup = this.getSecurityGroupsByName(request.getName()); if (securityGroup != null) { logger.info("Security group '" + request.getName() + "' already exists."); return null; } if (logger.isLoggable(Level.FINE)) { logger.fine("Create security group : " + request.getName()); } final String response = this.doPost("security-groups", jsonRequest); final SecurityGroup created = JsonUtils.unwrapRootToObject(SecurityGroup.class, response); return created; } catch (UniformInterfaceException e) { throw this.createOpenstackServerException(e); } } } /** * Delete a security group. * * @param securityGroupId * The id of the security group to delete * @throws OpenstackException * Thrown when something went wrong with the request. */ public void deleteSecurityGroup(final String securityGroupId) throws OpenstackException { this.doDelete("security-groups/" + securityGroupId, CODE_OK_204); } /** * Create a security group rule. * * @param request * The request. * @return The security group updated with the new rule. * @throws OpenstackException * Thrown when something went wrong with the request. */ public SecurityGroupRule createSecurityGroupRule(final SecurityGroupRule request) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Create securityGroupRule=" + request); } final String jsonRequest = JsonUtils.toJson(request); String response = null; try { response = this.doPost("security-group-rules", jsonRequest); } catch (final OpenstackServerException e) { if (e.getMessage().contains("already exists")) { logger.warning("Rule already exists: " + request); return null; } else { logger.warning(e.getMessage()); } } final SecurityGroupRule created = JsonUtils.unwrapRootToObject(SecurityGroupRule.class, response); return created; } /** * Delete a security group rule. * * @param securityGroupRuleId * The id of the rule to delete. * @throws OpenstackException * Thrown if something went wrong with the request. */ public void deleteSecurityGroupRule(final String securityGroupRuleId) throws OpenstackException { this.doDelete("security-group-rules/" + securityGroupRuleId, CODE_OK_204); } /** * Retrieve existing security groups by tenant id. * * @param tenantId * The tenant's id. * @return A list of security groups that match the specified tenant id. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<SecurityGroupRule> getSecurityGroupRulesByTenantId(final String tenantId) throws OpenstackException { final String response = this.doGet("security-group-rules", new String[] { "tenant_id", tenantId }); return JsonUtils.unwrapRootToList(SecurityGroupRule.class, response); } /** * Create a subnet. * * @param request * The request. * @return The created subnet. * @throws OpenstackException * Thrown if something went wrong with the request. */ public Subnet createSubnet(final Subnet request) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Create subnet=" + request); } String jsonRequest = JsonUtils.toJson(request); // When getwayIp="null" this means that Openstack should not automatically assign a gateway to the subnet. jsonRequest = jsonRequest.replaceAll("\"gateway_ip\"\\s*:\\s*\"null\"", "\"gateway_ip\" : null"); Subnet subnet = null; try { final String response = this.doPost("subnets", jsonRequest); subnet = JsonUtils.unwrapRootToObject(Subnet.class, response); } catch (final UniformInterfaceException e) { throw this.createOpenstackServerException(e); } return subnet; } /** * Get all subnets of a given network. * * @param networkId * The network id. * @return A list of subnets associated to a network. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<Subnet> getSubnetsByNetworkId(final String networkId) throws OpenstackException { final String response = this.doGet("subnets", new String[] { "network_id", networkId }); final List<Subnet> subnets = JsonUtils.unwrapRootToList(Subnet.class, response); return subnets; } /** * Get all subnets of a given network. * * @param networkName * The network name. * @return A list of subnets belonging to a network. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<Subnet> getSubnetsByNetworkName(final String networkName) throws OpenstackException { final Network network = this.getNetworkByName(networkName); if (network != null) { return this.getSubnetsByNetworkId(network.getId()); } return null; } /** * Get all subnets associated with the networks of the given tenant id. * * @param tenantId * The network id. * @return A list of subnets associated with the networks of the given tenant id. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<Subnet> getSubnetsByTenantId(final String tenantId) throws OpenstackException { final List<Subnet> subnets = new ArrayList<Subnet>(); final List<Network> tenantNetworks = this.getNetworksByTenantId(tenantId); for (Network tenantNetwork : tenantNetworks) { subnets.addAll(getSubnetsByNetworkId(tenantNetwork.getId())); } return subnets; } /** * Get all subnets visible to this tenant. * * @return A list of subnets belonging to a network. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<Subnet> getSubnets() throws OpenstackException { final List<Subnet> subnets = new ArrayList<Subnet>(); final List<Network> networks = this.getNetworks(); for (Network network : networks) { subnets.addAll(getSubnetsByNetworkId(network.getId())); } return subnets; } /** * Get quotas for the current tenant. * * @return quota object, containing different quotas * @throws OpenstackException * Thrown when something went wrong with the request. */ public Quota getQuotas() throws OpenstackException { String tenantId = getTenantId(); if (StringUtils.isBlank(tenantId)) { throw new OpenstackException("Tenant id not found"); } return getQuotasForTenant(tenantId); } /** * Get quotas for the specified tenant. * * @param tenantId * The id of the relevant tenant * @return quota object, containing different quotas * @throws OpenstackException * Thrown when something went wrong with the request. */ public Quota getQuotasForTenant(final String tenantId) throws OpenstackException { final String response = this.doGet("quotas/" + tenantId); return JsonUtils.unwrapRootToObject(Quota.class, response); } }