/******************************************************************************* * 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.ComputeLimits; import org.cloudifysource.esc.driver.provisioning.openstack.rest.Flavor; import org.cloudifysource.esc.driver.provisioning.openstack.rest.Image; import org.cloudifysource.esc.driver.provisioning.openstack.rest.NovaServer; import org.cloudifysource.esc.driver.provisioning.openstack.rest.NovaServerAddress; import org.cloudifysource.esc.driver.provisioning.openstack.rest.NovaServerResquest; import org.cloudifysource.esc.driver.provisioning.openstack.rest.NovaServerSecurityGroup; /** * A client for Openstack Nova. * * @author victor * @since 2.7.0 * */ public class OpenStackComputeClient extends OpenStackBaseClient { private static final int RESOURCE_NOT_FOUND_STATUS = 404; private static final Logger logger = Logger.getLogger(OpenStackComputeClient.class.getName()); private String serviceName; /** Testing purpose. */ OpenStackComputeClient() { } public OpenStackComputeClient(final String endpoint, final String username, final String password, final String tenant, final String region) throws OpenstackJsonSerializationException { this(endpoint, username, password, tenant, region, null); } public OpenStackComputeClient(final String endpoint, final String username, final String password, final String tenant, final String region, final String serviceName) throws OpenstackJsonSerializationException { super(endpoint, username, password, tenant, region); this.serviceName = serviceName; } @Override protected String getServiceName() { return this.serviceName; } @Override protected String getServiceType() { return "compute"; } /** * Returns the Openstack image. * * @param imageId * image id to check * @return The image. * @throws OpenstackException * {@link OpenstackException} */ public Image getImage(final String imageId) throws OpenstackException { final String response = this.doGet("images/" + imageId); final Image image = JsonUtils.unwrapRootToObject(Image.class, response); return image; } /** * Return the list of images available in Openstack. * * @return The list of images available in Openstack. * @throws OpenstackException * {@link OpenstackException} */ public List<Image> getImages() throws OpenstackException { final String response = this.doGet("images"); final List<Image> image = JsonUtils.unwrapRootToList(Image.class, response); return image; } /** * Returns the Openstack flavor. * * @param flavorId * hardware/flavor to check * @return the Openstack flavor. * @throws OpenstackException * {@link OpenstackException} */ public Flavor getFlavor(final String flavorId) throws OpenstackException { final String response = this.doGet("flavors/" + flavorId); final Flavor flavor = JsonUtils.unwrapRootToObject(Flavor.class, response); return flavor; } /** * Return the list of flavors available in Openstack. * * @return The list of flavors available in Openstack. * @throws OpenstackException * {@link OpenstackException} */ public List<Flavor> getFlavors() throws OpenstackException { final String response = this.doGet("flavors"); final List<Flavor> flavors = JsonUtils.unwrapRootToList(Flavor.class, response); return flavors; } /** * Create a new VM instance. * * @param request * The request. * @return The server details. * @throws OpenstackException * Thrown when a problem occurs with the request. */ public NovaServer createServer(final NovaServerResquest request) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Launch instance=" + request); } final String computeRequest = JsonUtils.toJson(request, false); final String response = this.doPost("servers", computeRequest); final NovaServer nsr = JsonUtils.unwrapRootToObject(NovaServer.class, response); return nsr; } /** * List existing servers. * * @return A list of existing servers. * @throws OpenstackException * Thrown when a problem occurs with the request. */ public List<NovaServer> getServers() throws OpenstackException { final String response = this.doGet("servers"); final List<NovaServer> servers = JsonUtils.unwrapRootToList(NovaServer.class, response); final List<NovaServer> detailServers = new ArrayList<NovaServer>(servers.size()); for (final NovaServer sv : servers) { final NovaServer serverDetails = this.getServerDetails(sv.getId()); detailServers.add(serverDetails); } return detailServers; } /** * Get a list of instances that match the prefix name. * * @param prefix * The prefix to be match. * @return A list of instances prefixed by the given name. * @throws OpenstackException * Thrown when something went wrong with the request. */ public List<NovaServer> getServersByPrefix(final String prefix) throws OpenstackException { final String response; try { response = this.doGet("servers", new String[] { "name", prefix }); } catch (OpenstackServerException e) { if (RESOURCE_NOT_FOUND_STATUS == e.getStatusCode()) { return null; } throw e; } final List<NovaServer> servers = JsonUtils.unwrapRootToList(NovaServer.class, response); final List<NovaServer> detailServers = new ArrayList<NovaServer>(servers.size()); for (final NovaServer sv : servers) { final NovaServer serverDetails = this.getServerDetails(sv.getId()); detailServers.add(serverDetails); } return detailServers; } /** * Get an instance by ip. * * @param serverIp * The ip of the server to get. * @return The server instance that match the ip. * @throws OpenstackException * Thrown when something went wrong with the request. */ public NovaServer getServerByIp(final String serverIp) throws OpenstackException { final List<NovaServer> servers = this.getServers(); for (final NovaServer server : servers) { final NovaServer serverDetails = this.getServerDetails(server.getId()); if (serverDetails != null) { final List<NovaServerAddress> addresses = serverDetails.getAddresses(); if (addresses != null) { for (final NovaServerAddress novaServerAddress : addresses) { final String addr = novaServerAddress.getAddr(); if (StringUtils.equals(addr, serverIp)) { return serverDetails; } } } } } return null; } /** * Get an instance by ip and security group name. * * @param serverIp * The ip of the server. * @param secgroupName * The security group name which must be present in the server. * @return The server instance which match the request. * @throws OpenstackException * Thrown when something went wrong with the request. */ public NovaServer getServerByIpAndSecurityGroup(final String serverIp, final String secgroupName) throws OpenstackException { final List<NovaServer> servers = this.getServers(); for (final NovaServer server : servers) { final NovaServer serverDetails = this.getServerDetails(server.getId()); if (serverDetails != null) { final List<NovaServerAddress> addresses = serverDetails.getAddresses(); if (addresses != null) { for (final NovaServerAddress novaServerAddress : addresses) { final String addr = novaServerAddress.getAddr(); if (StringUtils.equals(addr, serverIp)) { for (final NovaServerSecurityGroup secgroup : serverDetails.getSecurityGroups()) { if (secgroup.getName().equals(secgroupName)) { return serverDetails; } } } } } } } return null; } /** * Retrieve server's details. * * @param serverId * The id of the server. * @return An instance of the server with all its details. * @throws OpenstackException * Thrown when something went wrong with the request. */ public NovaServer getServerDetails(final String serverId) throws OpenstackException { final String response; try { response = doGet("servers/" + serverId); } catch (final OpenstackServerException e) { if (RESOURCE_NOT_FOUND_STATUS == e.getStatusCode()) { return null; } throw e; } final NovaServer nsr = JsonUtils.unwrapRootToObject(NovaServer.class, response, false); return nsr; } /** * Terminate a server instance in Openstack. * * @param serverId * The server id tto terminate. * @throws OpenstackException * Thrown when something went wrong with the request. */ public void deleteServer(final String serverId) throws OpenstackException { if (logger.isLoggable(Level.FINE)) { logger.fine("Terminate serverId=" + serverId); } this.doDelete("servers/" + serverId, CODE_OK_204); } /** * Returns the compute resource limit such as * max total cores and max total memory. * @return * An object containing compute resource limit data. * @throws OpenstackException * Thrown when something went wrong with the request. */ public ComputeLimits getLimits() throws OpenstackException { final String response; try { response = doGet("limits"); } catch (final OpenstackServerException e) { if (RESOURCE_NOT_FOUND_STATUS == e.getStatusCode()) { return null; } throw e; } final ComputeLimits limits = JsonUtils.unwrapRootToObject(ComputeLimits.class, response, false); return limits; } }