mirror of
https://github.com/Fishwaldo/rundeck-api-java-client.git
synced 2025-07-08 14:08:33 +00:00
commit
663d1c2366
64 changed files with 3221 additions and 75 deletions
2
pom.xml
2
pom.xml
|
@ -27,7 +27,7 @@
|
||||||
<!-- Project informations -->
|
<!-- Project informations -->
|
||||||
<groupId>org.rundeck</groupId>
|
<groupId>org.rundeck</groupId>
|
||||||
<artifactId>rundeck-api-java-client</artifactId>
|
<artifactId>rundeck-api-java-client</artifactId>
|
||||||
<version>10.1-SNAPSHOT</version>
|
<version>11.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>RunDeck API - Java Client</name>
|
<name>RunDeck API - Java Client</name>
|
||||||
<description>Java client for the RunDeck REST API</description>
|
<description>Java client for the RunDeck REST API</description>
|
||||||
|
|
|
@ -22,6 +22,22 @@
|
||||||
<author>Vincent Behar</author>
|
<author>Vincent Behar</author>
|
||||||
</properties>
|
</properties>
|
||||||
<body>
|
<body>
|
||||||
|
<release date='2014-04-24' description='Rundeck API version 11' version='11.0'>
|
||||||
|
<action type='add' dev='gschueler'>Project creation</action>
|
||||||
|
<action type='add' dev='gschueler'>Get Project configuration</action>
|
||||||
|
<action type='add' dev='gschueler'>Set Project configuration</action>
|
||||||
|
<action type='add' dev='gschueler'>Get/Set Project configuration keys</action>
|
||||||
|
<action type='add' dev='gschueler'>Delete project</action>
|
||||||
|
<action type='add' dev='gschueler'>Export project archive</action>
|
||||||
|
<action type='add' dev='gschueler'>Import project archive</action>
|
||||||
|
<action type='add' dev='gschueler'>Key file upload</action>
|
||||||
|
<action type='add' dev='gschueler'>Key file delete</action>
|
||||||
|
<action type='add' dev='gschueler'>Key file list</action>
|
||||||
|
<action type='add' dev='gschueler'>Key file get</action>
|
||||||
|
<action type='add' dev='gschueler'>API Token create</action>
|
||||||
|
<action type='add' dev='gschueler'>API Token list</action>
|
||||||
|
<action type='add' dev='gschueler'>API Token delete</action>
|
||||||
|
</release>
|
||||||
<release date='2014-02-27' description='Rundeck API version 10' version='10.0'>
|
<release date='2014-02-27' description='Rundeck API version 10' version='10.0'>
|
||||||
<action type='add' dev='gschueler'>
|
<action type='add' dev='gschueler'>
|
||||||
Execution State - Retrieve workflow step and node state information
|
Execution State - Retrieve workflow step and node state information
|
||||||
|
|
|
@ -15,23 +15,18 @@
|
||||||
*/
|
*/
|
||||||
package org.rundeck.api;
|
package org.rundeck.api;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.http.Header;
|
import org.apache.http.*;
|
||||||
import org.apache.http.HttpException;
|
|
||||||
import org.apache.http.HttpRequest;
|
|
||||||
import org.apache.http.HttpRequestInterceptor;
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.NameValuePair;
|
|
||||||
import org.apache.http.ParseException;
|
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
import org.apache.http.client.methods.HttpDelete;
|
import org.apache.http.client.methods.*;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.client.methods.HttpRequestBase;
|
|
||||||
import org.apache.http.conn.scheme.Scheme;
|
import org.apache.http.conn.scheme.Scheme;
|
||||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||||
import org.apache.http.conn.ssl.TrustStrategy;
|
import org.apache.http.conn.ssl.TrustStrategy;
|
||||||
|
import org.apache.http.entity.BasicHttpEntity;
|
||||||
|
import org.apache.http.entity.EntityTemplate;
|
||||||
|
import org.apache.http.entity.FileEntity;
|
||||||
import org.apache.http.entity.mime.HttpMultipartMode;
|
import org.apache.http.entity.mime.HttpMultipartMode;
|
||||||
import org.apache.http.entity.mime.MultipartEntity;
|
import org.apache.http.entity.mime.MultipartEntity;
|
||||||
import org.apache.http.entity.mime.content.InputStreamBody;
|
import org.apache.http.entity.mime.content.InputStreamBody;
|
||||||
|
@ -48,11 +43,9 @@ import org.rundeck.api.RundeckApiException.RundeckApiTokenException;
|
||||||
import org.rundeck.api.parser.ParserHelper;
|
import org.rundeck.api.parser.ParserHelper;
|
||||||
import org.rundeck.api.parser.XmlNodeParser;
|
import org.rundeck.api.parser.XmlNodeParser;
|
||||||
import org.rundeck.api.util.AssertUtil;
|
import org.rundeck.api.util.AssertUtil;
|
||||||
|
import org.rundeck.api.util.DocumentContentProducer;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.ProxySelector;
|
import java.net.ProxySelector;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
|
@ -270,6 +263,27 @@ class ApiCall {
|
||||||
public <T> T post(ApiPathBuilder apiPath, XmlNodeParser<T> parser) throws RundeckApiException,
|
public <T> T post(ApiPathBuilder apiPath, XmlNodeParser<T> parser) throws RundeckApiException,
|
||||||
RundeckApiLoginException, RundeckApiTokenException {
|
RundeckApiLoginException, RundeckApiTokenException {
|
||||||
HttpPost httpPost = new HttpPost(client.getUrl() + client.getApiEndpoint() + apiPath);
|
HttpPost httpPost = new HttpPost(client.getUrl() + client.getApiEndpoint() + apiPath);
|
||||||
|
return requestWithEntity(apiPath, parser, httpPost);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Execute an HTTP PUT request to the RunDeck instance, on the given path. We will login first, and then execute
|
||||||
|
* the API call. At the end, the given parser will be used to convert the response to a more useful result object.
|
||||||
|
*
|
||||||
|
* @param apiPath on which we will make the HTTP request - see {@link ApiPathBuilder}
|
||||||
|
* @param parser used to parse the response
|
||||||
|
* @return the result of the call, as formatted by the parser
|
||||||
|
* @throws RundeckApiException in case of error when calling the API
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
*/
|
||||||
|
public <T> T put(ApiPathBuilder apiPath, XmlNodeParser<T> parser) throws RundeckApiException,
|
||||||
|
RundeckApiLoginException, RundeckApiTokenException {
|
||||||
|
HttpPut httpPut = new HttpPut(client.getUrl() + client.getApiEndpoint() + apiPath);
|
||||||
|
return requestWithEntity(apiPath, parser, httpPut);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T requestWithEntity(ApiPathBuilder apiPath, XmlNodeParser<T> parser, HttpEntityEnclosingRequestBase
|
||||||
|
httpPost) {
|
||||||
if(null!= apiPath.getAccept()) {
|
if(null!= apiPath.getAccept()) {
|
||||||
httpPost.setHeader("Accept", apiPath.getAccept());
|
httpPost.setHeader("Accept", apiPath.getAccept());
|
||||||
}
|
}
|
||||||
|
@ -286,6 +300,18 @@ class ApiCall {
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new RundeckApiException("Unsupported encoding: " + e.getMessage(), e);
|
throw new RundeckApiException("Unsupported encoding: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
}else if(apiPath.getContentStream() !=null && apiPath.getContentType()!=null){
|
||||||
|
BasicHttpEntity entity = new BasicHttpEntity();
|
||||||
|
entity.setContent(apiPath.getContentStream());
|
||||||
|
entity.setContentType(apiPath.getContentType());
|
||||||
|
httpPost.setEntity(entity);
|
||||||
|
}else if(apiPath.getContentFile() !=null && apiPath.getContentType()!=null){
|
||||||
|
httpPost.setEntity(new FileEntity(apiPath.getContentFile(), apiPath.getContentType()));
|
||||||
|
}else if(apiPath.getXmlDocument()!=null) {
|
||||||
|
httpPost.setHeader("Content-Type", "application/xml");
|
||||||
|
httpPost.setEntity(new EntityTemplate(new DocumentContentProducer(apiPath.getXmlDocument())));
|
||||||
|
}else if(apiPath.isEmptyContent()){
|
||||||
|
//empty content
|
||||||
}else {
|
}else {
|
||||||
throw new IllegalArgumentException("No Form or Multipart entity for POST content-body");
|
throw new IllegalArgumentException("No Form or Multipart entity for POST content-body");
|
||||||
}
|
}
|
||||||
|
@ -308,6 +334,22 @@ class ApiCall {
|
||||||
RundeckApiLoginException, RundeckApiTokenException {
|
RundeckApiLoginException, RundeckApiTokenException {
|
||||||
return execute(new HttpDelete(client.getUrl() + client.getApiEndpoint() + apiPath), parser);
|
return execute(new HttpDelete(client.getUrl() + client.getApiEndpoint() + apiPath), parser);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Execute an HTTP DELETE request to the RunDeck instance, on the given path, and expect a 204 response.
|
||||||
|
*
|
||||||
|
* @param apiPath on which we will make the HTTP request - see {@link ApiPathBuilder}
|
||||||
|
* @throws RundeckApiException in case of error when calling the API
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
*/
|
||||||
|
public void delete(ApiPathBuilder apiPath) throws RundeckApiException,
|
||||||
|
RundeckApiLoginException, RundeckApiTokenException {
|
||||||
|
|
||||||
|
InputStream response = execute(new HttpDelete(client.getUrl() + client.getApiEndpoint() + apiPath));
|
||||||
|
if(null!=response){
|
||||||
|
throw new RundeckApiException("Unexpected Rundeck response content, expected no content!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute an HTTP request to the RunDeck instance. We will login first, and then execute the API call. At the end,
|
* Execute an HTTP request to the RunDeck instance. We will login first, and then execute the API call. At the end,
|
||||||
|
@ -323,13 +365,39 @@ class ApiCall {
|
||||||
private <T> T execute(HttpRequestBase request, XmlNodeParser<T> parser) throws RundeckApiException,
|
private <T> T execute(HttpRequestBase request, XmlNodeParser<T> parser) throws RundeckApiException,
|
||||||
RundeckApiLoginException, RundeckApiTokenException {
|
RundeckApiLoginException, RundeckApiTokenException {
|
||||||
// execute the request
|
// execute the request
|
||||||
InputStream response = execute(request);
|
return new ParserHandler<T>(parser).handle(execute(request, new ResultHandler()));
|
||||||
|
|
||||||
// read and parse the response
|
|
||||||
Document xmlDocument = ParserHelper.loadDocument(response);
|
|
||||||
return parser.parseXmlNode(xmlDocument);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute an HTTP GET request to the RunDeck instance, on the given path. We will login first, and then execute the
|
||||||
|
* API call. At the end, the given parser will be used to convert the response to a more useful result object.
|
||||||
|
*
|
||||||
|
* @param apiPath on which we will make the HTTP request - see {@link ApiPathBuilder}
|
||||||
|
* @param parser used to parse the response
|
||||||
|
*
|
||||||
|
* @return the result of the call, as formatted by the parser
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
*/
|
||||||
|
public int get(ApiPathBuilder apiPath, OutputStream outputStream) throws RundeckApiException,
|
||||||
|
RundeckApiLoginException, RundeckApiTokenException, IOException {
|
||||||
|
HttpGet request = new HttpGet(client.getUrl() + client.getApiEndpoint() + apiPath);
|
||||||
|
if (null != apiPath.getAccept()) {
|
||||||
|
request.setHeader("Accept", apiPath.getAccept());
|
||||||
|
}
|
||||||
|
final WriteOutHandler writeOutHandler = new WriteOutHandler(outputStream);
|
||||||
|
Handler<HttpResponse,Integer> handler = writeOutHandler;
|
||||||
|
if(null!=apiPath.getRequiredContentType()){
|
||||||
|
handler = new RequireContentTypeHandler<Integer>(apiPath.getRequiredContentType(), handler);
|
||||||
|
}
|
||||||
|
final int wrote = execute(request, handler);
|
||||||
|
if(writeOutHandler.thrown!=null){
|
||||||
|
throw writeOutHandler.thrown;
|
||||||
|
}
|
||||||
|
return wrote;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Execute an HTTP request to the RunDeck instance. We will login first, and then execute the API call.
|
* Execute an HTTP request to the RunDeck instance. We will login first, and then execute the API call.
|
||||||
*
|
*
|
||||||
|
@ -339,7 +407,129 @@ class ApiCall {
|
||||||
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
*/
|
*/
|
||||||
private ByteArrayInputStream execute(HttpRequestBase request) throws RundeckApiException, RundeckApiLoginException,
|
private ByteArrayInputStream execute(HttpUriRequest request) throws RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException {
|
||||||
|
return execute(request, new ResultHandler() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles one type into another
|
||||||
|
* @param <T>
|
||||||
|
* @param <V>
|
||||||
|
*/
|
||||||
|
private static interface Handler<T,V>{
|
||||||
|
public V handle(T response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles parsing inputstream via a parser
|
||||||
|
* @param <S>
|
||||||
|
*/
|
||||||
|
private static class ParserHandler<S> implements Handler<InputStream,S> {
|
||||||
|
XmlNodeParser<S> parser;
|
||||||
|
|
||||||
|
private ParserHandler(XmlNodeParser<S> parser) {
|
||||||
|
this.parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S handle(InputStream response) {
|
||||||
|
// read and parse the response
|
||||||
|
return parser.parseXmlNode(ParserHelper.loadDocument(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles writing response to an output stream
|
||||||
|
*/
|
||||||
|
private static class ChainHandler<T> implements Handler<HttpResponse,T> {
|
||||||
|
Handler<HttpResponse, T> chain;
|
||||||
|
private ChainHandler(Handler<HttpResponse,T> chain) {
|
||||||
|
this.chain=chain;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public T handle(final HttpResponse response) {
|
||||||
|
return chain.handle(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles writing response to an output stream
|
||||||
|
*/
|
||||||
|
private static class RequireContentTypeHandler<T> extends ChainHandler<T> {
|
||||||
|
String contentType;
|
||||||
|
|
||||||
|
private RequireContentTypeHandler(final String contentType, final Handler<HttpResponse, T> chain) {
|
||||||
|
super(chain);
|
||||||
|
this.contentType = contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T handle(final HttpResponse response) {
|
||||||
|
final Header firstHeader = response.getFirstHeader("Content-Type");
|
||||||
|
final String[] split = firstHeader.getValue().split(";");
|
||||||
|
boolean matched=false;
|
||||||
|
for (int i = 0; i < split.length; i++) {
|
||||||
|
String s = split[i];
|
||||||
|
if (this.contentType.equalsIgnoreCase(s.trim())) {
|
||||||
|
matched=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!matched) {
|
||||||
|
throw new RundeckApiException.RundeckApiHttpContentTypeException(firstHeader.getValue(),
|
||||||
|
this.contentType);
|
||||||
|
}
|
||||||
|
return super.handle(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles writing response to an output stream
|
||||||
|
*/
|
||||||
|
private static class WriteOutHandler implements Handler<HttpResponse,Integer> {
|
||||||
|
private WriteOutHandler(OutputStream writeOut) {
|
||||||
|
this.writeOut = writeOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputStream writeOut;
|
||||||
|
IOException thrown;
|
||||||
|
@Override
|
||||||
|
public Integer handle(final HttpResponse response) {
|
||||||
|
try {
|
||||||
|
return IOUtils.copy(response.getEntity().getContent(), writeOut);
|
||||||
|
} catch (IOException e) {
|
||||||
|
thrown=e;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles reading response into a byte array stream
|
||||||
|
*/
|
||||||
|
private static class ResultHandler implements Handler<HttpResponse,ByteArrayInputStream> {
|
||||||
|
@Override
|
||||||
|
public ByteArrayInputStream handle(final HttpResponse response) {
|
||||||
|
// return a new inputStream, so that we can close all network resources
|
||||||
|
try {
|
||||||
|
return new ByteArrayInputStream(EntityUtils.toByteArray(response.getEntity()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RundeckApiException("Failed to consume entity and convert the inputStream", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Execute an HTTP request to the RunDeck instance. We will login first, and then execute the API call.
|
||||||
|
*
|
||||||
|
* @param request to execute. see {@link HttpGet}, {@link HttpDelete}, and so on...
|
||||||
|
* @return a new {@link InputStream} instance, not linked with network resources
|
||||||
|
* @throws RundeckApiException in case of error when calling the API
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
*/
|
||||||
|
private <T> T execute(HttpUriRequest request, Handler<HttpResponse,T> handler) throws RundeckApiException,
|
||||||
|
RundeckApiLoginException,
|
||||||
RundeckApiTokenException {
|
RundeckApiTokenException {
|
||||||
HttpClient httpClient = instantiateHttpClient();
|
HttpClient httpClient = instantiateHttpClient();
|
||||||
try {
|
try {
|
||||||
|
@ -360,7 +550,8 @@ class ApiCall {
|
||||||
|
|
||||||
// in case of error, we get a redirect to /api/error
|
// in case of error, we get a redirect to /api/error
|
||||||
// that we need to follow manually for POST and DELETE requests (as GET)
|
// that we need to follow manually for POST and DELETE requests (as GET)
|
||||||
if (response.getStatusLine().getStatusCode() / 100 == 3) {
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
if (statusCode / 100 == 3) {
|
||||||
String newLocation = response.getFirstHeader("Location").getValue();
|
String newLocation = response.getFirstHeader("Location").getValue();
|
||||||
try {
|
try {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
|
@ -370,33 +561,31 @@ class ApiCall {
|
||||||
request = new HttpGet(newLocation);
|
request = new HttpGet(newLocation);
|
||||||
try {
|
try {
|
||||||
response = httpClient.execute(request);
|
response = httpClient.execute(request);
|
||||||
|
statusCode = response.getStatusLine().getStatusCode();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RundeckApiException("Failed to execute an HTTP GET on url : " + request.getURI(), e);
|
throw new RundeckApiException("Failed to execute an HTTP GET on url : " + request.getURI(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the response code (should be 2xx, even in case of error : error message is in the XML result)
|
// check the response code (should be 2xx, even in case of error : error message is in the XML result)
|
||||||
if (response.getStatusLine().getStatusCode() / 100 != 2) {
|
if (statusCode / 100 != 2) {
|
||||||
if (response.getStatusLine().getStatusCode() == 403 &&
|
if (statusCode == 403 &&
|
||||||
(client.getToken() != null || client.getSessionID() != null)) {
|
(client.getToken() != null || client.getSessionID() != null)) {
|
||||||
throw new RundeckApiTokenException("Invalid Token or sessionID ! Got HTTP response '" + response.getStatusLine()
|
throw new RundeckApiTokenException("Invalid Token or sessionID ! Got HTTP response '" + response.getStatusLine()
|
||||||
+ "' for " + request.getURI());
|
+ "' for " + request.getURI());
|
||||||
} else {
|
} else {
|
||||||
throw new RundeckApiException("Invalid HTTP response '" + response.getStatusLine() + "' for "
|
throw new RundeckApiException.RundeckApiHttpStatusException("Invalid HTTP response '" + response.getStatusLine() + "' for "
|
||||||
+ request.getURI());
|
+ request.getURI(), statusCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(statusCode==204){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (response.getEntity() == null) {
|
if (response.getEntity() == null) {
|
||||||
throw new RundeckApiException("Empty RunDeck response ! HTTP status line is : "
|
throw new RundeckApiException("Empty RunDeck response ! HTTP status line is : "
|
||||||
+ response.getStatusLine());
|
+ response.getStatusLine());
|
||||||
}
|
}
|
||||||
|
return handler.handle(response);
|
||||||
// return a new inputStream, so that we can close all network resources
|
|
||||||
try {
|
|
||||||
return new ByteArrayInputStream(EntityUtils.toByteArray(response.getEntity()));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RundeckApiException("Failed to consume entity and convert the inputStream", e);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
httpClient.getConnectionManager().shutdown();
|
httpClient.getConnectionManager().shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.rundeck.api;
|
package org.rundeck.api;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -26,6 +27,8 @@ import java.util.Properties;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.rundeck.api.generator.XmlDocumentGenerator;
|
||||||
import org.rundeck.api.util.ParametersUtil;
|
import org.rundeck.api.util.ParametersUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,6 +46,12 @@ class ApiPathBuilder {
|
||||||
/** When POSTing, we can add attachments */
|
/** When POSTing, we can add attachments */
|
||||||
private final Map<String, InputStream> attachments;
|
private final Map<String, InputStream> attachments;
|
||||||
private final List<NameValuePair> form = new ArrayList<NameValuePair>();
|
private final List<NameValuePair> form = new ArrayList<NameValuePair>();
|
||||||
|
private Document xmlDocument;
|
||||||
|
private InputStream contentStream;
|
||||||
|
private File contentFile;
|
||||||
|
private String contentType;
|
||||||
|
private String requiredContentType;
|
||||||
|
private boolean emptyContent = false;
|
||||||
|
|
||||||
/** Marker for using the right separator between parameters ("?" or "&") */
|
/** Marker for using the right separator between parameters ("?" or "&") */
|
||||||
private boolean firstParamDone = false;
|
private boolean firstParamDone = false;
|
||||||
|
@ -56,6 +65,10 @@ class ApiPathBuilder {
|
||||||
public ApiPathBuilder(String... paths) {
|
public ApiPathBuilder(String... paths) {
|
||||||
apiPath = new StringBuilder();
|
apiPath = new StringBuilder();
|
||||||
attachments = new HashMap<String, InputStream>();
|
attachments = new HashMap<String, InputStream>();
|
||||||
|
paths(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiPathBuilder paths(String... paths) {
|
||||||
if (paths != null) {
|
if (paths != null) {
|
||||||
for (String path : paths) {
|
for (String path : paths) {
|
||||||
if (StringUtils.isNotBlank(path)) {
|
if (StringUtils.isNotBlank(path)) {
|
||||||
|
@ -63,6 +76,7 @@ class ApiPathBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -266,6 +280,69 @@ class ApiPathBuilder {
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* When POSTing a request, use the given {@link InputStream} as the content of the request. This
|
||||||
|
* will only add the stream if it is not null.
|
||||||
|
*
|
||||||
|
* @param contentType MIME content type ofr hte request
|
||||||
|
* @param stream content stream
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public ApiPathBuilder content(final String contentType, final InputStream stream) {
|
||||||
|
if (stream != null && contentType != null) {
|
||||||
|
this.contentStream=stream;
|
||||||
|
this.contentType=contentType;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* When POSTing a request, use the given {@link File} as the content of the request. This
|
||||||
|
* will only add the stream if it is not null.
|
||||||
|
*
|
||||||
|
* @param contentType MIME content type ofr hte request
|
||||||
|
* @param file content from a file
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public ApiPathBuilder content(final String contentType, final File file) {
|
||||||
|
if (file != null && contentType != null) {
|
||||||
|
this.contentFile=file;
|
||||||
|
this.contentType=contentType;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* When POSTing a request, send an empty request.
|
||||||
|
*
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public ApiPathBuilder emptyContent() {
|
||||||
|
this.emptyContent=true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* When POSTing a request, add the given XMl Document as the content of the request.
|
||||||
|
*
|
||||||
|
* @param document XMl document to send
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public ApiPathBuilder xml(final Document document) {
|
||||||
|
if (document != null) {
|
||||||
|
xmlDocument = document;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* When POSTing a request, add the given XMl Document as the content of the request.
|
||||||
|
*
|
||||||
|
* @param document XMl document to send
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public ApiPathBuilder xml(final XmlDocumentGenerator document) {
|
||||||
|
if (document != null) {
|
||||||
|
xmlDocument = document.generateXmlDocument();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return all attachments to be POSTed, with their names
|
* @return all attachments to be POSTed, with their names
|
||||||
|
@ -311,7 +388,7 @@ class ApiPathBuilder {
|
||||||
* Return true if there are any Attachments or Form data for a POST request.
|
* Return true if there are any Attachments or Form data for a POST request.
|
||||||
*/
|
*/
|
||||||
public boolean hasPostContent() {
|
public boolean hasPostContent() {
|
||||||
return getAttachments().size() > 0 || getForm().size() > 0;
|
return getAttachments().size() > 0 || getForm().size() > 0 || null != xmlDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -321,6 +398,35 @@ class ApiPathBuilder {
|
||||||
return accept;
|
return accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Document getXmlDocument() {
|
||||||
|
return xmlDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getContentStream() {
|
||||||
|
return contentStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentType() {
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getContentFile() {
|
||||||
|
return contentFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmptyContent() {
|
||||||
|
return emptyContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiPathBuilder requireContentType(String contentType) {
|
||||||
|
this.requiredContentType=contentType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequiredContentType() {
|
||||||
|
return requiredContentType;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BuildsParameters can add URL or POST parameters to an {@link ApiPathBuilder}
|
* BuildsParameters can add URL or POST parameters to an {@link ApiPathBuilder}
|
||||||
*
|
*
|
||||||
|
|
|
@ -82,5 +82,65 @@ public class RundeckApiException extends RuntimeException {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Error due to unexpected HTTP status
|
||||||
|
*/
|
||||||
|
public static class RundeckApiHttpStatusException extends RundeckApiAuthException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private int statusCode;
|
||||||
|
|
||||||
|
public RundeckApiHttpStatusException(String message, int statusCode) {
|
||||||
|
super(message);
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RundeckApiHttpStatusException(String message, Throwable cause, int statusCode) {
|
||||||
|
super(message, cause);
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error due to unexpected HTTP content-type
|
||||||
|
*/
|
||||||
|
public static class RundeckApiHttpContentTypeException extends RundeckApiAuthException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private String contentType;
|
||||||
|
private String requiredContentType;
|
||||||
|
|
||||||
|
public RundeckApiHttpContentTypeException(final String contentType,
|
||||||
|
final String requiredContentType) {
|
||||||
|
super("Unexpected content-type: '" + contentType + "', expected: '" + requiredContentType + "'");
|
||||||
|
this.contentType = contentType;
|
||||||
|
this.requiredContentType = requiredContentType;
|
||||||
|
}
|
||||||
|
public RundeckApiHttpContentTypeException(final String message, final String contentType,
|
||||||
|
final String requiredContentType) {
|
||||||
|
super(message);
|
||||||
|
this.contentType = contentType;
|
||||||
|
this.requiredContentType = requiredContentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RundeckApiHttpContentTypeException(final String message, final Throwable cause, final String contentType,
|
||||||
|
final String requiredContentType) {
|
||||||
|
super(message, cause);
|
||||||
|
this.contentType = contentType;
|
||||||
|
this.requiredContentType = requiredContentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentType() {
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequiredContentType() {
|
||||||
|
return requiredContentType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,25 +18,22 @@ package org.rundeck.api;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.dom4j.Document;
|
||||||
import org.rundeck.api.RundeckApiException.RundeckApiLoginException;
|
import org.rundeck.api.RundeckApiException.RundeckApiLoginException;
|
||||||
import org.rundeck.api.RundeckApiException.RundeckApiTokenException;
|
import org.rundeck.api.RundeckApiException.RundeckApiTokenException;
|
||||||
import org.rundeck.api.domain.*;
|
import org.rundeck.api.domain.*;
|
||||||
import org.rundeck.api.domain.RundeckExecution.ExecutionStatus;
|
import org.rundeck.api.domain.RundeckExecution.ExecutionStatus;
|
||||||
|
import org.rundeck.api.generator.ProjectConfigGenerator;
|
||||||
|
import org.rundeck.api.generator.ProjectConfigPropertyGenerator;
|
||||||
|
import org.rundeck.api.generator.ProjectGenerator;
|
||||||
import org.rundeck.api.parser.*;
|
import org.rundeck.api.parser.*;
|
||||||
import org.rundeck.api.query.ExecutionQuery;
|
import org.rundeck.api.query.ExecutionQuery;
|
||||||
import org.rundeck.api.util.AssertUtil;
|
import org.rundeck.api.util.AssertUtil;
|
||||||
import org.rundeck.api.util.PagedResults;
|
import org.rundeck.api.util.PagedResults;
|
||||||
import org.rundeck.api.util.ParametersUtil;
|
import org.rundeck.api.util.ParametersUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileInputStream;
|
import java.util.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,6 +81,8 @@ public class RundeckClient implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
public static final String JOBS_IMPORT = "/jobs/import";
|
public static final String JOBS_IMPORT = "/jobs/import";
|
||||||
|
public static final String STORAGE_ROOT_PATH = "/storage/";
|
||||||
|
public static final String STORAGE_KEYS_PATH = "keys/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supported version numbers
|
* Supported version numbers
|
||||||
|
@ -95,6 +94,7 @@ public class RundeckClient implements Serializable {
|
||||||
V8(8),
|
V8(8),
|
||||||
V9(9),
|
V9(9),
|
||||||
V10(10),
|
V10(10),
|
||||||
|
V11(11),
|
||||||
;
|
;
|
||||||
|
|
||||||
private int versionNumber;
|
private int versionNumber;
|
||||||
|
@ -108,7 +108,7 @@ public class RundeckClient implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Version of the API supported */
|
/** Version of the API supported */
|
||||||
public static final transient int API_VERSION = Version.V10.getVersionNumber();
|
public static final transient int API_VERSION = Version.V11.getVersionNumber();
|
||||||
|
|
||||||
private static final String API = "/api/";
|
private static final String API = "/api/";
|
||||||
|
|
||||||
|
@ -274,10 +274,26 @@ public class RundeckClient implements Serializable {
|
||||||
testAuth();
|
testAuth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return root xpath for xml api results. for v11 and later it is empty, for earlier it is "result"
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String rootXpath() {
|
||||||
|
return getApiVersion() < Version.V11.getVersionNumber() ? "result" : "";
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Projects
|
* Projects
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private ProjectParser createProjectParser() {
|
||||||
|
return createProjectParser(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProjectParser createProjectParser(final String xpath) {
|
||||||
|
return new ProjectParserV11(xpath);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all projects
|
* List all projects
|
||||||
*
|
*
|
||||||
|
@ -289,7 +305,8 @@ public class RundeckClient implements Serializable {
|
||||||
public List<RundeckProject> getProjects() throws RundeckApiException, RundeckApiLoginException,
|
public List<RundeckProject> getProjects() throws RundeckApiException, RundeckApiLoginException,
|
||||||
RundeckApiTokenException {
|
RundeckApiTokenException {
|
||||||
return new ApiCall(this).get(new ApiPathBuilder("/projects"),
|
return new ApiCall(this).get(new ApiPathBuilder("/projects"),
|
||||||
new ListParser<RundeckProject>(new ProjectParser(), "result/projects/project"));
|
new ListParser<RundeckProject>(createProjectParser(), rootXpath() +
|
||||||
|
"/projects/project"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -306,7 +323,274 @@ public class RundeckClient implements Serializable {
|
||||||
RundeckApiTokenException, IllegalArgumentException {
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
AssertUtil.notBlank(projectName, "projectName is mandatory to get the details of a project !");
|
AssertUtil.notBlank(projectName, "projectName is mandatory to get the details of a project !");
|
||||||
return new ApiCall(this).get(new ApiPathBuilder("/project/", projectName),
|
return new ApiCall(this).get(new ApiPathBuilder("/project/", projectName),
|
||||||
new ProjectParser("result/projects/project"));
|
createProjectParser(rootXpath() +
|
||||||
|
(getApiVersion() < Version.V11.getVersionNumber()
|
||||||
|
? "/projects/project"
|
||||||
|
: "/project"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new project, and return the new definition
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
* @param configuration project configuration properties
|
||||||
|
*
|
||||||
|
* @return a {@link RundeckProject} instance - won't be null
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public RundeckProject createProject(String projectName, Map<String, String> configuration) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to create a project !");
|
||||||
|
return new ApiCall(this)
|
||||||
|
.post(new ApiPathBuilder("/projects").xml(
|
||||||
|
projectDocument(projectName, configuration)
|
||||||
|
), createProjectParser(rootXpath() +
|
||||||
|
(getApiVersion() < Version.V11.getVersionNumber()
|
||||||
|
? "/projects/project"
|
||||||
|
: "/project"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Delete a project
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public void deleteProject(String projectName) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to create a project !");
|
||||||
|
new ApiCall(this).delete(new ApiPathBuilder("/project/", projectName));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience method to export the archive of a project to the specified file.
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
* @param out file to write to
|
||||||
|
* @return number of bytes written to the stream
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public int exportProject(final String projectName, final File out) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException, IOException {
|
||||||
|
final FileOutputStream fileOutputStream = new FileOutputStream(out);
|
||||||
|
try {
|
||||||
|
return exportProject(projectName, fileOutputStream);
|
||||||
|
}finally {
|
||||||
|
fileOutputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Export the archive of a project to the specified outputstream
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
* @return number of bytes written to the stream
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public int exportProject(String projectName, OutputStream out) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException, IOException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to export a project archive!");
|
||||||
|
return new ApiCall(this).get(
|
||||||
|
new ApiPathBuilder("/project/", projectName, "/export")
|
||||||
|
.accept("application/zip"),
|
||||||
|
out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a archive file to the specified project.
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
* @param archiveFile zip archive file
|
||||||
|
* @param includeExecutions if true, import executions defined in the archive, otherwise skip them
|
||||||
|
* @param preserveJobUuids if true, do not remove UUIDs from imported jobs, otherwise remove them
|
||||||
|
*
|
||||||
|
* @return Result of the import request, may contain a list of import error messages
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public ArchiveImport importArchive(final String projectName, final File archiveFile,
|
||||||
|
final boolean includeExecutions, final boolean preserveJobUuids) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException, IOException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to import a project archive!");
|
||||||
|
AssertUtil.notNull(archiveFile, "archiveFile is mandatory to import a project archive!"); ;
|
||||||
|
return callImportProject(projectName, includeExecutions, preserveJobUuids,
|
||||||
|
new ApiPathBuilder().content("application/zip", archiveFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArchiveImport callImportProject(final String projectName, final boolean includeExecutions, final boolean preserveJobUuids,
|
||||||
|
final ApiPathBuilder param) {
|
||||||
|
param.paths("/project/", projectName, "/import")
|
||||||
|
.param("importExecutions", includeExecutions)
|
||||||
|
.param("jobUuidOption", preserveJobUuids ? "preserve" : "remove");
|
||||||
|
return new ApiCall(this).put(
|
||||||
|
param,
|
||||||
|
new ArchiveImportParser()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the configuration of a project
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
*
|
||||||
|
* @return a {@link ProjectConfig} instance - won't be null
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public ProjectConfig getProjectConfig(String projectName) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to get the config of a project !");
|
||||||
|
return new ApiCall(this)
|
||||||
|
.get(new ApiPathBuilder("/project/", projectName, "/config"), new ProjectConfigParser("/config"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get a single project configuration key
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
* @param key name of the configuration key
|
||||||
|
*
|
||||||
|
* @return value, or null if the value is not set
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public String getProjectConfig(final String projectName, final String key) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to get the config of a project !");
|
||||||
|
AssertUtil.notBlank(key, "key is mandatory to get the config key value!");
|
||||||
|
|
||||||
|
ConfigProperty configProperty = null;
|
||||||
|
try {
|
||||||
|
configProperty = new ApiCall(this)
|
||||||
|
.get(new ApiPathBuilder("/project/", projectName, "/config/", key),
|
||||||
|
new ProjectConfigPropertyParser("/property"));
|
||||||
|
} catch (RundeckApiException.RundeckApiHttpStatusException e) {
|
||||||
|
if(404==e.getStatusCode()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return configProperty.getValue();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set a single project configuration property value
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
* @param key name of the configuration property
|
||||||
|
* @param value value of the property
|
||||||
|
*
|
||||||
|
* @return new value
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public String setProjectConfig(final String projectName, final String key, final String value) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to set the config of a project !");
|
||||||
|
AssertUtil.notBlank(key, "key is mandatory to set the config key value!");
|
||||||
|
AssertUtil.notBlank(value, "value is mandatory to set the config key value!");
|
||||||
|
|
||||||
|
final ConfigProperty configProperty = new ApiCall(this)
|
||||||
|
.put(new ApiPathBuilder("/project/", projectName, "/config/", key)
|
||||||
|
.xml(new ProjectConfigPropertyGenerator(new ConfigProperty(key, value))),
|
||||||
|
new ProjectConfigPropertyParser("/property"));
|
||||||
|
|
||||||
|
return configProperty.getValue();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set a single project configuration property value
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
* @param key name of the configuration property
|
||||||
|
* @param value value of the property
|
||||||
|
*
|
||||||
|
* @return new value
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public void deleteProjectConfig(final String projectName, final String key) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to set the config of a project !");
|
||||||
|
AssertUtil.notBlank(key, "key is mandatory to set the config key value!");
|
||||||
|
|
||||||
|
new ApiCall(this).delete(new ApiPathBuilder("/project/", projectName, "/config/",
|
||||||
|
key).accept("application/xml"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return the configuration of a project
|
||||||
|
*
|
||||||
|
* @param projectName name of the project - mandatory
|
||||||
|
*
|
||||||
|
* @return a {@link ProjectConfig} instance - won't be null
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException in case of error when calling the API (non-existent project with this name)
|
||||||
|
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
|
||||||
|
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
|
||||||
|
* @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace)
|
||||||
|
*/
|
||||||
|
public ProjectConfig setProjectConfig(String projectName, Map<String,String> configuration) throws
|
||||||
|
RundeckApiException, RundeckApiLoginException,
|
||||||
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
|
|
||||||
|
AssertUtil.notBlank(projectName, "projectName is mandatory to get the config of a project !");
|
||||||
|
return new ApiCall(this)
|
||||||
|
.put(new ApiPathBuilder("/project/", projectName, "/config")
|
||||||
|
.xml(new ProjectConfigGenerator(new ProjectConfig(configuration)))
|
||||||
|
, new ProjectConfigParser("/config"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Document projectDocument(String projectName, Map<String, String> configuration) {
|
||||||
|
RundeckProject project = new RundeckProject();
|
||||||
|
project.setName(projectName);
|
||||||
|
if (null != configuration) {
|
||||||
|
project.setProjectConfig(new ProjectConfig(configuration));
|
||||||
|
}
|
||||||
|
return new ProjectGenerator(project).generateXmlDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -366,7 +650,7 @@ public class RundeckClient implements Serializable {
|
||||||
.param("jobFilter", jobFilter)
|
.param("jobFilter", jobFilter)
|
||||||
.param("groupPath", groupPath)
|
.param("groupPath", groupPath)
|
||||||
.param("idlist", StringUtils.join(jobIds, ",")),
|
.param("idlist", StringUtils.join(jobIds, ",")),
|
||||||
new ListParser<RundeckJob>(new JobParser(), "result/jobs/job"));
|
new ListParser<RundeckJob>(new JobParser(), rootXpath()+"/jobs/job"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -699,7 +983,7 @@ public class RundeckClient implements Serializable {
|
||||||
//API v8
|
//API v8
|
||||||
request.param("project", rundeckJobsImport.getProject());
|
request.param("project", rundeckJobsImport.getProject());
|
||||||
}
|
}
|
||||||
return new ApiCall(this).post(request, new JobsImportResultParser("result"));
|
return new ApiCall(this).post(request, new JobsImportResultParser(rootXpath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -755,7 +1039,7 @@ public class RundeckClient implements Serializable {
|
||||||
public String deleteJob(String jobId) throws RundeckApiException, RundeckApiLoginException,
|
public String deleteJob(String jobId) throws RundeckApiException, RundeckApiLoginException,
|
||||||
RundeckApiTokenException, IllegalArgumentException {
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
AssertUtil.notBlank(jobId, "jobId is mandatory to delete a job !");
|
AssertUtil.notBlank(jobId, "jobId is mandatory to delete a job !");
|
||||||
return new ApiCall(this).delete(new ApiPathBuilder("/job/", jobId), new StringParser("result/success/message"));
|
return new ApiCall(this).delete(new ApiPathBuilder("/job/", jobId), new StringParser(rootXpath()+"/success/message"));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Delete multiple jobs, identified by the given IDs
|
* Delete multiple jobs, identified by the given IDs
|
||||||
|
@ -773,7 +1057,7 @@ public class RundeckClient implements Serializable {
|
||||||
throw new IllegalArgumentException("jobIds are mandatory to delete a job");
|
throw new IllegalArgumentException("jobIds are mandatory to delete a job");
|
||||||
}
|
}
|
||||||
return new ApiCall(this).post(new ApiPathBuilder("/jobs/delete").field("ids",jobIds),
|
return new ApiCall(this).post(new ApiPathBuilder("/jobs/delete").field("ids",jobIds),
|
||||||
new BulkDeleteParser("result/deleteJobs"));
|
new BulkDeleteParser(rootXpath()+"/deleteJobs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -798,7 +1082,7 @@ public class RundeckClient implements Serializable {
|
||||||
if(null!=jobRun.getAsUser()) {
|
if(null!=jobRun.getAsUser()) {
|
||||||
apiPath.param("asUser", jobRun.getAsUser());
|
apiPath.param("asUser", jobRun.getAsUser());
|
||||||
}
|
}
|
||||||
return new ApiCall(this).get(apiPath, new ExecutionParser("result/executions/execution"));
|
return new ApiCall(this).get(apiPath, new ExecutionParser(rootXpath()+"/executions/execution"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -896,7 +1180,7 @@ public class RundeckClient implements Serializable {
|
||||||
if(null!= command.getAsUser()) {
|
if(null!= command.getAsUser()) {
|
||||||
apiPath.param("asUser", command.getAsUser());
|
apiPath.param("asUser", command.getAsUser());
|
||||||
}
|
}
|
||||||
RundeckExecution execution = new ApiCall(this).get(apiPath, new ExecutionParser("result/execution"));
|
RundeckExecution execution = new ApiCall(this).get(apiPath, new ExecutionParser(rootXpath()+"/execution"));
|
||||||
// the first call just returns the ID of the execution, so we need another call to get a "real" execution
|
// the first call just returns the ID of the execution, so we need another call to get a "real" execution
|
||||||
return getExecution(execution.getId());
|
return getExecution(execution.getId());
|
||||||
}
|
}
|
||||||
|
@ -1030,7 +1314,7 @@ public class RundeckClient implements Serializable {
|
||||||
if(null!=script.getAsUser()) {
|
if(null!=script.getAsUser()) {
|
||||||
apiPath.param("asUser", script.getAsUser());
|
apiPath.param("asUser", script.getAsUser());
|
||||||
}
|
}
|
||||||
RundeckExecution execution = new ApiCall(this).post(apiPath, new ExecutionParser("result/execution"));
|
RundeckExecution execution = new ApiCall(this).post(apiPath, new ExecutionParser(rootXpath()+"/execution"));
|
||||||
// the first call just returns the ID of the execution, so we need another call to get a "real" execution
|
// the first call just returns the ID of the execution, so we need another call to get a "real" execution
|
||||||
return getExecution(execution.getId());
|
return getExecution(execution.getId());
|
||||||
}
|
}
|
||||||
|
@ -1177,7 +1461,7 @@ public class RundeckClient implements Serializable {
|
||||||
AssertUtil.notBlank(project, "project is mandatory get all running executions !");
|
AssertUtil.notBlank(project, "project is mandatory get all running executions !");
|
||||||
return new ApiCall(this).get(new ApiPathBuilder("/executions/running").param("project", project),
|
return new ApiCall(this).get(new ApiPathBuilder("/executions/running").param("project", project),
|
||||||
new ListParser<RundeckExecution>(new ExecutionParser(),
|
new ListParser<RundeckExecution>(new ExecutionParser(),
|
||||||
"result/executions/execution"));
|
rootXpath()+"/executions/execution"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1275,7 +1559,7 @@ public class RundeckClient implements Serializable {
|
||||||
.param("max", max)
|
.param("max", max)
|
||||||
.param("offset", offset),
|
.param("offset", offset),
|
||||||
new ListParser<RundeckExecution>(new ExecutionParser(),
|
new ListParser<RundeckExecution>(new ExecutionParser(),
|
||||||
"result/executions/execution"));
|
rootXpath()+"/executions/execution"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1302,7 +1586,7 @@ public class RundeckClient implements Serializable {
|
||||||
.param("offset", offset),
|
.param("offset", offset),
|
||||||
new PagedResultParser<RundeckExecution>(
|
new PagedResultParser<RundeckExecution>(
|
||||||
new ListParser<RundeckExecution>(new ExecutionParser(), "execution"),
|
new ListParser<RundeckExecution>(new ExecutionParser(), "execution"),
|
||||||
"result/executions"
|
rootXpath()+"/executions"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1321,7 +1605,7 @@ public class RundeckClient implements Serializable {
|
||||||
RundeckApiTokenException, IllegalArgumentException {
|
RundeckApiTokenException, IllegalArgumentException {
|
||||||
AssertUtil.notNull(executionId, "executionId is mandatory to get the details of an execution !");
|
AssertUtil.notNull(executionId, "executionId is mandatory to get the details of an execution !");
|
||||||
return new ApiCall(this).get(new ApiPathBuilder("/execution/", executionId.toString()),
|
return new ApiCall(this).get(new ApiPathBuilder("/execution/", executionId.toString()),
|
||||||
new ExecutionParser("result/executions/execution"));
|
new ExecutionParser(rootXpath()+"/executions/execution"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1356,7 +1640,7 @@ public class RundeckClient implements Serializable {
|
||||||
if(null!=asUser) {
|
if(null!=asUser) {
|
||||||
apiPath.param("asUser", asUser);
|
apiPath.param("asUser", asUser);
|
||||||
}
|
}
|
||||||
return new ApiCall(this).get(apiPath, new AbortParser("result/abort"));
|
return new ApiCall(this).get(apiPath, new AbortParser(rootXpath()+"/abort"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1548,7 +1832,7 @@ public class RundeckClient implements Serializable {
|
||||||
.param("end", end)
|
.param("end", end)
|
||||||
.param("max", max)
|
.param("max", max)
|
||||||
.param("offset", offset),
|
.param("offset", offset),
|
||||||
new HistoryParser("result/events"));
|
new HistoryParser(rootXpath()+"/events"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1595,7 +1879,7 @@ public class RundeckClient implements Serializable {
|
||||||
.param("max", max)
|
.param("max", max)
|
||||||
.param("offset", offset);
|
.param("offset", offset);
|
||||||
|
|
||||||
return new ApiCall(this).postOrGet(builder, new HistoryParser("result/events"));
|
return new ApiCall(this).postOrGet(builder, new HistoryParser(rootXpath()+"/events"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1773,7 +2057,7 @@ public class RundeckClient implements Serializable {
|
||||||
param.param("maxlines", maxlines);
|
param.param("maxlines", maxlines);
|
||||||
}
|
}
|
||||||
return new ApiCall(this).get(param,
|
return new ApiCall(this).get(param,
|
||||||
new OutputParser("result/output", createOutputEntryParser()));
|
new OutputParser(rootXpath()+"/output", createOutputEntryParser()));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get the execution state of the given execution
|
* Get the execution state of the given execution
|
||||||
|
@ -1792,7 +2076,7 @@ public class RundeckClient implements Serializable {
|
||||||
"/execution/", executionId.toString(),
|
"/execution/", executionId.toString(),
|
||||||
"/state");
|
"/state");
|
||||||
|
|
||||||
return new ApiCall(this).get(param, new ExecutionStateParser("result/executionState"));
|
return new ApiCall(this).get(param, new ExecutionStateParser(rootXpath()+"/executionState"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1834,7 +2118,7 @@ public class RundeckClient implements Serializable {
|
||||||
param.param("maxlines", maxlines);
|
param.param("maxlines", maxlines);
|
||||||
}
|
}
|
||||||
return new ApiCall(this).get(param,
|
return new ApiCall(this).get(param,
|
||||||
new OutputParser("result/output", createOutputEntryParser()));
|
new OutputParser(rootXpath()+"/output", createOutputEntryParser()));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get the execution output of the given execution for the specified step
|
* Get the execution output of the given execution for the specified step
|
||||||
|
@ -1875,7 +2159,7 @@ public class RundeckClient implements Serializable {
|
||||||
param.param("maxlines", maxlines);
|
param.param("maxlines", maxlines);
|
||||||
}
|
}
|
||||||
return new ApiCall(this).get(param,
|
return new ApiCall(this).get(param,
|
||||||
new OutputParser("result/output", createOutputEntryParser()));
|
new OutputParser(rootXpath()+"/output", createOutputEntryParser()));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get the execution output of the given execution for the specified step
|
* Get the execution output of the given execution for the specified step
|
||||||
|
@ -1919,7 +2203,7 @@ public class RundeckClient implements Serializable {
|
||||||
param.param("maxlines", maxlines);
|
param.param("maxlines", maxlines);
|
||||||
}
|
}
|
||||||
return new ApiCall(this).get(param,
|
return new ApiCall(this).get(param,
|
||||||
new OutputParser("result/output", createOutputEntryParser()));
|
new OutputParser(rootXpath()+"/output", createOutputEntryParser()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1966,7 +2250,7 @@ public class RundeckClient implements Serializable {
|
||||||
if (maxlines > 0) {
|
if (maxlines > 0) {
|
||||||
param.param("maxlines", maxlines);
|
param.param("maxlines", maxlines);
|
||||||
}
|
}
|
||||||
return new ApiCall(this).get(param, new OutputParser("result/output", createOutputEntryParser()));
|
return new ApiCall(this).get(param, new OutputParser(rootXpath()+"/output", createOutputEntryParser()));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get the execution state output sequence of the given job
|
* Get the execution state output sequence of the given job
|
||||||
|
@ -1997,7 +2281,7 @@ public class RundeckClient implements Serializable {
|
||||||
if(stateOnly) {
|
if(stateOnly) {
|
||||||
param.param("stateOnly", true);
|
param.param("stateOnly", true);
|
||||||
}
|
}
|
||||||
return new ApiCall(this).get(param, new OutputParser("result/output", createOutputEntryParser()));
|
return new ApiCall(this).get(param, new OutputParser(rootXpath()+"/output", createOutputEntryParser()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private OutputEntryParser createOutputEntryParser() {
|
private OutputEntryParser createOutputEntryParser() {
|
||||||
|
@ -2023,7 +2307,204 @@ public class RundeckClient implements Serializable {
|
||||||
*/
|
*/
|
||||||
public RundeckSystemInfo getSystemInfo() throws RundeckApiException, RundeckApiLoginException,
|
public RundeckSystemInfo getSystemInfo() throws RundeckApiException, RundeckApiLoginException,
|
||||||
RundeckApiTokenException {
|
RundeckApiTokenException {
|
||||||
return new ApiCall(this).get(new ApiPathBuilder("/system/info"), new SystemInfoParser("result/system"));
|
return new ApiCall(this).get(new ApiPathBuilder("/system/info"), new SystemInfoParser(rootXpath()+"/system"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* API token
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List API tokens for a user.
|
||||||
|
* @param user username
|
||||||
|
* @return list of tokens
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public List<RundeckToken> listApiTokens(final String user) throws RundeckApiException {
|
||||||
|
AssertUtil.notNull(user, "user is mandatory to list API tokens for a user.");
|
||||||
|
return new ApiCall(this).
|
||||||
|
get(new ApiPathBuilder("/tokens/", user),
|
||||||
|
new ListParser<RundeckToken>(new RundeckTokenParser(), "/tokens/token"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all API tokens
|
||||||
|
* @return list of tokens
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public List<RundeckToken> listApiTokens() throws RundeckApiException {
|
||||||
|
return new ApiCall(this).
|
||||||
|
get(new ApiPathBuilder("/tokens"),
|
||||||
|
new ListParser<RundeckToken>(new RundeckTokenParser(), "/tokens/token"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an API token for a user.
|
||||||
|
* @param user
|
||||||
|
* @return
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public String generateApiToken(final String user) throws RundeckApiException{
|
||||||
|
AssertUtil.notNull(user, "user is mandatory to generate an API token for a user.");
|
||||||
|
RundeckToken result = new ApiCall(this).
|
||||||
|
post(new ApiPathBuilder("/tokens/", user).emptyContent(),
|
||||||
|
new RundeckTokenParser("/token"));
|
||||||
|
return result.getToken();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Delete an existing token
|
||||||
|
* @param token
|
||||||
|
* @return
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public boolean deleteApiToken(final String token) throws RundeckApiException{
|
||||||
|
AssertUtil.notNull(token, "token is mandatory to delete an API token.");
|
||||||
|
new ApiCall(this).delete(new ApiPathBuilder("/token/", token));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return user info for an existing token
|
||||||
|
* @param token
|
||||||
|
* @return token info
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public RundeckToken getApiToken(final String token) throws RundeckApiException{
|
||||||
|
AssertUtil.notNull(token, "token is mandatory to get an API token.");
|
||||||
|
return new ApiCall(this).get(new ApiPathBuilder("/token/", token), new RundeckTokenParser("/token"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store an key file
|
||||||
|
* @param path ssh key storage path, must start with "keys/"
|
||||||
|
* @param keyfile key file
|
||||||
|
* @param privateKey true to store private key, false to store public key
|
||||||
|
* @return the key resource
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public KeyResource storeKey(final String path, final File keyfile, boolean privateKey) throws RundeckApiException{
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to store an key.");
|
||||||
|
AssertUtil.notNull(keyfile, "keyfile is mandatory to store an key.");
|
||||||
|
if (!path.startsWith(STORAGE_KEYS_PATH)) {
|
||||||
|
throw new IllegalArgumentException("key storage path must start with: " + STORAGE_KEYS_PATH);
|
||||||
|
}
|
||||||
|
return new ApiCall(this).post(
|
||||||
|
new ApiPathBuilder(STORAGE_ROOT_PATH, path).content(
|
||||||
|
privateKey ? "application/octet-stream" : "application/pgp-keys",
|
||||||
|
keyfile
|
||||||
|
),
|
||||||
|
new SSHKeyResourceParser("/resource")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get metadata for an key file
|
||||||
|
*
|
||||||
|
* @param path ssh key storage path, must start with "keys/"
|
||||||
|
*
|
||||||
|
* @return the ssh key resource
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException if there is an error, or if the path is a directory not a file
|
||||||
|
*/
|
||||||
|
public KeyResource getKey(final String path) throws RundeckApiException {
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to get an key.");
|
||||||
|
if (!path.startsWith(STORAGE_KEYS_PATH)) {
|
||||||
|
throw new IllegalArgumentException("key storage path must start with: " + STORAGE_KEYS_PATH);
|
||||||
|
}
|
||||||
|
KeyResource storageResource = new ApiCall(this).get(
|
||||||
|
new ApiPathBuilder(STORAGE_ROOT_PATH, path),
|
||||||
|
new SSHKeyResourceParser("/resource")
|
||||||
|
);
|
||||||
|
if (storageResource.isDirectory()) {
|
||||||
|
throw new RundeckApiException("Key Path is a directory: " + path);
|
||||||
|
}
|
||||||
|
return storageResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get content for a public key file
|
||||||
|
* @param path ssh key storage path, must start with "keys/"
|
||||||
|
* @param out outputstream to write data to
|
||||||
|
*
|
||||||
|
* @return length of written data
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public int getPublicKeyContent(final String path, final OutputStream out) throws
|
||||||
|
RundeckApiException, IOException {
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to get an key.");
|
||||||
|
if (!path.startsWith(STORAGE_KEYS_PATH)) {
|
||||||
|
throw new IllegalArgumentException("key storage path must start with: " + STORAGE_KEYS_PATH);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new ApiCall(this).get(
|
||||||
|
new ApiPathBuilder(STORAGE_ROOT_PATH, path)
|
||||||
|
.accept("application/pgp-keys")
|
||||||
|
.requireContentType("application/pgp-keys"),
|
||||||
|
out
|
||||||
|
);
|
||||||
|
} catch (RundeckApiException.RundeckApiHttpContentTypeException e) {
|
||||||
|
throw new RundeckApiException("Requested Key path was not a Public key: " + path, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get content for a public key file
|
||||||
|
* @param path ssh key storage path, must start with "keys/"
|
||||||
|
* @param out file to write data to
|
||||||
|
* @return length of written data
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public int getPublicKeyContent(final String path, final File out) throws
|
||||||
|
RundeckApiException, IOException {
|
||||||
|
final FileOutputStream fileOutputStream = new FileOutputStream(out);
|
||||||
|
try {
|
||||||
|
return getPublicKeyContent(path, fileOutputStream);
|
||||||
|
}finally {
|
||||||
|
fileOutputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List contents of root key directory
|
||||||
|
*
|
||||||
|
* @return list of key resources
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public List<KeyResource> listKeyDirectoryRoot() throws RundeckApiException {
|
||||||
|
return listKeyDirectory(STORAGE_KEYS_PATH);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* List contents of key directory
|
||||||
|
*
|
||||||
|
* @param path ssh key storage path, must start with "keys/"
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException if there is an error, or if the path is a file not a directory
|
||||||
|
*/
|
||||||
|
public List<KeyResource> listKeyDirectory(final String path) throws RundeckApiException {
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to get an key.");
|
||||||
|
if (!path.startsWith(STORAGE_KEYS_PATH)) {
|
||||||
|
throw new IllegalArgumentException("key storage path must start with: " + STORAGE_KEYS_PATH);
|
||||||
|
}
|
||||||
|
KeyResource storageResource = new ApiCall(this).get(
|
||||||
|
new ApiPathBuilder(STORAGE_ROOT_PATH, path),
|
||||||
|
new SSHKeyResourceParser("/resource")
|
||||||
|
);
|
||||||
|
if(!storageResource.isDirectory()) {
|
||||||
|
throw new RundeckApiException("key path is not a directory path: " + path);
|
||||||
|
}
|
||||||
|
return storageResource.getDirectoryContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an key file
|
||||||
|
* @param path a path to a key file, must start with "keys/"
|
||||||
|
*/
|
||||||
|
public void deleteKey(final String path){
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to delete an key.");
|
||||||
|
if (!path.startsWith(STORAGE_KEYS_PATH)) {
|
||||||
|
throw new IllegalArgumentException("key storage path must start with: " + STORAGE_KEYS_PATH);
|
||||||
|
}
|
||||||
|
new ApiCall(this).delete(new ApiPathBuilder(STORAGE_ROOT_PATH, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
38
src/main/java/org/rundeck/api/domain/ArchiveImport.java
Normal file
38
src/main/java/org/rundeck/api/domain/ArchiveImport.java
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ArchiveImport describes the result of an {@link org.rundeck.api.RundeckClient#importArchive(String, java.io.File,
|
||||||
|
* boolean, boolean)} request.
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-03-09
|
||||||
|
*/
|
||||||
|
public class ArchiveImport {
|
||||||
|
private boolean successful;
|
||||||
|
private List<String> errorMessages;
|
||||||
|
|
||||||
|
public ArchiveImport(final boolean successful, final List<String> errorMessages) {
|
||||||
|
this.successful = successful;
|
||||||
|
this.errorMessages = errorMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if successful
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isSuccessful() {
|
||||||
|
return successful;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of error messages if unsuccessful
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> getErrorMessages() {
|
||||||
|
return errorMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
src/main/java/org/rundeck/api/domain/BaseKeyResource.java
Normal file
58
src/main/java/org/rundeck/api/domain/BaseKeyResource.java
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseKeyResource is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public class BaseKeyResource extends BaseStorageResource implements KeyResource {
|
||||||
|
private boolean privateKey;
|
||||||
|
|
||||||
|
public BaseKeyResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivateKey(boolean privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<KeyResource> keyResources = new ArrayList<KeyResource>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDirectoryContents(List<? extends StorageResource> directoryContents) {
|
||||||
|
for (StorageResource directoryContent : directoryContents) {
|
||||||
|
keyResources.add(from(directoryContent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<KeyResource> getDirectoryContents() {
|
||||||
|
return keyResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseKeyResource from(final StorageResource source) {
|
||||||
|
final BaseKeyResource baseSshKeyResource = new BaseKeyResource();
|
||||||
|
baseSshKeyResource.setDirectory(source.isDirectory());
|
||||||
|
baseSshKeyResource.setPath(source.getPath());
|
||||||
|
baseSshKeyResource.setName(source.getName());
|
||||||
|
baseSshKeyResource.setMetadata(source.getMetadata());
|
||||||
|
baseSshKeyResource.setUrl(source.getUrl());
|
||||||
|
if (!baseSshKeyResource.isDirectory()) {
|
||||||
|
baseSshKeyResource.setPrivateKey(
|
||||||
|
null != baseSshKeyResource.getMetadata() && "private".equals(baseSshKeyResource.getMetadata().get
|
||||||
|
("Rundeck-key-type"))
|
||||||
|
);
|
||||||
|
} else if (null != source.getDirectoryContents()) {
|
||||||
|
baseSshKeyResource.setDirectoryContents(source.getDirectoryContents());
|
||||||
|
}
|
||||||
|
return baseSshKeyResource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseStorageResource is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public class BaseStorageResource implements StorageResource {
|
||||||
|
private String path;
|
||||||
|
private String url;
|
||||||
|
private String name;
|
||||||
|
private Map<String,String> metadata;
|
||||||
|
private boolean directory;
|
||||||
|
private List<? extends StorageResource> directoryContents;
|
||||||
|
|
||||||
|
public BaseStorageResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPath(String path) {
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetadata(Map<String, String> metadata) {
|
||||||
|
this.metadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDirectory() {
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirectory(boolean directory) {
|
||||||
|
this.directory = directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<? extends StorageResource> getDirectoryContents() {
|
||||||
|
return directoryContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirectoryContents(List<? extends StorageResource> directoryContents) {
|
||||||
|
this.directoryContents = directoryContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "BaseStorageResource{" +
|
||||||
|
"path='" + path + '\'' +
|
||||||
|
", url='" + url + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", directory=" + directory +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
68
src/main/java/org/rundeck/api/domain/ConfigProperty.java
Normal file
68
src/main/java/org/rundeck/api/domain/ConfigProperty.java
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigProperty is a single configuration property key and value.
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-03-07
|
||||||
|
*/
|
||||||
|
public class ConfigProperty implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private String key;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public ConfigProperty() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigProperty(String key, String value) {
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof ConfigProperty)) return false;
|
||||||
|
|
||||||
|
ConfigProperty that = (ConfigProperty) o;
|
||||||
|
|
||||||
|
if (!key.equals(that.key)) return false;
|
||||||
|
if (!value.equals(that.value)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = key.hashCode();
|
||||||
|
result = 31 * result + value.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ConfigProperty{" +
|
||||||
|
"key='" + key + '\'' +
|
||||||
|
", value='" + value + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
23
src/main/java/org/rundeck/api/domain/KeyResource.java
Normal file
23
src/main/java/org/rundeck/api/domain/KeyResource.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KeyResource represents a directory or an SSH key file
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public interface KeyResource extends StorageResource {
|
||||||
|
/**
|
||||||
|
* Return true if this is a file and is a private SSH key file.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isPrivateKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of SSH Key resources if this is a directory
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<KeyResource> getDirectoryContents();
|
||||||
|
}
|
64
src/main/java/org/rundeck/api/domain/ProjectConfig.java
Normal file
64
src/main/java/org/rundeck/api/domain/ProjectConfig.java
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectConfig is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectConfig implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private LinkedHashMap<String, String> properties = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
public ProjectConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfig(Map<String, String> properties) {
|
||||||
|
setProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperty(final String key, final String value) {
|
||||||
|
getProperties().put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addProperties(final Map<String, String> values) {
|
||||||
|
getProperties().putAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperties(final Map<String, String> properties) {
|
||||||
|
this.properties = new LinkedHashMap<String, String>(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof ProjectConfig)) return false;
|
||||||
|
|
||||||
|
ProjectConfig that = (ProjectConfig) o;
|
||||||
|
|
||||||
|
if (properties != null ? !properties.equals(that.properties) : that.properties != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return properties != null ? properties.hashCode() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ProjectConfig{" +
|
||||||
|
"properties=" + properties +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,8 @@ public class RundeckProject implements Serializable {
|
||||||
|
|
||||||
private String resourceModelProviderUrl;
|
private String resourceModelProviderUrl;
|
||||||
|
|
||||||
|
private ProjectConfig projectConfig;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -56,10 +58,20 @@ public class RundeckProject implements Serializable {
|
||||||
this.resourceModelProviderUrl = resourceModelProviderUrl;
|
this.resourceModelProviderUrl = resourceModelProviderUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProjectConfig getProjectConfig() {
|
||||||
|
return projectConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProjectConfig(ProjectConfig projectConfig) {
|
||||||
|
this.projectConfig = projectConfig;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "RundeckProject [name=" + name + ", description=" + description + ", resourceModelProviderUrl="
|
return "RundeckProject [name=" + name + ", description=" + description
|
||||||
+ resourceModelProviderUrl + "]";
|
+ (null!=resourceModelProviderUrl? ", resourceModelProviderUrl=" + resourceModelProviderUrl : "")
|
||||||
|
+ ", config="
|
||||||
|
+ projectConfig + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,6 +81,7 @@ public class RundeckProject implements Serializable {
|
||||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
result = prime * result + ((resourceModelProviderUrl == null) ? 0 : resourceModelProviderUrl.hashCode());
|
result = prime * result + ((resourceModelProviderUrl == null) ? 0 : resourceModelProviderUrl.hashCode());
|
||||||
|
result = prime * result + ((projectConfig == null) ? 0 : projectConfig.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +109,11 @@ public class RundeckProject implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
} else if (!resourceModelProviderUrl.equals(other.resourceModelProviderUrl))
|
} else if (!resourceModelProviderUrl.equals(other.resourceModelProviderUrl))
|
||||||
return false;
|
return false;
|
||||||
|
if (projectConfig == null) {
|
||||||
|
if (other.projectConfig != null)
|
||||||
|
return false;
|
||||||
|
} else if (!projectConfig.equals(other.projectConfig))
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
36
src/main/java/org/rundeck/api/domain/RundeckToken.java
Normal file
36
src/main/java/org/rundeck/api/domain/RundeckToken.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RundeckToken is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public class RundeckToken {
|
||||||
|
private String user;
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public RundeckToken() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public RundeckToken(String user, String token) {
|
||||||
|
this.setUser(user);
|
||||||
|
this.setToken(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(String user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
}
|
54
src/main/java/org/rundeck/api/domain/StorageResource.java
Normal file
54
src/main/java/org/rundeck/api/domain/StorageResource.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StorageResource represents a directory or a file
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public interface StorageResource {
|
||||||
|
/**
|
||||||
|
* Return the storage path for this resource
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the URL for this resource
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getUrl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the file name if this is a file
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the metadata for this file if this is a file
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Map<String, String> getMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if this is a directory, false if this is a file
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isDirectory();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of directory contents if this is a directory
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<? extends StorageResource> getDirectoryContents();
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.rundeck.api.generator;
|
||||||
|
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseDocGenerator generates a document using the element as the root.
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public abstract class BaseDocGenerator implements XmlDocumentGenerator {
|
||||||
|
@Override
|
||||||
|
public Document generateXmlDocument() {
|
||||||
|
return DocumentFactory.getInstance().createDocument(generateXmlElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.rundeck.api.generator;
|
||||||
|
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentFactory;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.rundeck.api.domain.ProjectConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectConfigGenerator is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectConfigGenerator extends BaseDocGenerator {
|
||||||
|
private ProjectConfig config;
|
||||||
|
|
||||||
|
public ProjectConfigGenerator(ProjectConfig config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element generateXmlElement() {
|
||||||
|
Element configEl = DocumentFactory.getInstance().createElement("config");
|
||||||
|
if (null != config.getProperties()) {
|
||||||
|
for (String s : config.getProperties().keySet()) {
|
||||||
|
Element property = configEl.addElement("property");
|
||||||
|
property.addAttribute("key", s);
|
||||||
|
property.addAttribute("value", config.getProperties().get(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return configEl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.rundeck.api.generator;
|
||||||
|
|
||||||
|
import org.dom4j.DocumentFactory;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.rundeck.api.domain.ConfigProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectConfigPropertyGenerator generates a {@literal <property/>} element representing a configuration property.
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-03-07
|
||||||
|
*/
|
||||||
|
public class ProjectConfigPropertyGenerator extends BaseDocGenerator {
|
||||||
|
private ConfigProperty property;
|
||||||
|
|
||||||
|
public ProjectConfigPropertyGenerator(ConfigProperty property) {
|
||||||
|
this.property = property;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element generateXmlElement() {
|
||||||
|
Element propElem = DocumentFactory.getInstance().createElement("property");
|
||||||
|
propElem.addAttribute("key", property.getKey());
|
||||||
|
propElem.addAttribute("value", property.getValue());
|
||||||
|
|
||||||
|
return propElem;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package org.rundeck.api.generator;
|
||||||
|
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentFactory;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.rundeck.api.domain.ProjectConfig;
|
||||||
|
import org.rundeck.api.domain.RundeckProject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectGenerator is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectGenerator extends BaseDocGenerator {
|
||||||
|
RundeckProject project;
|
||||||
|
|
||||||
|
public ProjectGenerator(RundeckProject project) {
|
||||||
|
this.project = project;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element generateXmlElement() {
|
||||||
|
Element rootElem = DocumentFactory.getInstance().createElement("project");
|
||||||
|
rootElem.addElement("name").setText(project.getName());
|
||||||
|
ProjectConfig configuration = project.getProjectConfig();
|
||||||
|
if (null != configuration) {
|
||||||
|
rootElem.add(new ProjectConfigGenerator(configuration).generateXmlElement());
|
||||||
|
}
|
||||||
|
return rootElem;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package org.rundeck.api.generator;
|
||||||
|
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.dom4j.Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XmlDocumentGenerator is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public interface XmlDocumentGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the XML {@link org.dom4j.Node}
|
||||||
|
*
|
||||||
|
* @return any object holding the converted value
|
||||||
|
*/
|
||||||
|
Element generateXmlElement();
|
||||||
|
/**
|
||||||
|
* Generate the XML {@link org.dom4j.Node}
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
*
|
||||||
|
* @return any object holding the converted value
|
||||||
|
*/
|
||||||
|
Document generateXmlDocument();
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Node;
|
||||||
|
import org.rundeck.api.domain.ArchiveImport;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ArchiveImportParser is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-03-09
|
||||||
|
*/
|
||||||
|
public class ArchiveImportParser implements XmlNodeParser<ArchiveImport> {
|
||||||
|
String xpath;
|
||||||
|
|
||||||
|
public ArchiveImportParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArchiveImportParser(final String xpath) {
|
||||||
|
this.xpath = xpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArchiveImport parseXmlNode(final Node node) {
|
||||||
|
final Node importNode = xpath != null ? node.selectSingleNode(xpath) : node;
|
||||||
|
|
||||||
|
boolean issuccess = "successful".equals(importNode.valueOf("/import/@status"));
|
||||||
|
final ArrayList<String> messages = new ArrayList<String>();
|
||||||
|
for (final Object o : importNode.selectNodes("/import/errors/error")) {
|
||||||
|
messages.add(((Node) o).getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArchiveImport(issuccess, messages);
|
||||||
|
}
|
||||||
|
}
|
29
src/main/java/org/rundeck/api/parser/BaseXpathParser.java
Normal file
29
src/main/java/org/rundeck/api/parser/BaseXpathParser.java
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseXpathParser is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public abstract class BaseXpathParser<T> implements XmlNodeParser<T> {
|
||||||
|
private String xpath;
|
||||||
|
|
||||||
|
public BaseXpathParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseXpathParser(String xpath) {
|
||||||
|
|
||||||
|
this.xpath = xpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract T parse(Node node);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T parseXmlNode(Node node) {
|
||||||
|
Node selectedNode = xpath != null ? node.selectSingleNode(xpath) : node;
|
||||||
|
return parse(selectedNode);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Node;
|
||||||
|
import org.rundeck.api.domain.ProjectConfig;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectConfigParser parses project "config" element contents
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectConfigParser implements XmlNodeParser<ProjectConfig> {
|
||||||
|
private String xpath;
|
||||||
|
|
||||||
|
public ProjectConfigParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfigParser(String xpath) {
|
||||||
|
this.xpath = xpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProjectConfig parseXmlNode(Node node) {
|
||||||
|
Node config1 = getXpath() != null ? node.selectSingleNode(getXpath()) : node;
|
||||||
|
ProjectConfig config = new ProjectConfig();
|
||||||
|
List property = config1.selectNodes("property");
|
||||||
|
for (Object o : property) {
|
||||||
|
Node propnode = (Node) o;
|
||||||
|
String key = propnode.valueOf("@key");
|
||||||
|
String value = propnode.valueOf("@value");
|
||||||
|
if (null != key && null != value) {
|
||||||
|
config.setProperty(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getXpath() {
|
||||||
|
return xpath;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Node;
|
||||||
|
import org.rundeck.api.domain.ConfigProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectConfigPropertyParser parses a {@literal <property/>} element representing
|
||||||
|
* a configuration property.
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-03-07
|
||||||
|
*/
|
||||||
|
public class ProjectConfigPropertyParser implements XmlNodeParser<ConfigProperty> {
|
||||||
|
private String xpath;
|
||||||
|
|
||||||
|
public ProjectConfigPropertyParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfigPropertyParser(final String xpath) {
|
||||||
|
this.setXpath(xpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigProperty parseXmlNode(final Node node) {
|
||||||
|
final Node propnode = getXpath() != null ? node.selectSingleNode(getXpath()) : node;
|
||||||
|
final String key = propnode.valueOf("@key");
|
||||||
|
final String value = propnode.valueOf("@value");
|
||||||
|
final ConfigProperty config = new ConfigProperty();
|
||||||
|
config.setKey(key);
|
||||||
|
config.setValue(value);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getXpath() {
|
||||||
|
return xpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXpath(final String xpath) {
|
||||||
|
this.xpath = xpath;
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ public class ProjectParser implements XmlNodeParser<RundeckProject> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RundeckProject parseXmlNode(Node node) {
|
public RundeckProject parseXmlNode(Node node) {
|
||||||
Node projectNode = xpath != null ? node.selectSingleNode(xpath) : node;
|
Node projectNode = getXpath() != null ? node.selectSingleNode(getXpath()) : node;
|
||||||
|
|
||||||
RundeckProject project = new RundeckProject();
|
RundeckProject project = new RundeckProject();
|
||||||
|
|
||||||
|
@ -53,4 +53,7 @@ public class ProjectParser implements XmlNodeParser<RundeckProject> {
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getXpath() {
|
||||||
|
return xpath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
36
src/main/java/org/rundeck/api/parser/ProjectParserV11.java
Normal file
36
src/main/java/org/rundeck/api/parser/ProjectParserV11.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Node;
|
||||||
|
import org.rundeck.api.domain.ProjectConfig;
|
||||||
|
import org.rundeck.api.domain.RundeckProject;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectParserV11 supports embedded "config" element.
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectParserV11 extends ProjectParser {
|
||||||
|
public ProjectParserV11() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectParserV11(final String xpath) {
|
||||||
|
super(xpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RundeckProject parseXmlNode(final Node node) {
|
||||||
|
final RundeckProject rundeckProject = super.parseXmlNode(node);
|
||||||
|
final Node projectNode = getXpath() != null ? node.selectSingleNode(getXpath()) : node;
|
||||||
|
final Node config1 = projectNode.selectSingleNode("config");
|
||||||
|
if (config1 == null) {
|
||||||
|
return rundeckProject;
|
||||||
|
}
|
||||||
|
|
||||||
|
rundeckProject.setProjectConfig(new ProjectConfigParser().parseXmlNode(config1));
|
||||||
|
|
||||||
|
return rundeckProject;
|
||||||
|
}
|
||||||
|
}
|
33
src/main/java/org/rundeck/api/parser/RundeckTokenParser.java
Normal file
33
src/main/java/org/rundeck/api/parser/RundeckTokenParser.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Node;
|
||||||
|
import org.rundeck.api.domain.RundeckToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RundeckTokenParser is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public class RundeckTokenParser implements XmlNodeParser<RundeckToken> {
|
||||||
|
String xpath;
|
||||||
|
|
||||||
|
public RundeckTokenParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public RundeckTokenParser(String xpath) {
|
||||||
|
this.xpath = xpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RundeckToken parseXmlNode(Node node) {
|
||||||
|
Node targetNode = xpath != null ? node.selectSingleNode(xpath) : node;
|
||||||
|
RundeckToken rundeckToken = new RundeckToken();
|
||||||
|
String token = targetNode.valueOf("@id");
|
||||||
|
String user = targetNode.valueOf("@user");
|
||||||
|
rundeckToken.setToken(token);
|
||||||
|
rundeckToken.setUser(user);
|
||||||
|
|
||||||
|
return rundeckToken;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Node;
|
||||||
|
import org.rundeck.api.domain.BaseKeyResource;
|
||||||
|
import org.rundeck.api.domain.KeyResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSHKeyResourceParser is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public class SSHKeyResourceParser extends BaseXpathParser<KeyResource> implements XmlNodeParser<KeyResource> {
|
||||||
|
public SSHKeyResourceParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SSHKeyResourceParser(String xpath) {
|
||||||
|
super(xpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyResource parse(Node node) {
|
||||||
|
return BaseKeyResource.from(new StorageResourceParser().parse(node));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.dom4j.Node;
|
||||||
|
import org.rundeck.api.domain.BaseStorageResource;
|
||||||
|
import org.rundeck.api.domain.StorageResource;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StorageResourceParser is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public class StorageResourceParser extends BaseXpathParser<StorageResource> {
|
||||||
|
private BaseStorageResource holder;
|
||||||
|
public StorageResourceParser() {
|
||||||
|
|
||||||
|
}
|
||||||
|
public StorageResourceParser(BaseStorageResource holder){
|
||||||
|
this.holder=holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageResourceParser(String xpath) {
|
||||||
|
super(xpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StorageResource parse(Node node) {
|
||||||
|
String path = node.valueOf("@path");
|
||||||
|
String type = node.valueOf("@type");
|
||||||
|
String url = node.valueOf("@url");
|
||||||
|
BaseStorageResource storageResource = null == holder ? new BaseStorageResource() : holder;
|
||||||
|
storageResource.setDirectory("directory".equals(type));
|
||||||
|
storageResource.setPath(path);
|
||||||
|
storageResource.setUrl(url);
|
||||||
|
|
||||||
|
if (storageResource.isDirectory()) {
|
||||||
|
if (node.selectSingleNode("contents") != null) {
|
||||||
|
storageResource.setDirectoryContents(new ListParser<StorageResource>(new StorageResourceParser(),
|
||||||
|
"contents/resource").parseXmlNode(node));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String name = node.valueOf("@name");
|
||||||
|
storageResource.setName(name);
|
||||||
|
|
||||||
|
Node meta = node.selectSingleNode("resource-meta");
|
||||||
|
HashMap<String, String> metamap = new HashMap<String, String>();
|
||||||
|
if (null != meta) {
|
||||||
|
Element metaEl = (Element) meta;
|
||||||
|
for (Object o : metaEl.elements()) {
|
||||||
|
Element sub = (Element) o;
|
||||||
|
metamap.put(sub.getName(), sub.getText().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storageResource.setMetadata(metamap);
|
||||||
|
}
|
||||||
|
return storageResource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.rundeck.api.util;
|
||||||
|
|
||||||
|
import org.apache.http.entity.ContentProducer;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.io.OutputFormat;
|
||||||
|
import org.dom4j.io.XMLWriter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DocumentContentProducer writes XML document to a stream
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class DocumentContentProducer implements ContentProducer {
|
||||||
|
Document document;
|
||||||
|
private OutputFormat format;
|
||||||
|
|
||||||
|
public DocumentContentProducer(final Document document, final OutputFormat format) {
|
||||||
|
this.document = document;
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentContentProducer(final Document document) {
|
||||||
|
this.document = document;
|
||||||
|
format = new OutputFormat("", false, "UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(final OutputStream outstream) throws IOException {
|
||||||
|
|
||||||
|
final XMLWriter xmlWriter = new XMLWriter(outstream, format);
|
||||||
|
xmlWriter.write(document);
|
||||||
|
xmlWriter.flush();
|
||||||
|
}
|
||||||
|
}
|
|
@ -93,3 +93,23 @@ h2. RunDeck API version 10
|
||||||
* Execution Output - Retrieve log output for a particular node or step - OK
|
* Execution Output - Retrieve log output for a particular node or step - OK
|
||||||
* Execution Info - added successfulNodes and failedNodes detail. - OK
|
* Execution Info - added successfulNodes and failedNodes detail. - OK
|
||||||
* Deprecation: Remove methods deprecated until version 10. - OK
|
* Deprecation: Remove methods deprecated until version 10. - OK
|
||||||
|
|
||||||
|
|
||||||
|
h2. RunDeck API version 11
|
||||||
|
|
||||||
|
[Documentation of the RunDeck API version 11|http://rundeck.org/2.1.0/api/index.html]
|
||||||
|
|
||||||
|
* Project creation - OK
|
||||||
|
* Get Project configuration - OK
|
||||||
|
* Set Project configuration - OK
|
||||||
|
* Get/Set Project configuration keys - OK
|
||||||
|
* Delete project - OK
|
||||||
|
* Export project archive - OK
|
||||||
|
* Import project archive - OK
|
||||||
|
* Key file upload - OK
|
||||||
|
* Key file delete - OK
|
||||||
|
* Key file list - OK
|
||||||
|
* Key file get - OK
|
||||||
|
* API Token create - OK
|
||||||
|
* API Token list - OK
|
||||||
|
* API Token delete - OK
|
||||||
|
|
|
@ -19,6 +19,7 @@ import betamax.Betamax;
|
||||||
import betamax.MatchRule;
|
import betamax.MatchRule;
|
||||||
import betamax.Recorder;
|
import betamax.Recorder;
|
||||||
import betamax.TapeMode;
|
import betamax.TapeMode;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
|
@ -27,8 +28,7 @@ import org.rundeck.api.domain.*;
|
||||||
import org.rundeck.api.query.ExecutionQuery;
|
import org.rundeck.api.query.ExecutionQuery;
|
||||||
import org.rundeck.api.util.PagedResults;
|
import org.rundeck.api.util.PagedResults;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ public class RundeckClientTest {
|
||||||
public static final String TEST_TOKEN_4 = "sN5RRSNvu15DnV6EcNDdc2CkdPcv3s32";
|
public static final String TEST_TOKEN_4 = "sN5RRSNvu15DnV6EcNDdc2CkdPcv3s32";
|
||||||
public static final String TEST_TOKEN_5 = "C3O6d5O98Kr6Dpv71sdE4ERdCuU12P6d";
|
public static final String TEST_TOKEN_5 = "C3O6d5O98Kr6Dpv71sdE4ERdCuU12P6d";
|
||||||
public static final String TEST_TOKEN_6 = "Do4d3NUD5DKk21DR4sNK755RcPk618vn";
|
public static final String TEST_TOKEN_6 = "Do4d3NUD5DKk21DR4sNK755RcPk618vn";
|
||||||
|
public static final String TEST_TOKEN_7 = "8Dp9op111ER6opsDRkddvE86K9sE499s";
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public Recorder recorder = new Recorder();
|
public Recorder recorder = new Recorder();
|
||||||
|
@ -82,6 +83,131 @@ public class RundeckClientTest {
|
||||||
Assert.assertNull(projects.get(0).getDescription());
|
Assert.assertNull(projects.get(0).getDescription());
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
|
@Betamax(tape = "create_projectv11")
|
||||||
|
public void createProject() throws Exception {
|
||||||
|
|
||||||
|
RundeckProject project = createClient(TEST_TOKEN_6,11).createProject("monkey1", null);
|
||||||
|
Assert.assertEquals("monkey1", project.getName());
|
||||||
|
Assert.assertEquals(null, project.getDescription());
|
||||||
|
Assert.assertNotNull(project.getProjectConfig());
|
||||||
|
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "delete_projectv11")
|
||||||
|
public void deleteProject() throws Exception {
|
||||||
|
RundeckClient client1 = createClient(TEST_TOKEN_6, 11);
|
||||||
|
client1.deleteProject("delete_me");
|
||||||
|
RundeckProject delete_me = null;
|
||||||
|
try {
|
||||||
|
delete_me = client1.getProject("delete_me");
|
||||||
|
Assert.fail();
|
||||||
|
} catch (RundeckApiException.RundeckApiHttpStatusException e) {
|
||||||
|
Assert.assertEquals(404,e.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "get_project_configv11")
|
||||||
|
public void getProjectConfig() throws Exception {
|
||||||
|
ProjectConfig config = createClient(TEST_TOKEN_6, 11).getProjectConfig("monkey1");
|
||||||
|
Assert.assertNotNull(config);
|
||||||
|
Assert.assertNotNull(config.getProperties());
|
||||||
|
Assert.assertEquals(9,config.getProperties().size());
|
||||||
|
Assert.assertEquals("monkey1", config.getProperties().get("project.name"));
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "set_project_configv11")
|
||||||
|
public void setProjectConfig() throws Exception {
|
||||||
|
HashMap<String, String> config = new HashMap<String, String>();
|
||||||
|
config.put("alphabetty", "spaghetti");
|
||||||
|
config.put("blha.blee", "a big amazing thingy so there.");
|
||||||
|
ProjectConfig result = createClient(TEST_TOKEN_6, 11).setProjectConfig("monkey1", config);
|
||||||
|
Assert.assertNotNull(result);
|
||||||
|
Assert.assertNotNull(result.getProperties());
|
||||||
|
Assert.assertEquals(3, result.getProperties().size());
|
||||||
|
Assert.assertEquals("monkey1", result.getProperties().get("project.name"));
|
||||||
|
Assert.assertEquals("spaghetti", result.getProperties().get("alphabetty"));
|
||||||
|
Assert.assertEquals("a big amazing thingy so there.", result.getProperties().get("blha.blee"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "get_project_config_keyedv11")
|
||||||
|
public void getProjectConfigKeyed() throws Exception {
|
||||||
|
String value = createClient(TEST_TOKEN_6, 11).getProjectConfig("ABC", "project.name");
|
||||||
|
Assert.assertNotNull(value);
|
||||||
|
Assert.assertEquals("ABC", value);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "get_project_config_keyed_dne_v11")
|
||||||
|
public void getProjectConfigKeyedDNE() throws Exception {
|
||||||
|
String value = createClient(TEST_TOKEN_6, 11).getProjectConfig("ABC", "does-not-exist");
|
||||||
|
Assert.assertNull(value);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "set_project_config_keyedv11")
|
||||||
|
public void setProjectConfigKeyed() throws Exception {
|
||||||
|
String value = createClient(TEST_TOKEN_6, 11).setProjectConfig("ABC", "monkey-burrito", "lemon pie");
|
||||||
|
Assert.assertNotNull(value);
|
||||||
|
Assert.assertEquals("lemon pie", value);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "delete_project_config_keyedv11")
|
||||||
|
public void deleteProjectConfigKeyed() throws Exception {
|
||||||
|
RundeckClient client1 = createClient(TEST_TOKEN_6, 11);
|
||||||
|
Assert.assertEquals("7up", client1.setProjectConfig("ABC", "monkey-burrito", "7up"));
|
||||||
|
client1.deleteProjectConfig("ABC", "monkey-burrito");
|
||||||
|
String value=client1.getProjectConfig("ABC", "monkey-burrito");
|
||||||
|
Assert.assertNull(value);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "export_projectv11")
|
||||||
|
public void exportProject() throws Exception {
|
||||||
|
RundeckClient client1 = createClient(TEST_TOKEN_6, 11);
|
||||||
|
File temp = File.createTempFile("test-archive", ".zip");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
int i = client1.exportProject("DEF1", temp);
|
||||||
|
Assert.assertEquals(8705, i);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "import_project_suv11",mode = TapeMode.READ_ONLY)
|
||||||
|
public void importProjectSuccess() throws Exception {
|
||||||
|
RundeckClient client1 = createClient(TEST_TOKEN_6, 11);
|
||||||
|
InputStream resourceAsStream = getClass().getResourceAsStream("test-archive.zip");
|
||||||
|
File temp = File.createTempFile("test-archive", ".zip");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
IOUtils.copy(resourceAsStream, new FileOutputStream(temp));
|
||||||
|
ArchiveImport def1 = client1.importArchive("DEF2", temp, true, true);
|
||||||
|
Assert.assertTrue(def1.isSuccessful());
|
||||||
|
Assert.assertEquals(0, def1.getErrorMessages().size());
|
||||||
|
|
||||||
|
ArchiveImport def2 = client1.importArchive("DEF2", temp, false, true);
|
||||||
|
Assert.assertTrue(def2.isSuccessful());
|
||||||
|
Assert.assertEquals(0, def2.getErrorMessages().size());
|
||||||
|
|
||||||
|
ArchiveImport def3 = client1.importArchive("DEF2", temp, true, false);
|
||||||
|
Assert.assertTrue(def3.isSuccessful());
|
||||||
|
Assert.assertEquals(0, def3.getErrorMessages().size());
|
||||||
|
temp.delete();
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "import_project_failure_v11", mode = TapeMode.READ_ONLY)
|
||||||
|
public void importProjectFailure() throws Exception {
|
||||||
|
RundeckClient client1 = createClient(TEST_TOKEN_6, 11);
|
||||||
|
InputStream resourceAsStream = getClass().getResourceAsStream("test-archive.zip");
|
||||||
|
File temp = File.createTempFile("test-archive", ".zip");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
IOUtils.copy(resourceAsStream, new FileOutputStream(temp));
|
||||||
|
ArchiveImport def1 = client1.importArchive("DEF1", temp, false, true);
|
||||||
|
Assert.assertFalse(def1.isSuccessful());
|
||||||
|
Assert.assertEquals(10, def1.getErrorMessages().size());
|
||||||
|
Assert.assertEquals("Job at index [1] at archive path: " +
|
||||||
|
"rundeck-DEF1/jobs/job-6fd1808c-eafb-49ac-abf2-4de7ec75872f.xml had errors: Validation errors: Cannot" +
|
||||||
|
" create a Job with UUID 6fd1808c-eafb-49ac-abf2-4de7ec75872f: a Job already exists with this UUID. " +
|
||||||
|
"Change the UUID or delete the other Job.", def1.getErrorMessages().get(0));
|
||||||
|
|
||||||
|
}
|
||||||
|
@Test
|
||||||
@Betamax(tape = "get_history")
|
@Betamax(tape = "get_history")
|
||||||
public void getHistory() throws Exception {
|
public void getHistory() throws Exception {
|
||||||
final RundeckHistory test = client.getHistory("test");
|
final RundeckHistory test = client.getHistory("test");
|
||||||
|
@ -1072,6 +1198,298 @@ public class RundeckClientTest {
|
||||||
Assert.assertEquals(RundeckWFExecState.SUCCEEDED,output.getExecutionState());
|
Assert.assertEquals(RundeckWFExecState.SUCCEEDED,output.getExecutionState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate api token
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "api_token_generate", mode = TapeMode.READ_ONLY)
|
||||||
|
public void generateApiToken() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
String token = client.generateApiToken("bob");
|
||||||
|
|
||||||
|
Assert.assertNotNull(token);
|
||||||
|
Assert.assertEquals("MiquQjELTrEaugpmdgAKs1W3a7xonAwU", token);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get api token
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "api_token_get", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getApiToken() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
RundeckToken token = client.getApiToken("MiquQjELTrEaugpmdgAKs1W3a7xonAwU");
|
||||||
|
|
||||||
|
Assert.assertNotNull(token);
|
||||||
|
Assert.assertEquals("MiquQjELTrEaugpmdgAKs1W3a7xonAwU", token.getToken());
|
||||||
|
Assert.assertEquals("bob", token.getUser());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* list api tokens for user
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "api_tokens_list_user", mode = TapeMode.READ_ONLY)
|
||||||
|
public void listApiTokens_user() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
List<RundeckToken> tokens = client.listApiTokens("bob");
|
||||||
|
|
||||||
|
Assert.assertNotNull(tokens);
|
||||||
|
Assert.assertEquals(3, tokens.size());
|
||||||
|
Assert.assertEquals("hINp5eGzvYA9UePbUChaKHd5NiRkwWbx", tokens.get(0).getToken());
|
||||||
|
Assert.assertEquals("bob", tokens.get(0).getUser());
|
||||||
|
Assert.assertEquals("NaNnwVzAHAG83qOS7Wtwh6mjcXViyWUV", tokens.get(1).getToken());
|
||||||
|
Assert.assertEquals("bob", tokens.get(1).getUser());
|
||||||
|
Assert.assertEquals("MiquQjELTrEaugpmdgAKs1W3a7xonAwU", tokens.get(2).getToken());
|
||||||
|
Assert.assertEquals("bob", tokens.get(2).getUser());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* list api tokens all
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "api_tokens_list_all", mode = TapeMode.READ_ONLY)
|
||||||
|
public void listApiTokens() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
List<RundeckToken> tokens = client.listApiTokens();
|
||||||
|
|
||||||
|
Assert.assertNotNull(tokens);
|
||||||
|
Assert.assertEquals(4, tokens.size());
|
||||||
|
Assert.assertEquals("8Dp9op111ER6opsDRkddvE86K9sE499s", tokens.get(0).getToken());
|
||||||
|
Assert.assertEquals("admin", tokens.get(0).getUser());
|
||||||
|
Assert.assertEquals("hINp5eGzvYA9UePbUChaKHd5NiRkwWbx", tokens.get(1).getToken());
|
||||||
|
Assert.assertEquals("bob", tokens.get(1).getUser());
|
||||||
|
Assert.assertEquals("NaNnwVzAHAG83qOS7Wtwh6mjcXViyWUV", tokens.get(2).getToken());
|
||||||
|
Assert.assertEquals("bob", tokens.get(2).getUser());
|
||||||
|
Assert.assertEquals("MiquQjELTrEaugpmdgAKs1W3a7xonAwU", tokens.get(3).getToken());
|
||||||
|
Assert.assertEquals("bob", tokens.get(3).getUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get api token
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "api_token_delete", mode = TapeMode.READ_ONLY)
|
||||||
|
public void deleteApiToken() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
|
||||||
|
client.deleteApiToken("MiquQjELTrEaugpmdgAKs1W3a7xonAwU");
|
||||||
|
|
||||||
|
//get should now return 404
|
||||||
|
try {
|
||||||
|
client.getApiToken("MiquQjELTrEaugpmdgAKs1W3a7xonAwU");
|
||||||
|
Assert.fail("expected failure");
|
||||||
|
} catch (RundeckApiException.RundeckApiHttpStatusException e) {
|
||||||
|
Assert.assertEquals(404, e.getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Store ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_store_private", mode = TapeMode.READ_ONLY)
|
||||||
|
public void storeKey_private() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
File temp = File.createTempFile("test-key", ".tmp");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
FileOutputStream out = new FileOutputStream(temp);
|
||||||
|
try{
|
||||||
|
out.write("test1".getBytes());
|
||||||
|
}finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
KeyResource storageResource = client.storeKey("keys/test/example/file1.pem", temp, true);
|
||||||
|
Assert.assertNotNull(storageResource);
|
||||||
|
Assert.assertFalse(storageResource.isDirectory());
|
||||||
|
Assert.assertTrue(storageResource.isPrivateKey());
|
||||||
|
Assert.assertEquals("file1.pem", storageResource.getName());
|
||||||
|
Assert.assertEquals("keys/test/example/file1.pem", storageResource.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/keys/test/example/file1.pem",
|
||||||
|
storageResource.getUrl());
|
||||||
|
Assert.assertEquals(0, storageResource.getDirectoryContents().size());
|
||||||
|
Map<String, String> metadata = storageResource.getMetadata();
|
||||||
|
Assert.assertNotNull(metadata);
|
||||||
|
Assert.assertEquals("application/octet-stream", metadata.get("Rundeck-content-type"));
|
||||||
|
Assert.assertEquals("private", metadata.get("Rundeck-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Store ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_store_public", mode = TapeMode.READ_ONLY)
|
||||||
|
public void storeKey_public() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
File temp = File.createTempFile("test-key", ".tmp");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
FileOutputStream out = new FileOutputStream(temp);
|
||||||
|
try{
|
||||||
|
out.write("test1".getBytes());
|
||||||
|
}finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
KeyResource storageResource = client.storeKey("keys/test/example/file2.pub", temp, false);
|
||||||
|
Assert.assertNotNull(storageResource);
|
||||||
|
Assert.assertFalse(storageResource.isDirectory());
|
||||||
|
Assert.assertFalse(storageResource.isPrivateKey());
|
||||||
|
Assert.assertEquals("file2.pub", storageResource.getName());
|
||||||
|
Assert.assertEquals("keys/test/example/file2.pub", storageResource.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/keys/test/example/file2.pub",
|
||||||
|
storageResource.getUrl());
|
||||||
|
Assert.assertEquals(0, storageResource.getDirectoryContents().size());
|
||||||
|
Map<String, String> metadata = storageResource.getMetadata();
|
||||||
|
Assert.assertNotNull(metadata);
|
||||||
|
Assert.assertEquals("application/pgp-keys", metadata.get("Rundeck-content-type"));
|
||||||
|
Assert.assertEquals("public", metadata.get("Rundeck-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_get_public", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getKey_public() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
KeyResource storageResource = client.getKey("keys/test/example/file2.pub");
|
||||||
|
Assert.assertNotNull(storageResource);
|
||||||
|
Assert.assertFalse(storageResource.isDirectory());
|
||||||
|
Assert.assertFalse(storageResource.isPrivateKey());
|
||||||
|
Assert.assertEquals("file2.pub", storageResource.getName());
|
||||||
|
Assert.assertEquals("keys/test/example/file2.pub", storageResource.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/keys/test/example/file2.pub",
|
||||||
|
storageResource.getUrl());
|
||||||
|
Assert.assertEquals(0, storageResource.getDirectoryContents().size());
|
||||||
|
Map<String, String> metadata = storageResource.getMetadata();
|
||||||
|
Assert.assertNotNull(metadata);
|
||||||
|
Assert.assertEquals("application/pgp-keys", metadata.get("Rundeck-content-type"));
|
||||||
|
Assert.assertEquals("public", metadata.get("Rundeck-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_get_private", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getKey_private() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
KeyResource storageResource = client.getKey("keys/test/example/file1.pem");
|
||||||
|
Assert.assertNotNull(storageResource);
|
||||||
|
Assert.assertFalse(storageResource.isDirectory());
|
||||||
|
Assert.assertTrue(storageResource.isPrivateKey());
|
||||||
|
Assert.assertEquals("file1.pem", storageResource.getName());
|
||||||
|
Assert.assertEquals("keys/test/example/file1.pem", storageResource.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/keys/test/example/file1.pem",
|
||||||
|
storageResource.getUrl());
|
||||||
|
Assert.assertEquals(0, storageResource.getDirectoryContents().size());
|
||||||
|
Map<String, String> metadata = storageResource.getMetadata();
|
||||||
|
Assert.assertNotNull(metadata);
|
||||||
|
Assert.assertEquals("application/octet-stream", metadata.get("Rundeck-content-type"));
|
||||||
|
Assert.assertEquals("private", metadata.get("Rundeck-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get ssh key data
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_get_data_private", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getKeyData_private() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
File temp = File.createTempFile("test-key", ".tmp");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
try {
|
||||||
|
int data = client.getPublicKeyContent("keys/test/example/file1.pem", temp);
|
||||||
|
Assert.fail("expected failure");
|
||||||
|
} catch (RundeckApiException e) {
|
||||||
|
Assert.assertEquals("Requested Key path was not a Public key: keys/test/example/file1.pem",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get ssh key data
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_get_data_public", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getKeyData_public() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
File temp = File.createTempFile("test-key", ".tmp");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
int length = client.getPublicKeyContent("keys/test/example/file2.pub", temp);
|
||||||
|
Assert.assertEquals(5, length);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* list directory
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_list_directory", mode = TapeMode.READ_ONLY)
|
||||||
|
public void listKeyDirectory() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
List<KeyResource> list = client.listKeyDirectory("keys/test/example");
|
||||||
|
Assert.assertEquals(2, list.size());
|
||||||
|
KeyResource storageResource1 = list.get(0);
|
||||||
|
KeyResource storageResource2 = list.get(1);
|
||||||
|
|
||||||
|
Assert.assertFalse(storageResource2.isDirectory());
|
||||||
|
Assert.assertTrue(storageResource2.isPrivateKey());
|
||||||
|
Assert.assertEquals("file1.pem", storageResource2.getName());
|
||||||
|
Assert.assertEquals("keys/test/example/file1.pem", storageResource2.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/keys/test/example/file1.pem", storageResource2.getUrl());
|
||||||
|
Assert.assertNotNull(storageResource2.getMetadata());
|
||||||
|
|
||||||
|
Assert.assertEquals("application/octet-stream", storageResource2.getMetadata().get("Rundeck-content-type"));
|
||||||
|
Assert.assertEquals("private", storageResource2.getMetadata().get("Rundeck-key-type"));
|
||||||
|
|
||||||
|
Assert.assertFalse(storageResource1.isDirectory());
|
||||||
|
Assert.assertFalse(storageResource1.isPrivateKey());
|
||||||
|
Assert.assertEquals("file2.pub", storageResource1.getName());
|
||||||
|
Assert.assertEquals("keys/test/example/file2.pub", storageResource1.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/keys/test/example/file2.pub",
|
||||||
|
storageResource1.getUrl());
|
||||||
|
Assert.assertNotNull(storageResource1.getMetadata());
|
||||||
|
Assert.assertEquals("application/pgp-keys", storageResource1.getMetadata().get("Rundeck-content-type"));
|
||||||
|
Assert.assertEquals("public", storageResource1.getMetadata().get("Rundeck-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* list root
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_list_root", mode = TapeMode.READ_ONLY)
|
||||||
|
public void listKeyDirectoryRoot() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
List<KeyResource> list = client.listKeyDirectoryRoot();
|
||||||
|
Assert.assertEquals(2, list.size());
|
||||||
|
KeyResource storageResource0 = list.get(0);
|
||||||
|
KeyResource storageResource1 = list.get(1);
|
||||||
|
|
||||||
|
Assert.assertFalse(storageResource0.isDirectory());
|
||||||
|
Assert.assertTrue(storageResource0.isPrivateKey());
|
||||||
|
Assert.assertEquals("test1.pem", storageResource0.getName());
|
||||||
|
Assert.assertEquals("keys/test1.pem", storageResource0.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/keys/test1.pem", storageResource0.getUrl());
|
||||||
|
Assert.assertNotNull(storageResource0.getMetadata());
|
||||||
|
|
||||||
|
Assert.assertEquals("application/octet-stream", storageResource0.getMetadata().get("Rundeck-content-type"));
|
||||||
|
Assert.assertEquals("private", storageResource0.getMetadata().get("Rundeck-key-type"));
|
||||||
|
|
||||||
|
Assert.assertTrue(storageResource1.toString(), storageResource1.isDirectory());
|
||||||
|
Assert.assertEquals(null, storageResource1.getName());
|
||||||
|
Assert.assertEquals("keys/test", storageResource1.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/keys/test",
|
||||||
|
storageResource1.getUrl());
|
||||||
|
Assert.assertNull(storageResource1.getMetadata());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "key_delete", mode = TapeMode.READ_ONLY)
|
||||||
|
public void deleteKey() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
client.deleteKey("keys/test/example/file2.pub");
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.getKey("keys/test/example/file2.pub");
|
||||||
|
Assert.fail("expected failure");
|
||||||
|
} catch (RundeckApiException.RundeckApiHttpStatusException e) {
|
||||||
|
Assert.assertEquals(404,e.getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
// not that you can put whatever here, because we don't actually connect to the RunDeck instance
|
// not that you can put whatever here, because we don't actually connect to the RunDeck instance
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.rundeck.api.generator;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.dom4j.io.XMLWriter;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.rundeck.api.domain.ProjectConfig;
|
||||||
|
import org.rundeck.api.domain.RundeckProject;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectConfigGeneratorTest is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectConfigGeneratorTest {
|
||||||
|
@Test
|
||||||
|
public void generate() throws Exception {
|
||||||
|
ProjectConfig config = new ProjectConfig();
|
||||||
|
config.setProperty("abc", "123");
|
||||||
|
config.setProperty("monkey.bonanza", "pale\ncomparison");
|
||||||
|
|
||||||
|
Document doc = new ProjectConfigGenerator(config).generateXmlDocument();
|
||||||
|
XMLWriter xmlWriter = new XMLWriter(System.out);
|
||||||
|
xmlWriter.write(doc);
|
||||||
|
xmlWriter.flush();
|
||||||
|
Element configElement = doc.getRootElement();
|
||||||
|
Assert.assertEquals("config", configElement.getName());
|
||||||
|
Assert.assertNotNull(configElement.selectSingleNode("property[1]"));
|
||||||
|
Assert.assertEquals("abc", configElement.selectSingleNode("property[1]/@key").getText());
|
||||||
|
Assert.assertEquals("123", configElement.selectSingleNode("property[1]/@value").getText());
|
||||||
|
|
||||||
|
Assert.assertNotNull(configElement.selectSingleNode("property[2]"));
|
||||||
|
Assert.assertEquals("monkey.bonanza", configElement.selectSingleNode("property[2]/@key").getText());
|
||||||
|
Assert.assertEquals("pale\ncomparison", configElement.selectSingleNode("property[2]/@value").getText());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package org.rundeck.api.generator;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.rundeck.api.domain.RundeckProject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectGeneratorTest is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectGeneratorTest {
|
||||||
|
@Test
|
||||||
|
public void generate() {
|
||||||
|
RundeckProject project = new RundeckProject();
|
||||||
|
project.setName("monkey1");
|
||||||
|
|
||||||
|
Document doc = new ProjectGenerator(project).generateXmlDocument();
|
||||||
|
Assert.assertEquals("project", doc.getRootElement().getName());
|
||||||
|
Assert.assertNotNull(doc.selectSingleNode("/project/name"));
|
||||||
|
Assert.assertEquals("monkey1", doc.selectSingleNode("/project/name").getText());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.rundeck.api.domain.ProjectConfig;
|
||||||
|
import org.rundeck.api.domain.RundeckProject;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectConfigParserTest is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectConfigParserTest {
|
||||||
|
@Test
|
||||||
|
public void parseProject() throws Exception {
|
||||||
|
InputStream input = getClass().getResourceAsStream("projectv11.xml");
|
||||||
|
Document document = ParserHelper.loadDocument(input);
|
||||||
|
|
||||||
|
ProjectConfig config = new ProjectConfigParser("project/config").parseXmlNode(document);
|
||||||
|
|
||||||
|
Assert.assertEquals(10, config.getProperties().size());
|
||||||
|
Assert.assertEquals("ziggy", config.getProperties().get("project.name"));
|
||||||
|
Assert.assertEquals("false", config.getProperties().get("resources.source.1.config.requireFileExists"));
|
||||||
|
Assert.assertEquals("privateKey", config.getProperties().get("project.ssh-authentication"));
|
||||||
|
Assert.assertEquals("jsch-ssh", config.getProperties().get("service.NodeExecutor.default.provider"));
|
||||||
|
Assert.assertEquals("false", config.getProperties().get("resources.source.1.config.includeServerNode"));
|
||||||
|
Assert.assertEquals("false", config.getProperties().get("resources.source.1.config.generateFileAutomatically"));
|
||||||
|
Assert.assertEquals("/var/rundeck/projects/${project.name}/etc/resources.xml",
|
||||||
|
config.getProperties().get("resources.source.1.config.file"));
|
||||||
|
Assert.assertEquals("/var/lib/rundeck/.ssh/id_rsa", config.getProperties().get("project.ssh-keypath"));
|
||||||
|
Assert.assertEquals("jsch-scp", config.getProperties().get("service.FileCopier.default.provider"));
|
||||||
|
Assert.assertEquals("file", config.getProperties().get("resources.source.1.type"));
|
||||||
|
/*
|
||||||
|
<property key='project.name' value='ziggy'/>
|
||||||
|
<property key='resources.source.1.config.requireFileExists' value='false'/>
|
||||||
|
<property key='project.ssh-authentication' value='privateKey'/>
|
||||||
|
<property key='service.NodeExecutor.default.provider' value='jsch-ssh'/>
|
||||||
|
<property key='resources.source.1.config.includeServerNode' value='false'/>
|
||||||
|
<property key='resources.source.1.config.generateFileAutomatically' value='false'/>
|
||||||
|
<property key='resources.source.1.config.file'
|
||||||
|
value='/var/rundeck/projects/${project.name}/etc/resources.xml'/>
|
||||||
|
<property key='project.ssh-keypath' value='/var/lib/rundeck/.ssh/id_rsa'/>
|
||||||
|
<property key='service.FileCopier.default.provider' value='jsch-scp'/>
|
||||||
|
<property key='resources.source.1.type' value='file'/>
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
import org.rundeck.api.domain.ConfigProperty;
|
||||||
|
import org.rundeck.api.domain.ProjectConfig;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-03-07
|
||||||
|
*/
|
||||||
|
public class ProjectConfigPropertyParserTest {
|
||||||
|
@Test
|
||||||
|
public void parseFromProject() throws Exception {
|
||||||
|
InputStream input = getClass().getResourceAsStream("projectv11.xml");
|
||||||
|
Document document = ParserHelper.loadDocument(input);
|
||||||
|
|
||||||
|
ConfigProperty config = new ProjectConfigPropertyParser("project/config/property[1]").parseXmlNode(document);
|
||||||
|
Assert.assertEquals("project.name", config.getKey());
|
||||||
|
Assert.assertEquals("ziggy", config.getValue());
|
||||||
|
/**
|
||||||
|
* <property key='project.name' value='ziggy'/>
|
||||||
|
<property key='resources.source.1.config.requireFileExists' value='false'/>
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void parseProperty() throws Exception {
|
||||||
|
Document document = ParserHelper.loadDocument(new ByteArrayInputStream(("<property key='project.name' " +
|
||||||
|
"value='ABC' />").getBytes()));
|
||||||
|
|
||||||
|
ConfigProperty config = new ProjectConfigPropertyParser("/property").parseXmlNode(document);
|
||||||
|
Assert.assertEquals("project.name", config.getKey());
|
||||||
|
Assert.assertEquals("ABC", config.getValue());
|
||||||
|
/**
|
||||||
|
* <property key='project.name' value='ziggy'/>
|
||||||
|
<property key='resources.source.1.config.requireFileExists' value='false'/>
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.rundeck.api.domain.RundeckProject;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectParserV11Test is ...
|
||||||
|
*
|
||||||
|
* @author greg
|
||||||
|
* @since 2014-02-27
|
||||||
|
*/
|
||||||
|
public class ProjectParserV11Test {
|
||||||
|
@Test
|
||||||
|
public void parseProject() throws Exception {
|
||||||
|
InputStream input = getClass().getResourceAsStream("projectv11.xml");
|
||||||
|
Document document = ParserHelper.loadDocument(input);
|
||||||
|
|
||||||
|
RundeckProject project = new ProjectParserV11("project").parseXmlNode(document);
|
||||||
|
|
||||||
|
Assert.assertEquals("ziggy", project.getName());
|
||||||
|
Assert.assertNull(project.getDescription());
|
||||||
|
Assert.assertNotNull(project.getProjectConfig());
|
||||||
|
}
|
||||||
|
}
|
36
src/test/resources/betamax/tapes/api_token_delete.yaml
Normal file
36
src/test/resources/betamax/tapes/api_token_delete.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
!tape
|
||||||
|
name: api_token_delete
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T18:38:18.432Z
|
||||||
|
request:
|
||||||
|
method: DELETE
|
||||||
|
uri: http://rundeck.local:4440/api/11/token/MiquQjELTrEaugpmdgAKs1W3a7xonAwU
|
||||||
|
headers:
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 204
|
||||||
|
headers:
|
||||||
|
Content-Type: text/html;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=j0fidhqqsmlt1qmvaawr52a42;Path=/
|
||||||
|
- recorded: 2014-04-04T18:38:18.523Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/token/MiquQjELTrEaugpmdgAKs1W3a7xonAwU
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 404
|
||||||
|
headers:
|
||||||
|
Content-Type: text/xml;charset=UTF-8
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
body: "<result error='true' apiversion='11'>\n <error code='api.error.item.doesnotexist'>\n <message>Token does not exist: MiquQjELTrEaugpmdgAKs1W3a7xonAwU</message>\n </error>\n</result>"
|
25
src/test/resources/betamax/tapes/api_token_generate.yaml
Normal file
25
src/test/resources/betamax/tapes/api_token_generate.yaml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
!tape
|
||||||
|
name: api_token_generate
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T18:21:07.759Z
|
||||||
|
request:
|
||||||
|
method: POST
|
||||||
|
uri: http://rundeck.local:4440/api/11/tokens/bob
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Length: '0'
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 201
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=1gt9t2gch2zff1a0werz1us5wk;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PHRva2VuIGlkPSdNaXF1UWpFTFRyRWF1Z3BtZGdBS3MxVzNhN3hvbkF3VScgdXNlcj0nYm9iJyAvPg==
|
24
src/test/resources/betamax/tapes/api_token_get.yaml
Normal file
24
src/test/resources/betamax/tapes/api_token_get.yaml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
!tape
|
||||||
|
name: api_token_get
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T18:23:05.986Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/token/MiquQjELTrEaugpmdgAKs1W3a7xonAwU
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=1tdpszk6b3v191p0ng2u94rohw;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PHRva2VuIGlkPSdNaXF1UWpFTFRyRWF1Z3BtZGdBS3MxVzNhN3hvbkF3VScgdXNlcj0nYm9iJyAvPg==
|
24
src/test/resources/betamax/tapes/api_tokens_list_all.yaml
Normal file
24
src/test/resources/betamax/tapes/api_tokens_list_all.yaml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
!tape
|
||||||
|
name: api_tokens_list_all
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T18:32:37.397Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/tokens
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=ixag173yjktz1c5o9yrbe5z5a;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PHRva2VucyBjb3VudD0nNCcgYWxsdXNlcnM9J3RydWUnPgogIDx0b2tlbiBpZD0nOERwOW9wMTExRVI2b3BzRFJrZGR2RTg2SzlzRTQ5OXMnIHVzZXI9J2FkbWluJyAvPgogIDx0b2tlbiBpZD0naElOcDVlR3p2WUE5VWVQYlVDaGFLSGQ1TmlSa3dXYngnIHVzZXI9J2JvYicgLz4KICA8dG9rZW4gaWQ9J05hTm53VnpBSEFHODNxT1M3V3R3aDZtamNYVml5V1VWJyB1c2VyPSdib2InIC8+CiAgPHRva2VuIGlkPSdNaXF1UWpFTFRyRWF1Z3BtZGdBS3MxVzNhN3hvbkF3VScgdXNlcj0nYm9iJyAvPgo8L3Rva2Vucz4=
|
24
src/test/resources/betamax/tapes/api_tokens_list_user.yaml
Normal file
24
src/test/resources/betamax/tapes/api_tokens_list_user.yaml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
!tape
|
||||||
|
name: api_tokens_list_user
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T18:26:33.394Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/tokens/bob
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=114794elwavo26cx4ugkv7pe7;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PHRva2VucyBjb3VudD0nMycgdXNlcj0nYm9iJz4KICA8dG9rZW4gaWQ9J2hJTnA1ZUd6dllBOVVlUGJVQ2hhS0hkNU5pUmt3V2J4JyB1c2VyPSdib2InIC8+CiAgPHRva2VuIGlkPSdOYU5ud1Z6QUhBRzgzcU9TN1d0d2g2bWpjWFZpeVdVVicgdXNlcj0nYm9iJyAvPgogIDx0b2tlbiBpZD0nTWlxdVFqRUxUckVhdWdwbWRnQUtzMVczYTd4b25Bd1UnIHVzZXI9J2JvYicgLz4KPC90b2tlbnM+
|
26
src/test/resources/betamax/tapes/create_projectv11.yaml
Normal file
26
src/test/resources/betamax/tapes/create_projectv11.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
!tape
|
||||||
|
name: create_projectv11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-02-27T19:45:35.430Z
|
||||||
|
request:
|
||||||
|
method: POST
|
||||||
|
uri: http://rundeck.local:4440/api/11/projects
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Type: application/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
Transfer-Encoding: chunked
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=1h2r5l35j4ynqo19dsm6xa2gv;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PHByb2plY3QgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3Byb2plY3QvbW9ua2V5MSc+CiAgPG5hbWU+bW9ua2V5MTwvbmFtZT4KICA8ZGVzY3JpcHRpb24+PC9kZXNjcmlwdGlvbj4KICA8Y29uZmlnPgogICAgPHByb3BlcnR5IGtleT0ncHJvamVjdC5uYW1lJyB2YWx1ZT0nbW9ua2V5MScgLz4KICAgIDxwcm9wZXJ0eSBrZXk9J3Byb2plY3Quc3NoLWF1dGhlbnRpY2F0aW9uJyB2YWx1ZT0ncHJpdmF0ZUtleScgLz4KICAgIDxwcm9wZXJ0eSBrZXk9J3NlcnZpY2UuTm9kZUV4ZWN1dG9yLmRlZmF1bHQucHJvdmlkZXInIHZhbHVlPSdqc2NoLXNzaCcgLz4KICAgIDxwcm9wZXJ0eSBrZXk9J3Jlc291cmNlcy5zb3VyY2UuMS5jb25maWcuaW5jbHVkZVNlcnZlck5vZGUnIHZhbHVlPSd0cnVlJyAvPgogICAgPHByb3BlcnR5IGtleT0ncmVzb3VyY2VzLnNvdXJjZS4xLmNvbmZpZy5nZW5lcmF0ZUZpbGVBdXRvbWF0aWNhbGx5JyB2YWx1ZT0ndHJ1ZScgLz4KICAgIDxwcm9wZXJ0eSBrZXk9J3Jlc291cmNlcy5zb3VyY2UuMS5jb25maWcuZmlsZScgdmFsdWU9Jy9Vc2Vycy9ncmVnL3J1bmRlY2syZC9wcm9qZWN0cy9tb25rZXkxL2V0Yy9yZXNvdXJjZXMueG1sJyAvPgogICAgPHByb3BlcnR5IGtleT0ncHJvamVjdC5zc2gta2V5cGF0aCcgdmFsdWU9Jy9Vc2Vycy9ncmVnLy5zc2gvaWRfcnNhJyAvPgogICAgPHByb3BlcnR5IGtleT0nc2VydmljZS5GaWxlQ29waWVyLmRlZmF1bHQucHJvdmlkZXInIHZhbHVlPSdqc2NoLXNjcCcgLz4KICAgIDxwcm9wZXJ0eSBrZXk9J3Jlc291cmNlcy5zb3VyY2UuMS50eXBlJyB2YWx1ZT0nZmlsZScgLz4KICA8L2NvbmZpZz4KPC9wcm9qZWN0Pg==
|
|
@ -0,0 +1,57 @@
|
||||||
|
!tape
|
||||||
|
name: delete_project_config_keyedv11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-03-07T19:59:51.228Z
|
||||||
|
request:
|
||||||
|
method: PUT
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/ABC/config/monkey-burrito
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Type: application/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
Transfer-Encoding: chunked
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=bolnwf54stai1bo049hylrsua;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PHByb3BlcnR5IGtleT0nbW9ua2V5LWJ1cnJpdG8nIHZhbHVlPSc3dXAnIC8+
|
||||||
|
- recorded: 2014-03-07T19:59:51.325Z
|
||||||
|
request:
|
||||||
|
method: DELETE
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/ABC/config/monkey-burrito
|
||||||
|
headers:
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 204
|
||||||
|
headers:
|
||||||
|
Content-Type: text/html;charset=UTF-8
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
- recorded: 2014-03-07T19:59:51.402Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/ABC/config/monkey-burrito
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 404
|
||||||
|
headers:
|
||||||
|
Content-Type: text/xml;charset=UTF-8
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
body: "<result error='true' apiversion='11'>\n <error code='api.error.item.doesnotexist'>\n <message>property does not exist: monkey-burrito</message>\n </error>\n</result>"
|
36
src/test/resources/betamax/tapes/delete_projectv11.yaml
Normal file
36
src/test/resources/betamax/tapes/delete_projectv11.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
!tape
|
||||||
|
name: delete_projectv11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-03-07T20:34:06.758Z
|
||||||
|
request:
|
||||||
|
method: DELETE
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/delete_me
|
||||||
|
headers:
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 204
|
||||||
|
headers:
|
||||||
|
Content-Type: text/html;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=17vo5m2nghd0e1dcg0hqsuxklu;Path=/
|
||||||
|
- recorded: 2014-03-07T20:34:06.903Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/delete_me
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 404
|
||||||
|
headers:
|
||||||
|
Content-Type: text/xml;charset=UTF-8
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
body: "<result error='true' apiversion='11'>\n <error code='api.error.item.doesnotexist'>\n <message>project does not exist: delete_me</message>\n </error>\n</result>"
|
23
src/test/resources/betamax/tapes/export_projectv11.yaml
Normal file
23
src/test/resources/betamax/tapes/export_projectv11.yaml
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,22 @@
|
||||||
|
!tape
|
||||||
|
name: get_project_config_keyed_dne_v11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-03-07T20:19:47.533Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/ABC/config/does-not-exist
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 404
|
||||||
|
headers:
|
||||||
|
Content-Type: text/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=2367tnltmmec14cn79ps4fam9;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
body: "<result error='true' apiversion='11'>\n <error code='api.error.item.doesnotexist'>\n <message>property does not exist: does-not-exist</message>\n </error>\n</result>"
|
|
@ -0,0 +1,24 @@
|
||||||
|
!tape
|
||||||
|
name: get_project_config_keyedv11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-03-07T19:50:29.035Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/ABC/config/project.name
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=jgign9nyxeyp4istq65l86lp;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PHByb3BlcnR5IGtleT0ncHJvamVjdC5uYW1lJyB2YWx1ZT0nQUJDJyAvPg==
|
24
src/test/resources/betamax/tapes/get_project_configv11.yaml
Normal file
24
src/test/resources/betamax/tapes/get_project_configv11.yaml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
!tape
|
||||||
|
name: get_project_configv11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-02-27T20:35:47.282Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/monkey1/config
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=bo96n10n268hsd1gi9y67nah;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PGNvbmZpZz4KICA8cHJvcGVydHkga2V5PSdwcm9qZWN0Lm5hbWUnIHZhbHVlPSdtb25rZXkxJyAvPgogIDxwcm9wZXJ0eSBrZXk9J3Byb2plY3Quc3NoLWF1dGhlbnRpY2F0aW9uJyB2YWx1ZT0ncHJpdmF0ZUtleScgLz4KICA8cHJvcGVydHkga2V5PSdzZXJ2aWNlLk5vZGVFeGVjdXRvci5kZWZhdWx0LnByb3ZpZGVyJyB2YWx1ZT0nanNjaC1zc2gnIC8+CiAgPHByb3BlcnR5IGtleT0ncmVzb3VyY2VzLnNvdXJjZS4xLmNvbmZpZy5pbmNsdWRlU2VydmVyTm9kZScgdmFsdWU9J3RydWUnIC8+CiAgPHByb3BlcnR5IGtleT0ncmVzb3VyY2VzLnNvdXJjZS4xLmNvbmZpZy5nZW5lcmF0ZUZpbGVBdXRvbWF0aWNhbGx5JyB2YWx1ZT0ndHJ1ZScgLz4KICA8cHJvcGVydHkga2V5PSdyZXNvdXJjZXMuc291cmNlLjEuY29uZmlnLmZpbGUnIHZhbHVlPScvVXNlcnMvZ3JlZy9ydW5kZWNrMmQvcHJvamVjdHMvbW9ua2V5MS9ldGMvcmVzb3VyY2VzLnhtbCcgLz4KICA8cHJvcGVydHkga2V5PSdwcm9qZWN0LnNzaC1rZXlwYXRoJyB2YWx1ZT0nL1VzZXJzL2dyZWcvLnNzaC9pZF9yc2EnIC8+CiAgPHByb3BlcnR5IGtleT0nc2VydmljZS5GaWxlQ29waWVyLmRlZmF1bHQucHJvdmlkZXInIHZhbHVlPSdqc2NoLXNjcCcgLz4KICA8cHJvcGVydHkga2V5PSdyZXNvdXJjZXMuc291cmNlLjEudHlwZScgdmFsdWU9J2ZpbGUnIC8+CjwvY29uZmlnPg==
|
|
@ -0,0 +1,27 @@
|
||||||
|
!tape
|
||||||
|
name: import_project_failure_v11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-03-10T00:01:12.170Z
|
||||||
|
request:
|
||||||
|
method: PUT
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/DEF1/import?importExecutions=false&jobUuidOption=preserve
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Length: '8705'
|
||||||
|
Content-Type: application/zip
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
body: ''
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=1q6qo7ev7f5uz11hlfd8e0sa82;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PGltcG9ydCBzdGF0dXM9J2ZhaWxlZCc+CiAgPGVycm9ycyBjb3VudD0nMTAnPgogICAgPGVycm9yPkpvYiBhdCBpbmRleCBbMV0gYXQgYXJjaGl2ZSBwYXRoOiBydW5kZWNrLURFRjEvam9icy9qb2ItNmZkMTgwOGMtZWFmYi00OWFjLWFiZjItNGRlN2VjNzU4NzJmLnhtbCBoYWQgZXJyb3JzOiBWYWxpZGF0aW9uIGVycm9yczogQ2Fubm90IGNyZWF0ZSBhIEpvYiB3aXRoIFVVSUQgNmZkMTgwOGMtZWFmYi00OWFjLWFiZjItNGRlN2VjNzU4NzJmOiBhIEpvYiBhbHJlYWR5IGV4aXN0cyB3aXRoIHRoaXMgVVVJRC4gQ2hhbmdlIHRoZSBVVUlEIG9yIGRlbGV0ZSB0aGUgb3RoZXIgSm9iLjwvZXJyb3I+CiAgICA8ZXJyb3I+Sm9iIGF0IGluZGV4IFsxXSBhdCBhcmNoaXZlIHBhdGg6IHJ1bmRlY2stREVGMS9qb2JzL2pvYi0wOTRiMGRjYy1lZDc1LTQxNWYtODQwOS0zMWU2YjIxYjUwMmQueG1sIGhhZCBlcnJvcnM6IFZhbGlkYXRpb24gZXJyb3JzOiBDYW5ub3QgY3JlYXRlIGEgSm9iIHdpdGggVVVJRCAwOTRiMGRjYy1lZDc1LTQxNWYtODQwOS0zMWU2YjIxYjUwMmQ6IGEgSm9iIGFscmVhZHkgZXhpc3RzIHdpdGggdGhpcyBVVUlELiBDaGFuZ2UgdGhlIFVVSUQgb3IgZGVsZXRlIHRoZSBvdGhlciBKb2IuPC9lcnJvcj4KICAgIDxlcnJvcj5Kb2IgYXQgaW5kZXggWzFdIGF0IGFyY2hpdmUgcGF0aDogcnVuZGVjay1ERUYxL2pvYnMvam9iLTJiZTk2NmU3LTQ0MGUtNDg5Ny04YTU5LTZhZDEyNmRmNjAzZS54bWwgaGFkIGVycm9yczogVmFsaWRhdGlvbiBlcnJvcnM6IENhbm5vdCBjcmVhdGUgYSBKb2Igd2l0aCBVVUlEIDJiZTk2NmU3LTQ0MGUtNDg5Ny04YTU5LTZhZDEyNmRmNjAzZTogYSBKb2IgYWxyZWFkeSBleGlzdHMgd2l0aCB0aGlzIFVVSUQuIENoYW5nZSB0aGUgVVVJRCBvciBkZWxldGUgdGhlIG90aGVyIEpvYi48L2Vycm9yPgogICAgPGVycm9yPkpvYiBhdCBpbmRleCBbMV0gYXQgYXJjaGl2ZSBwYXRoOiBydW5kZWNrLURFRjEvam9icy9qb2ItZTZmNjFhZTItYWVlMS00NjEwLTlmZTktOGM2ZGYyY2U4ZGJjLnhtbCBoYWQgZXJyb3JzOiBWYWxpZGF0aW9uIGVycm9yczogQ2Fubm90IGNyZWF0ZSBhIEpvYiB3aXRoIFVVSUQgZTZmNjFhZTItYWVlMS00NjEwLTlmZTktOGM2ZGYyY2U4ZGJjOiBhIEpvYiBhbHJlYWR5IGV4aXN0cyB3aXRoIHRoaXMgVVVJRC4gQ2hhbmdlIHRoZSBVVUlEIG9yIGRlbGV0ZSB0aGUgb3RoZXIgSm9iLjwvZXJyb3I+CiAgICA8ZXJyb3I+Sm9iIGF0IGluZGV4IFsxXSBhdCBhcmNoaXZlIHBhdGg6IHJ1bmRlY2stREVGMS9qb2JzL2pvYi0zZjY4NTNmOC1iNTg5LTRkYTgtYmE3Ni0xNjM2ZWY4MTFjZTYueG1sIGhhZCBlcnJvcnM6IFZhbGlkYXRpb24gZXJyb3JzOiBDYW5ub3QgY3JlYXRlIGEgSm9iIHdpdGggVVVJRCAzZjY4NTNmOC1iNTg5LTRkYTgtYmE3Ni0xNjM2ZWY4MTFjZTY6IGEgSm9iIGFscmVhZHkgZXhpc3RzIHdpdGggdGhpcyBVVUlELiBDaGFuZ2UgdGhlIFVVSUQgb3IgZGVsZXRlIHRoZSBvdGhlciBKb2IuPC9lcnJvcj4KICAgIDxlcnJvcj5Kb2IgYXQgaW5kZXggWzFdIGF0IGFyY2hpdmUgcGF0aDogcnVuZGVjay1ERUYxL2pvYnMvam9iLWFjNzhkZmJiLWE0OWMtNDBhYi1hY2Q5LTk0MDhiZTU2MWU3NC54bWwgaGFkIGVycm9yczogVmFsaWRhdGlvbiBlcnJvcnM6IENhbm5vdCBjcmVhdGUgYSBKb2Igd2l0aCBVVUlEIGFjNzhkZmJiLWE0OWMtNDBhYi1hY2Q5LTk0MDhiZTU2MWU3NDogYSBKb2IgYWxyZWFkeSBleGlzdHMgd2l0aCB0aGlzIFVVSUQuIENoYW5nZSB0aGUgVVVJRCBvciBkZWxldGUgdGhlIG90aGVyIEpvYi48L2Vycm9yPgogICAgPGVycm9yPkpvYiBhdCBpbmRleCBbMV0gYXQgYXJjaGl2ZSBwYXRoOiBydW5kZWNrLURFRjEvam9icy9qb2ItNzU2Yzk5ZjctMDRmYi00MzhjLTg0ZjUtMTcyMmQ5NjdkMWNiLnhtbCBoYWQgZXJyb3JzOiBWYWxpZGF0aW9uIGVycm9yczogQ2Fubm90IGNyZWF0ZSBhIEpvYiB3aXRoIFVVSUQgNzU2Yzk5ZjctMDRmYi00MzhjLTg0ZjUtMTcyMmQ5NjdkMWNiOiBhIEpvYiBhbHJlYWR5IGV4aXN0cyB3aXRoIHRoaXMgVVVJRC4gQ2hhbmdlIHRoZSBVVUlEIG9yIGRlbGV0ZSB0aGUgb3RoZXIgSm9iLjwvZXJyb3I+CiAgICA8ZXJyb3I+Sm9iIGF0IGluZGV4IFsxXSBhdCBhcmNoaXZlIHBhdGg6IHJ1bmRlY2stREVGMS9qb2JzL2pvYi0zYWVjN2RmYi05NTAyLTQ4NzYtODc2My0xYWE3ODhjOGZjOWMueG1sIGhhZCBlcnJvcnM6IFZhbGlkYXRpb24gZXJyb3JzOiBDYW5ub3QgY3JlYXRlIGEgSm9iIHdpdGggVVVJRCAzYWVjN2RmYi05NTAyLTQ4NzYtODc2My0xYWE3ODhjOGZjOWM6IGEgSm9iIGFscmVhZHkgZXhpc3RzIHdpdGggdGhpcyBVVUlELiBDaGFuZ2UgdGhlIFVVSUQgb3IgZGVsZXRlIHRoZSBvdGhlciBKb2IuPC9lcnJvcj4KICAgIDxlcnJvcj5Kb2IgYXQgaW5kZXggWzFdIGF0IGFyY2hpdmUgcGF0aDogcnVuZGVjay1ERUYxL2pvYnMvam9iLTg1OTZjYjljLTY4MzMtNDNmNy1hMGY3LTQ2NjNkZDhhYmMyOS54bWwgaGFkIGVycm9yczogVmFsaWRhdGlvbiBlcnJvcnM6IENhbm5vdCBjcmVhdGUgYSBKb2Igd2l0aCBVVUlEIDg1OTZjYjljLTY4MzMtNDNmNy1hMGY3LTQ2NjNkZDhhYmMyOTogYSBKb2IgYWxyZWFkeSBleGlzdHMgd2l0aCB0aGlzIFVVSUQuIENoYW5nZSB0aGUgVVVJRCBvciBkZWxldGUgdGhlIG90aGVyIEpvYi48L2Vycm9yPgogICAgPGVycm9yPkpvYiBhdCBpbmRleCBbMV0gYXQgYXJjaGl2ZSBwYXRoOiBydW5kZWNrLURFRjEvam9icy9qb2ItZDQwMjNhNzItNTRlMS00MWI1LWI0ZDQtNGRkN2U1ZDRmNWU0LnhtbCBoYWQgZXJyb3JzOiBWYWxpZGF0aW9uIGVycm9yczogQ2Fubm90IGNyZWF0ZSBhIEpvYiB3aXRoIFVVSUQgZDQwMjNhNzItNTRlMS00MWI1LWI0ZDQtNGRkN2U1ZDRmNWU0OiBhIEpvYiBhbHJlYWR5IGV4aXN0cyB3aXRoIHRoaXMgVVVJRC4gQ2hhbmdlIHRoZSBVVUlEIG9yIGRlbGV0ZSB0aGUgb3RoZXIgSm9iLjwvZXJyb3I+CiAgPC9lcnJvcnM+CjwvaW1wb3J0Pg==
|
71
src/test/resources/betamax/tapes/import_project_suv11.yaml
Normal file
71
src/test/resources/betamax/tapes/import_project_suv11.yaml
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
!tape
|
||||||
|
name: import_project_suv11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-03-09T23:57:25.471Z
|
||||||
|
request:
|
||||||
|
method: PUT
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/DEF2/import?importExecutions=true&jobUuidOption=preserve
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Length: '8705'
|
||||||
|
Content-Type: application/zip
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
body: ''
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=10hrj0jebdc621ukdlal6qqyu3;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PGltcG9ydCBzdGF0dXM9J3N1Y2Nlc3NmdWwnIC8+
|
||||||
|
- recorded: 2014-03-09T23:57:26.403Z
|
||||||
|
request:
|
||||||
|
method: PUT
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/DEF2/import?importExecutions=false&jobUuidOption=preserve
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Length: '8705'
|
||||||
|
Content-Type: application/zip
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
body: ''
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PGltcG9ydCBzdGF0dXM9J3N1Y2Nlc3NmdWwnIC8+
|
||||||
|
- recorded: 2014-03-09T23:57:27.155Z
|
||||||
|
request:
|
||||||
|
method: PUT
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/DEF2/import?importExecutions=true&jobUuidOption=remove
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Length: '8705'
|
||||||
|
Content-Type: application/zip
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
body: ''
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PGltcG9ydCBzdGF0dXM9J3N1Y2Nlc3NmdWwnIC8+
|
36
src/test/resources/betamax/tapes/key_delete.yaml
Normal file
36
src/test/resources/betamax/tapes/key_delete.yaml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_delete
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T23:16:02.256Z
|
||||||
|
request:
|
||||||
|
method: DELETE
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example/file2.pub
|
||||||
|
headers:
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 204
|
||||||
|
headers:
|
||||||
|
Content-Type: text/html;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=3rsjs6vicpc619b1uy7oshp4y;Path=/
|
||||||
|
- recorded: 2014-04-04T23:16:02.372Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example/file2.pub
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 404
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=utf-8
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
body: !!binary |-
|
||||||
|
PGVycm9yPnJlc291cmNlIG5vdCBmb3VuZDogL3NzaC1rZXkvdGVzdC9leGFtcGxlL2ZpbGUyLnB1YjwvZXJyb3I+
|
23
src/test/resources/betamax/tapes/key_get_data_private.yaml
Normal file
23
src/test/resources/betamax/tapes/key_get_data_private.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_get_data_private
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T19:50:59.155Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example/file1.pem
|
||||||
|
headers:
|
||||||
|
Accept: application/pgp-keys
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/json;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=1gzu37lkjr0fitxhf5fgkgsfu;Path=/
|
||||||
|
body: !!binary |-
|
||||||
|
eyJwYXRoIjoia2V5cy90ZXN0L2V4YW1wbGUvZmlsZTEucGVtIiwidHlwZSI6ImZpbGUiLCJuYW1lIjoiZmlsZTEucGVtIiwidXJsIjoiaHR0cDovL2RpZ25hbi5sb2NhbDo0NDQwL2FwaS8xMS9zdG9yYWdlL2tleXMvdGVzdC9leGFtcGxlL2ZpbGUxLnBlbSIsIm1ldGEiOnsiUnVuZGVjay1jb250ZW50LXR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJSdW5kZWNrLWNvbnRlbnQtc2l6ZSI6IjUiLCJSdW5kZWNrLWNvbnRlbnQtbWFzayI6ImNvbnRlbnQiLCJSdW5kZWNrLWtleS10eXBlIjoicHJpdmF0ZSJ9fQo=
|
||||||
|
|
22
src/test/resources/betamax/tapes/key_get_data_public.yaml
Normal file
22
src/test/resources/betamax/tapes/key_get_data_public.yaml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_get_data_public
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T20:20:44.331Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example/file2.pub
|
||||||
|
headers:
|
||||||
|
Accept: application/pgp-keys
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/pgp-keys
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=1mrub15qsorpf10cisx24h8h03;Path=/
|
||||||
|
body: !!binary |-
|
||||||
|
dGVzdDE=
|
23
src/test/resources/betamax/tapes/key_get_private.yaml
Normal file
23
src/test/resources/betamax/tapes/key_get_private.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_get_private
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T19:47:29.880Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example/file1.pem
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=utf-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=nc5p0he3nw19e4gegidc4bs7;Path=/
|
||||||
|
body: !!binary |-
|
||||||
|
PHJlc291cmNlIHBhdGg9J2tleXMvdGVzdC9leGFtcGxlL2ZpbGUxLnBlbScgdHlwZT0nZmlsZScgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3N0b3JhZ2Uva2V5cy90ZXN0L2V4YW1wbGUvZmlsZTEucGVtJyBuYW1lPSdmaWxlMS5wZW0nPjxyZXNvdXJjZS1tZXRhPjxSdW5kZWNrLWNvbnRlbnQtdHlwZT5hcHBsaWNhdGlvbi9vY3RldC1zdHJlYW08L1J1bmRlY2stY29udGVudC10eXBlPjxSdW5kZWNrLWNvbnRlbnQtc2l6ZT41PC9SdW5kZWNrLWNvbnRlbnQtc2l6ZT48UnVuZGVjay1jb250ZW50LW1hc2s+Y29udGVudDwvUnVuZGVjay1jb250ZW50LW1hc2s+PFJ1bmRlY2sta2V5LXR5cGU+cHJpdmF0ZTwvUnVuZGVjay1rZXktdHlwZT48L3Jlc291cmNlLW1ldGE+PC9yZXNvdXJjZT4K
|
||||||
|
|
23
src/test/resources/betamax/tapes/key_get_public.yaml
Normal file
23
src/test/resources/betamax/tapes/key_get_public.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_get_public
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T19:47:29.626Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example/file2.pub
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=utf-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=r6p6fl87ftrb1mkwwi0pcak5i;Path=/
|
||||||
|
body: !!binary |-
|
||||||
|
PHJlc291cmNlIHBhdGg9J2tleXMvdGVzdC9leGFtcGxlL2ZpbGUyLnB1YicgdHlwZT0nZmlsZScgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3N0b3JhZ2Uva2V5cy90ZXN0L2V4YW1wbGUvZmlsZTIucHViJyBuYW1lPSdmaWxlMi5wdWInPjxyZXNvdXJjZS1tZXRhPjxSdW5kZWNrLWNvbnRlbnQtdHlwZT5hcHBsaWNhdGlvbi9wZ3Ata2V5czwvUnVuZGVjay1jb250ZW50LXR5cGU+PFJ1bmRlY2stY29udGVudC1zaXplPjU8L1J1bmRlY2stY29udGVudC1zaXplPjxSdW5kZWNrLWtleS10eXBlPnB1YmxpYzwvUnVuZGVjay1rZXktdHlwZT48L3Jlc291cmNlLW1ldGE+PC9yZXNvdXJjZT4N
|
||||||
|
|
21
src/test/resources/betamax/tapes/key_list_directory.yaml
Normal file
21
src/test/resources/betamax/tapes/key_list_directory.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
!tape
|
||||||
|
name: key_list_directory
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T20:33:07.968Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: text/html;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=1stwtoatsosy91ca0gcrzde698;Path=/
|
||||||
|
body: <resource path='keys/test/example' type='directory' url='http://dignan.local:4440/api/11/storage/keys/test/example'><contents count='2'><resource path='keys/test/example/file2.pub' type='file' url='http://dignan.local:4440/api/11/storage/keys/test/example/file2.pub' name='file2.pub'><resource-meta><Rundeck-content-type>application/pgp-keys</Rundeck-content-type><Rundeck-content-size>5</Rundeck-content-size><Rundeck-key-type>public</Rundeck-key-type></resource-meta></resource><resource path='keys/test/example/file1.pem' type='file' url='http://dignan.local:4440/api/11/storage/keys/test/example/file1.pem' name='file1.pem'><resource-meta><Rundeck-content-type>application/octet-stream</Rundeck-content-type><Rundeck-content-size>5</Rundeck-content-size><Rundeck-content-mask>content</Rundeck-content-mask><Rundeck-key-type>private</Rundeck-key-type></resource-meta></resource></contents></resource>
|
21
src/test/resources/betamax/tapes/key_list_root.yaml
Normal file
21
src/test/resources/betamax/tapes/key_list_root.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
!tape
|
||||||
|
name: key_list_root
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T20:41:16.501Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: text/html;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=5sj36vytg4y1182mziim4868b;Path=/
|
||||||
|
body: <resource path='keys' type='directory' url='http://dignan.local:4440/api/11/storage/keys'><contents count='2'><resource path='keys/test1.pem' type='file' url='http://dignan.local:4440/api/11/storage/keys/test1.pem' name='test1.pem'><resource-meta><Rundeck-content-type>application/octet-stream</Rundeck-content-type><Rundeck-content-size>1679</Rundeck-content-size><Rundeck-content-mask>content</Rundeck-content-mask><Rundeck-key-type>private</Rundeck-key-type></resource-meta></resource><resource path='keys/test' type='directory' url='http://dignan.local:4440/api/11/storage/keys/test'></resource></contents></resource>
|
26
src/test/resources/betamax/tapes/key_store_private.yaml
Normal file
26
src/test/resources/betamax/tapes/key_store_private.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_store_private
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T19:30:35.367Z
|
||||||
|
request:
|
||||||
|
method: POST
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example/file1.pem
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Length: '5'
|
||||||
|
Content-Type: application/octet-stream
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
body: ''
|
||||||
|
response:
|
||||||
|
status: 201
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=utf-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=ktmwc4h53xfud6v2ch67x5p9;Path=/
|
||||||
|
body: !!binary |-
|
||||||
|
PHJlc291cmNlIHBhdGg9J2tleXMvdGVzdC9leGFtcGxlL2ZpbGUxLnBlbScgdHlwZT0nZmlsZScgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3N0b3JhZ2Uva2V5cy90ZXN0L2V4YW1wbGUvZmlsZTEucGVtJyBuYW1lPSdmaWxlMS5wZW0nPjxyZXNvdXJjZS1tZXRhPjxSdW5kZWNrLWNvbnRlbnQtdHlwZT5hcHBsaWNhdGlvbi9vY3RldC1zdHJlYW08L1J1bmRlY2stY29udGVudC10eXBlPjxSdW5kZWNrLWNvbnRlbnQtc2l6ZT41PC9SdW5kZWNrLWNvbnRlbnQtc2l6ZT48UnVuZGVjay1jb250ZW50LW1hc2s+Y29udGVudDwvUnVuZGVjay1jb250ZW50LW1hc2s+PFJ1bmRlY2sta2V5LXR5cGU+cHJpdmF0ZTwvUnVuZGVjay1rZXktdHlwZT48L3Jlc291cmNlLW1ldGE+PC9yZXNvdXJjZT4N
|
||||||
|
|
26
src/test/resources/betamax/tapes/key_store_public.yaml
Normal file
26
src/test/resources/betamax/tapes/key_store_public.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_store_public
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T19:34:02.683Z
|
||||||
|
request:
|
||||||
|
method: POST
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/keys/test/example/file2.pub
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Length: '5'
|
||||||
|
Content-Type: application/pgp-keys
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: 8Dp9op111ER6opsDRkddvE86K9sE499s
|
||||||
|
body: ''
|
||||||
|
response:
|
||||||
|
status: 201
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=utf-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=2l3g8m0tvwef19jn2bu23bzk6;Path=/
|
||||||
|
body: !!binary |-
|
||||||
|
PHJlc291cmNlIHBhdGg9J2tleXMvdGVzdC9leGFtcGxlL2ZpbGUyLnB1YicgdHlwZT0nZmlsZScgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3N0b3JhZ2Uva2V5cy90ZXN0L2V4YW1wbGUvZmlsZTIucHViJyBuYW1lPSdmaWxlMi5wdWInPjxyZXNvdXJjZS1tZXRhPjxSdW5kZWNrLWNvbnRlbnQtdHlwZT5hcHBsaWNhdGlvbi9wZ3Ata2V5czwvUnVuZGVjay1jb250ZW50LXR5cGU+PFJ1bmRlY2stY29udGVudC1zaXplPjU8L1J1bmRlY2stY29udGVudC1zaXplPjxSdW5kZWNrLWtleS10eXBlPnB1YmxpYzwvUnVuZGVjay1rZXktdHlwZT48L3Jlc291cmNlLW1ldGE+PC9yZXNvdXJjZT4K
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
!tape
|
||||||
|
name: set_project_config_keyedv11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-03-07T19:59:51.009Z
|
||||||
|
request:
|
||||||
|
method: PUT
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/ABC/config/monkey-burrito
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Type: application/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
Transfer-Encoding: chunked
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=3ssp8chdwsuw16hihk5frgpzy;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PHByb3BlcnR5IGtleT0nbW9ua2V5LWJ1cnJpdG8nIHZhbHVlPSdsZW1vbiBwaWUnIC8+
|
26
src/test/resources/betamax/tapes/set_project_configv11.yaml
Normal file
26
src/test/resources/betamax/tapes/set_project_configv11.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
!tape
|
||||||
|
name: set_project_configv11
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-02-27T21:00:27.197Z
|
||||||
|
request:
|
||||||
|
method: PUT
|
||||||
|
uri: http://rundeck.local:4440/api/11/project/monkey1/config
|
||||||
|
headers:
|
||||||
|
Accept: text/xml
|
||||||
|
Content-Type: application/xml
|
||||||
|
Host: rundeck.local:4440
|
||||||
|
Proxy-Connection: Keep-Alive
|
||||||
|
Transfer-Encoding: chunked
|
||||||
|
User-Agent: RunDeck API Java Client 11
|
||||||
|
X-RunDeck-Auth-Token: Do4d3NUD5DKk21DR4sNK755RcPk618vn
|
||||||
|
response:
|
||||||
|
status: 200
|
||||||
|
headers:
|
||||||
|
Content-Type: application/xml;charset=UTF-8
|
||||||
|
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||||
|
Server: Jetty(7.6.0.v20120127)
|
||||||
|
Set-Cookie: JSESSIONID=19npj7cd0hpm71nfljn7nlbvh8;Path=/
|
||||||
|
X-Rundeck-API-Version: '11'
|
||||||
|
X-Rundeck-API-XML-Response-Wrapper: 'false'
|
||||||
|
body: !!binary |-
|
||||||
|
PGNvbmZpZz4KICA8cHJvcGVydHkga2V5PSdwcm9qZWN0Lm5hbWUnIHZhbHVlPSdtb25rZXkxJyAvPgogIDxwcm9wZXJ0eSBrZXk9J2FscGhhYmV0dHknIHZhbHVlPSdzcGFnaGV0dGknIC8+CiAgPHByb3BlcnR5IGtleT0nYmxoYS5ibGVlJyB2YWx1ZT0nYSBiaWcgYW1hemluZyB0aGluZ3kgc28gdGhlcmUuJyAvPgo8L2NvbmZpZz4=
|
17
src/test/resources/org/rundeck/api/parser/projectv11.xml
Normal file
17
src/test/resources/org/rundeck/api/parser/projectv11.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<project url='http://dignan.local:4440/api/11/project/ziggy'>
|
||||||
|
<name>ziggy</name>
|
||||||
|
<description></description>
|
||||||
|
<config>
|
||||||
|
<property key='project.name' value='ziggy'/>
|
||||||
|
<property key='resources.source.1.config.requireFileExists' value='false'/>
|
||||||
|
<property key='project.ssh-authentication' value='privateKey'/>
|
||||||
|
<property key='service.NodeExecutor.default.provider' value='jsch-ssh'/>
|
||||||
|
<property key='resources.source.1.config.includeServerNode' value='false'/>
|
||||||
|
<property key='resources.source.1.config.generateFileAutomatically' value='false'/>
|
||||||
|
<property key='resources.source.1.config.file'
|
||||||
|
value='/var/rundeck/projects/${project.name}/etc/resources.xml'/>
|
||||||
|
<property key='project.ssh-keypath' value='/var/lib/rundeck/.ssh/id_rsa'/>
|
||||||
|
<property key='service.FileCopier.default.provider' value='jsch-scp'/>
|
||||||
|
<property key='resources.source.1.type' value='file'/>
|
||||||
|
</config>
|
||||||
|
</project>
|
BIN
src/test/resources/org/rundeck/api/test-archive.zip
Normal file
BIN
src/test/resources/org/rundeck/api/test-archive.zip
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue