jenkins_api_client 0.9.1 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -0
- data/CHANGELOG.md +9 -2
- data/Gemfile +1 -0
- data/README.md +15 -0
- data/Rakefile +2 -0
- data/java_deps/jenkins-cli.jar +0 -0
- data/jenkins_api_client.gemspec +100 -0
- data/lib/jenkins_api_client/build_queue.rb +3 -0
- data/lib/jenkins_api_client/cli/base.rb +7 -1
- data/lib/jenkins_api_client/cli/helper.rb +8 -0
- data/lib/jenkins_api_client/cli/job.rb +24 -1
- data/lib/jenkins_api_client/cli/node.rb +12 -0
- data/lib/jenkins_api_client/cli/system.rb +5 -0
- data/lib/jenkins_api_client/client.rb +150 -32
- data/lib/jenkins_api_client/exceptions.rb +16 -0
- data/lib/jenkins_api_client/job.rb +5 -1
- data/lib/jenkins_api_client/node.rb +2 -0
- data/lib/jenkins_api_client/system.rb +2 -0
- data/lib/jenkins_api_client/version.rb +7 -2
- data/lib/jenkins_api_client/view.rb +3 -0
- data/scripts/login_with_irb.rb +39 -1
- data/spec/unit_tests/client_spec.rb +51 -0
- data/spec/unit_tests/job_spec.rb +4 -2
- metadata +156 -127
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,10 +4,17 @@ CHANGELOG
|
|
4
4
|
upcoming
|
5
5
|
--------
|
6
6
|
|
7
|
+
v0.10.0 [24-APR-2013]
|
8
|
+
----------------------
|
9
|
+
* new function to execute jenkins CLI `cli_exec`. Credit: @missedone
|
10
|
+
* Add ability to use http proxy. Credit: @woodbusy
|
11
|
+
* prompt the user for credentials when using irb login script. @woodbusy
|
12
|
+
* bugfix for job.console_output. Credit: @drnic
|
13
|
+
* add ssl support. Credit: @madisp
|
14
|
+
|
7
15
|
v0.9.1 [01-APR-2013]
|
8
16
|
---------------------
|
9
|
-
* Removed the dependency of ActiveSupport and Builder as they were not being
|
10
|
-
* used.
|
17
|
+
* Removed the dependency of ActiveSupport and Builder as they were not being used.
|
11
18
|
|
12
19
|
v0.9.0 [10-MAR-2013]
|
13
20
|
---------------------
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -147,6 +147,21 @@ initial_jobs.each do |job|
|
|
147
147
|
end
|
148
148
|
```
|
149
149
|
|
150
|
+
### Running Jenkins CLI
|
151
|
+
To running [Jenkins CLI](https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI)
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
@client = JenkinsApi::Client.new(:server_ip => '0.0.0.0',
|
155
|
+
:username => 'somename', :password => 'secret password')
|
156
|
+
# The following call will return the version of Jenkins instance
|
157
|
+
puts @client.exec_cli("version")
|
158
|
+
```
|
159
|
+
|
160
|
+
Before you run the CLI, please make sure the following requirements are fulfilled:
|
161
|
+
* JRE/JDK 6 (or above) is installed, and 'java' is on the $PATH environment variable
|
162
|
+
* The ```jenkins_api_client/java_deps/jenkins-cli.jar``` is required as the client to run the CLI. You can retrieve the available commands via accessing the URL: ```http://<server>:<port>/cli```
|
163
|
+
* (Optional) required if you run the Groovy Script through CLI, make sure the *user* have the privilige to run script
|
164
|
+
|
150
165
|
### Using with command line
|
151
166
|
Command line interface is supported only from version 0.2.0.
|
152
167
|
See help using <tt>jenkinscli help</tt>
|
data/Rakefile
CHANGED
Binary file
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "jenkins_api_client"
|
8
|
+
s.version = "0.9.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Kannan Manickam"]
|
12
|
+
s.date = "2013-04-16"
|
13
|
+
s.description = "\nThis is a simple and easy-to-use Jenkins Api client with features focused on\nautomating Job configuration programaticaly and so forth"
|
14
|
+
s.email = ["arangamani.kannan@gmail.com"]
|
15
|
+
s.executables = ["jenkinscli"]
|
16
|
+
s.files = [
|
17
|
+
".gitignore",
|
18
|
+
".jenkins.yml",
|
19
|
+
".travis.yml",
|
20
|
+
"CHANGELOG.md",
|
21
|
+
"Gemfile",
|
22
|
+
"LICENCE",
|
23
|
+
"README.md",
|
24
|
+
"Rakefile",
|
25
|
+
"bin/jenkinscli",
|
26
|
+
"config/login.yml.example",
|
27
|
+
"java_deps/jenkins-cli.jar",
|
28
|
+
"lib/jenkins_api_client.rb",
|
29
|
+
"lib/jenkins_api_client/build_queue.rb",
|
30
|
+
"lib/jenkins_api_client/cli/base.rb",
|
31
|
+
"lib/jenkins_api_client/cli/helper.rb",
|
32
|
+
"lib/jenkins_api_client/cli/job.rb",
|
33
|
+
"lib/jenkins_api_client/cli/node.rb",
|
34
|
+
"lib/jenkins_api_client/cli/system.rb",
|
35
|
+
"lib/jenkins_api_client/client.rb",
|
36
|
+
"lib/jenkins_api_client/exceptions.rb",
|
37
|
+
"lib/jenkins_api_client/job.rb",
|
38
|
+
"lib/jenkins_api_client/node.rb",
|
39
|
+
"lib/jenkins_api_client/system.rb",
|
40
|
+
"lib/jenkins_api_client/version.rb",
|
41
|
+
"lib/jenkins_api_client/view.rb",
|
42
|
+
"scripts/login_with_irb.rb",
|
43
|
+
"spec/func_tests/client_spec.rb",
|
44
|
+
"spec/func_tests/job_spec.rb",
|
45
|
+
"spec/func_tests/node_spec.rb",
|
46
|
+
"spec/func_tests/spec_helper.rb",
|
47
|
+
"spec/func_tests/system_spec.rb",
|
48
|
+
"spec/func_tests/view_spec.rb",
|
49
|
+
"spec/unit_tests/build_queue_spec.rb",
|
50
|
+
"spec/unit_tests/client_spec.rb",
|
51
|
+
"spec/unit_tests/fixtures/files/computer_sample.xml",
|
52
|
+
"spec/unit_tests/fixtures/files/job_sample.xml",
|
53
|
+
"spec/unit_tests/job_spec.rb",
|
54
|
+
"spec/unit_tests/node_spec.rb",
|
55
|
+
"spec/unit_tests/spec_helper.rb",
|
56
|
+
"spec/unit_tests/system_spec.rb",
|
57
|
+
"spec/unit_tests/view_spec.rb"
|
58
|
+
]
|
59
|
+
s.homepage = "https://github.com/arangamani/jenkins_api_client"
|
60
|
+
s.require_paths = ["lib"]
|
61
|
+
s.rubygems_version = "1.8.25"
|
62
|
+
s.summary = "Jenkins JSON API Client"
|
63
|
+
|
64
|
+
if s.respond_to? :specification_version then
|
65
|
+
s.specification_version = 3
|
66
|
+
|
67
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
68
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
|
69
|
+
s.add_runtime_dependency(%q<thor>, [">= 0.16.0"])
|
70
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
71
|
+
s.add_runtime_dependency(%q<terminal-table>, [">= 1.4.0"])
|
72
|
+
s.add_runtime_dependency(%q<mixlib-shellout>, ["~> 1.1.0"])
|
73
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0"])
|
74
|
+
s.add_development_dependency(%q<jeweler>, [">= 1.6.4"])
|
75
|
+
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
76
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
79
|
+
s.add_dependency(%q<thor>, [">= 0.16.0"])
|
80
|
+
s.add_dependency(%q<json>, [">= 0"])
|
81
|
+
s.add_dependency(%q<terminal-table>, [">= 1.4.0"])
|
82
|
+
s.add_dependency(%q<mixlib-shellout>, ["~> 1.1.0"])
|
83
|
+
s.add_dependency(%q<bundler>, [">= 1.0"])
|
84
|
+
s.add_dependency(%q<jeweler>, [">= 1.6.4"])
|
85
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
86
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
87
|
+
end
|
88
|
+
else
|
89
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
90
|
+
s.add_dependency(%q<thor>, [">= 0.16.0"])
|
91
|
+
s.add_dependency(%q<json>, [">= 0"])
|
92
|
+
s.add_dependency(%q<terminal-table>, [">= 1.4.0"])
|
93
|
+
s.add_dependency(%q<mixlib-shellout>, ["~> 1.1.0"])
|
94
|
+
s.add_dependency(%q<bundler>, [">= 1.0"])
|
95
|
+
s.add_dependency(%q<jeweler>, [">= 1.6.4"])
|
96
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
97
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
@@ -22,6 +22,9 @@
|
|
22
22
|
|
23
23
|
module JenkinsApi
|
24
24
|
class Client
|
25
|
+
# This classes communicates with the Build Queue API exposed by Jenkins at
|
26
|
+
# "/queue" that gives information about jobs/tasks in the queue and their
|
27
|
+
# details.
|
25
28
|
class BuildQueue
|
26
29
|
|
27
30
|
# Initializes a new BuildQueue object.
|
@@ -27,8 +27,10 @@ require "#{File.dirname(__FILE__)}/job.rb"
|
|
27
27
|
require "#{File.dirname(__FILE__)}/system.rb"
|
28
28
|
|
29
29
|
module JenkinsApi
|
30
|
+
# This is the base module for all command line interface for Jenkins API.
|
30
31
|
module CLI
|
31
|
-
|
32
|
+
# This is the base class for the command line interface which adds other
|
33
|
+
# classes as subcommands to the CLI.
|
32
34
|
class Base < Thor
|
33
35
|
|
34
36
|
class_option :username, :aliases => "-u", :desc => "Name of Jenkins user"
|
@@ -46,10 +48,12 @@ module JenkinsApi
|
|
46
48
|
map "-v" => :version
|
47
49
|
|
48
50
|
desc "version", "Shows current version"
|
51
|
+
# CLI command that returns the version of Jenkins API Client
|
49
52
|
def version
|
50
53
|
puts JenkinsApi::Client::VERSION
|
51
54
|
end
|
52
55
|
|
56
|
+
# Register the CLI::Node class as "node" subcommand to CLI
|
53
57
|
register(
|
54
58
|
CLI::Node,
|
55
59
|
'node',
|
@@ -57,6 +61,7 @@ module JenkinsApi
|
|
57
61
|
'Provides functions to access the node interface of Jenkins CI server'
|
58
62
|
)
|
59
63
|
|
64
|
+
# Register the CLI::Job class as "job" subcommand to CLI
|
60
65
|
register(
|
61
66
|
CLI::Job,
|
62
67
|
'job',
|
@@ -64,6 +69,7 @@ module JenkinsApi
|
|
64
69
|
'Provides functions to access the job interface of Jenkins CI server'
|
65
70
|
)
|
66
71
|
|
72
|
+
# Register the CLI::System class as "system" subcommand to CLI
|
67
73
|
register(
|
68
74
|
CLI::System,
|
69
75
|
'system',
|
@@ -24,7 +24,15 @@ require 'fileutils'
|
|
24
24
|
|
25
25
|
module JenkinsApi
|
26
26
|
module CLI
|
27
|
+
# This is the helper class that sets up the credentials from the command
|
28
|
+
# line parameters given and initializes the Jenkins API Client.
|
27
29
|
class Helper
|
30
|
+
# Sets up the credentials and initializes the Jenkins API Client
|
31
|
+
#
|
32
|
+
# @param [Hash] options Options obtained from the command line
|
33
|
+
#
|
34
|
+
# @return [JenkinsApi::Client] A new Client object
|
35
|
+
#
|
28
36
|
def self.setup(options)
|
29
37
|
if options[:username] && options[:server_ip] && \
|
30
38
|
(options[:password] || options[:password_base64])
|
@@ -25,7 +25,7 @@ require 'thor/group'
|
|
25
25
|
|
26
26
|
module JenkinsApi
|
27
27
|
module CLI
|
28
|
-
|
28
|
+
# This class provides various command line operations related to jobs.
|
29
29
|
class Job < Thor
|
30
30
|
include Thor::Actions
|
31
31
|
|
@@ -33,6 +33,8 @@ module JenkinsApi
|
|
33
33
|
method_option :status, :aliases => "-t", :desc => "Status to filter"
|
34
34
|
method_option :filter, :aliases => "-f",
|
35
35
|
:desc => "Regular expression to filter jobs"
|
36
|
+
# CLI command to list all jobs in Jenkins or the ones matched by status
|
37
|
+
# or a regular expression
|
36
38
|
def list
|
37
39
|
@client = Helper.setup(parent_options)
|
38
40
|
if options[:filter] && options[:status]
|
@@ -48,24 +50,37 @@ module JenkinsApi
|
|
48
50
|
end
|
49
51
|
|
50
52
|
desc "recreate JOB", "Recreate a specified job"
|
53
|
+
# CLI command to recreate a job on Jenkins
|
51
54
|
def recreate(job)
|
52
55
|
@client = Helper.setup(parent_options)
|
53
56
|
@client.job.recreate(job)
|
54
57
|
end
|
55
58
|
|
56
59
|
desc "build JOB", "Build a job"
|
60
|
+
# CLI command to build a job given the name of the job
|
61
|
+
#
|
62
|
+
# @param [String] job Name of the job
|
63
|
+
#
|
57
64
|
def build(job)
|
58
65
|
@client = Helper.setup(parent_options)
|
59
66
|
@client.job.build(job)
|
60
67
|
end
|
61
68
|
|
62
69
|
desc "status JOB", "Get the current build status of a job"
|
70
|
+
# CLI command to get the status of a job
|
71
|
+
#
|
72
|
+
# @param [String] job Name of the job
|
73
|
+
#
|
63
74
|
def status(job)
|
64
75
|
@client = Helper.setup(parent_options)
|
65
76
|
puts @client.job.get_current_build_status(job)
|
66
77
|
end
|
67
78
|
|
68
79
|
desc "delete JOB", "Delete the job"
|
80
|
+
# CLI command to delete a job
|
81
|
+
#
|
82
|
+
# @param [String] job Name of the job
|
83
|
+
#
|
69
84
|
def delete(job)
|
70
85
|
@client = Helper.setup(parent_options)
|
71
86
|
puts @client.job.delete(job)
|
@@ -74,6 +89,10 @@ module JenkinsApi
|
|
74
89
|
desc "console JOB", "Print the progressive console output of a job"
|
75
90
|
method_option :sleep, :aliases => "-z",
|
76
91
|
:desc => "Time to wait between querying the API for console output"
|
92
|
+
# CLI command to obtain console output for a job
|
93
|
+
#
|
94
|
+
# @param [String] job Name of the job
|
95
|
+
#
|
77
96
|
def console(job)
|
78
97
|
@client = Helper.setup(parent_options)
|
79
98
|
# If debug is enabled, disable it. It shouldn't interfere
|
@@ -101,6 +120,10 @@ module JenkinsApi
|
|
101
120
|
|
102
121
|
desc "restrict JOB", "Restricts a job to a specific node"
|
103
122
|
method_option :node, :aliases => "-n", :desc => "Node to be restricted to"
|
123
|
+
# CLI command to restrict a job to a node
|
124
|
+
#
|
125
|
+
# @param [String] job Name of the job
|
126
|
+
#
|
104
127
|
def restrict(job)
|
105
128
|
@client = Helper.setup(parent_options)
|
106
129
|
if options[:node]
|
@@ -26,6 +26,7 @@ require 'terminal-table'
|
|
26
26
|
|
27
27
|
module JenkinsApi
|
28
28
|
module CLI
|
29
|
+
# This class provides various command line operations for the Node class.
|
29
30
|
class Node < Thor
|
30
31
|
include Thor::Actions
|
31
32
|
include Terminal
|
@@ -33,6 +34,8 @@ module JenkinsApi
|
|
33
34
|
desc "list", "List all nodes"
|
34
35
|
method_option :filter, :aliases => "-f",
|
35
36
|
:desc => "Regular expression to filter jobs"
|
37
|
+
# CLI command that lists all nodes/slaves available in Jenkins or the
|
38
|
+
# ones matching the filter provided
|
36
39
|
def list
|
37
40
|
@client = Helper.setup(parent_options)
|
38
41
|
if options[:filter]
|
@@ -43,6 +46,7 @@ module JenkinsApi
|
|
43
46
|
end
|
44
47
|
|
45
48
|
desc "print_general_attributes", "Prints general attributes of nodes"
|
49
|
+
# CLI command that prints the general attribtues of nodes
|
46
50
|
def print_general_attributes
|
47
51
|
@client = Helper.setup(parent_options)
|
48
52
|
general_attributes = Client::Node::GENERAL_ATTRIBUTES
|
@@ -55,6 +59,10 @@ module JenkinsApi
|
|
55
59
|
end
|
56
60
|
|
57
61
|
desc "print_node_attributes NODE", "Prints attributes specific to a node"
|
62
|
+
# CLI command to print the attributes specific to a node
|
63
|
+
#
|
64
|
+
# @param [String] node Name of the node
|
65
|
+
#
|
58
66
|
def print_node_attributes(node)
|
59
67
|
@client = Helper.setup(parent_options)
|
60
68
|
node_attributes = Client::Node::NODE_ATTRIBUTES
|
@@ -68,6 +76,10 @@ module JenkinsApi
|
|
68
76
|
end
|
69
77
|
|
70
78
|
desc "print_node_properties NODE", "Prints properties of a node"
|
79
|
+
# CLI command to print the properties of a specific node
|
80
|
+
#
|
81
|
+
# @param [String] node Name of the node
|
82
|
+
#
|
71
83
|
def print_node_properties(node)
|
72
84
|
@client = Helper.setup(parent_options)
|
73
85
|
node_properties = Client::Node::NODE_PROPERTIES
|
@@ -25,22 +25,26 @@ require 'thor/group'
|
|
25
25
|
|
26
26
|
module JenkinsApi
|
27
27
|
module CLI
|
28
|
+
# This class provides various command line operations to System class.
|
28
29
|
class System < Thor
|
29
30
|
include Thor::Actions
|
30
31
|
|
31
32
|
desc "quietdown", "Puts the Jenkins server in Quiet down mode"
|
33
|
+
# CLI command that puts Jenkins in Quiet Down mode
|
32
34
|
def quietdown
|
33
35
|
@client = Helper.setup(parent_options)
|
34
36
|
@client.system.quiet_down
|
35
37
|
end
|
36
38
|
|
37
39
|
desc "cancel_quietdown", "Cancels the Quiet down mode of Jenkins server"
|
40
|
+
# CLI command that cancels Jenkins from Quiet Down mode
|
38
41
|
def cancel_quietdown
|
39
42
|
@client = Helper.setup(parent_options)
|
40
43
|
@client.system.cancel_quiet_down
|
41
44
|
end
|
42
45
|
|
43
46
|
desc "reload", "Reload Jenkins server"
|
47
|
+
# CLI command to reload Jenkins configuration from disk
|
44
48
|
def reload
|
45
49
|
@client = Helper.setup(parent_options)
|
46
50
|
@client.system.reload
|
@@ -49,6 +53,7 @@ module JenkinsApi
|
|
49
53
|
desc "restart", "Restarts the Jenkins server"
|
50
54
|
method_option :force, :type => :boolean, :aliases => "-s",
|
51
55
|
:desc => "Force restart"
|
56
|
+
# CLI command to (force) restart Jenkins
|
52
57
|
def restart
|
53
58
|
@client = Helper.setup(parent_options)
|
54
59
|
force = options[:force] ? true : false
|
@@ -24,24 +24,34 @@ require 'rubygems'
|
|
24
24
|
require 'json'
|
25
25
|
require 'net/http'
|
26
26
|
require 'nokogiri'
|
27
|
-
#require 'active_support/core_ext'
|
28
|
-
#require 'active_support/builder'
|
29
27
|
require 'base64'
|
28
|
+
require "mixlib/shellout"
|
30
29
|
|
30
|
+
# The main module that contains the Client class and all subclasses that
|
31
|
+
# communicate with the Jenkins's Remote Access API.
|
31
32
|
module JenkinsApi
|
33
|
+
# This is the client class that acts as the bridge between the subclasses and
|
34
|
+
# Jnekins. This class contains methods that performs GET and POST requests
|
35
|
+
# for various operations.
|
32
36
|
class Client
|
33
37
|
attr_accessor :debug, :timeout
|
38
|
+
# Default port to be used to connect to Jenkins
|
34
39
|
DEFAULT_SERVER_PORT = 8080
|
40
|
+
# Default timeout in seconds to be used while performing operations
|
35
41
|
DEFAULT_TIMEOUT = 120
|
42
|
+
# Parameters that are permitted as options while initializing the client
|
36
43
|
VALID_PARAMS = [
|
37
44
|
"server_ip",
|
38
45
|
"server_port",
|
46
|
+
"proxy_ip",
|
47
|
+
"proxy_port",
|
39
48
|
"jenkins_path",
|
40
49
|
"username",
|
41
50
|
"password",
|
42
51
|
"password_base64",
|
43
52
|
"debug",
|
44
|
-
"timeout"
|
53
|
+
"timeout",
|
54
|
+
"ssl"
|
45
55
|
].freeze
|
46
56
|
|
47
57
|
# Initialize a Client object with Jenkins CI server credentials
|
@@ -51,6 +61,12 @@ module JenkinsApi
|
|
51
61
|
# * the +:server_port+ param is the port on which the Jenkins listens
|
52
62
|
# * the +:username+ param is the username used for connecting to the server
|
53
63
|
# * the +:password+ param is the password for connecting to the CI server
|
64
|
+
# * the +:ssl+ param indicates if Jenkins is accessible over HTTPS
|
65
|
+
# (defaults to false)
|
66
|
+
#
|
67
|
+
# @return [JenkinsApi::Client] a client object to Jenkins API
|
68
|
+
#
|
69
|
+
# @raise [ArgumentError] when required options are not provided.
|
54
70
|
#
|
55
71
|
def initialize(args)
|
56
72
|
args.each do |key, value|
|
@@ -58,18 +74,25 @@ module JenkinsApi
|
|
58
74
|
instance_variable_set("@#{key}", value)
|
59
75
|
end
|
60
76
|
end if args.is_a? Hash
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
77
|
+
unless @server_ip
|
78
|
+
raise ArgumentError, "Server IP is required to connect to Jenkins"
|
79
|
+
end
|
80
|
+
unless @username && (@password || @password_base64)
|
81
|
+
raise ArgumentError, "Credentials are required to connect to Jenkins"
|
82
|
+
end
|
83
|
+
if @proxy_ip.nil? ^ @proxy_port.nil?
|
84
|
+
raise ArgumentError, "Proxy IP and port must both be specified or" +
|
85
|
+
" both left nil"
|
86
|
+
end
|
87
|
+
@server_port = DEFAULT_SERVER_PORT unless @server_port
|
88
|
+
@timeout = DEFAULT_TIMEOUT unless @timeout
|
89
|
+
@ssl ||= false
|
90
|
+
@debug = false unless @debug
|
68
91
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
92
|
+
# Base64 decode inserts a newline character at the end. As a workaround
|
93
|
+
# added chomp to remove newline characters. I hope nobody uses newline
|
94
|
+
# characters at the end of their passwords :)
|
95
|
+
@password = Base64.decode64(@password_base64).chomp if @password_base64
|
73
96
|
end
|
74
97
|
|
75
98
|
# This method toggles the debug parameter in run time
|
@@ -80,56 +103,91 @@ module JenkinsApi
|
|
80
103
|
|
81
104
|
# Creates an instance to the Job class by passing a reference to self
|
82
105
|
#
|
106
|
+
# @return [JenkinsApi::Client::Job] An object to Job subclass
|
107
|
+
#
|
83
108
|
def job
|
84
109
|
JenkinsApi::Client::Job.new(self)
|
85
110
|
end
|
86
111
|
|
87
112
|
# Creates an instance to the System class by passing a reference to self
|
88
113
|
#
|
114
|
+
# @return [JenkinsApi::Client::System] An object to System subclass
|
115
|
+
#
|
89
116
|
def system
|
90
117
|
JenkinsApi::Client::System.new(self)
|
91
118
|
end
|
92
119
|
|
93
120
|
# Creates an instance to the Node class by passing a reference to self
|
94
121
|
#
|
122
|
+
# @return [JenkinsApi::Client::Node] An object to Node subclass
|
123
|
+
#
|
95
124
|
def node
|
96
125
|
JenkinsApi::Client::Node.new(self)
|
97
126
|
end
|
98
127
|
|
99
128
|
# Creates an instance to the View class by passing a reference to self
|
100
129
|
#
|
130
|
+
# @return [JenkinsApi::Client::View] An object to View subclass
|
131
|
+
#
|
101
132
|
def view
|
102
133
|
JenkinsApi::Client::View.new(self)
|
103
134
|
end
|
104
135
|
|
105
136
|
# Creates an instance to the BuildQueue by passing a reference to self
|
106
137
|
#
|
138
|
+
# @return [JenkinsApi::Client::BuildQueue] An object to BuildQueue subclass
|
139
|
+
#
|
107
140
|
def queue
|
108
141
|
JenkinsApi::Client::BuildQueue.new(self)
|
109
142
|
end
|
110
143
|
|
111
144
|
# Returns a string representing the class name
|
112
145
|
#
|
146
|
+
# @return [String] string representation of class name
|
147
|
+
#
|
113
148
|
def to_s
|
114
149
|
"#<JenkinsApi::Client>"
|
115
150
|
end
|
116
151
|
|
152
|
+
# Connects to the Jenkins server, sends the specified request and returns
|
153
|
+
# the response.
|
154
|
+
#
|
155
|
+
# @param [Net::HTTPRequest] request The request object to send
|
156
|
+
#
|
157
|
+
# @return [Net::HTTPResponse] Response from Jenkins
|
158
|
+
def make_http_request( request )
|
159
|
+
Net::HTTP.start(
|
160
|
+
@server_ip, @server_port, @proxy_ip, @proxy_port, :use_ssl => @ssl
|
161
|
+
) do |http|
|
162
|
+
return http.request(request)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
protected :make_http_request
|
166
|
+
|
117
167
|
# Obtains the root of Jenkins server. This function is used to see if
|
118
168
|
# Jenkins is running
|
169
|
+
#
|
170
|
+
# @return [Net::HTTP::Response] Response from Jenkins for "/"
|
171
|
+
#
|
119
172
|
def get_root
|
120
|
-
http = Net::HTTP.start(@server_ip, @server_port)
|
121
173
|
request = Net::HTTP::Get.new("/")
|
122
174
|
request.basic_auth @username, @password
|
123
|
-
|
175
|
+
make_http_request(request)
|
124
176
|
end
|
125
177
|
|
126
178
|
# Sends a GET request to the Jenkins CI server with the specified URL
|
127
179
|
#
|
128
|
-
# @param [String] url_prefix
|
180
|
+
# @param [String] url_prefix The prefix to use in the URL
|
181
|
+
# @param [String] tree A specific JSON tree to optimize the API call
|
182
|
+
# @param [String] url_suffix The suffix to be used in the URL
|
183
|
+
# @param [Boolean] raw_response Return complete Response object instead of
|
184
|
+
# JSON body of response
|
185
|
+
#
|
186
|
+
# @return [String, JSON] JSON response from Jenkins
|
129
187
|
#
|
130
|
-
def api_get_request(url_prefix, tree = nil, url_suffix ="/api/json"
|
188
|
+
def api_get_request(url_prefix, tree = nil, url_suffix ="/api/json",
|
189
|
+
raw_response = false)
|
131
190
|
url_prefix = "#{@jenkins_path}#{url_prefix}"
|
132
|
-
http = Net::HTTP.start(@server_ip, @server_port)
|
133
191
|
to_get = ""
|
134
192
|
if tree
|
135
193
|
to_get = "#{url_prefix}#{url_suffix}?#{tree}"
|
@@ -140,55 +198,62 @@ module JenkinsApi
|
|
140
198
|
request = Net::HTTP::Get.new(to_get)
|
141
199
|
puts "[INFO] GET #{to_get}" if @debug
|
142
200
|
request.basic_auth @username, @password
|
143
|
-
response =
|
144
|
-
|
201
|
+
response = make_http_request(request)
|
202
|
+
if raw_response
|
203
|
+
response
|
204
|
+
else
|
205
|
+
handle_exception(response, "body", url_suffix =~ /json/)
|
206
|
+
end
|
145
207
|
end
|
146
208
|
|
147
209
|
# Sends a POST message to the Jenkins CI server with the specified URL
|
148
210
|
#
|
149
|
-
# @param [String] url_prefix
|
150
|
-
# @param [Hash] form_data
|
211
|
+
# @param [String] url_prefix The prefix to be used in the URL
|
212
|
+
# @param [Hash] form_data Form data to send with POST request
|
213
|
+
#
|
214
|
+
# @return [String] Response code form Jenkins Response
|
151
215
|
#
|
152
216
|
def api_post_request(url_prefix, form_data = nil)
|
153
217
|
url_prefix = URI.escape("#{@jenkins_path}#{url_prefix}")
|
154
|
-
http = Net::HTTP.start(@server_ip, @server_port)
|
155
218
|
request = Net::HTTP::Post.new("#{url_prefix}")
|
156
219
|
puts "[INFO] PUT #{url_prefix}" if @debug
|
157
220
|
request.basic_auth @username, @password
|
158
221
|
request.content_type = 'application/json'
|
159
222
|
request.set_form_data(form_data) unless form_data.nil?
|
160
|
-
response =
|
223
|
+
response = make_http_request(request)
|
161
224
|
handle_exception(response)
|
162
225
|
end
|
163
226
|
|
164
227
|
# Obtains the configuration of a component from the Jenkins CI server
|
165
228
|
#
|
166
|
-
# @param [String] url_prefix
|
229
|
+
# @param [String] url_prefix The prefix to be used in the URL
|
230
|
+
#
|
231
|
+
# @return [String] XML configuration obtained from Jenkins
|
167
232
|
#
|
168
233
|
def get_config(url_prefix)
|
169
234
|
url_prefix = URI.escape("#{@jenkins_path}#{url_prefix}")
|
170
|
-
http = Net::HTTP.start(@server_ip, @server_port)
|
171
235
|
request = Net::HTTP::Get.new("#{url_prefix}/config.xml")
|
172
236
|
puts "[INFO] GET #{url_prefix}/config.xml" if @debug
|
173
237
|
request.basic_auth @username, @password
|
174
|
-
response =
|
238
|
+
response = make_http_request(request)
|
175
239
|
handle_exception(response, "body")
|
176
240
|
end
|
177
241
|
|
178
242
|
# Posts the given xml configuration to the url given
|
179
243
|
#
|
180
|
-
# @param [String] url_prefix
|
181
|
-
# @param [String] xml
|
244
|
+
# @param [String] url_prefix The prefix to be used in the URL
|
245
|
+
# @param [String] xml The XML configuration to be sent to Jenkins
|
246
|
+
#
|
247
|
+
# @return [String] Response code returned from Jenkins
|
182
248
|
#
|
183
249
|
def post_config(url_prefix, xml)
|
184
250
|
url_prefix = URI.escape("#{@jenkins_path}#{url_prefix}")
|
185
|
-
http = Net::HTTP.start(@server_ip, @server_port)
|
186
251
|
request = Net::HTTP::Post.new("#{url_prefix}")
|
187
252
|
puts "[INFO] PUT #{url_prefix}" if @debug
|
188
253
|
request.basic_auth @username, @password
|
189
254
|
request.body = xml
|
190
255
|
request.content_type = 'application/xml'
|
191
|
-
response =
|
256
|
+
response = make_http_request(request)
|
192
257
|
handle_exception(response)
|
193
258
|
end
|
194
259
|
|
@@ -219,8 +284,61 @@ module JenkinsApi
|
|
219
284
|
response["Date"]
|
220
285
|
end
|
221
286
|
|
287
|
+
# Execute the Jenkins CLI
|
288
|
+
#
|
289
|
+
# @param command [String] command name
|
290
|
+
# @param args [Array] the arguments for the command
|
291
|
+
#
|
292
|
+
# @return [String] command output from the CLI
|
293
|
+
#
|
294
|
+
# @raise [Exceptions::CLIException] if there are issues in running the
|
295
|
+
# commands using CLI
|
296
|
+
#
|
297
|
+
def exec_cli(command, args = [])
|
298
|
+
base_dir = File.dirname(__FILE__)
|
299
|
+
server_url = "http://#{@server_ip}:#{@server_port}/#{@jenkins_path}"
|
300
|
+
cmd = "java -jar #{base_dir}/../../java_deps/jenkins-cli.jar" +
|
301
|
+
" -s #{server_url} #{command}" +
|
302
|
+
" --username #{@username} --password #{@password} " +
|
303
|
+
args.join(' ')
|
304
|
+
java_cmd = Mixlib::ShellOut.new(cmd)
|
305
|
+
|
306
|
+
# Run the command
|
307
|
+
java_cmd.run_command
|
308
|
+
if java_cmd.stderr.empty?
|
309
|
+
java_cmd.stdout.chomp
|
310
|
+
else
|
311
|
+
# The stderr has a stack trace of the Java program. We'll already have
|
312
|
+
# a stack trace for Ruby. So just display a descriptive message for the
|
313
|
+
# error thrown by the CLI.
|
314
|
+
raise Exceptions::CLIException.new(java_cmd.stderr.split("\n").first)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
222
318
|
private
|
223
319
|
|
320
|
+
# Private method that handles the exception and raises with proper error
|
321
|
+
# message with the type of exception and returns the required values if no
|
322
|
+
# exceptions are raised.
|
323
|
+
#
|
324
|
+
# @param [Net::HTTP::Response] response Response from Jenkins
|
325
|
+
# @param [String] to_send What should be returned as a response. Allowed
|
326
|
+
# values: "code" and "body".
|
327
|
+
# @param [Boolean] send_json Boolean value used to determine whether to
|
328
|
+
# load the JSON or send the response as is.
|
329
|
+
#
|
330
|
+
# @return [String, JSON] Response returned whether loaded JSON or raw
|
331
|
+
# string
|
332
|
+
#
|
333
|
+
# @raise [Exceptions::UnauthorizedException] When invalid credentials are
|
334
|
+
# provided to connect to Jenkins
|
335
|
+
# @raise [Exceptions::NotFoundException] When the requested page on Jenkins
|
336
|
+
# is found
|
337
|
+
# @raise [Exceptions::InternelServerErrorException] When Jenkins returns a
|
338
|
+
# 500 Internel Server Error
|
339
|
+
# @raise [Exceptions::ApiException] Any other exception returned from
|
340
|
+
# Jenkins that are not categorized in the API Client.
|
341
|
+
#
|
224
342
|
def handle_exception(response, to_send = "code", send_json = false)
|
225
343
|
msg = "HTTP Code: #{response.code}, Response Body: #{response.body}"
|
226
344
|
case response.code.to_i
|