jenkins_api_client 1.5.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a4d136e1d892db0bf4411fbaa520ff62efc5162c
4
- data.tar.gz: 12dd02a2aefaf038614bb1c2ca74990890730a33
2
+ SHA256:
3
+ metadata.gz: aadb30157bc60ba6690d00e65c6f4189c9b67a99d28b237b1d6109eba3fb96dc
4
+ data.tar.gz: 56d061edfd578401afe42ab0ed595db447945a6dc09e36fabc6ca22dd5413af4
5
5
  SHA512:
6
- metadata.gz: 639225407882ad7ad86443327ee0de6e9d54df384e068d22dbfeea478e58e96cbc85f18cb5e5138e66beb2b121433a3f71335e641c8b65c8b13c09e2b613b36f
7
- data.tar.gz: a5e5b5d15e33dfe19f8b797524d250b2e78422ea41b7e57ee36d32ee7fed273ee32f5c77e0c01fc9b9c6122db7b0b3a48b0423662652024ec282b4dc8091276e
6
+ metadata.gz: 78c788fc101b7d84afa16a832bbb427c8edb56b9c4625c5ec8a2f494404eba2ebb5d57677fef03a173d7ae1bd6a1fe2916baf101bb1d1fb6642317a183926665
7
+ data.tar.gz: 04e8ab2ff60a70604b082cfa10a2f4cbafd11387893eeb39a8c45fc08291cde4f71f4c1fa4e7616e3d593e6a193006163a98d16162a2800cc795c48807d7dd4b
@@ -6,18 +6,15 @@ Gem::Specification.new do |s|
6
6
  s.name = "jenkins_api_client"
7
7
  s.version = ::JenkinsApi::Client::VERSION
8
8
 
9
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
- s.require_paths = ["lib"]
11
9
  s.authors = ["Kannan Manickam"]
12
10
  s.description = "\nThis is a simple and easy-to-use Jenkins Api client with features focused on\nautomating Job configuration programaticaly and so forth"
13
11
  s.email = ["arangamani.kannan@gmail.com"]
14
12
  s.executables = ['jenkinscli']
15
13
  s.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r{lib/|bin/|java_deps/|gemspec}) }
16
- s.require_paths = ['lib']
17
14
  s.homepage = 'https://github.com/arangamani/jenkins_api_client'
18
- s.required_ruby_version = ::Gem::Requirement.new('~> 2.1')
19
- s.rubygems_version = "2.4.5.1"
15
+ s.required_ruby_version = '>= 2.7'
20
16
  s.summary = "Jenkins JSON API Client"
17
+ s.licenses = ["MIT"]
21
18
 
22
19
  s.add_dependency 'nokogiri', '~> 1.6'
23
20
  s.add_dependency 'thor', '>= 0.16.0'
@@ -25,5 +22,5 @@ Gem::Specification.new do |s|
25
22
  s.add_dependency 'mixlib-shellout', '>= 1.1.0'
26
23
  s.add_dependency 'socksify', '>= 1.7.0'
27
24
  s.add_dependency 'json', '>= 1.0'
25
+ s.add_dependency 'addressable', '~> 2.7'
28
26
  end
29
-
@@ -30,6 +30,7 @@ require 'mixlib/shellout'
30
30
  require 'uri'
31
31
  require 'logger'
32
32
  require 'socksify/http'
33
+ require 'open-uri'
33
34
 
34
35
  # The main module that contains the Client class and all subclasses that
35
36
  # communicate with the Jenkins's Remote Access API.
@@ -66,6 +67,9 @@ module JenkinsApi
66
67
  "http_open_timeout",
67
68
  "http_read_timeout",
68
69
  "ssl",
70
+ "pkcs_file_path",
71
+ "pass_phrase",
72
+ "ca_file",
69
73
  "follow_redirects",
70
74
  "identity_file",
71
75
  "cookies"
