OpenNebula.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package hudson.plugins.ec2;
  2. import hudson.Extension;
  3. import hudson.plugins.ec2.one.OneEC2Cloud;
  4. import hudson.plugins.ec2.one.OneSlaveTemplate;
  5. import hudson.util.FormValidation;
  6. import hudson.util.IOException2;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.net.MalformedURLException;
  10. import java.net.URL;
  11. import java.net.URLConnection;
  12. import java.security.GeneralSecurityException;
  13. import java.security.KeyManagementException;
  14. import java.security.NoSuchAlgorithmException;
  15. import java.security.cert.X509Certificate;
  16. import java.util.List;
  17. import javax.net.ssl.HostnameVerifier;
  18. import javax.net.ssl.HttpsURLConnection;
  19. import javax.net.ssl.SSLContext;
  20. import javax.net.ssl.SSLSession;
  21. import javax.net.ssl.TrustManager;
  22. import javax.net.ssl.X509TrustManager;
  23. import javax.servlet.ServletException;
  24. import org.dom4j.Document;
  25. import org.dom4j.Element;
  26. import org.kohsuke.stapler.DataBoundConstructor;
  27. import org.kohsuke.stapler.QueryParameter;
  28. /**
  29. * The original implementation of {@link EC2Cloud}.
  30. *
  31. * @author Kohsuke Kawaguchi
  32. */
  33. public class OpenNebula extends OneEC2Cloud {
  34. private transient Metadata metadata;
  35. // Used when running unit tests
  36. public static boolean testMode;
  37. public final URL url;
  38. @DataBoundConstructor
  39. public OpenNebula(final String url, final String accessId,
  40. final String secretKey, final String privateKey,
  41. final String instanceCapStr,
  42. final List<OneSlaveTemplate> templates)
  43. throws MalformedURLException {
  44. this(new URL(url), accessId, secretKey, privateKey,
  45. instanceCapStr, templates);
  46. }
  47. @DataBoundConstructor
  48. public OpenNebula(final URL url, final String accessId,
  49. final String secretKey, final String privateKey,
  50. final String instanceCapStr,
  51. final List<OneSlaveTemplate> templates) {
  52. super("one-", accessId, secretKey, privateKey, instanceCapStr,
  53. templates);
  54. this.url = url;
  55. }
  56. private Metadata getMetadata() throws IOException {
  57. if (metadata == null) {
  58. metadata = new Metadata(url);
  59. }
  60. return metadata;
  61. }
  62. @Override
  63. public URL getEc2EndpointUrl() throws IOException {
  64. return getMetadata().ec2endpoint;
  65. }
  66. @Override
  67. public URL getS3EndpointUrl() throws IOException {
  68. return getMetadata().s3endpoint;
  69. }
  70. @Extension
  71. public static class DescriptorImpl extends OneEC2Cloud.DescriptorImpl {
  72. @Override
  73. public String getDisplayName() {
  74. return "OpenNebula";
  75. }
  76. @Override
  77. public FormValidation doTestConnection(
  78. @QueryParameter final URL url,
  79. @QueryParameter final String accessId,
  80. @QueryParameter final String secretKey,
  81. @QueryParameter final String privateKey)
  82. throws IOException, ServletException {
  83. return super.doTestConnection(new Metadata(url).ec2endpoint,
  84. accessId, secretKey, privateKey);
  85. }
  86. }
  87. /**
  88. * OpenNebula service endpoint metadata.
  89. */
  90. static class Metadata {
  91. final URL ec2endpoint, s3endpoint;
  92. Metadata(final URL oneUrl) throws IOException {
  93. // InputStream is = readMetadata(oneUrl);
  94. ec2endpoint = getUrl(oneUrl);
  95. s3endpoint = getUrl(oneUrl);
  96. }
  97. /**
  98. * @param oneUrl
  99. * @return
  100. * @throws MalformedURLException
  101. */
  102. private URL getUrl(final URL oneUrl) throws MalformedURLException {
  103. return (null != oneUrl) ? oneUrl : new URL(
  104. "http://opennebula:4568");
  105. }
  106. /**
  107. * @param oneUrl
  108. * @param metadataUrl
  109. * @throws IOException
  110. * @throws NoSuchAlgorithmException
  111. * @throws KeyManagementException
  112. */
  113. private InputStream readMetadata(final URL url)
  114. throws IOException, NoSuchAlgorithmException,
  115. KeyManagementException {
  116. InputStream is = null;
  117. URL metadataUrl = new URL(getUrl(url), "/");
  118. try {
  119. if (getUrl(url).getProtocol().equals("https")) {
  120. HttpsURLConnection con =
  121. (HttpsURLConnection) getUrl(metadataUrl)
  122. .openConnection();
  123. makeIgnoreCertificate(con);
  124. is = con.getInputStream();
  125. } else {
  126. URLConnection con =
  127. getUrl(metadataUrl).openConnection();
  128. is = con.getInputStream();
  129. }
  130. } catch (IOException e) {
  131. throw new IOException2(
  132. "Failed to parse OpenNebula metadata at "
  133. + getUrl(metadataUrl), e);
  134. } catch (GeneralSecurityException e) {
  135. throw new IOException2(
  136. "Failed to parse OpenNebula metadata at "
  137. + getUrl(metadataUrl), e);
  138. }
  139. return is;
  140. }
  141. /**
  142. * Configures the given {@link HttpsURLConnection} so that it'll ignore
  143. * all the HTTPS certificate checks, as typical Eucalyptus
  144. * implementation doesn't come with a valid certificate.
  145. */
  146. private void makeIgnoreCertificate(final HttpsURLConnection con)
  147. throws NoSuchAlgorithmException, KeyManagementException {
  148. SSLContext sc = SSLContext.getInstance("SSL");
  149. TrustManager[] tma = {new X509TrustManager() {
  150. public X509Certificate[] getAcceptedIssuers() {
  151. return null;
  152. }
  153. public void checkClientTrusted(
  154. final X509Certificate[] certs,
  155. final String authType) {
  156. }
  157. public void checkServerTrusted(
  158. final X509Certificate[] certs,
  159. final String authType) {
  160. }
  161. } };
  162. sc.init(null, tma, null);
  163. con.setSSLSocketFactory(sc.getSocketFactory());
  164. con.setHostnameVerifier(new HostnameVerifier() {
  165. public boolean verify(final String s,
  166. final SSLSession sslSession) {
  167. return true; // everything goes
  168. }
  169. });
  170. }
  171. @Deprecated
  172. private URL readURLFromMetadata(final Document metadata,
  173. final String serviceName) throws MalformedURLException {
  174. Element e =
  175. (Element) metadata
  176. .selectSingleNode("//Service[Name/text()='"
  177. + serviceName + "']/EndpointUrl");
  178. if (e == null) {
  179. throw new IllegalStateException(
  180. "Service metadata didn't contain " + serviceName);
  181. }
  182. return new URL(e.getTextTrim());
  183. }
  184. }
  185. }