jenkins_api_client 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|