@@ -91,6 +95,9 @@ module JenkinsApi
91
95
  # @option args [String] :proxy_protocol the proxy protocol ('socks' or 'http' (defaults to HTTP)
92
96
  # @option args [String] :jenkins_path ("/") the optional context path for Jenkins
93
97
  # @option args [Boolean] :ssl (false) indicates if Jenkins is accessible over HTTPS
98
+ # @option args [String] :pkcs_file_path ("/") the optional context path for pfx or p12 binary certificate file
99
+ # @option args [String] :pass_phrase password for pkcs_file_path certificate file
100
+ # @option args [String] :ca_file the path to a PEM encoded file containing trusted certificates used to verify peer certificate
94
101
  # @option args [Boolean] :follow_redirects this argument causes the client to follow a redirect (jenkins can
95
102
  # return a 30x when starting a build)
96
103
  # @option args [Fixnum] :timeout (120) This argument sets the timeout for operations that take longer (in seconds)
@@ -237,6 +244,14 @@ module JenkinsApi
237
244
  JenkinsApi::Client::User.new(self)
238
245
  end
239
246
 
247
+ # Creates an instance of the Root class by passing a reference to self
248
+ #
249
+ # @return [JenkinsApi::Client::Root] An object of Root subclass
250
+ #
251
+ def root
252
+ JenkinsApi::Client::Root.new(self)
253
+ end
254
+
240
255
  # Returns a string representing the class name
241
256
  #
242
257
  # @return [String] string representation of class name
@@ -252,6 +267,7 @@ module JenkinsApi
252
267
  def inspect
253
268
  "#<JenkinsApi::Client:0x#{(self.__id__ * 2).to_s(16)}" +
254
269
  " @ssl=#{@ssl.inspect}," +
270
+ " @ca_file=#{@ca_file.inspect}," +
255
271
  " @log_location=#{@log_location.inspect}," +
256
272
  " @log_level=#{@log_level.inspect}," +
257
273
  " @crumbs_enabled=#{@crumbs_enabled.inspect}," +
@@ -269,13 +285,7 @@ module JenkinsApi
269
285
  #
270
286
  def get_artifact(job_name,filename)
271
287
  @artifact = job.find_artifact(job_name)
272
- uri = URI.parse(@artifact)
273
- http = Net::HTTP.new(uri.host, uri.port)
274
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
275
- http.use_ssl = @ssl
276
- request = Net::HTTP::Get.new(uri.request_uri)
277
- request.basic_auth(@username, @password)
278
- response = http.request(request)
288
+ response = make_http_request(Net::HTTP::Get.new(@artifact))
279
289
  if response.code == "200"
280
290
  File.write(File.expand_path(filename), response.body)
281
291
  else
@@ -283,6 +293,41 @@ module JenkinsApi
283
293
  end
284
294
  end
285
295
 
296
+ # Connects to the server and download all artifacts of a build to a specified location
297
+ #
298
+ # @param [String] job_name
299
+ # @param [String] dldir location to save artifacts
300
+ # @param [Integer] build_number optional, defaults to current build
301
+ # @returns [String, Array] list of retrieved artifacts
302
+ #
303
+ def get_artifacts(job_name, dldir, build_number = nil)
304
+ @artifacts = job.find_artifacts(job_name,build_number)
305
+ results = []
306
+ @artifacts.each do |artifact|
307
+ uri = URI.parse(artifact)
308
+ http = Net::HTTP.new(uri.host, uri.port)
309
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
310
+ http.use_ssl = @ssl
311
+ request = Net::HTTP::Get.new(uri.request_uri)
312
+ request.basic_auth(@username, @password)
313
+ response = http.request(request)
314
+ # we want every thing after the last 'build' in the path to become the filename
315
+ if artifact.include?('/build/')
316
+ filename = artifact.split("/build/").last.gsub('/','-')
317
+ else
318
+ filename = File.basename(artifact)
319
+ end
320
+ filename = File.join(dldir, filename)
321
+ results << filename
322
+ if response.code == "200"
323
+ File.write(File.expand_path(filename), response.body)
324
+ else
325
+ raise "Couldn't get the artifact #{artifact} for job #{job}"
326
+ end
327
+ end
328
+ results
329
+ end
330
+
286
331
  # Connects to the Jenkins server, sends the specified request and returns
