mirror of
https://github.com/Fishwaldo/rundeck-api-java-client.git
synced 2025-07-06 04:58:26 +00:00
Add support for SSH key management (api v11)
This commit is contained in:
parent
c7153a5613
commit
459b498d35
21 changed files with 1002 additions and 6 deletions
|
@ -387,10 +387,14 @@ class ApiCall {
|
||||||
if (null != apiPath.getAccept()) {
|
if (null != apiPath.getAccept()) {
|
||||||
request.setHeader("Accept", apiPath.getAccept());
|
request.setHeader("Accept", apiPath.getAccept());
|
||||||
}
|
}
|
||||||
WriteOutHandler handler = new WriteOutHandler(outputStream);
|
final WriteOutHandler writeOutHandler = new WriteOutHandler(outputStream);
|
||||||
int wrote = execute(request, handler);
|
Handler<HttpResponse,Integer> handler = writeOutHandler;
|
||||||
if(handler.thrown!=null){
|
if(null!=apiPath.getRequiredContentType()){
|
||||||
throw handler.thrown;
|
handler = new RequireContentTypeHandler<Integer>(apiPath.getRequiredContentType(), handler);
|
||||||
|
}
|
||||||
|
final int wrote = execute(request, handler);
|
||||||
|
if(writeOutHandler.thrown!=null){
|
||||||
|
throw writeOutHandler.thrown;
|
||||||
}
|
}
|
||||||
return wrote;
|
return wrote;
|
||||||
}
|
}
|
||||||
|
@ -435,6 +439,51 @@ class ApiCall {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Handles writing response to an output stream
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -50,6 +50,7 @@ class ApiPathBuilder {
|
||||||
private InputStream contentStream;
|
private InputStream contentStream;
|
||||||
private File contentFile;
|
private File contentFile;
|
||||||
private String contentType;
|
private String contentType;
|
||||||
|
private String requiredContentType;
|
||||||
private boolean emptyContent = false;
|
private boolean emptyContent = false;
|
||||||
|
|
||||||
/** Marker for using the right separator between parameters ("?" or "&") */
|
/** Marker for using the right separator between parameters ("?" or "&") */
|
||||||
|
@ -416,6 +417,16 @@ class ApiPathBuilder {
|
||||||
public boolean isEmptyContent() {
|
public boolean isEmptyContent() {
|
||||||
return emptyContent;
|
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}
|
||||||
*
|
*
|
||||||
|
|
|
@ -105,4 +105,42 @@ public class RundeckApiException extends RuntimeException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,6 @@ 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.dom4j.Document;
|
||||||
import org.dom4j.DocumentFactory;
|
|
||||||
import org.dom4j.Element;
|
|
||||||
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.*;
|
||||||
|
@ -83,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 SSH_KEY_PATH = "ssh-key/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supported version numbers
|
* Supported version numbers
|
||||||
|
@ -2374,6 +2374,139 @@ public class RundeckClient implements Serializable {
|
||||||
return new ApiCall(this).get(new ApiPathBuilder("/token/", token), new RundeckTokenParser("/token"));
|
return new ApiCall(this).get(new ApiPathBuilder("/token/", token), new RundeckTokenParser("/token"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store an SSH key file
|
||||||
|
* @param path ssh key storage path, must start with "ssh-key/"
|
||||||
|
* @param keyfile key file
|
||||||
|
* @param privateKey true to store private key, false to store public key
|
||||||
|
* @return the SSH key resource
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public SSHKeyResource storeSshKey(final String path, final File keyfile, boolean privateKey) throws RundeckApiException{
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to store an SSH key.");
|
||||||
|
AssertUtil.notNull(keyfile, "keyfile is mandatory to store an SSH key.");
|
||||||
|
if (!path.startsWith(SSH_KEY_PATH)) {
|
||||||
|
throw new IllegalArgumentException("SSH key storage path must start with: " + SSH_KEY_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 SSH key file
|
||||||
|
*
|
||||||
|
* @param path ssh key storage path, must start with "ssh-key/"
|
||||||
|
*
|
||||||
|
* @return the ssh key resource
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException if there is an error, or if the path is a directory not a file
|
||||||
|
*/
|
||||||
|
public SSHKeyResource getSshKey(final String path) throws RundeckApiException {
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to get an SSH key.");
|
||||||
|
if (!path.startsWith(SSH_KEY_PATH)) {
|
||||||
|
throw new IllegalArgumentException("SSH key storage path must start with: " + SSH_KEY_PATH);
|
||||||
|
}
|
||||||
|
SSHKeyResource storageResource = new ApiCall(this).get(
|
||||||
|
new ApiPathBuilder(STORAGE_ROOT_PATH, path),
|
||||||
|
new SSHKeyResourceParser("/resource")
|
||||||
|
);
|
||||||
|
if (storageResource.isDirectory()) {
|
||||||
|
throw new RundeckApiException("SSH Key Path is a directory: " + path);
|
||||||
|
}
|
||||||
|
return storageResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get content for a public SSH key file
|
||||||
|
* @param path ssh key storage path, must start with "ssh-key/"
|
||||||
|
* @param out outputstream to write data to
|
||||||
|
*
|
||||||
|
* @return length of written data
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public int getPublicSshKeyContent(final String path, final OutputStream out) throws
|
||||||
|
RundeckApiException, IOException {
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to get an SSH key.");
|
||||||
|
if (!path.startsWith(SSH_KEY_PATH)) {
|
||||||
|
throw new IllegalArgumentException("SSH key storage path must start with: " + SSH_KEY_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 SSH Key path was not a Public key: " + path, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get content for a public SSH key file
|
||||||
|
* @param path ssh key storage path, must start with "ssh-key/"
|
||||||
|
* @param out file to write data to
|
||||||
|
* @return length of written data
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public int getPublicSshKeyContent(final String path, final File out) throws
|
||||||
|
RundeckApiException, IOException {
|
||||||
|
final FileOutputStream fileOutputStream = new FileOutputStream(out);
|
||||||
|
try {
|
||||||
|
return getPublicSshKeyContent(path, fileOutputStream);
|
||||||
|
}finally {
|
||||||
|
fileOutputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List contents of root SSH key directory
|
||||||
|
*
|
||||||
|
* @return list of SSH key resources
|
||||||
|
* @throws RundeckApiException
|
||||||
|
*/
|
||||||
|
public List<SSHKeyResource> listSshKeyDirectoryRoot() throws RundeckApiException {
|
||||||
|
return listSshKeyDirectory(SSH_KEY_PATH);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* List contents of SSH key directory
|
||||||
|
*
|
||||||
|
* @param path ssh key storage path, must start with "ssh-key/"
|
||||||
|
*
|
||||||
|
* @throws RundeckApiException if there is an error, or if the path is a file not a directory
|
||||||
|
*/
|
||||||
|
public List<SSHKeyResource> listSshKeyDirectory(final String path) throws RundeckApiException {
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to get an SSH key.");
|
||||||
|
if (!path.startsWith(SSH_KEY_PATH)) {
|
||||||
|
throw new IllegalArgumentException("SSH key storage path must start with: " + SSH_KEY_PATH);
|
||||||
|
}
|
||||||
|
SSHKeyResource storageResource = new ApiCall(this).get(
|
||||||
|
new ApiPathBuilder(STORAGE_ROOT_PATH, path),
|
||||||
|
new SSHKeyResourceParser("/resource")
|
||||||
|
);
|
||||||
|
if(!storageResource.isDirectory()) {
|
||||||
|
throw new RundeckApiException("SSH key path is not a directory path: " + path);
|
||||||
|
}
|
||||||
|
return storageResource.getDirectoryContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an SSH key file
|
||||||
|
* @param path a path to a SSH key file, must start with "ssh-key/"
|
||||||
|
*/
|
||||||
|
public void deleteSshKey(final String path){
|
||||||
|
AssertUtil.notNull(path, "path is mandatory to delete an SSH key.");
|
||||||
|
if (!path.startsWith(SSH_KEY_PATH)) {
|
||||||
|
throw new IllegalArgumentException("SSH key storage path must start with: " + SSH_KEY_PATH);
|
||||||
|
}
|
||||||
|
new ApiCall(this).delete(new ApiPathBuilder(STORAGE_ROOT_PATH, path));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the URL of the RunDeck instance ("http://localhost:4440", "http://rundeck.your-compagny.com/", etc)
|
* @return the URL of the RunDeck instance ("http://localhost:4440", "http://rundeck.your-compagny.com/", etc)
|
||||||
*/
|
*/
|
||||||
|
|
61
src/main/java/org/rundeck/api/domain/BaseSSHKeyResource.java
Normal file
61
src/main/java/org/rundeck/api/domain/BaseSSHKeyResource.java
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import org.rundeck.api.RundeckClient;
|
||||||
|
import org.rundeck.api.parser.StorageResourceParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseSSHKeyResource is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public class BaseSSHKeyResource extends BaseStorageResource implements SSHKeyResource {
|
||||||
|
private boolean privateKey;
|
||||||
|
|
||||||
|
public BaseSSHKeyResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivateKey(boolean privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<SSHKeyResource> sshKeyResources = new ArrayList<SSHKeyResource>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDirectoryContents(List<? extends StorageResource> directoryContents) {
|
||||||
|
for (StorageResource directoryContent : directoryContents) {
|
||||||
|
sshKeyResources.add(from(directoryContent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SSHKeyResource> getDirectoryContents() {
|
||||||
|
return sshKeyResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseSSHKeyResource from(final StorageResource source) {
|
||||||
|
final BaseSSHKeyResource baseSshKeyResource = new BaseSSHKeyResource();
|
||||||
|
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-ssh-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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
23
src/main/java/org/rundeck/api/domain/SSHKeyResource.java
Normal file
23
src/main/java/org/rundeck/api/domain/SSHKeyResource.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package org.rundeck.api.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSHKeyResource represents a directory or an SSH key file
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public interface SSHKeyResource 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<SSHKeyResource> getDirectoryContents();
|
||||||
|
}
|
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();
|
||||||
|
}
|
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,26 @@
|
||||||
|
package org.rundeck.api.parser;
|
||||||
|
|
||||||
|
import org.dom4j.Node;
|
||||||
|
import org.rundeck.api.RundeckClient;
|
||||||
|
import org.rundeck.api.domain.BaseSSHKeyResource;
|
||||||
|
import org.rundeck.api.domain.SSHKeyResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSHKeyResourceParser is ...
|
||||||
|
*
|
||||||
|
* @author Greg Schueler <greg@simplifyops.com>
|
||||||
|
* @since 2014-04-04
|
||||||
|
*/
|
||||||
|
public class SSHKeyResourceParser extends BaseXpathParser<SSHKeyResource> implements XmlNodeParser<SSHKeyResource> {
|
||||||
|
public SSHKeyResourceParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SSHKeyResourceParser(String xpath) {
|
||||||
|
super(xpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SSHKeyResource parse(Node node) {
|
||||||
|
return BaseSSHKeyResource.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1280,6 +1280,215 @@ public class RundeckClientTest {
|
||||||
Assert.assertEquals(404, e.getStatusCode());
|
Assert.assertEquals(404, e.getStatusCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Store ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_store_private", mode = TapeMode.READ_ONLY)
|
||||||
|
public void storeSshKey_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();
|
||||||
|
}
|
||||||
|
SSHKeyResource storageResource = client.storeSshKey("ssh-key/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("ssh-key/test/example/file1.pem", storageResource.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Store ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_store_public", mode = TapeMode.READ_ONLY)
|
||||||
|
public void storeSshKey_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();
|
||||||
|
}
|
||||||
|
SSHKeyResource storageResource = client.storeSshKey("ssh-key/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("ssh-key/test/example/file2.pub", storageResource.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_get_public", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getSshKey_public() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
SSHKeyResource storageResource = client.getSshKey("ssh-key/test/example/file2.pub");
|
||||||
|
Assert.assertNotNull(storageResource);
|
||||||
|
Assert.assertFalse(storageResource.isDirectory());
|
||||||
|
Assert.assertFalse(storageResource.isPrivateKey());
|
||||||
|
Assert.assertEquals("file2.pub", storageResource.getName());
|
||||||
|
Assert.assertEquals("ssh-key/test/example/file2.pub", storageResource.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_get_private", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getSshKey_private() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
SSHKeyResource storageResource = client.getSshKey("ssh-key/test/example/file1.pem");
|
||||||
|
Assert.assertNotNull(storageResource);
|
||||||
|
Assert.assertFalse(storageResource.isDirectory());
|
||||||
|
Assert.assertTrue(storageResource.isPrivateKey());
|
||||||
|
Assert.assertEquals("file1.pem", storageResource.getName());
|
||||||
|
Assert.assertEquals("ssh-key/test/example/file1.pem", storageResource.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get ssh key data
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_get_data_private", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getSshKeyData_private() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
File temp = File.createTempFile("test-key", ".tmp");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
try {
|
||||||
|
int data = client.getPublicSshKeyContent("ssh-key/test/example/file1.pem", temp);
|
||||||
|
Assert.fail("expected failure");
|
||||||
|
} catch (RundeckApiException e) {
|
||||||
|
Assert.assertEquals("Requested SSH Key path was not a Public key: ssh-key/test/example/file1.pem",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get ssh key data
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_get_data_public", mode = TapeMode.READ_ONLY)
|
||||||
|
public void getSshKeyData_public() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
File temp = File.createTempFile("test-key", ".tmp");
|
||||||
|
temp.deleteOnExit();
|
||||||
|
int length = client.getPublicSshKeyContent("ssh-key/test/example/file2.pub", temp);
|
||||||
|
Assert.assertEquals(5, length);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* list directory
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_list_directory", mode = TapeMode.READ_ONLY)
|
||||||
|
public void listSshKeyDirectory() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
List<SSHKeyResource> list = client.listSshKeyDirectory("ssh-key/test/example");
|
||||||
|
Assert.assertEquals(2, list.size());
|
||||||
|
SSHKeyResource storageResource1 = list.get(0);
|
||||||
|
SSHKeyResource storageResource2 = list.get(1);
|
||||||
|
|
||||||
|
Assert.assertFalse(storageResource2.isDirectory());
|
||||||
|
Assert.assertTrue(storageResource2.isPrivateKey());
|
||||||
|
Assert.assertEquals("file1.pem", storageResource2.getName());
|
||||||
|
Assert.assertEquals("ssh-key/test/example/file1.pem", storageResource2.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type"));
|
||||||
|
|
||||||
|
Assert.assertFalse(storageResource1.isDirectory());
|
||||||
|
Assert.assertFalse(storageResource1.isPrivateKey());
|
||||||
|
Assert.assertEquals("file2.pub", storageResource1.getName());
|
||||||
|
Assert.assertEquals("ssh-key/test/example/file2.pub", storageResource1.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type"));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* list root
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_list_root", mode = TapeMode.READ_ONLY)
|
||||||
|
public void listSshKeyDirectoryRoot() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
List<SSHKeyResource> list = client.listSshKeyDirectoryRoot();
|
||||||
|
Assert.assertEquals(2, list.size());
|
||||||
|
SSHKeyResource storageResource0 = list.get(0);
|
||||||
|
SSHKeyResource storageResource1 = list.get(1);
|
||||||
|
|
||||||
|
Assert.assertFalse(storageResource0.isDirectory());
|
||||||
|
Assert.assertTrue(storageResource0.isPrivateKey());
|
||||||
|
Assert.assertEquals("test1.pem", storageResource0.getName());
|
||||||
|
Assert.assertEquals("ssh-key/test1.pem", storageResource0.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type"));
|
||||||
|
|
||||||
|
Assert.assertTrue(storageResource1.toString(), storageResource1.isDirectory());
|
||||||
|
Assert.assertEquals(null, storageResource1.getName());
|
||||||
|
Assert.assertEquals("ssh-key/test", storageResource1.getPath());
|
||||||
|
Assert.assertEquals("http://dignan.local:4440/api/11/storage/ssh-key/test",
|
||||||
|
storageResource1.getUrl());
|
||||||
|
Assert.assertNull(storageResource1.getMetadata());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete ssh key
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Betamax(tape = "ssh_key_delete", mode = TapeMode.READ_ONLY)
|
||||||
|
public void deleteSshKey() throws Exception {
|
||||||
|
final RundeckClient client = createClient(TEST_TOKEN_7, 11);
|
||||||
|
client.deleteSshKey("ssh-key/test/example/file2.pub");
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.getSshKey("ssh-key/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 {
|
||||||
|
|
36
src/test/resources/betamax/tapes/ssh_key_delete.yaml
Normal file
36
src/test/resources/betamax/tapes/ssh_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/ssh-key/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/ssh-key/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+
|
|
@ -0,0 +1,22 @@
|
||||||
|
!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/ssh-key/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 |-
|
||||||
|
eyJwYXRoIjoic3NoLWtleS90ZXN0L2V4YW1wbGUvZmlsZTEucGVtIiwidHlwZSI6ImZpbGUiLCJuYW1lIjoiZmlsZTEucGVtIiwidXJsIjoiaHR0cDovL2RpZ25hbi5sb2NhbDo0NDQwL2FwaS8xMS9zdG9yYWdlL3NzaC1rZXkvdGVzdC9leGFtcGxlL2ZpbGUxLnBlbSIsIm1ldGEiOnsiUnVuZGVjay1jb250ZW50LXR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJSdW5kZWNrLWNvbnRlbnQtc2l6ZSI6IjUiLCJSdW5kZWNrLWNvbnRlbnQtbWFzayI6ImNvbnRlbnQiLCJSdW5kZWNrLXNzaC1rZXktdHlwZSI6InByaXZhdGUifX0=
|
|
@ -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/ssh-key/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=
|
22
src/test/resources/betamax/tapes/ssh_key_get_private.yaml
Normal file
22
src/test/resources/betamax/tapes/ssh_key_get_private.yaml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
!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/ssh-key/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 |-
|
||||||
|
PHJlc291cmNlIHBhdGg9J3NzaC1rZXkvdGVzdC9leGFtcGxlL2ZpbGUxLnBlbScgdHlwZT0nZmlsZScgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3N0b3JhZ2Uvc3NoLWtleS90ZXN0L2V4YW1wbGUvZmlsZTEucGVtJyBuYW1lPSdmaWxlMS5wZW0nPjxyZXNvdXJjZS1tZXRhPjxSdW5kZWNrLWNvbnRlbnQtdHlwZT5hcHBsaWNhdGlvbi9vY3RldC1zdHJlYW08L1J1bmRlY2stY29udGVudC10eXBlPjxSdW5kZWNrLWNvbnRlbnQtc2l6ZT41PC9SdW5kZWNrLWNvbnRlbnQtc2l6ZT48UnVuZGVjay1jb250ZW50LW1hc2s+Y29udGVudDwvUnVuZGVjay1jb250ZW50LW1hc2s+PFJ1bmRlY2stc3NoLWtleS10eXBlPnByaXZhdGU8L1J1bmRlY2stc3NoLWtleS10eXBlPjwvcmVzb3VyY2UtbWV0YT48L3Jlc291cmNlPg==
|
22
src/test/resources/betamax/tapes/ssh_key_get_public.yaml
Normal file
22
src/test/resources/betamax/tapes/ssh_key_get_public.yaml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
!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/ssh-key/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 |-
|
||||||
|
PHJlc291cmNlIHBhdGg9J3NzaC1rZXkvdGVzdC9leGFtcGxlL2ZpbGUyLnB1YicgdHlwZT0nZmlsZScgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3N0b3JhZ2Uvc3NoLWtleS90ZXN0L2V4YW1wbGUvZmlsZTIucHViJyBuYW1lPSdmaWxlMi5wdWInPjxyZXNvdXJjZS1tZXRhPjxSdW5kZWNrLWNvbnRlbnQtdHlwZT5hcHBsaWNhdGlvbi9wZ3Ata2V5czwvUnVuZGVjay1jb250ZW50LXR5cGU+PFJ1bmRlY2stY29udGVudC1zaXplPjU8L1J1bmRlY2stY29udGVudC1zaXplPjxSdW5kZWNrLXNzaC1rZXktdHlwZT5wdWJsaWM8L1J1bmRlY2stc3NoLWtleS10eXBlPjwvcmVzb3VyY2UtbWV0YT48L3Jlc291cmNlPg==
|
21
src/test/resources/betamax/tapes/ssh_key_list_directory.yaml
Normal file
21
src/test/resources/betamax/tapes/ssh_key_list_directory.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_list_directory
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T20:33:07.968Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/ssh-key/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='ssh-key/test/example' type='directory' url='http://dignan.local:4440/api/11/storage/ssh-key/test/example'><contents count='2'><resource path='ssh-key/test/example/file2.pub' type='file' url='http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type>public</Rundeck-ssh-key-type></resource-meta></resource><resource path='ssh-key/test/example/file1.pem' type='file' url='http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type>private</Rundeck-ssh-key-type></resource-meta></resource></contents></resource>
|
21
src/test/resources/betamax/tapes/ssh_key_list_root.yaml
Normal file
21
src/test/resources/betamax/tapes/ssh_key_list_root.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
!tape
|
||||||
|
name: ssh_key_list_root
|
||||||
|
interactions:
|
||||||
|
- recorded: 2014-04-04T20:41:16.501Z
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
uri: http://rundeck.local:4440/api/11/storage/ssh-key/
|
||||||
|
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='ssh-key' type='directory' url='http://dignan.local:4440/api/11/storage/ssh-key'><contents count='2'><resource path='ssh-key/test1.pem' type='file' url='http://dignan.local:4440/api/11/storage/ssh-key/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-ssh-key-type>private</Rundeck-ssh-key-type></resource-meta></resource><resource path='ssh-key/test' type='directory' url='http://dignan.local:4440/api/11/storage/ssh-key/test'></resource></contents></resource>
|
25
src/test/resources/betamax/tapes/ssh_key_store_private.yaml
Normal file
25
src/test/resources/betamax/tapes/ssh_key_store_private.yaml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
!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/ssh-key/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 |-
|
||||||
|
PHJlc291cmNlIHBhdGg9J3NzaC1rZXkvdGVzdC9leGFtcGxlL2ZpbGUxLnBlbScgdHlwZT0nZmlsZScgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3N0b3JhZ2Uvc3NoLWtleS90ZXN0L2V4YW1wbGUvZmlsZTEucGVtJyBuYW1lPSdmaWxlMS5wZW0nPjxyZXNvdXJjZS1tZXRhPjxSdW5kZWNrLWNvbnRlbnQtdHlwZT5hcHBsaWNhdGlvbi9vY3RldC1zdHJlYW08L1J1bmRlY2stY29udGVudC10eXBlPjxSdW5kZWNrLWNvbnRlbnQtc2l6ZT41PC9SdW5kZWNrLWNvbnRlbnQtc2l6ZT48UnVuZGVjay1jb250ZW50LW1hc2s+Y29udGVudDwvUnVuZGVjay1jb250ZW50LW1hc2s+PFJ1bmRlY2stc3NoLWtleS10eXBlPnByaXZhdGU8L1J1bmRlY2stc3NoLWtleS10eXBlPjwvcmVzb3VyY2UtbWV0YT48L3Jlc291cmNlPg==
|
25
src/test/resources/betamax/tapes/ssh_key_store_public.yaml
Normal file
25
src/test/resources/betamax/tapes/ssh_key_store_public.yaml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
!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/ssh-key/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 |-
|
||||||
|
PHJlc291cmNlIHBhdGg9J3NzaC1rZXkvdGVzdC9leGFtcGxlL2ZpbGUyLnB1YicgdHlwZT0nZmlsZScgdXJsPSdodHRwOi8vZGlnbmFuLmxvY2FsOjQ0NDAvYXBpLzExL3N0b3JhZ2Uvc3NoLWtleS90ZXN0L2V4YW1wbGUvZmlsZTIucHViJyBuYW1lPSdmaWxlMi5wdWInPjxyZXNvdXJjZS1tZXRhPjxSdW5kZWNrLWNvbnRlbnQtdHlwZT5hcHBsaWNhdGlvbi9wZ3Ata2V5czwvUnVuZGVjay1jb250ZW50LXR5cGU+PFJ1bmRlY2stY29udGVudC1zaXplPjU8L1J1bmRlY2stY29udGVudC1zaXplPjxSdW5kZWNrLXNzaC1rZXktdHlwZT5wdWJsaWM8L1J1bmRlY2stc3NoLWtleS10eXBlPjwvcmVzb3VyY2UtbWV0YT48L3Jlc291cmNlPg==
|
Loading…
Add table
Add a link
Reference in a new issue