mirror of
https://github.com/Fishwaldo/rundeck-api-java-client.git
synced 2025-07-06 13:08:38 +00:00
Support keyed config get/set/delete for apiv11
This commit is contained in:
parent
29459d9ee1
commit
f49aa63043
10 changed files with 430 additions and 0 deletions
|
@ -26,6 +26,7 @@ import org.rundeck.api.RundeckApiException.RundeckApiTokenException;
|
|||
import org.rundeck.api.domain.*;
|
||||
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.query.ExecutionQuery;
|
||||
|
@ -380,6 +381,92 @@ public class RundeckClient implements Serializable {
|
|||
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
|
||||
*
|
||||
|
|
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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -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,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;
|
||||
}
|
||||
}
|
|
@ -116,6 +116,35 @@ public class RundeckClientTest {
|
|||
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 = "get_history")
|
||||
public void getHistory() throws Exception {
|
||||
|
|
|
@ -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,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>"
|
|
@ -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==
|
|
@ -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+
|
Loading…
Add table
Add a link
Reference in a new issue