287
332
  # the response.
288
333
  #
@@ -302,17 +347,24 @@ module JenkinsApi
302
347
  when 'socks'
303
348
  http = Net::HTTP::SOCKSProxy(@proxy_ip, @proxy_port).start(@server_ip, @server_port)
304
349
  else
305
- raise "unknwon proxy protocol: '#{@proxy_protocol}'"
350
+ raise "unknown proxy protocol: '#{@proxy_protocol}'"
306
351
  end
307
352
  else
308
353
  http = Net::HTTP.new(@server_ip, @server_port)
309
354
  end
310
355
 
311
- if @ssl
356
+ if @ssl && @pkcs_file_path
312
357
  http.use_ssl = true
358
+ pkcs12 =OpenSSL::PKCS12.new(File.binread(@pkcs_file_path), @pass_phrase!=nil ? @pass_phrase : "")
359
+ http.cert = pkcs12.certificate
360
+ http.key = pkcs12.key
313
361
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
314
- end
362
+ elsif @ssl
363
+ http.use_ssl = true
315
364
 
365
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
366
+ http.ca_file = @ca_file if @ca_file
367
+ end
316
368
  http.open_timeout = @http_open_timeout
317
369
  http.read_timeout = @http_read_timeout
318
370
 
@@ -490,7 +542,7 @@ module JenkinsApi
490
542
  @logger.info "Initializing Jenkins Update Center..."
491
543
  @logger.debug "Obtaining the JSON data for Update Center..."
492
544
  # TODO: Clean me up
493
- update_center_data = open("http://updates.jenkins-ci.org/update-center.json").read
545
+ update_center_data = open("https://updates.jenkins.io/current/update-center.json").read
494
546
  # The Jenkins mirror returns the data in the following format
495
547
  # updateCenter.post(
496
548
  # {.. JSON data...}
@@ -299,6 +299,16 @@ module JenkinsApi
299
299
  xml.description
300
300
  xml.keepDependencies "#{params[:keep_dependencies]}"
301
301
  xml.properties
302
+ #buildlogs related stuff
303
+ if params[:discard_old_builds]
304
+ xml.logRotator(:class => 'hudson.tasks.LogRotator') do
305
+ xml.daysToKeep params[:discard_old_builds][:daysToKeep] || -1
306
+ xml.numToKeep params[:discard_old_builds][:numToKeep] || -1
307
+ xml.artifactDaysToKeep params[:discard_old_builds][:artifactDaysToKeep] || -1
308
+ xml.artifactNumToKeep params[:discard_old_builds][:artifactNumToKeep] || -1
309
+ end
310
+ end
311
+
302
312
  # SCM related stuff
303
313
  if params[:scm_provider] == 'subversion'
304
314
  # Build subversion related XML portion
@@ -744,13 +754,30 @@ module JenkinsApi
744
754
  "not_run"
745
755
  when "aborted"
746
756
  "aborted"
757
+ when "disabled"
758
+ "disabled"
747
759
  else
748
760
  "invalid"
749
761
  end
750
762
  end
751
763
 
764
+ # Determine if the build is queued
765
+ #
766
+ # @param [String] job_name
767
+ #
768
+ # @return [Integer] build number if queued, or [Boolean] false if not queued
769
+ #
770
+ def queued?(job_name)
771
+ queue_result = @client.api_get_request("/job/#{path_encode job_name}")['inQueue']
772
+ if queue_result
773
+ return @client.api_get_request("/job/#{path_encode job_name}")['nextBuildNumber']
774
+ else
775
+ return queue_result
776
+ end
777
+ end
778
+
752
779
  # Obtain the current build status of the job
