1 /* 2 * Copyright 2011 Vincent Behar 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.rundeck.api; 17 18 import java.io.File; 19 import java.io.FileInputStream; 20 import java.io.IOException; 21 import java.io.InputStream; 22 import java.io.Serializable; 23 import java.util.ArrayList; 24 import java.util.Date; 25 import java.util.List; 26 import java.util.Properties; 27 import java.util.concurrent.TimeUnit; 28 import org.apache.commons.io.FileUtils; 29 import org.apache.commons.io.IOUtils; 30 import org.apache.commons.lang.StringUtils; 31 import org.rundeck.api.RundeckApiException.RundeckApiLoginException; 32 import org.rundeck.api.RundeckApiException.RundeckApiTokenException; 33 import org.rundeck.api.domain.RundeckAbort; 34 import org.rundeck.api.domain.RundeckExecution; 35 import org.rundeck.api.domain.RundeckHistory; 36 import org.rundeck.api.domain.RundeckJob; 37 import org.rundeck.api.domain.RundeckJobsImportMethod; 38 import org.rundeck.api.domain.RundeckJobsImportResult; 39 import org.rundeck.api.domain.RundeckNode; 40 import org.rundeck.api.domain.RundeckProject; 41 import org.rundeck.api.domain.RundeckSystemInfo; 42 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; 43 import org.rundeck.api.parser.AbortParser; 44 import org.rundeck.api.parser.ExecutionParser; 45 import org.rundeck.api.parser.HistoryParser; 46 import org.rundeck.api.parser.JobParser; 47 import org.rundeck.api.parser.JobsImportResultParser; 48 import org.rundeck.api.parser.ListParser; 49 import org.rundeck.api.parser.NodeParser; 50 import org.rundeck.api.parser.ProjectParser; 51 import org.rundeck.api.parser.StringParser; 52 import org.rundeck.api.parser.SystemInfoParser; 53 import org.rundeck.api.util.AssertUtil; 54 import org.rundeck.api.util.ParametersUtil; 55 56 /** 57 * Main entry point to talk to a RunDeck instance.<br> 58 * You have 2 methods for authentication : login-based or token-based. If you want to use the first, you need to provide 59 * both a "login" and a "password". Otherwise, just provide a "token" (also called "auth-token"). See the RunDeck 60 * documentation for generating such a token.<br> 61 * <br> 62 * Usage : <br> 63 * <code> 64 * <pre> 65 * // using login-based authentication : 66 * RundeckClient rundeck = new RundeckClient("http://localhost:4440", "admin", "admin"); 67 * // or for a token-based authentication : 68 * RundeckClient rundeck = new RundeckClient("http://localhost:4440", "PDDNKo5VE29kpk4prOUDr2rsKdRkEvsD"); 69 * 70 * List<RundeckProject> projects = rundeck.getProjects(); 71 * 72 * RundeckJob job = rundeck.findJob("my-project", "main-group/sub-group", "job-name"); 73 * RundeckExecution execution = rundeck.triggerJob(job.getId(), 74 * new OptionsBuilder().addOption("version", "1.2.0").toProperties()); 75 * 76 * List<RundeckExecution> runningExecutions = rundeck.getRunningExecutions("my-project"); 77 * 78 * rundeck.exportJobsToFile("/tmp/jobs.xml", FileType.XML, "my-project"); 79 * rundeck.importJobs("/tmp/jobs.xml", FileType.XML); 80 * </pre> 81 * </code> 82 * 83 * @author Vincent Behar 84 */ 85 public class RundeckClient implements Serializable { 86 87 private static final long serialVersionUID = 1L; 88 89 /** Version of the API supported */ 90 public static final transient int API_VERSION = 2; 91 92 /** End-point of the API */ 93 public static final transient String API_ENDPOINT = "/api/" + API_VERSION; 94 95 /** Default value for the "pooling interval" used when running jobs/commands/scripts */ 96 private static final transient long DEFAULT_POOLING_INTERVAL = 5; 97 98 /** Default unit of the "pooling interval" used when running jobs/commands/scripts */ 99 private static final transient TimeUnit DEFAULT_POOLING_UNIT = TimeUnit.SECONDS; 100 101 /** URL of the RunDeck instance ("http://localhost:4440" target="alexandria_uri">http://localhost:4440", "http://rundeck.your-compagny.com/", etc) */ 102 private final String url; 103 104 /** Auth-token for authentication (if not using login-based auth) */ 105 private final String token; 106 107 /** Login to use for authentication on the RunDeck instance (if not using token-based auth) */ 108 private final String login; 109 110 /** Password to use for authentication on the RunDeck instance (if not using token-based auth) */ 111 private final String password; 112 113 /** 114 * Instantiate a new {@link RundeckClient} for the RunDeck instance at the given url, using login-based 115 * authentication. 116 * 117 * @param url of the RunDeck instance ("http://localhost:4440", "http://rundeck.your-compagny.com/", etc) 118 * @param login to use for authentication on the RunDeck instance 119 * @param password to use for authentication on the RunDeck instance 120 * @throws IllegalArgumentException if the url, login or password is blank (null, empty or whitespace) 121 */ 122 public RundeckClient(String url, String login, String password) throws IllegalArgumentException { 123 super(); 124 AssertUtil.notBlank(url, "The RunDeck URL is mandatory !"); 125 AssertUtil.notBlank(login, "The RunDeck login is mandatory !"); 126 AssertUtil.notBlank(password, "The RunDeck password is mandatory !"); 127 this.url = url; 128 this.login = login; 129 this.password = password; 130 this.token = null; 131 } 132 133 /** 134 * Instantiate a new {@link RundeckClient} for the RunDeck instance at the given url, using token-based 135 * authentication. 136 * 137 * @param url of the RunDeck instance ("http://localhost:4440", "http://rundeck.your-compagny.com/", etc) 138 * @param token to use for authentication on the RunDeck instance 139 * @throws IllegalArgumentException if the url or token is blank (null, empty or whitespace) 140 */ 141 public RundeckClient(String url, String token) throws IllegalArgumentException { 142 super(); 143 AssertUtil.notBlank(url, "The RunDeck URL is mandatory !"); 144 AssertUtil.notBlank(token, "The RunDeck auth-token is mandatory !"); 145 this.url = url; 146 this.token = token; 147 this.login = null; 148 this.password = null; 149 } 150 151 /** 152 * Try to "ping" the RunDeck instance to see if it is alive 153 * 154 * @throws RundeckApiException if the ping fails 155 */ 156 public void ping() throws RundeckApiException { 157 new ApiCall(this).ping(); 158 } 159 160 /** 161 * Test the authentication on the RunDeck instance. 162 * 163 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 164 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 165 */ 166 public void testAuth() throws RundeckApiLoginException, RundeckApiTokenException { 167 new ApiCall(this).testAuth(); 168 } 169 170 /** 171 * @deprecated Use {@link #testAuth()} 172 * @see #testAuth() 173 */ 174 @Deprecated 175 public void testCredentials() throws RundeckApiLoginException, RundeckApiTokenException { 176 testAuth(); 177 } 178 179 /* 180 * Projects 181 */ 182 183 /** 184 * List all projects 185 * 186 * @return a {@link List} of {@link RundeckProject} : might be empty, but won't be null 187 * @throws RundeckApiException in case of error when calling the API 188 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 189 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 190 */ 191 public List<RundeckProject> getProjects() throws RundeckApiException, RundeckApiLoginException, 192 RundeckApiTokenException { 193 return new ApiCall(this).get(new ApiPathBuilder("/projects"), 194 new ListParser<RundeckProject>(new ProjectParser(), "result/projects/project")); 195 } 196 197 /** 198 * Get the definition of a single project, identified by the given name 199 * 200 * @param projectName name of the project - mandatory 201 * @return a {@link RundeckProject} instance - won't be null 202 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 203 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 204 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 205 * @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace) 206 */ 207 public RundeckProject getProject(String projectName) throws RundeckApiException, RundeckApiLoginException, 208 RundeckApiTokenException, IllegalArgumentException { 209 AssertUtil.notBlank(projectName, "projectName is mandatory to get the details of a project !"); 210 return new ApiCall(this).get(new ApiPathBuilder("/project/", projectName), 211 new ProjectParser("result/projects/project")); 212 } 213 214 /* 215 * Jobs 216 */ 217 218 /** 219 * List all jobs (for all projects) 220 * 221 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null 222 * @throws RundeckApiException in case of error when calling the API 223 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 224 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 225 */ 226 public List<RundeckJob> getJobs() throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException { 227 List<RundeckJob> jobs = new ArrayList<RundeckJob>(); 228 for (RundeckProject project : getProjects()) { 229 jobs.addAll(getJobs(project.getName())); 230 } 231 return jobs; 232 } 233 234 /** 235 * List all jobs that belongs to the given project 236 * 237 * @param project name of the project - mandatory 238 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null 239 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 240 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 241 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 242 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 243 * @see #getJobs(String, String, String, String...) 244 */ 245 public List<RundeckJob> getJobs(String project) throws RundeckApiException, RundeckApiLoginException, 246 RundeckApiTokenException, IllegalArgumentException { 247 return getJobs(project, null, null, new String[0]); 248 } 249 250 /** 251 * List the jobs that belongs to the given project, and matches the given criteria (jobFilter, groupPath and jobIds) 252 * 253 * @param project name of the project - mandatory 254 * @param jobFilter a filter for the job Name - optional 255 * @param groupPath a group or partial group path to include all jobs within that group path - optional 256 * @param jobIds a list of Job IDs to include - optional 257 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null 258 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 259 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 260 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 261 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 262 * @see #getJobs(String) 263 */ 264 public List<RundeckJob> getJobs(String project, String jobFilter, String groupPath, String... jobIds) 265 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 266 AssertUtil.notBlank(project, "project is mandatory to get all jobs !"); 267 return new ApiCall(this).get(new ApiPathBuilder("/jobs").param("project", project) 268 .param("jobFilter", jobFilter) 269 .param("groupPath", groupPath) 270 .param("idlist", StringUtils.join(jobIds, ",")), 271 new ListParser<RundeckJob>(new JobParser(), "result/jobs/job")); 272 } 273 274 /** 275 * Export the definitions of all jobs that belongs to the given project 276 * 277 * @param filename path of the file where the content should be saved - mandatory 278 * @param format of the export. See {@link FileType} - mandatory 279 * @param project name of the project - mandatory 280 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 281 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 282 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 283 * @throws IllegalArgumentException if the format or project is blank (null, empty or whitespace), or the format is 284 * invalid 285 * @throws IOException if we failed to write to the file 286 * @see #exportJobsToFile(String, FileType, String, String, String, String...) 287 * @see #exportJobs(String, String) 288 */ 289 public void exportJobsToFile(String filename, String format, String project) throws RundeckApiException, 290 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 291 AssertUtil.notBlank(format, "format is mandatory to export jobs !"); 292 exportJobsToFile(filename, FileType.valueOf(StringUtils.upperCase(format)), project); 293 } 294 295 /** 296 * Export the definitions of all jobs that belongs to the given project 297 * 298 * @param filename path of the file where the content should be saved - mandatory 299 * @param format of the export. See {@link FileType} - mandatory 300 * @param project name of the project - mandatory 301 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 302 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 303 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 304 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the format is null 305 * @throws IOException if we failed to write to the file 306 * @see #exportJobsToFile(String, FileType, String, String, String, String...) 307 * @see #exportJobs(FileType, String) 308 */ 309 public void exportJobsToFile(String filename, FileType format, String project) throws RundeckApiException, 310 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 311 exportJobsToFile(filename, format, project, null, null, new String[0]); 312 } 313 314 /** 315 * Export the definitions of the jobs that belongs to the given project, and matches the given criteria (jobFilter, 316 * groupPath and jobIds) 317 * 318 * @param filename path of the file where the content should be saved - mandatory 319 * @param format of the export. See {@link FileType} - mandatory 320 * @param project name of the project - mandatory 321 * @param jobFilter a filter for the job Name - optional 322 * @param groupPath a group or partial group path to include all jobs within that group path - optional 323 * @param jobIds a list of Job IDs to include - optional 324 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 325 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 326 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 327 * @throws IllegalArgumentException if the filename, format or project is blank (null, empty or whitespace), or the 328 * format is invalid 329 * @throws IOException if we failed to write to the file 330 * @see #exportJobsToFile(String, FileType, String, String, String, String...) 331 * @see #exportJobs(FileType, String, String, String, String...) 332 */ 333 public void exportJobsToFile(String filename, String format, String project, String jobFilter, String groupPath, 334 String... jobIds) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 335 IllegalArgumentException, IOException { 336 AssertUtil.notBlank(format, "format is mandatory to export jobs !"); 337 exportJobsToFile(filename, 338 FileType.valueOf(StringUtils.upperCase(format)), 339 project, 340 jobFilter, 341 groupPath, 342 jobIds); 343 } 344 345 /** 346 * Export the definitions of the jobs that belongs to the given project, and matches the given criteria (jobFilter, 347 * groupPath and jobIds) 348 * 349 * @param filename path of the file where the content should be saved - mandatory 350 * @param format of the export. See {@link FileType} - mandatory 351 * @param project name of the project - mandatory 352 * @param jobFilter a filter for the job Name - optional 353 * @param groupPath a group or partial group path to include all jobs within that group path - optional 354 * @param jobIds a list of Job IDs to include - optional 355 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 356 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 357 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 358 * @throws IllegalArgumentException if the filename or project is blank (null, empty or whitespace), or the format 359 * is null 360 * @throws IOException if we failed to write to the file 361 * @see #exportJobs(FileType, String, String, String, String...) 362 */ 363 public void exportJobsToFile(String filename, FileType format, String project, String jobFilter, String groupPath, 364 String... jobIds) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 365 IllegalArgumentException, IOException { 366 AssertUtil.notBlank(filename, "filename is mandatory to export a job !"); 367 InputStream inputStream = exportJobs(format, project, jobFilter, groupPath, jobIds); 368 FileUtils.writeByteArrayToFile(new File(filename), IOUtils.toByteArray(inputStream)); 369 } 370 371 /** 372 * Export the definitions of all jobs that belongs to the given project 373 * 374 * @param format of the export. See {@link FileType} - mandatory 375 * @param project name of the project - mandatory 376 * @return an {@link InputStream} instance, not linked to any network resources - won't be null 377 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 378 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 379 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 380 * @throws IllegalArgumentException if the format or project is blank (null, empty or whitespace), or the format is 381 * invalid 382 * @see #exportJobs(FileType, String, String, String, String...) 383 * @see #exportJobsToFile(String, String, String) 384 */ 385 public InputStream exportJobs(String format, String project) throws RundeckApiException, RundeckApiLoginException, 386 RundeckApiTokenException, IllegalArgumentException { 387 AssertUtil.notBlank(format, "format is mandatory to export jobs !"); 388 return exportJobs(FileType.valueOf(StringUtils.upperCase(format)), project); 389 } 390 391 /** 392 * Export the definitions of all jobs that belongs to the given project 393 * 394 * @param format of the export. See {@link FileType} - mandatory 395 * @param project name of the project - mandatory 396 * @return an {@link InputStream} instance, not linked to any network resources - won't be null 397 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 398 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 399 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 400 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the format is null 401 * @see #exportJobs(FileType, String, String, String, String...) 402 * @see #exportJobsToFile(String, FileType, String) 403 */ 404 public InputStream exportJobs(FileType format, String project) throws RundeckApiException, 405 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 406 return exportJobs(format, project, null, null, new String[0]); 407 } 408 409 /** 410 * Export the definitions of the jobs that belongs to the given project, and matches the given criteria (jobFilter, 411 * groupPath and jobIds) 412 * 413 * @param format of the export. See {@link FileType} - mandatory 414 * @param project name of the project - mandatory 415 * @param jobFilter a filter for the job Name - optional 416 * @param groupPath a group or partial group path to include all jobs within that group path - optional 417 * @param jobIds a list of Job IDs to include - optional 418 * @return an {@link InputStream} instance, not linked to any network resources - won't be null 419 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 420 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 421 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 422 * @throws IllegalArgumentException if the format or project is blank (null, empty or whitespace), or the format is 423 * invalid 424 * @see #exportJobs(FileType, String, String, String, String...) 425 * @see #exportJobsToFile(String, String, String, String, String, String...) 426 */ 427 public InputStream exportJobs(String format, String project, String jobFilter, String groupPath, String... jobIds) 428 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 429 AssertUtil.notBlank(format, "format is mandatory to export jobs !"); 430 return exportJobs(FileType.valueOf(StringUtils.upperCase(format)), project, jobFilter, groupPath, jobIds); 431 } 432 433 /** 434 * Export the definitions of the jobs that belongs to the given project, and matches the given criteria (jobFilter, 435 * groupPath and jobIds) 436 * 437 * @param format of the export. See {@link FileType} - mandatory 438 * @param project name of the project - mandatory 439 * @param jobFilter a filter for the job Name - optional 440 * @param groupPath a group or partial group path to include all jobs within that group path - optional 441 * @param jobIds a list of Job IDs to include - optional 442 * @return an {@link InputStream} instance, not linked to any network resources - won't be null 443 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 444 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 445 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 446 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the format is null 447 * @see #exportJobsToFile(String, FileType, String, String, String, String...) 448 */ 449 public InputStream exportJobs(FileType format, String project, String jobFilter, String groupPath, String... jobIds) 450 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 451 AssertUtil.notNull(format, "format is mandatory to export jobs !"); 452 AssertUtil.notBlank(project, "project is mandatory to export jobs !"); 453 return new ApiCall(this).get(new ApiPathBuilder("/jobs/export").param("format", format) 454 .param("project", project) 455 .param("jobFilter", jobFilter) 456 .param("groupPath", groupPath) 457 .param("idlist", StringUtils.join(jobIds, ","))); 458 } 459 460 /** 461 * Export the definition of a single job (identified by the given ID) 462 * 463 * @param filename path of the file where the content should be saved - mandatory 464 * @param format of the export. See {@link FileType} - mandatory 465 * @param jobId identifier of the job - mandatory 466 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 467 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 468 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 469 * @throws IllegalArgumentException if the filename, format or jobId is blank (null, empty or whitespace), or the 470 * format is invalid 471 * @throws IOException if we failed to write to the file 472 * @see #exportJobToFile(String, FileType, String) 473 * @see #exportJob(String, String) 474 * @see #getJob(String) 475 */ 476 public void exportJobToFile(String filename, String format, String jobId) throws RundeckApiException, 477 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 478 AssertUtil.notBlank(format, "format is mandatory to export a job !"); 479 exportJobToFile(filename, FileType.valueOf(StringUtils.upperCase(format)), jobId); 480 } 481 482 /** 483 * Export the definition of a single job (identified by the given ID) 484 * 485 * @param filename path of the file where the content should be saved - mandatory 486 * @param format of the export. See {@link FileType} - mandatory 487 * @param jobId identifier of the job - mandatory 488 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 489 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 490 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 491 * @throws IllegalArgumentException if the filename or jobId is blank (null, empty or whitespace), or the format is 492 * null 493 * @throws IOException if we failed to write to the file 494 * @see #exportJob(FileType, String) 495 * @see #getJob(String) 496 */ 497 public void exportJobToFile(String filename, FileType format, String jobId) throws RundeckApiException, 498 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 499 AssertUtil.notBlank(filename, "filename is mandatory to export a job !"); 500 InputStream inputStream = exportJob(format, jobId); 501 FileUtils.writeByteArrayToFile(new File(filename), IOUtils.toByteArray(inputStream)); 502 } 503 504 /** 505 * Export the definition of a single job, identified by the given ID 506 * 507 * @param format of the export. See {@link FileType} - mandatory 508 * @param jobId identifier of the job - mandatory 509 * @return an {@link InputStream} instance, not linked to any network resources - won't be null 510 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 511 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 512 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 513 * @throws IllegalArgumentException if the format or jobId is blank (null, empty or whitespace), or the format is 514 * invalid 515 * @see #exportJobToFile(String, String, String) 516 * @see #getJob(String) 517 */ 518 public InputStream exportJob(String format, String jobId) throws RundeckApiException, RundeckApiLoginException, 519 RundeckApiTokenException, IllegalArgumentException { 520 AssertUtil.notBlank(format, "format is mandatory to export a job !"); 521 return exportJob(FileType.valueOf(StringUtils.upperCase(format)), jobId); 522 } 523 524 /** 525 * Export the definition of a single job, identified by the given ID 526 * 527 * @param format of the export. See {@link FileType} - mandatory 528 * @param jobId identifier of the job - mandatory 529 * @return an {@link InputStream} instance, not linked to any network resources - won't be null 530 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 531 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 532 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 533 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace), or the format is null 534 * @see #exportJobToFile(String, FileType, String) 535 * @see #getJob(String) 536 */ 537 public InputStream exportJob(FileType format, String jobId) throws RundeckApiException, RundeckApiLoginException, 538 RundeckApiTokenException, IllegalArgumentException { 539 AssertUtil.notNull(format, "format is mandatory to export a job !"); 540 AssertUtil.notBlank(jobId, "jobId is mandatory to export a job !"); 541 return new ApiCall(this).get(new ApiPathBuilder("/job/", jobId).param("format", format)); 542 } 543 544 /** 545 * Import the definitions of jobs, from the given file 546 * 547 * @param filename of the file containing the jobs definitions - mandatory 548 * @param fileType type of the file. See {@link FileType} - mandatory 549 * @return a {@link RundeckJobsImportResult} instance - won't be null 550 * @throws RundeckApiException in case of error when calling the API 551 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 552 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 553 * @throws IllegalArgumentException if the filename or fileType is blank (null, empty or whitespace), or the 554 * fileType is invalid 555 * @throws IOException if we failed to read the file 556 * @see #importJobs(InputStream, String) 557 * @see #importJobs(String, FileType, RundeckJobsImportMethod) 558 */ 559 public RundeckJobsImportResult importJobs(String filename, String fileType) throws RundeckApiException, 560 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 561 AssertUtil.notBlank(fileType, "fileType is mandatory to import jobs !"); 562 return importJobs(filename, FileType.valueOf(StringUtils.upperCase(fileType))); 563 } 564 565 /** 566 * Import the definitions of jobs, from the given file 567 * 568 * @param filename of the file containing the jobs definitions - mandatory 569 * @param fileType type of the file. See {@link FileType} - mandatory 570 * @return a {@link RundeckJobsImportResult} instance - won't be null 571 * @throws RundeckApiException in case of error when calling the API 572 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 573 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 574 * @throws IllegalArgumentException if the filename is blank (null, empty or whitespace), or the fileType is null 575 * @throws IOException if we failed to read the file 576 * @see #importJobs(InputStream, FileType) 577 * @see #importJobs(String, FileType, RundeckJobsImportMethod) 578 */ 579 public RundeckJobsImportResult importJobs(String filename, FileType fileType) throws RundeckApiException, 580 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 581 return importJobs(filename, fileType, (RundeckJobsImportMethod) null); 582 } 583 584 /** 585 * Import the definitions of jobs, from the given file, using the given behavior 586 * 587 * @param filename of the file containing the jobs definitions - mandatory 588 * @param fileType type of the file. See {@link FileType} - mandatory 589 * @param importBehavior see {@link RundeckJobsImportMethod} 590 * @return a {@link RundeckJobsImportResult} instance - won't be null 591 * @throws RundeckApiException in case of error when calling the API 592 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 593 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 594 * @throws IllegalArgumentException if the filename or fileType is blank (null, empty or whitespace), or the 595 * fileType or behavior is not valid 596 * @throws IOException if we failed to read the file 597 * @see #importJobs(InputStream, String, String) 598 * @see #importJobs(String, FileType, RundeckJobsImportMethod) 599 */ 600 public RundeckJobsImportResult importJobs(String filename, String fileType, String importBehavior) 601 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, 602 IOException { 603 AssertUtil.notBlank(fileType, "fileType is mandatory to import jobs !"); 604 return importJobs(filename, 605 FileType.valueOf(StringUtils.upperCase(fileType)), 606 RundeckJobsImportMethod.valueOf(StringUtils.upperCase(importBehavior))); 607 } 608 609 /** 610 * Import the definitions of jobs, from the given file, using the given behavior 611 * 612 * @param filename of the file containing the jobs definitions - mandatory 613 * @param fileType type of the file. See {@link FileType} - mandatory 614 * @param importBehavior see {@link RundeckJobsImportMethod} 615 * @return a {@link RundeckJobsImportResult} instance - won't be null 616 * @throws RundeckApiException in case of error when calling the API 617 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 618 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 619 * @throws IllegalArgumentException if the filename is blank (null, empty or whitespace), or the fileType is null 620 * @throws IOException if we failed to read the file 621 * @see #importJobs(InputStream, FileType, RundeckJobsImportMethod) 622 */ 623 public RundeckJobsImportResult importJobs(String filename, FileType fileType, RundeckJobsImportMethod importBehavior) 624 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, 625 IOException { 626 AssertUtil.notBlank(filename, "filename (of jobs file) is mandatory to import jobs !"); 627 FileInputStream stream = null; 628 try { 629 stream = FileUtils.openInputStream(new File(filename)); 630 return importJobs(stream, fileType, importBehavior); 631 } finally { 632 IOUtils.closeQuietly(stream); 633 } 634 } 635 636 /** 637 * Import the definitions of jobs, from the given input stream 638 * 639 * @param stream inputStream for reading the definitions - mandatory 640 * @param fileType type of the file. See {@link FileType} - mandatory 641 * @return a {@link RundeckJobsImportResult} instance - won't be null 642 * @throws RundeckApiException in case of error when calling the API 643 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 644 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 645 * @throws IllegalArgumentException if the stream is null, or the fileType is blank (null, empty or whitespace) or 646 * invalid 647 * @see #importJobs(String, String) 648 * @see #importJobs(InputStream, FileType, RundeckJobsImportMethod) 649 */ 650 public RundeckJobsImportResult importJobs(InputStream stream, String fileType) throws RundeckApiException, 651 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 652 AssertUtil.notBlank(fileType, "fileType is mandatory to import jobs !"); 653 return importJobs(stream, FileType.valueOf(StringUtils.upperCase(fileType))); 654 } 655 656 /** 657 * Import the definitions of jobs, from the given input stream 658 * 659 * @param stream inputStream for reading the definitions - mandatory 660 * @param fileType type of the file. See {@link FileType} - mandatory 661 * @return a {@link RundeckJobsImportResult} instance - won't be null 662 * @throws RundeckApiException in case of error when calling the API 663 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 664 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 665 * @throws IllegalArgumentException if the stream or fileType is null 666 * @see #importJobs(String, FileType) 667 * @see #importJobs(InputStream, FileType, RundeckJobsImportMethod) 668 */ 669 public RundeckJobsImportResult importJobs(InputStream stream, FileType fileType) throws RundeckApiException, 670 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 671 return importJobs(stream, fileType, (RundeckJobsImportMethod) null); 672 } 673 674 /** 675 * Import the definitions of jobs, from the given input stream, using the given behavior 676 * 677 * @param stream inputStream for reading the definitions - mandatory 678 * @param fileType type of the file. See {@link FileType} - mandatory 679 * @param importBehavior see {@link RundeckJobsImportMethod} 680 * @return a {@link RundeckJobsImportResult} instance - won't be null 681 * @throws RundeckApiException in case of error when calling the API 682 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 683 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 684 * @throws IllegalArgumentException if the stream is null, or the fileType is blank (null, empty or whitespace), or 685 * the fileType or behavior is not valid 686 * @see #importJobs(String, String, String) 687 * @see #importJobs(InputStream, FileType, RundeckJobsImportMethod) 688 */ 689 public RundeckJobsImportResult importJobs(InputStream stream, String fileType, String importBehavior) 690 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 691 AssertUtil.notBlank(fileType, "fileType is mandatory to import jobs !"); 692 return importJobs(stream, 693 FileType.valueOf(StringUtils.upperCase(fileType)), 694 RundeckJobsImportMethod.valueOf(StringUtils.upperCase(importBehavior))); 695 } 696 697 /** 698 * Import the definitions of jobs, from the given input stream, using the given behavior 699 * 700 * @param stream inputStream for reading the definitions - mandatory 701 * @param fileType type of the file. See {@link FileType} - mandatory 702 * @param importBehavior see {@link RundeckJobsImportMethod} 703 * @return a {@link RundeckJobsImportResult} instance - won't be null 704 * @throws RundeckApiException in case of error when calling the API 705 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 706 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 707 * @throws IllegalArgumentException if the stream or fileType is null 708 * @see #importJobs(String, FileType, RundeckJobsImportMethod) 709 */ 710 public RundeckJobsImportResult importJobs(InputStream stream, FileType fileType, 711 RundeckJobsImportMethod importBehavior) throws RundeckApiException, RundeckApiLoginException, 712 RundeckApiTokenException, IllegalArgumentException { 713 AssertUtil.notNull(stream, "inputStream of jobs is mandatory to import jobs !"); 714 AssertUtil.notNull(fileType, "fileType is mandatory to import jobs !"); 715 return new ApiCall(this).post(new ApiPathBuilder("/jobs/import").param("format", fileType) 716 .param("dupeOption", importBehavior) 717 .attach("xmlBatch", stream), 718 new JobsImportResultParser("result")); 719 } 720 721 /** 722 * Find a job, identified by its project, group and name. Note that the groupPath is optional, as a job does not 723 * need to belong to a group (either pass null, or an empty string). 724 * 725 * @param project name of the project - mandatory 726 * @param groupPath group to which the job belongs (if it belongs to a group) - optional 727 * @param name of the job to find - mandatory 728 * @return a {@link RundeckJob} instance - null if not found 729 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 730 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 731 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 732 * @throws IllegalArgumentException if the project or the name is blank (null, empty or whitespace) 733 * @see #getJob(String) 734 */ 735 public RundeckJob findJob(String project, String groupPath, String name) throws RundeckApiException, 736 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 737 AssertUtil.notBlank(project, "project is mandatory to find a job !"); 738 AssertUtil.notBlank(name, "job name is mandatory to find a job !"); 739 List<RundeckJob> jobs = getJobs(project, name, groupPath, new String[0]); 740 return jobs.isEmpty() ? null : jobs.get(0); 741 } 742 743 /** 744 * Get the definition of a single job, identified by the given ID 745 * 746 * @param jobId identifier of the job - mandatory 747 * @return a {@link RundeckJob} instance - won't be null 748 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 749 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 750 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 751 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 752 * @see #findJob(String, String, String) 753 * @see #exportJob(String, String) 754 */ 755 public RundeckJob getJob(String jobId) throws RundeckApiException, RundeckApiLoginException, 756 RundeckApiTokenException, IllegalArgumentException { 757 AssertUtil.notBlank(jobId, "jobId is mandatory to get the details of a job !"); 758 return new ApiCall(this).get(new ApiPathBuilder("/job/", jobId), new JobParser("joblist/job")); 759 } 760 761 /** 762 * Delete a single job, identified by the given ID 763 * 764 * @param jobId identifier of the job - mandatory 765 * @return the success message (note that in case of error, you'll get an exception) 766 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 767 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 768 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 769 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 770 */ 771 public String deleteJob(String jobId) throws RundeckApiException, RundeckApiLoginException, 772 RundeckApiTokenException, IllegalArgumentException { 773 AssertUtil.notBlank(jobId, "jobId is mandatory to delete a job !"); 774 return new ApiCall(this).delete(new ApiPathBuilder("/job/", jobId), new StringParser("result/success/message")); 775 } 776 777 /** 778 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the 779 * end of the job execution) 780 * 781 * @param jobId identifier of the job - mandatory 782 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 783 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 784 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 785 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 786 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 787 * @see #triggerJob(String, Properties, Properties) 788 * @see #runJob(String) 789 */ 790 public RundeckExecution triggerJob(String jobId) throws RundeckApiException, RundeckApiLoginException, 791 RundeckApiTokenException, IllegalArgumentException { 792 return triggerJob(jobId, null); 793 } 794 795 /** 796 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the 797 * end of the job execution) 798 * 799 * @param jobId identifier of the job - mandatory 800 * @param options of the job - optional. See {@link OptionsBuilder}. 801 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 802 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 803 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 804 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 805 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 806 * @see #triggerJob(String, Properties, Properties) 807 * @see #runJob(String, Properties) 808 */ 809 public RundeckExecution triggerJob(String jobId, Properties options) throws RundeckApiException, 810 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 811 return triggerJob(jobId, options, null); 812 } 813 814 /** 815 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the 816 * end of the job execution) 817 * 818 * @param jobId identifier of the job - mandatory 819 * @param options of the job - optional. See {@link OptionsBuilder}. 820 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See 821 * {@link NodeFiltersBuilder} 822 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 823 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 824 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 825 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 826 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 827 * @see #triggerJob(String) 828 * @see #runJob(String, Properties, Properties) 829 */ 830 public RundeckExecution triggerJob(String jobId, Properties options, Properties nodeFilters) 831 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 832 AssertUtil.notBlank(jobId, "jobId is mandatory to trigger a job !"); 833 return new ApiCall(this).get(new ApiPathBuilder("/job/", jobId, "/run").param("argString", 834 ParametersUtil.generateArgString(options)) 835 .nodeFilters(nodeFilters), 836 new ExecutionParser("result/executions/execution")); 837 } 838 839 /** 840 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. 841 * We will poll the RunDeck server at regular interval (every 5 seconds) to know if the execution is finished (or 842 * aborted) or is still running. 843 * 844 * @param jobId identifier of the job - mandatory 845 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 846 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 847 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 848 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 849 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 850 * @see #triggerJob(String) 851 * @see #runJob(String, Properties, Properties, long, TimeUnit) 852 */ 853 public RundeckExecution runJob(String jobId) throws RundeckApiException, RundeckApiLoginException, 854 RundeckApiTokenException, IllegalArgumentException { 855 return runJob(jobId, null); 856 } 857 858 /** 859 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. 860 * We will poll the RunDeck server at regular interval (every 5 seconds) to know if the execution is finished (or 861 * aborted) or is still running. 862 * 863 * @param jobId identifier of the job - mandatory 864 * @param options of the job - optional. See {@link OptionsBuilder}. 865 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 866 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 867 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 868 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 869 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 870 * @see #triggerJob(String, Properties) 871 * @see #runJob(String, Properties, Properties, long, TimeUnit) 872 */ 873 public RundeckExecution runJob(String jobId, Properties options) throws RundeckApiException, 874 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 875 return runJob(jobId, options, null); 876 } 877 878 /** 879 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. 880 * We will poll the RunDeck server at regular interval (every 5 seconds) to know if the execution is finished (or 881 * aborted) or is still running. 882 * 883 * @param jobId identifier of the job - mandatory 884 * @param options of the job - optional. See {@link OptionsBuilder}. 885 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See 886 * {@link NodeFiltersBuilder} 887 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 888 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 889 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 890 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 891 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 892 * @see #triggerJob(String, Properties, Properties) 893 * @see #runJob(String, Properties, Properties, long, TimeUnit) 894 */ 895 public RundeckExecution runJob(String jobId, Properties options, Properties nodeFilters) 896 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 897 return runJob(jobId, options, nodeFilters, DEFAULT_POOLING_INTERVAL, DEFAULT_POOLING_UNIT); 898 } 899 900 /** 901 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. 902 * We will poll the RunDeck server at regular interval (configured by the poolingInterval/poolingUnit couple) to 903 * know if the execution is finished (or aborted) or is still running. 904 * 905 * @param jobId identifier of the job - mandatory 906 * @param options of the job - optional. See {@link OptionsBuilder}. 907 * @param poolingInterval for checking the status of the execution. Must be > 0. 908 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 909 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 910 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 911 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 912 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 913 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 914 * @see #triggerJob(String, Properties) 915 * @see #runJob(String, Properties, Properties, long, TimeUnit) 916 */ 917 public RundeckExecution runJob(String jobId, Properties options, long poolingInterval, TimeUnit poolingUnit) 918 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 919 return runJob(jobId, options, null, poolingInterval, poolingUnit); 920 } 921 922 /** 923 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. 924 * We will poll the RunDeck server at regular interval (configured by the poolingInterval/poolingUnit couple) to 925 * know if the execution is finished (or aborted) or is still running. 926 * 927 * @param jobId identifier of the job - mandatory 928 * @param options of the job - optional. See {@link OptionsBuilder}. 929 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See 930 * {@link NodeFiltersBuilder} 931 * @param poolingInterval for checking the status of the execution. Must be > 0. 932 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 933 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 934 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 935 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 936 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 937 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 938 * @see #triggerJob(String, Properties) 939 * @see #runJob(String, Properties, Properties, long, TimeUnit) 940 */ 941 public RundeckExecution runJob(String jobId, Properties options, Properties nodeFilters, long poolingInterval, 942 TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 943 IllegalArgumentException { 944 if (poolingInterval <= 0) { 945 poolingInterval = DEFAULT_POOLING_INTERVAL; 946 poolingUnit = DEFAULT_POOLING_UNIT; 947 } 948 if (poolingUnit == null) { 949 poolingUnit = DEFAULT_POOLING_UNIT; 950 } 951 952 RundeckExecution execution = triggerJob(jobId, options, nodeFilters); 953 while (ExecutionStatus.RUNNING.equals(execution.getStatus())) { 954 try { 955 Thread.sleep(poolingUnit.toMillis(poolingInterval)); 956 } catch (InterruptedException e) { 957 break; 958 } 959 execution = getExecution(execution.getId()); 960 } 961 return execution; 962 } 963 964 /* 965 * Ad-hoc commands 966 */ 967 968 /** 969 * Trigger the execution of an ad-hoc command, and return immediately (without waiting the end of the execution). 970 * The command will not be dispatched to nodes, but be executed on the RunDeck server. 971 * 972 * @param project name of the project - mandatory 973 * @param command to be executed - mandatory 974 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 975 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 976 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 977 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 978 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 979 * @see #triggerAdhocCommand(String, String, Properties, Integer, Boolean) 980 * @see #runAdhocCommand(String, String) 981 */ 982 public RundeckExecution triggerAdhocCommand(String project, String command) throws RundeckApiException, 983 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 984 return triggerAdhocCommand(project, command, null); 985 } 986 987 /** 988 * Trigger the execution of an ad-hoc command, and return immediately (without waiting the end of the execution). 989 * The command will be dispatched to nodes, accordingly to the nodeFilters parameter. 990 * 991 * @param project name of the project - mandatory 992 * @param command to be executed - mandatory 993 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 994 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 995 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 996 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 997 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 998 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 999 * @see #triggerAdhocCommand(String, String, Properties, Integer, Boolean) 1000 * @see #runAdhocCommand(String, String, Properties) 1001 */ 1002 public RundeckExecution triggerAdhocCommand(String project, String command, Properties nodeFilters) 1003 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1004 return triggerAdhocCommand(project, command, nodeFilters, null, null); 1005 } 1006 1007 /** 1008 * Trigger the execution of an ad-hoc command, and return immediately (without waiting the end of the execution). 1009 * The command will be dispatched to nodes, accordingly to the nodeFilters parameter. 1010 * 1011 * @param project name of the project - mandatory 1012 * @param command to be executed - mandatory 1013 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1014 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1015 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1016 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1017 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1018 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1019 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1020 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 1021 * @see #triggerAdhocCommand(String, String) 1022 * @see #runAdhocCommand(String, String, Properties) 1023 */ 1024 public RundeckExecution triggerAdhocCommand(String project, String command, Properties nodeFilters, 1025 Integer nodeThreadcount, Boolean nodeKeepgoing) throws RundeckApiException, RundeckApiLoginException, 1026 RundeckApiTokenException, IllegalArgumentException { 1027 AssertUtil.notBlank(project, "project is mandatory to trigger an ad-hoc command !"); 1028 AssertUtil.notBlank(command, "command is mandatory to trigger an ad-hoc command !"); 1029 RundeckExecution execution = new ApiCall(this).get(new ApiPathBuilder("/run/command").param("project", project) 1030 .param("exec", command) 1031 .param("nodeThreadcount", 1032 nodeThreadcount) 1033 .param("nodeKeepgoing", 1034 nodeKeepgoing) 1035 .nodeFilters(nodeFilters), 1036 new ExecutionParser("result/execution")); 1037 // the first call just returns the ID of the execution, so we need another call to get a "real" execution 1038 return getExecution(execution.getId()); 1039 } 1040 1041 /** 1042 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1043 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1044 * running. The command will not be dispatched to nodes, but be executed on the RunDeck server. 1045 * 1046 * @param project name of the project - mandatory 1047 * @param command to be executed - mandatory 1048 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1049 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1050 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1051 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1052 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 1053 * @see #runAdhocCommand(String, String, Properties, Integer, Boolean, long, TimeUnit) 1054 * @see #triggerAdhocCommand(String, String) 1055 */ 1056 public RundeckExecution runAdhocCommand(String project, String command) throws RundeckApiException, 1057 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1058 return runAdhocCommand(project, command, null); 1059 } 1060 1061 /** 1062 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1063 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1064 * finished (or aborted) or is still running. The command will not be dispatched to nodes, but be executed on the 1065 * RunDeck server. 1066 * 1067 * @param project name of the project - mandatory 1068 * @param command to be executed - mandatory 1069 * @param poolingInterval for checking the status of the execution. Must be > 0. 1070 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1071 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1072 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1073 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1074 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1075 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 1076 * @see #runAdhocCommand(String, String, Properties, Integer, Boolean, long, TimeUnit) 1077 * @see #triggerAdhocCommand(String, String) 1078 */ 1079 public RundeckExecution runAdhocCommand(String project, String command, long poolingInterval, TimeUnit poolingUnit) 1080 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1081 return runAdhocCommand(project, command, null, poolingInterval, poolingUnit); 1082 } 1083 1084 /** 1085 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1086 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1087 * running. The command will be dispatched to nodes, accordingly to the nodeFilters parameter. 1088 * 1089 * @param project name of the project - mandatory 1090 * @param command to be executed - mandatory 1091 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1092 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1093 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1094 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1095 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1096 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 1097 * @see #runAdhocCommand(String, String, Properties, Integer, Boolean, long, TimeUnit) 1098 * @see #triggerAdhocCommand(String, String, Properties) 1099 */ 1100 public RundeckExecution runAdhocCommand(String project, String command, Properties nodeFilters) 1101 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1102 return runAdhocCommand(project, command, nodeFilters, null, null); 1103 } 1104 1105 /** 1106 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1107 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1108 * finished (or aborted) or is still running. The command will be dispatched to nodes, accordingly to the 1109 * nodeFilters parameter. 1110 * 1111 * @param project name of the project - mandatory 1112 * @param command to be executed - mandatory 1113 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1114 * @param poolingInterval for checking the status of the execution. Must be > 0. 1115 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1116 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1117 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1118 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1119 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1120 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 1121 * @see #runAdhocCommand(String, String, Properties, Integer, Boolean, long, TimeUnit) 1122 * @see #triggerAdhocCommand(String, String, Properties) 1123 */ 1124 public RundeckExecution runAdhocCommand(String project, String command, Properties nodeFilters, 1125 long poolingInterval, TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, 1126 RundeckApiTokenException, IllegalArgumentException { 1127 return runAdhocCommand(project, command, nodeFilters, null, null, poolingInterval, poolingUnit); 1128 } 1129 1130 /** 1131 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1132 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1133 * running. The command will be dispatched to nodes, accordingly to the nodeFilters parameter. 1134 * 1135 * @param project name of the project - mandatory 1136 * @param command to be executed - mandatory 1137 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1138 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1139 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1140 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1141 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1142 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1143 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1144 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 1145 * @see #runAdhocCommand(String, String, Properties, Integer, Boolean, long, TimeUnit) 1146 * @see #triggerAdhocCommand(String, String, Properties, Integer, Boolean) 1147 */ 1148 public RundeckExecution runAdhocCommand(String project, String command, Properties nodeFilters, 1149 Integer nodeThreadcount, Boolean nodeKeepgoing) throws RundeckApiException, RundeckApiLoginException, 1150 RundeckApiTokenException, IllegalArgumentException { 1151 return runAdhocCommand(project, 1152 command, 1153 nodeFilters, 1154 nodeThreadcount, 1155 nodeKeepgoing, 1156 DEFAULT_POOLING_INTERVAL, 1157 DEFAULT_POOLING_UNIT); 1158 } 1159 1160 /** 1161 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1162 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1163 * finished (or aborted) or is still running. The command will be dispatched to nodes, accordingly to the 1164 * nodeFilters parameter. 1165 * 1166 * @param project name of the project - mandatory 1167 * @param command to be executed - mandatory 1168 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1169 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1170 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1171 * @param poolingInterval for checking the status of the execution. Must be > 0. 1172 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1173 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1174 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1175 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1176 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1177 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) 1178 * @see #triggerAdhocCommand(String, String, Properties, Integer, Boolean) 1179 */ 1180 public RundeckExecution runAdhocCommand(String project, String command, Properties nodeFilters, 1181 Integer nodeThreadcount, Boolean nodeKeepgoing, long poolingInterval, TimeUnit poolingUnit) 1182 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1183 if (poolingInterval <= 0) { 1184 poolingInterval = DEFAULT_POOLING_INTERVAL; 1185 poolingUnit = DEFAULT_POOLING_UNIT; 1186 } 1187 if (poolingUnit == null) { 1188 poolingUnit = DEFAULT_POOLING_UNIT; 1189 } 1190 1191 RundeckExecution execution = triggerAdhocCommand(project, command, nodeFilters, nodeThreadcount, nodeKeepgoing); 1192 while (ExecutionStatus.RUNNING.equals(execution.getStatus())) { 1193 try { 1194 Thread.sleep(poolingUnit.toMillis(poolingInterval)); 1195 } catch (InterruptedException e) { 1196 break; 1197 } 1198 execution = getExecution(execution.getId()); 1199 } 1200 return execution; 1201 } 1202 1203 /* 1204 * Ad-hoc scripts 1205 */ 1206 1207 /** 1208 * Trigger the execution of an ad-hoc script, and return immediately (without waiting the end of the execution). The 1209 * script will not be dispatched to nodes, but be executed on the RunDeck server. 1210 * 1211 * @param project name of the project - mandatory 1212 * @param scriptFilename filename of the script to be executed - mandatory 1213 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1214 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1215 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1216 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1217 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1218 * @throws IOException if we failed to read the file 1219 * @see #triggerAdhocScript(String, String, Properties, Properties, Integer, Boolean) 1220 * @see #runAdhocScript(String, String) 1221 */ 1222 public RundeckExecution triggerAdhocScript(String project, String scriptFilename) throws RundeckApiException, 1223 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 1224 return triggerAdhocScript(project, scriptFilename, null); 1225 } 1226 1227 /** 1228 * Trigger the execution of an ad-hoc script, and return immediately (without waiting the end of the execution). The 1229 * script will not be dispatched to nodes, but be executed on the RunDeck server. 1230 * 1231 * @param project name of the project - mandatory 1232 * @param scriptFilename filename of the script to be executed - mandatory 1233 * @param options of the script - optional. See {@link OptionsBuilder}. 1234 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1235 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1236 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1237 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1238 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1239 * @throws IOException if we failed to read the file 1240 * @see #triggerAdhocScript(String, String, Properties, Properties, Integer, Boolean) 1241 * @see #runAdhocScript(String, String, Properties) 1242 */ 1243 public RundeckExecution triggerAdhocScript(String project, String scriptFilename, Properties options) 1244 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, 1245 IOException { 1246 return triggerAdhocScript(project, scriptFilename, options, null); 1247 } 1248 1249 /** 1250 * Trigger the execution of an ad-hoc script, and return immediately (without waiting the end of the execution). The 1251 * script will be dispatched to nodes, accordingly to the nodeFilters parameter. 1252 * 1253 * @param project name of the project - mandatory 1254 * @param scriptFilename filename of the script to be executed - mandatory 1255 * @param options of the script - optional. See {@link OptionsBuilder}. 1256 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1257 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1258 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1259 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1260 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1261 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1262 * @throws IOException if we failed to read the file 1263 * @see #triggerAdhocScript(String, String, Properties, Properties, Integer, Boolean) 1264 * @see #runAdhocScript(String, String, Properties, Properties) 1265 */ 1266 public RundeckExecution triggerAdhocScript(String project, String scriptFilename, Properties options, 1267 Properties nodeFilters) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 1268 IllegalArgumentException, IOException { 1269 return triggerAdhocScript(project, scriptFilename, options, nodeFilters, null, null); 1270 } 1271 1272 /** 1273 * Trigger the execution of an ad-hoc script, and return immediately (without waiting the end of the execution). The 1274 * script will be dispatched to nodes, accordingly to the nodeFilters parameter. 1275 * 1276 * @param project name of the project - mandatory 1277 * @param scriptFilename filename of the script to be executed - mandatory 1278 * @param options of the script - optional. See {@link OptionsBuilder}. 1279 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1280 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1281 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1282 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1283 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1284 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1285 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1286 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1287 * @throws IOException if we failed to read the file 1288 * @see #triggerAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean) 1289 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1290 */ 1291 public RundeckExecution triggerAdhocScript(String project, String scriptFilename, Properties options, 1292 Properties nodeFilters, Integer nodeThreadcount, Boolean nodeKeepgoing) throws RundeckApiException, 1293 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 1294 AssertUtil.notBlank(scriptFilename, "scriptFilename is mandatory to trigger an ad-hoc script !"); 1295 FileInputStream stream = null; 1296 try { 1297 stream = FileUtils.openInputStream(new File(scriptFilename)); 1298 return triggerAdhocScript(project, stream, options, nodeFilters, nodeThreadcount, nodeKeepgoing); 1299 } finally { 1300 IOUtils.closeQuietly(stream); 1301 } 1302 } 1303 1304 /** 1305 * Trigger the execution of an ad-hoc script, and return immediately (without waiting the end of the execution). The 1306 * script will not be dispatched to nodes, but be executed on the RunDeck server. 1307 * 1308 * @param project name of the project - mandatory 1309 * @param script inputStream for reading the script to be executed - mandatory 1310 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1311 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1312 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1313 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1314 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1315 * @see #triggerAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean) 1316 * @see #runAdhocScript(String, InputStream) 1317 */ 1318 public RundeckExecution triggerAdhocScript(String project, InputStream script) throws RundeckApiException, 1319 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1320 return triggerAdhocScript(project, script, null); 1321 } 1322 1323 /** 1324 * Trigger the execution of an ad-hoc script, and return immediately (without waiting the end of the execution). The 1325 * script will not be dispatched to nodes, but be executed on the RunDeck server. 1326 * 1327 * @param project name of the project - mandatory 1328 * @param script inputStream for reading the script to be executed - mandatory 1329 * @param options of the script - optional. See {@link OptionsBuilder}. 1330 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1331 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1332 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1333 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1334 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1335 * @see #triggerAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean) 1336 * @see #runAdhocScript(String, InputStream, Properties) 1337 */ 1338 public RundeckExecution triggerAdhocScript(String project, InputStream script, Properties options) 1339 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1340 return triggerAdhocScript(project, script, options, null); 1341 } 1342 1343 /** 1344 * Trigger the execution of an ad-hoc script, and return immediately (without waiting the end of the execution). The 1345 * script will be dispatched to nodes, accordingly to the nodeFilters parameter. 1346 * 1347 * @param project name of the project - mandatory 1348 * @param script inputStream for reading the script to be executed - mandatory 1349 * @param options of the script - optional. See {@link OptionsBuilder}. 1350 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1351 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1352 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1353 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1354 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1355 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1356 * @see #triggerAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean) 1357 * @see #runAdhocScript(String, InputStream, Properties, Properties) 1358 */ 1359 public RundeckExecution triggerAdhocScript(String project, InputStream script, Properties options, 1360 Properties nodeFilters) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 1361 IllegalArgumentException { 1362 return triggerAdhocScript(project, script, options, nodeFilters, null, null); 1363 } 1364 1365 /** 1366 * Trigger the execution of an ad-hoc script, and return immediately (without waiting the end of the execution). The 1367 * script will be dispatched to nodes, accordingly to the nodeFilters parameter. 1368 * 1369 * @param project name of the project - mandatory 1370 * @param script inputStream for reading the script to be executed - mandatory 1371 * @param options of the script - optional. See {@link OptionsBuilder}. 1372 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} 1373 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1374 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1375 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 1376 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1377 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1378 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1379 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1380 * @see #triggerAdhocScript(String, String, Properties, Properties, Integer, Boolean) 1381 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1382 */ 1383 public RundeckExecution triggerAdhocScript(String project, InputStream script, Properties options, 1384 Properties nodeFilters, Integer nodeThreadcount, Boolean nodeKeepgoing) throws RundeckApiException, 1385 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1386 AssertUtil.notBlank(project, "project is mandatory to trigger an ad-hoc script !"); 1387 AssertUtil.notNull(script, "script is mandatory to trigger an ad-hoc script !"); 1388 RundeckExecution execution = new ApiCall(this).post(new ApiPathBuilder("/run/script").param("project", project) 1389 .attach("scriptFile", 1390 script) 1391 .param("argString", 1392 ParametersUtil.generateArgString(options)) 1393 .param("nodeThreadcount", 1394 nodeThreadcount) 1395 .param("nodeKeepgoing", 1396 nodeKeepgoing) 1397 .nodeFilters(nodeFilters), 1398 new ExecutionParser("result/execution")); 1399 // the first call just returns the ID of the execution, so we need another call to get a "real" execution 1400 return getExecution(execution.getId()); 1401 } 1402 1403 /** 1404 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1405 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1406 * running. The script will not be dispatched to nodes, but be executed on the RunDeck server. 1407 * 1408 * @param project name of the project - mandatory 1409 * @param scriptFilename filename of the script to be executed - mandatory 1410 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1411 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1412 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1413 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1414 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1415 * @throws IOException if we failed to read the file 1416 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1417 * @see #triggerAdhocScript(String, String) 1418 */ 1419 public RundeckExecution runAdhocScript(String project, String scriptFilename) throws RundeckApiException, 1420 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 1421 return runAdhocScript(project, scriptFilename, null); 1422 } 1423 1424 /** 1425 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1426 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1427 * finished (or aborted) or is still running. The script will not be dispatched to nodes, but be executed on the 1428 * RunDeck server. 1429 * 1430 * @param project name of the project - mandatory 1431 * @param scriptFilename filename of the script to be executed - mandatory 1432 * @param poolingInterval for checking the status of the execution. Must be > 0. 1433 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1434 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1435 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1436 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1437 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1438 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1439 * @throws IOException if we failed to read the file 1440 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1441 * @see #triggerAdhocScript(String, String) 1442 */ 1443 public RundeckExecution runAdhocScript(String project, String scriptFilename, long poolingInterval, 1444 TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 1445 IllegalArgumentException, IOException { 1446 return runAdhocScript(project, scriptFilename, null, poolingInterval, poolingUnit); 1447 } 1448 1449 /** 1450 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1451 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1452 * running. The script will not be dispatched to nodes, but be executed on the RunDeck server. 1453 * 1454 * @param project name of the project - mandatory 1455 * @param scriptFilename filename of the script to be executed - mandatory 1456 * @param options of the script - optional. See {@link OptionsBuilder}. 1457 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1458 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1459 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1460 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1461 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1462 * @throws IOException if we failed to read the file 1463 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1464 * @see #triggerAdhocScript(String, String, Properties) 1465 */ 1466 public RundeckExecution runAdhocScript(String project, String scriptFilename, Properties options) 1467 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, 1468 IOException { 1469 return runAdhocScript(project, scriptFilename, options, null); 1470 } 1471 1472 /** 1473 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1474 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1475 * finished (or aborted) or is still running. The script will not be dispatched to nodes, but be executed on the 1476 * RunDeck server. 1477 * 1478 * @param project name of the project - mandatory 1479 * @param scriptFilename filename of the script to be executed - mandatory 1480 * @param options of the script - optional. See {@link OptionsBuilder}. 1481 * @param poolingInterval for checking the status of the execution. Must be > 0. 1482 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1483 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1484 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1485 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1486 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1487 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1488 * @throws IOException if we failed to read the file 1489 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1490 * @see #triggerAdhocScript(String, String, Properties) 1491 */ 1492 public RundeckExecution runAdhocScript(String project, String scriptFilename, Properties options, 1493 long poolingInterval, TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, 1494 RundeckApiTokenException, IllegalArgumentException, IOException { 1495 return runAdhocScript(project, scriptFilename, options, null, poolingInterval, poolingUnit); 1496 } 1497 1498 /** 1499 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1500 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1501 * running. The script will be dispatched to nodes, accordingly to the nodeFilters parameter. 1502 * 1503 * @param project name of the project - mandatory 1504 * @param scriptFilename filename of the script to be executed - mandatory 1505 * @param options of the script - optional. See {@link OptionsBuilder}. 1506 * @param nodeFilters for selecting nodes on which the script will be executed. See {@link NodeFiltersBuilder} 1507 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1508 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1509 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1510 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1511 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1512 * @throws IOException if we failed to read the file 1513 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1514 * @see #triggerAdhocScript(String, String, Properties, Properties) 1515 */ 1516 public RundeckExecution runAdhocScript(String project, String scriptFilename, Properties options, 1517 Properties nodeFilters) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 1518 IllegalArgumentException, IOException { 1519 return runAdhocScript(project, scriptFilename, options, nodeFilters, null, null); 1520 } 1521 1522 /** 1523 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1524 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1525 * finished (or aborted) or is still running. The script will be dispatched to nodes, accordingly to the nodeFilters 1526 * parameter. 1527 * 1528 * @param project name of the project - mandatory 1529 * @param scriptFilename filename of the script to be executed - mandatory 1530 * @param options of the script - optional. See {@link OptionsBuilder}. 1531 * @param nodeFilters for selecting nodes on which the script will be executed. See {@link NodeFiltersBuilder} 1532 * @param poolingInterval for checking the status of the execution. Must be > 0. 1533 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1534 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1535 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1536 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1537 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1538 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1539 * @throws IOException if we failed to read the file 1540 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1541 * @see #triggerAdhocScript(String, String, Properties, Properties) 1542 */ 1543 public RundeckExecution runAdhocScript(String project, String scriptFilename, Properties options, 1544 Properties nodeFilters, long poolingInterval, TimeUnit poolingUnit) throws RundeckApiException, 1545 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 1546 return runAdhocScript(project, scriptFilename, options, nodeFilters, null, null, poolingInterval, poolingUnit); 1547 } 1548 1549 /** 1550 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1551 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1552 * running. The script will be dispatched to nodes, accordingly to the nodeFilters parameter. 1553 * 1554 * @param project name of the project - mandatory 1555 * @param scriptFilename filename of the script to be executed - mandatory 1556 * @param options of the script - optional. See {@link OptionsBuilder}. 1557 * @param nodeFilters for selecting nodes on which the script will be executed. See {@link NodeFiltersBuilder} 1558 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1559 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1560 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1561 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1562 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1563 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1564 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1565 * @throws IOException if we failed to read the file 1566 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1567 * @see #triggerAdhocScript(String, String, Properties, Properties, Integer, Boolean) 1568 */ 1569 public RundeckExecution runAdhocScript(String project, String scriptFilename, Properties options, 1570 Properties nodeFilters, Integer nodeThreadcount, Boolean nodeKeepgoing) throws RundeckApiException, 1571 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 1572 return runAdhocScript(project, 1573 scriptFilename, 1574 options, 1575 nodeFilters, 1576 nodeThreadcount, 1577 nodeKeepgoing, 1578 DEFAULT_POOLING_INTERVAL, 1579 DEFAULT_POOLING_UNIT); 1580 } 1581 1582 /** 1583 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1584 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1585 * finished (or aborted) or is still running. The script will be dispatched to nodes, accordingly to the nodeFilters 1586 * parameter. 1587 * 1588 * @param project name of the project - mandatory 1589 * @param scriptFilename filename of the script to be executed - mandatory 1590 * @param options of the script - optional. See {@link OptionsBuilder}. 1591 * @param nodeFilters for selecting nodes on which the script will be executed. See {@link NodeFiltersBuilder} 1592 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1593 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1594 * @param poolingInterval for checking the status of the execution. Must be > 0. 1595 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1596 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1597 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1598 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1599 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1600 * @throws IllegalArgumentException if the project or scriptFilename is blank (null, empty or whitespace) 1601 * @throws IOException if we failed to read the file 1602 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1603 * @see #triggerAdhocScript(String, String, Properties, Properties, Integer, Boolean) 1604 */ 1605 public RundeckExecution runAdhocScript(String project, String scriptFilename, Properties options, 1606 Properties nodeFilters, Integer nodeThreadcount, Boolean nodeKeepgoing, long poolingInterval, 1607 TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 1608 IllegalArgumentException, IOException { 1609 AssertUtil.notBlank(scriptFilename, "scriptFilename is mandatory to run an ad-hoc script !"); 1610 FileInputStream stream = null; 1611 try { 1612 stream = FileUtils.openInputStream(new File(scriptFilename)); 1613 return runAdhocScript(project, 1614 stream, 1615 options, 1616 nodeFilters, 1617 nodeThreadcount, 1618 nodeKeepgoing, 1619 poolingInterval, 1620 poolingUnit); 1621 } finally { 1622 IOUtils.closeQuietly(stream); 1623 } 1624 } 1625 1626 /** 1627 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1628 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1629 * running. The script will not be dispatched to nodes, but be executed on the RunDeck server. 1630 * 1631 * @param project name of the project - mandatory 1632 * @param script inputStream for reading the script to be executed - mandatory 1633 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1634 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1635 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1636 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1637 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1638 * @throws IOException if we failed to read the file 1639 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1640 * @see #triggerAdhocScript(String, InputStream) 1641 */ 1642 public RundeckExecution runAdhocScript(String project, InputStream script) throws RundeckApiException, 1643 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 1644 return runAdhocScript(project, script, null); 1645 } 1646 1647 /** 1648 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1649 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1650 * finished (or aborted) or is still running. The script will not be dispatched to nodes, but be executed on the 1651 * RunDeck server. 1652 * 1653 * @param project name of the project - mandatory 1654 * @param script inputStream for reading the script to be executed - mandatory 1655 * @param poolingInterval for checking the status of the execution. Must be > 0. 1656 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1657 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1658 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1659 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1660 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1661 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1662 * @throws IOException if we failed to read the file 1663 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1664 * @see #triggerAdhocScript(String, InputStream) 1665 */ 1666 public RundeckExecution runAdhocScript(String project, InputStream script, long poolingInterval, 1667 TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 1668 IllegalArgumentException, IOException { 1669 return runAdhocScript(project, script, null, poolingInterval, poolingUnit); 1670 } 1671 1672 /** 1673 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1674 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1675 * running. The script will not be dispatched to nodes, but be executed on the RunDeck server. 1676 * 1677 * @param project name of the project - mandatory 1678 * @param script inputStream for reading the script to be executed - mandatory 1679 * @param options of the script - optional. See {@link OptionsBuilder}. 1680 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1681 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1682 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1683 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1684 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1685 * @throws IOException if we failed to read the file 1686 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1687 * @see #triggerAdhocScript(String, InputStream, Properties) 1688 */ 1689 public RundeckExecution runAdhocScript(String project, InputStream script, Properties options) 1690 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, 1691 IOException { 1692 return runAdhocScript(project, script, options, null); 1693 } 1694 1695 /** 1696 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1697 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1698 * finished (or aborted) or is still running. The script will not be dispatched to nodes, but be executed on the 1699 * RunDeck server. 1700 * 1701 * @param project name of the project - mandatory 1702 * @param script inputStream for reading the script to be executed - mandatory 1703 * @param options of the script - optional. See {@link OptionsBuilder}. 1704 * @param poolingInterval for checking the status of the execution. Must be > 0. 1705 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1706 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1707 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1708 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1709 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1710 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1711 * @throws IOException if we failed to read the file 1712 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1713 * @see #triggerAdhocScript(String, InputStream, Properties) 1714 */ 1715 public RundeckExecution runAdhocScript(String project, InputStream script, Properties options, 1716 long poolingInterval, TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, 1717 RundeckApiTokenException, IllegalArgumentException, IOException { 1718 return runAdhocScript(project, script, options, null, poolingInterval, poolingUnit); 1719 } 1720 1721 /** 1722 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1723 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1724 * running. The script will be dispatched to nodes, accordingly to the nodeFilters parameter. 1725 * 1726 * @param project name of the project - mandatory 1727 * @param script inputStream for reading the script to be executed - mandatory 1728 * @param options of the script - optional. See {@link OptionsBuilder}. 1729 * @param nodeFilters for selecting nodes on which the script will be executed. See {@link NodeFiltersBuilder} 1730 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1731 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1732 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1733 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1734 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1735 * @throws IOException if we failed to read the file 1736 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1737 * @see #triggerAdhocScript(String, InputStream, Properties, Properties) 1738 */ 1739 public RundeckExecution runAdhocScript(String project, InputStream script, Properties options, 1740 Properties nodeFilters) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 1741 IllegalArgumentException, IOException { 1742 return runAdhocScript(project, script, options, nodeFilters, null, null); 1743 } 1744 1745 /** 1746 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1747 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1748 * finished (or aborted) or is still running. The script will be dispatched to nodes, accordingly to the nodeFilters 1749 * parameter. 1750 * 1751 * @param project name of the project - mandatory 1752 * @param script inputStream for reading the script to be executed - mandatory 1753 * @param options of the script - optional. See {@link OptionsBuilder}. 1754 * @param nodeFilters for selecting nodes on which the script will be executed. See {@link NodeFiltersBuilder} 1755 * @param poolingInterval for checking the status of the execution. Must be > 0. 1756 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1757 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1758 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1759 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1760 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1761 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1762 * @throws IOException if we failed to read the file 1763 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1764 * @see #triggerAdhocScript(String, InputStream, Properties, Properties) 1765 */ 1766 public RundeckExecution runAdhocScript(String project, InputStream script, Properties options, 1767 Properties nodeFilters, long poolingInterval, TimeUnit poolingUnit) throws RundeckApiException, 1768 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 1769 return runAdhocScript(project, script, options, nodeFilters, null, null, poolingInterval, poolingUnit); 1770 } 1771 1772 /** 1773 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1774 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still 1775 * running. The script will be dispatched to nodes, accordingly to the nodeFilters parameter. 1776 * 1777 * @param project name of the project - mandatory 1778 * @param script inputStream for reading the script to be executed - mandatory 1779 * @param options of the script - optional. See {@link OptionsBuilder}. 1780 * @param nodeFilters for selecting nodes on which the script will be executed. See {@link NodeFiltersBuilder} 1781 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1782 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1783 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1784 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1785 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1786 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1787 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1788 * @throws IOException if we failed to read the file 1789 * @see #runAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean, long, TimeUnit) 1790 * @see #triggerAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean) 1791 */ 1792 public RundeckExecution runAdhocScript(String project, InputStream script, Properties options, 1793 Properties nodeFilters, Integer nodeThreadcount, Boolean nodeKeepgoing) throws RundeckApiException, 1794 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException, IOException { 1795 return runAdhocScript(project, 1796 script, 1797 options, 1798 nodeFilters, 1799 nodeThreadcount, 1800 nodeKeepgoing, 1801 DEFAULT_POOLING_INTERVAL, 1802 DEFAULT_POOLING_UNIT); 1803 } 1804 1805 /** 1806 * Run an ad-hoc script, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck 1807 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is 1808 * finished (or aborted) or is still running. The script will be dispatched to nodes, accordingly to the nodeFilters 1809 * parameter. 1810 * 1811 * @param project name of the project - mandatory 1812 * @param script inputStream for reading the script to be executed - mandatory 1813 * @param options of the script - optional. See {@link OptionsBuilder}. 1814 * @param nodeFilters for selecting nodes on which the script will be executed. See {@link NodeFiltersBuilder} 1815 * @param nodeThreadcount thread count to use (for parallelizing when running on multiple nodes) - optional 1816 * @param nodeKeepgoing if true, continue executing on other nodes even if some fail - optional 1817 * @param poolingInterval for checking the status of the execution. Must be > 0. 1818 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. 1819 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 1820 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1821 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1822 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1823 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) or the script is null 1824 * @throws IOException if we failed to read the file 1825 * @see #runAdhocScript(String, String, Properties, Properties, Integer, Boolean, long, TimeUnit) 1826 * @see #triggerAdhocScript(String, InputStream, Properties, Properties, Integer, Boolean) 1827 */ 1828 public RundeckExecution runAdhocScript(String project, InputStream script, Properties options, 1829 Properties nodeFilters, Integer nodeThreadcount, Boolean nodeKeepgoing, long poolingInterval, 1830 TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, 1831 IllegalArgumentException { 1832 if (poolingInterval <= 0) { 1833 poolingInterval = DEFAULT_POOLING_INTERVAL; 1834 poolingUnit = DEFAULT_POOLING_UNIT; 1835 } 1836 if (poolingUnit == null) { 1837 poolingUnit = DEFAULT_POOLING_UNIT; 1838 } 1839 1840 RundeckExecution execution = triggerAdhocScript(project, 1841 script, 1842 options, 1843 nodeFilters, 1844 nodeThreadcount, 1845 nodeKeepgoing); 1846 while (ExecutionStatus.RUNNING.equals(execution.getStatus())) { 1847 try { 1848 Thread.sleep(poolingUnit.toMillis(poolingInterval)); 1849 } catch (InterruptedException e) { 1850 break; 1851 } 1852 execution = getExecution(execution.getId()); 1853 } 1854 return execution; 1855 } 1856 1857 /* 1858 * Executions 1859 */ 1860 1861 /** 1862 * Get all running executions (for all projects) 1863 * 1864 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null 1865 * @throws RundeckApiException in case of error when calling the API 1866 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1867 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1868 * @see #getRunningExecutions(String) 1869 */ 1870 public List<RundeckExecution> getRunningExecutions() throws RundeckApiException, RundeckApiLoginException, 1871 RundeckApiTokenException { 1872 List<RundeckExecution> executions = new ArrayList<RundeckExecution>(); 1873 for (RundeckProject project : getProjects()) { 1874 executions.addAll(getRunningExecutions(project.getName())); 1875 } 1876 return executions; 1877 } 1878 1879 /** 1880 * Get the running executions for the given project 1881 * 1882 * @param project name of the project - mandatory 1883 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null 1884 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 1885 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1886 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1887 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 1888 * @see #getRunningExecutions() 1889 */ 1890 public List<RundeckExecution> getRunningExecutions(String project) throws RundeckApiException, 1891 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1892 AssertUtil.notBlank(project, "project is mandatory get all running executions !"); 1893 return new ApiCall(this).get(new ApiPathBuilder("/executions/running").param("project", project), 1894 new ListParser<RundeckExecution>(new ExecutionParser(), 1895 "result/executions/execution")); 1896 } 1897 1898 /** 1899 * Get the executions of the given job 1900 * 1901 * @param jobId identifier of the job - mandatory 1902 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null 1903 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 1904 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1905 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1906 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 1907 * @see #getJobExecutions(String, RundeckExecution.ExecutionStatus, Long, Long) 1908 */ 1909 public List<RundeckExecution> getJobExecutions(String jobId) throws RundeckApiException, RundeckApiLoginException, 1910 RundeckApiTokenException, IllegalArgumentException { 1911 return getJobExecutions(jobId, (ExecutionStatus) null); 1912 } 1913 1914 /** 1915 * Get the executions of the given job 1916 * 1917 * @param jobId identifier of the job - mandatory 1918 * @param status of the executions, see {@link ExecutionStatus} - optional (null for all) 1919 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null 1920 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 1921 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1922 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1923 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace), or the executionStatus is 1924 * invalid 1925 * @see #getJobExecutions(String, String, Long, Long) 1926 */ 1927 public List<RundeckExecution> getJobExecutions(String jobId, String status) throws RundeckApiException, 1928 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1929 return getJobExecutions(jobId, 1930 StringUtils.isBlank(status) ? null : ExecutionStatus.valueOf(StringUtils.upperCase(status))); 1931 } 1932 1933 /** 1934 * Get the executions of the given job 1935 * 1936 * @param jobId identifier of the job - mandatory 1937 * @param status of the executions, see {@link ExecutionStatus} - optional (null for all) 1938 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null 1939 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 1940 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1941 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1942 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 1943 * @see #getJobExecutions(String, RundeckExecution.ExecutionStatus, Long, Long) 1944 */ 1945 public List<RundeckExecution> getJobExecutions(String jobId, ExecutionStatus status) throws RundeckApiException, 1946 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1947 return getJobExecutions(jobId, status, null, null); 1948 } 1949 1950 /** 1951 * Get the executions of the given job 1952 * 1953 * @param jobId identifier of the job - mandatory 1954 * @param status of the executions, see {@link ExecutionStatus} - optional (null for all) 1955 * @param max number of results to return - optional (null for all) 1956 * @param offset the 0-indexed offset for the first result to return - optional 1957 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null 1958 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 1959 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1960 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1961 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace), or the executionStatus is 1962 * invalid 1963 * @see #getJobExecutions(String, RundeckExecution.ExecutionStatus, Long, Long) 1964 */ 1965 public List<RundeckExecution> getJobExecutions(String jobId, String status, Long max, Long offset) 1966 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1967 return getJobExecutions(jobId, 1968 StringUtils.isBlank(status) ? null : ExecutionStatus.valueOf(StringUtils.upperCase(status)), 1969 max, 1970 offset); 1971 } 1972 1973 /** 1974 * Get the executions of the given job 1975 * 1976 * @param jobId identifier of the job - mandatory 1977 * @param status of the executions, see {@link ExecutionStatus} - optional (null for all) 1978 * @param max number of results to return - optional (null for all) 1979 * @param offset the 0-indexed offset for the first result to return - optional 1980 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null 1981 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 1982 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 1983 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 1984 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) 1985 */ 1986 public List<RundeckExecution> getJobExecutions(String jobId, ExecutionStatus status, Long max, Long offset) 1987 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 1988 AssertUtil.notBlank(jobId, "jobId is mandatory to get the executions of a job !"); 1989 return new ApiCall(this).get(new ApiPathBuilder("/job/", jobId, "/executions").param("status", status) 1990 .param("max", max) 1991 .param("offset", offset), 1992 new ListParser<RundeckExecution>(new ExecutionParser(), 1993 "result/executions/execution")); 1994 } 1995 1996 /** 1997 * Get a single execution, identified by the given ID 1998 * 1999 * @param executionId identifier of the execution - mandatory 2000 * @return a {@link RundeckExecution} instance - won't be null 2001 * @throws RundeckApiException in case of error when calling the API (non-existent execution with this ID) 2002 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2003 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2004 * @throws IllegalArgumentException if the executionId is null 2005 */ 2006 public RundeckExecution getExecution(Long executionId) throws RundeckApiException, RundeckApiLoginException, 2007 RundeckApiTokenException, IllegalArgumentException { 2008 AssertUtil.notNull(executionId, "executionId is mandatory to get the details of an execution !"); 2009 return new ApiCall(this).get(new ApiPathBuilder("/execution/", executionId.toString()), 2010 new ExecutionParser("result/executions/execution")); 2011 } 2012 2013 /** 2014 * Abort an execution (identified by the given ID). The execution should be running... 2015 * 2016 * @param executionId identifier of the execution - mandatory 2017 * @return a {@link RundeckAbort} instance - won't be null 2018 * @throws RundeckApiException in case of error when calling the API (non-existent execution with this ID) 2019 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2020 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2021 * @throws IllegalArgumentException if the executionId is null 2022 */ 2023 public RundeckAbort abortExecution(Long executionId) throws RundeckApiException, RundeckApiLoginException, 2024 RundeckApiTokenException, IllegalArgumentException { 2025 AssertUtil.notNull(executionId, "executionId is mandatory to abort an execution !"); 2026 return new ApiCall(this).get(new ApiPathBuilder("/execution/", executionId.toString(), "/abort"), 2027 new AbortParser("result/abort")); 2028 } 2029 2030 /* 2031 * History 2032 */ 2033 2034 /** 2035 * Get the (events) history for the given project 2036 * 2037 * @param project name of the project - mandatory 2038 * @return a {@link RundeckHistory} instance - won't be null 2039 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2040 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2041 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2042 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2043 * @see #getHistory(String, String, String, String, String, Date, Date, Long, Long) 2044 */ 2045 public RundeckHistory getHistory(String project) throws RundeckApiException, RundeckApiLoginException, 2046 RundeckApiTokenException, IllegalArgumentException { 2047 return getHistory(project, null, null, null, null, null, null, null, null); 2048 } 2049 2050 /** 2051 * Get the (events) history for the given project 2052 * 2053 * @param project name of the project - mandatory 2054 * @param max number of results to return - optional (default to 20) 2055 * @param offset the 0-indexed offset for the first result to return - optional (default to O) 2056 * @return a {@link RundeckHistory} instance - won't be null 2057 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2058 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2059 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2060 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2061 * @see #getHistory(String, String, String, String, String, Date, Date, Long, Long) 2062 */ 2063 public RundeckHistory getHistory(String project, Long max, Long offset) throws RundeckApiException, 2064 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 2065 return getHistory(project, null, null, null, null, null, null, max, offset); 2066 } 2067 2068 /** 2069 * Get the (events) history for the given project 2070 * 2071 * @param project name of the project - mandatory 2072 * @param jobId include only events matching the given job ID - optional 2073 * @param reportId include only events matching the given report ID - optional 2074 * @param user include only events created by the given user - optional 2075 * @return a {@link RundeckHistory} instance - won't be null 2076 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2077 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2078 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2079 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2080 * @see #getHistory(String, String, String, String, String, Date, Date, Long, Long) 2081 */ 2082 public RundeckHistory getHistory(String project, String jobId, String reportId, String user) 2083 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 2084 return getHistory(project, jobId, reportId, user, null, null, null, null, null); 2085 } 2086 2087 /** 2088 * Get the (events) history for the given project 2089 * 2090 * @param project name of the project - mandatory 2091 * @param jobId include only events matching the given job ID - optional 2092 * @param reportId include only events matching the given report ID - optional 2093 * @param user include only events created by the given user - optional 2094 * @param max number of results to return - optional (default to 20) 2095 * @param offset the 0-indexed offset for the first result to return - optional (default to O) 2096 * @return a {@link RundeckHistory} instance - won't be null 2097 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2098 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2099 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2100 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2101 * @see #getHistory(String, String, String, String, String, Date, Date, Long, Long) 2102 */ 2103 public RundeckHistory getHistory(String project, String jobId, String reportId, String user, Long max, Long offset) 2104 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 2105 return getHistory(project, jobId, reportId, user, null, null, null, max, offset); 2106 } 2107 2108 /** 2109 * Get the (events) history for the given project 2110 * 2111 * @param project name of the project - mandatory 2112 * @param recent include only events matching the given period of time. Format : "XY", where X is an integer, and Y 2113 * is one of : "h" (hour), "d" (day), "w" (week), "m" (month), "y" (year). Example : "2w" (= last 2 2114 * weeks), "5d" (= last 5 days), etc. Optional. 2115 * @return a {@link RundeckHistory} instance - won't be null 2116 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2117 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2118 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2119 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2120 * @see #getHistory(String, String, String, String, String, Date, Date, Long, Long) 2121 */ 2122 public RundeckHistory getHistory(String project, String recent) throws RundeckApiException, 2123 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 2124 return getHistory(project, null, null, null, recent, null, null, null, null); 2125 } 2126 2127 /** 2128 * Get the (events) history for the given project 2129 * 2130 * @param project name of the project - mandatory 2131 * @param recent include only events matching the given period of time. Format : "XY", where X is an integer, and Y 2132 * is one of : "h" (hour), "d" (day), "w" (week), "m" (month), "y" (year). Example : "2w" (= last 2 2133 * weeks), "5d" (= last 5 days), etc. Optional. 2134 * @param max number of results to return - optional (default to 20) 2135 * @param offset the 0-indexed offset for the first result to return - optional (default to O) 2136 * @return a {@link RundeckHistory} instance - won't be null 2137 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2138 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2139 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2140 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2141 * @see #getHistory(String, String, String, String, String, Date, Date, Long, Long) 2142 */ 2143 public RundeckHistory getHistory(String project, String recent, Long max, Long offset) throws RundeckApiException, 2144 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 2145 return getHistory(project, null, null, null, recent, null, null, max, offset); 2146 } 2147 2148 /** 2149 * Get the (events) history for the given project 2150 * 2151 * @param project name of the project - mandatory 2152 * @param begin date for the earlier events to retrieve - optional 2153 * @param end date for the latest events to retrieve - optional 2154 * @return a {@link RundeckHistory} instance - won't be null 2155 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2156 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2157 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2158 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2159 * @see #getHistory(String, String, String, String, String, Date, Date, Long, Long) 2160 */ 2161 public RundeckHistory getHistory(String project, Date begin, Date end) throws RundeckApiException, 2162 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 2163 return getHistory(project, null, null, null, null, begin, end, null, null); 2164 } 2165 2166 /** 2167 * Get the (events) history for the given project 2168 * 2169 * @param project name of the project - mandatory 2170 * @param begin date for the earlier events to retrieve - optional 2171 * @param end date for the latest events to retrieve - optional 2172 * @param max number of results to return - optional (default to 20) 2173 * @param offset the 0-indexed offset for the first result to return - optional (default to O) 2174 * @return a {@link RundeckHistory} instance - won't be null 2175 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2176 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2177 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2178 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2179 * @see #getHistory(String, String, String, String, String, Date, Date, Long, Long) 2180 */ 2181 public RundeckHistory getHistory(String project, Date begin, Date end, Long max, Long offset) 2182 throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 2183 return getHistory(project, null, null, null, null, begin, end, max, offset); 2184 } 2185 2186 /** 2187 * Get the (events) history for the given project 2188 * 2189 * @param project name of the project - mandatory 2190 * @param jobId include only events matching the given job ID - optional 2191 * @param reportId include only events matching the given report ID - optional 2192 * @param user include only events created by the given user - optional 2193 * @param recent include only events matching the given period of time. Format : "XY", where X is an integer, and Y 2194 * is one of : "h" (hour), "d" (day), "w" (week), "m" (month), "y" (year). Example : "2w" (= last 2 2195 * weeks), "5d" (= last 5 days), etc. Optional. 2196 * @param begin date for the earlier events to retrieve - optional 2197 * @param end date for the latest events to retrieve - optional 2198 * @param max number of results to return - optional (default to 20) 2199 * @param offset the 0-indexed offset for the first result to return - optional (default to O) 2200 * @return a {@link RundeckHistory} instance - won't be null 2201 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2202 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2203 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2204 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2205 */ 2206 public RundeckHistory getHistory(String project, String jobId, String reportId, String user, String recent, 2207 Date begin, Date end, Long max, Long offset) throws RundeckApiException, RundeckApiLoginException, 2208 RundeckApiTokenException, IllegalArgumentException { 2209 AssertUtil.notBlank(project, "project is mandatory to get the history !"); 2210 return new ApiCall(this).get(new ApiPathBuilder("/history").param("project", project) 2211 .param("jobIdFilter", jobId) 2212 .param("reportIdFilter", reportId) 2213 .param("userFilter", user) 2214 .param("recentFilter", recent) 2215 .param("begin", begin) 2216 .param("end", end) 2217 .param("max", max) 2218 .param("offset", offset), 2219 new HistoryParser("result/events")); 2220 } 2221 2222 /* 2223 * Nodes 2224 */ 2225 2226 /** 2227 * List all nodes (for all projects) 2228 * 2229 * @return a {@link List} of {@link RundeckNode} : might be empty, but won't be null 2230 * @throws RundeckApiException in case of error when calling the API 2231 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2232 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2233 */ 2234 public List<RundeckNode> getNodes() throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException { 2235 List<RundeckNode> nodes = new ArrayList<RundeckNode>(); 2236 for (RundeckProject project : getProjects()) { 2237 nodes.addAll(getNodes(project.getName())); 2238 } 2239 return nodes; 2240 } 2241 2242 /** 2243 * List all nodes that belongs to the given project 2244 * 2245 * @param project name of the project - mandatory 2246 * @return a {@link List} of {@link RundeckNode} : might be empty, but won't be null 2247 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2248 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2249 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2250 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2251 * @see #getNodes(String, Properties) 2252 */ 2253 public List<RundeckNode> getNodes(String project) throws RundeckApiException, RundeckApiLoginException, 2254 RundeckApiTokenException, IllegalArgumentException { 2255 return getNodes(project, null); 2256 } 2257 2258 /** 2259 * List nodes that belongs to the given project 2260 * 2261 * @param project name of the project - mandatory 2262 * @param nodeFilters for filtering the nodes - optional. See {@link NodeFiltersBuilder} 2263 * @return a {@link List} of {@link RundeckNode} : might be empty, but won't be null 2264 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 2265 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2266 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2267 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) 2268 */ 2269 public List<RundeckNode> getNodes(String project, Properties nodeFilters) throws RundeckApiException, 2270 RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException { 2271 AssertUtil.notBlank(project, "project is mandatory to get all nodes !"); 2272 return new ApiCall(this).get(new ApiPathBuilder("/resources").param("project", project) 2273 .nodeFilters(nodeFilters), 2274 new ListParser<RundeckNode>(new NodeParser(), "project/node")); 2275 } 2276 2277 /** 2278 * Get the definition of a single node 2279 * 2280 * @param name of the node - mandatory 2281 * @param project name of the project - mandatory 2282 * @return a {@link RundeckNode} instance - won't be null 2283 * @throws RundeckApiException in case of error when calling the API (non-existent name or project with this name) 2284 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2285 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2286 * @throws IllegalArgumentException if the name or project is blank (null, empty or whitespace) 2287 */ 2288 public RundeckNode getNode(String name, String project) throws RundeckApiException, RundeckApiLoginException, 2289 RundeckApiTokenException, IllegalArgumentException { 2290 AssertUtil.notBlank(name, "the name of the node is mandatory to get a node !"); 2291 AssertUtil.notBlank(project, "project is mandatory to get a node !"); 2292 return new ApiCall(this).get(new ApiPathBuilder("/resource/", name).param("project", project), 2293 new NodeParser("project/node")); 2294 } 2295 2296 /* 2297 * System Info 2298 */ 2299 2300 /** 2301 * Get system informations about the RunDeck server 2302 * 2303 * @return a {@link RundeckSystemInfo} instance - won't be null 2304 * @throws RundeckApiException in case of error when calling the API 2305 * @throws RundeckApiLoginException if the login fails (in case of login-based authentication) 2306 * @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication) 2307 */ 2308 public RundeckSystemInfo getSystemInfo() throws RundeckApiException, RundeckApiLoginException, 2309 RundeckApiTokenException { 2310 return new ApiCall(this).get(new ApiPathBuilder("/system/info"), new SystemInfoParser("result/system")); 2311 } 2312 2313 /** 2314 * @return the URL of the RunDeck instance ("http://localhost:4440", "http://rundeck.your-compagny.com/", etc) 2315 */ 2316 public String getUrl() { 2317 return url; 2318 } 2319 2320 /** 2321 * @return the auth-token used for authentication on the RunDeck instance (null if using login-based auth) 2322 */ 2323 public String getToken() { 2324 return token; 2325 } 2326 2327 /** 2328 * @return the login used for authentication on the RunDeck instance (null if using token-based auth) 2329 */ 2330 public String getLogin() { 2331 return login; 2332 } 2333 2334 /** 2335 * @return the password used for authentication on the RunDeck instance (null if using token-based auth) 2336 */ 2337 public String getPassword() { 2338 return password; 2339 } 2340 2341 @Override 2342 public String toString() { 2343 StringBuilder str = new StringBuilder(); 2344 str.append("RundeckClient ").append(API_VERSION); 2345 str.append(" [").append(url).append("] "); 2346 if (token != null) { 2347 str.append("(token=").append(token).append(")"); 2348 } else { 2349 str.append("(credentials=").append(login).append("|").append(password).append(")"); 2350 } 2351 return str.toString(); 2352 } 2353 2354 @Override 2355 public int hashCode() { 2356 final int prime = 31; 2357 int result = 1; 2358 result = prime * result + ((login == null) ? 0 : login.hashCode()); 2359 result = prime * result + ((password == null) ? 0 : password.hashCode()); 2360 result = prime * result + ((token == null) ? 0 : token.hashCode()); 2361 result = prime * result + ((url == null) ? 0 : url.hashCode()); 2362 return result; 2363 } 2364 2365 @Override 2366 public boolean equals(Object obj) { 2367 if (this == obj) 2368 return true; 2369 if (obj == null) 2370 return false; 2371 if (getClass() != obj.getClass()) 2372 return false; 2373 RundeckClient other = (RundeckClient) obj; 2374 if (login == null) { 2375 if (other.login != null) 2376 return false; 2377 } else if (!login.equals(other.login)) 2378 return false; 2379 if (password == null) { 2380 if (other.password != null) 2381 return false; 2382 } else if (!password.equals(other.password)) 2383 return false; 2384 if (token == null) { 2385 if (other.token != null) 2386 return false; 2387 } else if (!token.equals(other.token)) 2388 return false; 2389 if (url == null) { 2390 if (other.url != null) 2391 return false; 2392 } else if (!url.equals(other.url)) 2393 return false; 2394 return true; 2395 } 2396 2397 }