Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use exact job name/group query for job run -j #46

Merged
merged 1 commit into from
Dec 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/main/java/org/rundeck/client/api/RundeckApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ public interface RundeckApi {
Call<List<JobItem>> listJobs(
@Path("project") String project,
@Query("jobFilter") String jobName,
@Query("groupPath") String groupPath
@Query("groupPath") String groupPath,
@Query("jobExactFilter") String jobNameExact,
@Query("groupPathExact") String groupPathExact
);

@Headers("Accept: application/json")
Expand All @@ -52,6 +54,8 @@ Call<ResponseBody> exportJobs(
@Path("project") String project,
@Query("jobFilter") String jobName,
@Query("groupPath") String groupPath,
@Query("jobExactFilter") String jobNameExact,
@Query("groupPathExact") String groupPathExact,
@Query("format") String format
);

Expand Down
15 changes: 13 additions & 2 deletions src/main/java/org/rundeck/client/tool/commands/Jobs.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ public boolean purge(Purge options, CommandOutput output) throws IOException, In
listCall = getClient().getService().listJobs(
projectOrEnv(options),
options.getJob(),
options.getGroup()
options.getGroup(),
options.getJobExact(),
options.getGroupExact()
);
List<JobItem> body = getClient().checkError(listCall);
for (JobItem jobItem : body) {
Expand All @@ -77,6 +79,11 @@ public boolean purge(Purge options, CommandOutput output) throws IOException, In
}
if (!options.isConfirm()) {
//request confirmation
if (null == System.console()) {
output.error("No user interaction available. Use --confirm to confirm purge without user interaction");
output.warning(String.format("Not deleting %d jobs", ids.size()));
return false;
}
String s = System.console().readLine("Really delete %d Jobs? (y/N) ", ids.size());

if (!"y".equals(s)) {
Expand Down Expand Up @@ -172,6 +179,8 @@ public void list(ListOpts options, CommandOutput output) throws IOException, Inp
project,
options.getJob(),
options.getGroup(),
options.getJobExact(),
options.getGroupExact(),
options.getFormat()
);
}
Expand Down Expand Up @@ -206,7 +215,9 @@ public void list(ListOpts options, CommandOutput output) throws IOException, Inp
listCall = getClient().getService().listJobs(
project,
options.getJob(),
options.getGroup()
options.getGroup(),
options.getJobExact(),
options.getGroupExact()
);
}
List<JobItem> body = getClient().checkError(listCall);
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/org/rundeck/client/tool/commands/Run.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ public boolean run(RunBaseOptions options, CommandOutput out) throws IOException
}
String job = options.getJob();
String[] parts = Jobs.splitJobNameParts(job);
Call<List<JobItem>> listCall = getClient().getService().listJobs(projectOrEnv(options), parts[1], parts[0]);
Call<List<JobItem>> listCall = getClient().getService().listJobs(
projectOrEnv(options),
null,
null,
parts[1],
parts[0]
);
List<JobItem> jobItems = getClient().checkError(listCall);
if (jobItems.size() != 1) {
out.error(String.format("Could not find a unique job with name: %s%n", job));
Expand Down
14 changes: 12 additions & 2 deletions src/main/java/org/rundeck/client/tool/options/JobListOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,26 @@
public interface JobListOptions extends JobBaseOptions{


@Option(shortName = "j", longName = "job", description = "Job name")
@Option(shortName = "j", longName = "job", description = "Job name filter")
String getJob();

boolean isJob();

@Option(shortName = "g", longName = "group", description = "Job Group")
@Option(shortName = "g", longName = "group", description = "Job Group filter")
String getGroup();

boolean isGroup();

@Option(shortName = "J", longName = "jobxact", description = "Exact Job name")
String getJobExact();

boolean isJobExact();

@Option(shortName = "G", longName = "groupxact", description = "Exact Job Group")
String getGroupExact();

boolean isGroupExact();

@Option(shortName = "i", longName = "idlist", description = "Comma separated list of Job IDs")
String getIdlist();

Expand Down
141 changes: 141 additions & 0 deletions src/test/groovy/org/rundeck/client/tool/commands/JobsSpec.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package org.rundeck.client.tool.commands

import com.simplifyops.toolbelt.CommandOutput
import okhttp3.MediaType
import okhttp3.ResponseBody
import org.rundeck.client.api.RundeckApi
import org.rundeck.client.api.model.DeleteJobsResult
import org.rundeck.client.api.model.JobItem
import org.rundeck.client.util.Client
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.mock.Calls
import spock.lang.Specification

/**
* @author greg
* @since 12/13/16
*/
class JobsSpec extends Specification {
File tempFile = File.createTempFile('data', 'out')

def setup() {
tempFile = File.createTempFile('data', 'out')
}

def cleanup() {
if (tempFile.exists()) {
tempFile.delete()
}
}

def "job list with input parameters"() {
given:
def api = Mock(RundeckApi)

def opts = Mock(Jobs.ListOpts) {
isJob() >> true
isProject() >> true
getProject() >> 'ProjectName'
getJobExact() >> jobexact
getGroupExact() >> groupexact
getJob() >> job
getGroup() >> group
}
def retrofit = new Retrofit.Builder().baseUrl('http://example.com/fake/').build()
def client = new Client(api, retrofit, 17)
def hasclient = Mock(ApiCommand.HasClient) {
getClient() >> client
}
Jobs jobs = new Jobs(hasclient)
def out = Mock(CommandOutput)
when:
jobs.list(opts, out)

then:
1 * api.listJobs('ProjectName', job, group, jobexact, groupexact) >>
Calls.response([new JobItem(id: 'fakeid')])
0 * api._(*_)

where:
job | group | jobexact | groupexact
'a' | 'b/c' | null | null
null | null | 'a' | 'b/c'
}

def "job list write to file with input parameters"() {
given:
def api = Mock(RundeckApi)
def opts = Mock(Jobs.ListOpts) {
isJob() >> true
isProject() >> true
getProject() >> 'ProjectName'
getJobExact() >> jobexact
getGroupExact() >> groupexact
getJob() >> job
getGroup() >> group
isFile() >> true
getFormat() >> 'xml'
getFile() >> tempFile
}
def retrofit = new Retrofit.Builder().baseUrl('http://example.com/fake/').build()
def client = new Client(api, retrofit, 17)
def hasclient = Mock(ApiCommand.HasClient) {
getClient() >> client
}
Jobs jobs = new Jobs(hasclient)
def out = Mock(CommandOutput)
when:
jobs.list(opts, out)

then:
1 * api.exportJobs('ProjectName', job, group, jobexact, groupexact, 'xml') >>
Calls.response(ResponseBody.create(MediaType.parse('application/xml'), 'abc'))
0 * api._(*_)
tempFile.exists()
tempFile.text == 'abc'

where:
job | group | jobexact | groupexact
'a' | 'b/c' | null | null
null | null | 'a' | 'b/c'
}


def "job purge with input parameters"() {
given:
def api = Mock(RundeckApi)

def opts = Mock(Jobs.Purge) {
isJob() >> true
isProject() >> true
getProject() >> 'ProjectName'
getJobExact() >> jobexact
getGroupExact() >> groupexact
getJob() >> job
getGroup() >> group
isConfirm() >> true
}
def retrofit = new Retrofit.Builder().baseUrl('http://example.com/fake/').build()
def client = new Client(api, retrofit, 17)
def hasclient = Mock(ApiCommand.HasClient) {
getClient() >> client
}
Jobs jobs = new Jobs(hasclient)
def out = Mock(CommandOutput)
when:
def result = jobs.purge(opts, out)

then:
1 * api.listJobs('ProjectName', job, group, jobexact, groupexact) >>
Calls.response([new JobItem(id: 'fakeid')])
1 * api.deleteJobs(['fakeid']) >> Calls.response(new DeleteJobsResult(allsuccessful: true))
0 * api._(*_)
result

where:
job | group | jobexact | groupexact
'a' | 'b/c' | null | null
null | null | 'a' | 'b/c'
}
}
47 changes: 47 additions & 0 deletions src/test/groovy/org/rundeck/client/tool/commands/RunSpec.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.rundeck.client.tool.commands

import com.simplifyops.toolbelt.CommandOutput
import org.rundeck.client.api.RundeckApi
import org.rundeck.client.api.model.Execution
import org.rundeck.client.api.model.JobItem
import org.rundeck.client.tool.options.RunBaseOptions
import org.rundeck.client.util.Client
import retrofit2.Retrofit
import retrofit2.mock.Calls
import spock.lang.Specification

/**
* @author greg
* @since 12/13/16
*/
class RunSpec extends Specification {
def "run command -j queries for exact job name and group"() {

given:
def api = Mock(RundeckApi)

def opts = Mock(RunBaseOptions) {
isJob() >> true
isProject() >> true
getProject() >> 'ProjectName'
getJob() >> 'a group/path/a job'
}
def retrofit = new Retrofit.Builder().baseUrl('http://example.com/fake/').build()
def client = new Client(api, retrofit, 17)
def hasclient = Mock(ApiCommand.HasClient) {
getClient() >> client
}
Run run = new Run(hasclient)
def out = Mock(CommandOutput)
when:
def result = run.run(opts, out)

then:
1 * api.listJobs('ProjectName', null, null, 'a job', 'a group/path') >>
Calls.response([new JobItem(id: 'fakeid')])
1 * api.runJob('fakeid', null, null, null, null) >> Calls.response(new Execution(id: 123, description: ''))
0 * api._(*_)
result

}
}