753
- # By defaule Jenkins returns the color of the job status icon
780
+ # By default Jenkins returns the color of the job status icon
754
781
  # This function translates the color into a meaningful status
755
782
  #
756
783
  # @param [String] job_name
@@ -1086,6 +1113,23 @@ module JenkinsApi
1086
1113
  nil
1087
1114
  end
1088
1115
 
1116
+ # Obtain the plugin results for a specific build of a job
1117
+ #
1118
+ # @param [String] job_name
1119
+ # @param [Number] build_num
1120
+ # @param [String] plugin_name
1121
+ #
1122
+ def get_plugin_results(job_name, build_num, plugin_name)
1123
+ build_num = get_current_build_number(job_name) if build_num == 0
1124
+ @logger.info "Obtaining the '#{plugin_name}' plugin results of '#{job_name}'" +
1125
+ " Build ##{build_num}"
1126
+ @client.api_get_request("/job/#{path_encode job_name}/#{build_num}/#{plugin_name}Result")
1127
+ rescue Exceptions::NotFound
1128
+ # Not found is acceptable, as not all builds will have plugin results
1129
+ # and this is what jenkins throws at us in that case
1130
+ nil
1131
+ end
1132
+
1089
1133
  # Obtain detailed build info for a job
1090
1134
  #
1091
1135
  # @param [String] job_name
@@ -1399,6 +1443,71 @@ module JenkinsApi
1399
1443
  post_config(job_name, xml_modified)
1400
1444
  end
1401
1445
 
1446
+ # Add upstream projects to a specific job given the job name,
1447
+ # projects to be added as upstream projects, and the threshold
1448
+ #
1449
+ # @param [String] job_name
1450
+ # @param [String] upstream_projects - separated with comma
1451
+ # @param [String] threshold - failure, success, or unstable
1452
+ # @param [Boolean] overwrite - true or false
1453
+ #
1454
+ # @return [String] response_code return code from HTTP POST
1455
+ #
1456
+ def add_upstream_projects(job_name,
1457
+ upstream_projects,
1458
+ threshold, overwrite = false)
1459
+ @logger.info "Adding #{upstream_projects.inspect} as upstream" +
1460
+ " projects for '#{job_name}' with the threshold of '#{threshold}'" +
1461
+ " and overwrite option of '#{overwrite}'"
1462
+ name, ord, col = get_threshold_params(threshold)
1463
+ xml = get_config(job_name)
1464
+ n_xml = Nokogiri::XML(xml)
1465
+ upstream_projects_node = n_xml.xpath("//upstreamProjects").first
1466
+ if upstream_projects_node
1467
+ if overwrite
1468
+ upstream_projects_node.content = "#{upstream_projects}"
1469
+ else
1470
+ to_replace = upstream_projects_node.content +
1471
+ ", #{upstream_projects}"
1472
+ upstream_projects_node.content = to_replace
1473
+ end
1474
+ else
1475
+ triggers_node = n_xml.xpath("//triggers").first
1476
+ reverse_build_trigger_node = triggers_node.add_child(
1477
+ "<jenkins.triggers.ReverseBuildTrigger/>"
1478
+ )
1479
+ reverse_build_trigger_node.first.add_child(
1480
+ "<spec/>"
1481
+ )
1482
+ reverse_build_trigger_node.first.add_child(
1483
+ "<upstreamProjects>#{upstream_projects}</upstreamProjects>"
1484
+ )
1485
+ threshold_node = reverse_build_trigger_node.first.add_child(
1486
+ "<threshold/>"
1487
+ )
1488
+ threshold_node.first.add_child(
1489
+ "<name>#{name}</name><ordinal>#{ord}</ordinal><color>#{col}</color>"
1490
+ )
1491
+ end
1492
+ xml_modified = n_xml.to_xml
1493
+ post_config(job_name, xml_modified)
1494
+ end
1495
+
1496
+ # Remove all upstream projects of a specific job
1497
+ #
1498
+ # @param [String] job_name
1499
+ #
1500
+ # @return [String] response_code return code from HTTP POST
1501
+ #
1502
+ def remove_upstream_projects(job_name)
1503
+ @logger.info "Removing the upstream projects of '#{job_name}'"
1504
+ xml = get_config(job_name)
1505
+ n_xml = Nokogiri::XML(xml)
1506
+ n_xml.search("//jenkins.triggers.ReverseBuildTrigger").remove
1507
+ xml_modified = n_xml.to_xml
1508
+ post_config(job_name, xml_modified)
1509
+ end
1510
+
1402
1511
  # Resctrict the given job to a specific node
1403
1512
  #
1404
1513
  # @param [String] job_name
@@ -1546,15 +1655,49 @@ module JenkinsApi
1546
1655
  #A Method to find artifacts path from the Current Build
1547
1656
  #
1548
1657
  # @param [String] job_name
1658
+ # @param [Integer] build_number
1659
+ # defaults to latest build
1549
1660
  #
1550
- def find_artifact(job_name)
1551
- current_build_number = get_current_build_number(job_name)
1552
- job_path = "job/#{path_encode job_name}/"
1553
- response_json = @client.api_get_request("/#{job_path}#{current_build_number}")
1554
- relative_build_path = response_json['artifacts'][0]['relativePath']
1555
- jenkins_path = response_json['url']
1556
- artifact_path = URI.escape("#{jenkins_path}artifact/#{relative_build_path}")
1557
- return artifact_path
1661
+ def find_artifact(job_name, build_number = 0)
1662
+ find_artifacts(job_name, build_number).first
1663
+ end
1664
+
1665
+ #A Method to check artifact exists path from the Current Build
1666
+ #
1667
+ # @param [String] job_name
1668
+ # @param [Integer] build_number
1669
+ # defaults to latest build
1670
+ #
1671
+ def artifact_exists?(job_name, build_number = 0)
1672
+ begin
1673
+ artifact_path(job_name: job_name, build_number: build_number)
1674
+
1675
+ return true
1676
+ rescue Exception => e
1677
+ return false
1678
+ end
1679
+ end
1680
+
1681
+ # Find the artifacts for build_number of job_name, defaulting to current job
1682
+ #
1683
+ # @param [String] job_name
1684
+ # @param [Integer] build_number Optional build number
1685
+ # @return [String, Hash] JSON response from Jenkins
1686
+ #
1687
+ def find_artifacts(job_name, build_number = nil)
1688
+ response_json = get_build_details(job_name, build_number)
1689
+ artifact_path(build_details: response_json).map do |p|
1690
+ path_encode("#{response_json['url']}artifact/#{p['relativePath']}")
1691
+ end
1692
+ end
1693
+
1694
+ # Find the artifacts for the current job
1695
+ #
1696
+ # @param [String] job_name
1697
+ # @return [String, Hash] JSON response from Jenkins
1698
+ #
1699
+ def find_latest_artifacts(job_name)
1700
+ find_artifacts(job_name)
1558
1701
  end
1559
1702
 
1560
1703
  private
@@ -1795,6 +1938,29 @@ module JenkinsApi
1795
1938
  return nil unless tree_value
1796
1939
  "tree=#{tree_value}"
1797
1940
  end
1941
+
1942
+ # This private method gets the artifact path or throws an exception
1943
+ #
1944
+ # @param [Hash] job_name, build_number or build_details object
1945
+ #
1946
+ def artifact_path(params)
1947
+ job_name = params[:job_name]
1948
+ build_number = params[:build_number] || 0
1949
+ build_details = params[:build_details]
1950
+
1951
+ build_details = get_build_details(job_name, build_number) if build_details.nil?
1952
+ artifacts = build_details['artifacts']
1953
+ artifact_paths = []
1954
+
1955
+ if artifacts && artifacts.any?
1956
+ artifact_paths = artifacts.find_all{ |a| a.key?('relativePath') }
1957
+ end
1958
+
1959
+ if artifact_paths.empty?
1960
+ raise "No artifacts found."
1961
+ end
1962
+ artifact_paths
1963
+ end
1798
1964
  end
1799
1965
  end
1800
1966
  end
@@ -211,18 +211,42 @@ module JenkinsApi
211
211
  list.each { |node| delete(node) unless node == "master" }
212
212
  end
213
213
 
214
+ # This method returns two lists 1) nodes online 2) nodes offline
215
+ #
216
+ # @param [String] filter a regex to filter node names
217
+ # @param [Bool] ignorecase whether to be case sensitive or not
218
+ #
219
+ def online_offline_lists(filter = nil, ignorecase = true)
220
+ @logger.info "Obtaining nodes from jenkins matching filter '#{filter}'"
221
+ offline_node_names = []
222
+ online_node_names = []
223
+ response_json = @client.api_get_request("/computer")
224
+ response_json["computer"].each do |computer|
225
+ if computer["displayName"] =~ /#{filter}/i
226
+ if computer["offline"] == true
227
+ offline_node_names << computer["displayName"]
228
+ else
229
+ online_node_names << computer["displayName"]
230
+ end
231
+ end
232
+ end
233
+ return online_node_names, offline_node_names
234
+ end
235
+
214
236
  # This method lists all nodes
215
237
  #
216
238
  # @param [String] filter a regex to filter node names
217
239
  # @param [Bool] ignorecase whether to be case sensitive or not
218
240
  #
219
- def list(filter = nil, ignorecase = true)
241
+ def list(filter = nil, ignorecase = true, slaveonly = false)
220
242
  @logger.info "Obtaining nodes from jenkins matching filter '#{filter}'"
221
243
  node_names = []
222
244
  response_json = @client.api_get_request("/computer")
223
245
  response_json["computer"].each do |computer|
224
246
  if computer["displayName"] =~ /#{filter}/i
225
- node_names << computer["displayName"]
247
+ unless slaveonly && computer["displayName"] == "master"
248
+ node_names << computer["displayName"]
249
+ end
226
250
  end
227
251
  end
228
252
  node_names
@@ -148,7 +148,7 @@ module JenkinsApi
148
148
  # "pinned"=>true,
149
149
  # "shortName"=>"ldap",
150
150
  # "supportsDynamicLoad"=>"MAYBE",
151
- # "url"=>"http://wiki.jenkins-ci.org/display/JENKINS/LDAP+Plugin",
151
+ # "url"=>"https://wiki.jenkins.io/display/JENKINS/LDAP+Plugin",
152
152
  # "version"=>"1.5"
153
153
  # }
154
154
  #
@@ -256,7 +256,7 @@ module JenkinsApi
256
256
  # => {
257
257
  # "name"=>"status-view",
258
258
  # "sourceId"=>"default",
259
- # "url"=>"http://updates.jenkins-ci.org/download/plugins/status-view/1.0/status-view.hpi",
259
+ # "url"=>"https://updates.jenkins.io/download/plugins/status-view/1.0/status-view.hpi",
260
260
  # "version"=>"1.0",
261
261
  # "categories"=>["ui"],
262
262
  # "compatibleSinceVersion"=>nil,
@@ -266,7 +266,7 @@ module JenkinsApi
266
266
  # "installed"=>nil, "neededDependencies"=>[],
267
267
  # "requiredCore"=>"1.342",
268
268
  # "title"=>"Status View Plugin",
269
- # "wiki"=>"https://wiki.jenkins-ci.org/display/JENKINS/Status+View+Plugin"
269
+ # "wiki"=>"https://wiki.jenkins.io/display/JENKINS/Status+View+Plugin"
270
270
  # }
271
271
  #
272
272
  def get_available_info(plugin)
@@ -0,0 +1,67 @@
1
+ #
2
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
3
+ # of this software and associated documentation files (the "Software"), to deal
4
+ # in the Software without restriction, including without limitation the rights
5
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6
+ # copies of the Software, and to permit persons to whom the Software is
7
+ # furnished to do so, subject to the following conditions:
8
+ #
9
+ # The above copyright notice and this permission notice shall be included in
10
+ # all copies or substantial portions of the Software.
11
+ #
12
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18
+ # THE SOFTWARE.
19
+ #
20
+
21
+ require 'jenkins_api_client/urihelper'
22
+
23
+ module JenkinsApi
24
+ class Client
25
+ # This class communicates with Jenkins API at the root address to obtain details
26
+ # on the page displayed to users on the Jenkins' 'homepage,' and other
27
+ # data items such as quietingDown
28
+ class Root
29
+ include JenkinsApi::UriHelper
30
+
31
+ # Initializes a new root object
32
+ #
33
+ # @param client [Client] the client object
34
+ #
35
+ # @return [Root] the root object
36
+ #
37
+ def initialize(client)
38
+ @client = client
39
+ @logger = @client.logger
40
+ end
41
+
42
+ # Return a string representation of the object
43
+ #
44
+ def to_s
45
+ "#<JenkinsApi::Client::Root>"
46
+ end
47
+
48
+ # Check if Jenkins is in shutdown mode
49
+ #
50
+ # @return [Boolean] true if server in shutdown mode
51
+ #
52
+ def quieting_down?
53
+ response_json = @client.api_get_request('', 'tree=quietingDown')
54
+ response_json['quietingDown']
55
+ end
56
+
57
+ # Get message displayed to users on the homepage
58
+ #
59
+ # @return [String] description - message displayed to users
60
+ #
61
+ def description
62
+ response_json = @client.api_get_request('', 'tree=description')
63
+ response_json['description']
64
+ end
65
+ end
66
+ end
67
+ end
@@ -54,13 +54,20 @@ module JenkinsApi
54
54
  @client.api_post_request("/quietDown")
55
55
  end
56
56
 
57
- # Cancels the quiet doen request sent to the server.
57
+ # Cancels the quiet down request sent to the server.
58
58
  #
59
59
  def cancel_quiet_down
60
60
  @logger.info "Cancelling jenkins form quiet down..."
61
61
  @client.api_post_request("/cancelQuietDown")
62
62
  end
63
63
 
64
+ # Checks if server is in quiet down mode.
65
+ #
66
+ def check_quiet_down?
67
+ @logger.info "Checking if jenkins is in quiet down mode..."
68
+ @client.root.quieting_down?
69
+ end
70
+
64
71
  # Restarts the Jenkins server
65
72
  #
66
73
  # @param [Boolean] force whether to force restart or wait till all
@@ -1,4 +1,5 @@
1
1
  require 'uri'
2
+ require 'addressable/uri'
2
3
 
3
4
  module JenkinsApi
4
5
  module UriHelper
@@ -11,7 +12,7 @@ module JenkinsApi
11
12
  # Encode a string for use in the hiearchical part of an URL
12
13
  #
13
14
  def path_encode(path)
14
- URI.escape(path.encode(Encoding::UTF_8))
15
+ Addressable::URI.escape(path.encode(Encoding::UTF_8))
15
16
  end
16
17
  end
17
18
  end
@@ -22,15 +22,7 @@
22
22
 
23
23
  module JenkinsApi
24
24
  class Client
25
- # Major version of the gem
26
- MAJOR = 1
27
- # Minor version of the gem
28
- MINOR = 5
29
- # Tiny version of the gem used for patches
30
- TINY = 3
31
- # Used for pre-releases
32
- PRE = nil
33
25
  # Version String of Jenkins API Client.
34
- VERSION = [MAJOR, MINOR, TINY, PRE].compact.join('.')
26
+ VERSION = "2.0.0"
35
27
  end
36
28
  end
@@ -257,6 +257,38 @@ module JenkinsApi
257
257
  @client.api_post_request(post_msg)
258
258
  end
259
259
 
260
+ # List (sub-)views in a view
261
+ #
262
+ # @param [String] view_name
263
+ #
264
+ # @return [Array] view_names list of (sub-)views in the specified view
265
+ #
266
+ def list_views(view_name)
267
+ @logger.info "Obtaining the views present in view '#{view_name}'"
268
+ view_names = []
269
+ raise "The view #{view_name} doesn't exists on the server"\
270
+ unless exists?(view_name)
271
+ response_json = @client.api_get_request("/view/#{path_encode view_name}")
272
+ response_json["views"].each do |view|
273
+ view_names << view["name"]
274
+ end
275
+ view_names
276
+ end
277
+
278
+ # List (sub-)views in view along with their details
279
+ #
280
+ # @param [String] view_name
281
+ #
282
+ # @return [Array<Hash>] the details of (sub-)views in the specified view
283
+ #
284
+ def list_views_with_details(view_name)
285
+ @logger.info "Obtaining the views present in view '#{view_name}'"
286
+ raise "The view #{view_name} doesn't exists on the server"\
287
+ unless exists?(view_name)
288
+ response_json = @client.api_get_request("/view/#{path_encode view_name}")
289
+ response_json["views"]
290
+ end
291
+
260
292
  # Obtain the configuration stored in config.xml of a specific view
261
293
  #
262
294
  # @param [String] view_name
@@ -30,6 +30,7 @@ require 'jenkins_api_client/view'
30
30
  require 'jenkins_api_client/build_queue'
31
31
  require 'jenkins_api_client/plugin_manager'
32
32
  require 'jenkins_api_client/user'
33
+ require 'jenkins_api_client/root'
33
34
 
34
35
  require 'jenkins_api_client/cli/helper'
35
36
  require 'jenkins_api_client/cli/base'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jenkins_api_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kannan Manickam
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-30 00:00:00.000000000 Z
11
+ date: 2023-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: addressable
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.7'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.7'
97
111
  description: |2-
98
112
 
99
113
  This is a simple and easy-to-use Jenkins Api client with features focused on
@@ -124,13 +138,15 @@ files:
124
138
  - lib/jenkins_api_client/plugin_settings/collection.rb
125
139
  - lib/jenkins_api_client/plugin_settings/hipchat.rb
126
140
  - lib/jenkins_api_client/plugin_settings/workspace_cleanup.rb
141
+ - lib/jenkins_api_client/root.rb
127
142
  - lib/jenkins_api_client/system.rb
128
143
  - lib/jenkins_api_client/urihelper.rb
129
144
  - lib/jenkins_api_client/user.rb
130
145
  - lib/jenkins_api_client/version.rb
131
146
  - lib/jenkins_api_client/view.rb
132
147
  homepage: https://github.com/arangamani/jenkins_api_client
133
- licenses: []
148
+ licenses:
149
+ - MIT
134
150
  metadata: {}
135
151
  post_install_message:
136
152
  rdoc_options: []
@@ -138,17 +154,16 @@ require_paths:
138
154
  - lib
139
155
  required_ruby_version: !ruby/object:Gem::Requirement
140
156
  requirements:
141
- - - "~>"
157
+ - - ">="
142
158
  - !ruby/object:Gem::Version
143
- version: '2.1'
159
+ version: '2.7'
144
160
  required_rubygems_version: !ruby/object:Gem::Requirement
145
161
  requirements:
146
162
  - - ">="
147
163
  - !ruby/object:Gem::Version
148
164
  version: '0'
149
165
  requirements: []
150
- rubyforge_project:
151
- rubygems_version: 2.2.5
166
+ rubygems_version: 3.1.6
152
167
  signing_key:
153
168
  specification_version: 4
154
169
  summary: Jenkins JSON API Client