improved_jenkins_client 1.6.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 19904a21383083aac042b3519246181d77b42a0dd70a9d24681c3f1b1f4107eb
4
+ data.tar.gz: 59edb7776fff8d492802d16cbc098af2b7caf6143c98f9126a480050fc5aa510
5
+ SHA512:
6
+ metadata.gz: 612ea06785632e4b6392bcd2b8ee6250945f3baa59f96cae4c08fe1b28dbc4d5169ab25a3fb645d857cbac1e59e8561e6617b32625aea626ab505d7a87ce8aa9
7
+ data.tar.gz: 7f60050161fb200ef85ecb5d6304830dd6c9f7b339ee4fc16a727b1bcdab75efe4474cdce6181e8bc3d89428c663e77c88fd7acb6247ea53e29f91dc2ca6db20
data/bin/jenkinscli ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
4
+ require 'improved_jenkins_client'
5
+ JenkinsApi::CLI::Base.start
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'improved_jenkins_client/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "improved_jenkins_client"
7
+ s.version = ::JenkinsApi::Client::VERSION
8
+
9
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
+ s.require_paths = ["lib"]
11
+ s.authors = ["Kannan Manickam", "Yugabyte engineering team"]
12
+ s.description =
13
+ "\nThis is a simple and easy-to-use Jenkins Api client with features focused on" +
14
+ "\nautomating Job configuration programaticaly. Based on the improved_jenkins_client with" +
15
+ "\nimprovements by Yugabyte engineering team."
16
+
17
+ s.email = ["yugabyte-ci@users.noreply.github.com"]
18
+ s.executables = ['jenkinscli']
19
+ s.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r{lib/|bin/|java_deps/|gemspec}) }
20
+ s.require_paths = ['lib']
21
+ s.homepage = 'https://github.com/yugabyte-db/improved-ruby-jenkins-client'
22
+ s.required_ruby_version = ::Gem::Requirement.new('~> 2.1')
23
+ s.rubygems_version = "2.4.5.1"
24
+ s.summary = "Improved Jenkins JSON API Client"
25
+ s.licenses = ["MIT"]
26
+
27
+ s.add_dependency 'nokogiri', '~> 1.6'
28
+ s.add_dependency 'thor', '>= 0.16.0'
29
+ s.add_dependency 'terminal-table', '>= 1.4.0'
30
+ s.add_dependency 'mixlib-shellout', '>= 1.1.0'
31
+ s.add_dependency 'socksify', '>= 1.7.0'
32
+ s.add_dependency 'json', '>= 1.0'
33
+ s.add_dependency 'addressable', '~> 2.7'
34
+ end
Binary file
@@ -0,0 +1,262 @@
1
+ #
2
+ # Copyright (c) 2012-2013 Kannan Manickam <arangamani.kannan@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsApi
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.
28
+ #
29
+ class BuildQueue
30
+
31
+ # Initializes a new BuildQueue object.
32
+ #
33
+ # @param client [Client] the client object
34
+ #
35
+ # @return [BuildQueue] the build queue object
36
+ #
37
+ def initialize(client)
38
+ @client = client
39
+ @logger = @client.logger
40
+ end
41
+
42
+ # Returns a string representation of BuildQueue class.
43
+ #
44
+ def to_s
45
+ "#<JenkinsApi::Client::BuildQueue>"
46
+ end
47
+
48
+ # Gives the number of jobs currently in the build queue
49
+ #
50
+ def size
51
+ @logger.info "Obtaining the number of tasks in build queue"
52
+ response_json = @client.api_get_request("/queue")
53
+ response_json["items"].size
54
+ end
55
+
56
+ # Lists all tasks currently in the build queue
57
+ #
58
+ def list
59
+ @logger.info "Obtaining the tasks currently in the build queue"
60
+ response_json = @client.api_get_request("/queue")
61
+ tasks = []
62
+ response_json["items"].each do |item|
63
+ tasks << item["task"]["name"]
64
+ end
65
+ tasks
66
+ end
67
+
68
+ # Gets the time number of seconds the task is in the queue
69
+ #
70
+ # @param [String] task_name Name of the task/job
71
+ #
72
+ # @return [Fixnum] age in seconds
73
+ #
74
+ def get_age(task_name)
75
+ @logger.info "Obtaining the age of task '#{task_name}' from the" +
76
+ " build queue"
77
+ age = nil
78
+ details = get_details(task_name)
79
+ unless details.empty?
80
+ age = Time.now - Time.at(details["inQueueSince"].to_i/1000)
81
+ end
82
+ age
83
+ end
84
+
85
+ # Obtains the detail Hash from the API response
86
+ #
87
+ # @param [String] task_name Name of the task/job
88
+ #
89
+ # @return [Hash] Queue details of the specified task/job
90
+ #
91
+ def get_details(task_name)
92
+ @logger.info "Obtaining the details of task '#{task_name}' from the" +
93
+ " build queue"
94
+ response_json = @client.api_get_request("/queue")
95
+ details = {}
96
+ response_json["items"].each do |item|
97
+ details = item if item["task"]["name"] == task_name
98
+ end
99
+ details
100
+ end
101
+
102
+ # Obtain the item in the queue provided the ID of the task
103
+ #
104
+ # @param task_id [String] the ID of the task
105
+ #
106
+ # @return [Hash] the details of the item in the queue
107
+ #
108
+ def get_item_by_id(task_id)
109
+ @logger.info "Obtaining the details of task with ID '#{task_id}'"
110
+ @client.api_get_request("/queue/item/#{task_id}")
111
+ end
112
+
113
+ # Obtains the causes from the build queue for the specified task
114
+ #
115
+ # @param [String] task_name
116
+ #
117
+ # @return [Array] causes for the task to be in queue
118
+ #
119
+ def get_causes(task_name)
120
+ @logger.info "Obtaining the causes of task '#{task_name}' from the" +
121
+ " build queue"
122
+ causes = nil
123
+ details = get_details(task_name)
124
+ unless details.empty?
125
+ causes = []
126
+ details["actions"].each do |action|
127
+ causes << action["causes"]
128
+ end
129
+ end
130
+ causes
131
+ end
132
+
133
+ # Obtains the reason why the task is in queue
134
+ #
135
+ # @param [String] task_name name of the task
136
+ #
137
+ # @return [String] reason for being in queue, nil if no task found
138
+ #
139
+ def get_reason(task_name)
140
+ @logger.info "Obtaining the reason of task '#{task_name}' from the" +
141
+ " build queue"
142
+ reason = nil
143
+ details = get_details(task_name)
144
+ unless details.empty?
145
+ reason = details["why"]
146
+ end
147
+ reason
148
+ end
149
+
150
+ # Obtains the ETA given by Jenkins if any
151
+ #
152
+ # @param [String] task_name name of the task
153
+ #
154
+ # @return [String] ETA for the task, nil if no task found and N/A for
155
+ # tasks with no ETA info.
156
+ #
157
+ def get_eta(task_name)
158
+ @logger.info "Obtaining the ETA for the task '#{task_name}' from the" +
159
+ " build queue"
160
+ eta = nil
161
+ details = get_details(task_name)
162
+ unless details.empty?
163
+ matched = details["why"].match(/.*\(ETA:(.*)\)/)
164
+ if matched.nil?
165
+ # Task is found, but ETA information is not available
166
+ eta = "N/A"
167
+ else
168
+ # ETA information is available
169
+ eta = matched[1].strip
170
+ end
171
+ end
172
+ eta
173
+ end
174
+
175
+ # Obtains the ID of the task from the queue
176
+ #
177
+ # @param [String] task_name name of the task
178
+ #
179
+ # @return [String] ID of the task, nil of no task is found
180
+ #
181
+ def get_id(task_name)
182
+ @logger.info "Obtaining the ID of task '#{task_name}' from the" +
183
+ " build queue"
184
+ id = nil
185
+ details = get_details(task_name)
186
+ unless details.empty?
187
+ id = details["id"]
188
+ end
189
+ id
190
+ end
191
+
192
+ # Obtains the params from the build queue
193
+ #
194
+ # @param [String] task_name name of the task
195
+ #
196
+ # @return [String] params, nil if the no task is found
197
+ #
198
+ def get_params(task_name)
199
+ @logger.info "Obtaining the build parameters of task '#{task_name}'" +
200
+ " from the build queue"
201
+ params = nil
202
+ details = get_details(task_name)
203
+ unless details.empty?
204
+ params = details["params"]
205
+ end
206
+ params
207
+ end
208
+
209
+ # Obtains whether the task is buildable
210
+ #
211
+ # @param [String] task_name name of the task
212
+ #
213
+ # @return [Boolean] buildable or not
214
+ #
215
+ def is_buildable?(task_name)
216
+ @logger.info "Checking if task '#{task_name}' from the build queue" +
217
+ " is buildable"
218
+ buildable = nil
219
+ details = get_details(task_name)
220
+ unless details.empty?
221
+ buildable = details["buildable"]
222
+ end
223
+ buildable
224
+ end
225
+
226
+ # Obtains whether the task is blocked
227
+ #
228
+ # @param [String] task_name name of the task
229
+ #
230
+ # @return [Boolean] blocked or not
231
+ #
232
+ def is_blocked?(task_name)
233
+ @logger.info "Checking if task '#{task_name}' from the build queue" +
234
+ " is blocked"
235
+ blocked = nil
236
+ details = get_details(task_name)
237
+ unless details.empty?
238
+ blocked = details["blocked"]
239
+ end
240
+ blocked
241
+ end
242
+
243
+ # Obtains whether the task is stuck
244
+ #
245
+ # @param [String] task_name name of the task
246
+ #
247
+ # @return [Boolean] stuck or not
248
+ #
249
+ def is_stuck?(task_name)
250
+ @logger.info "Checking if task '#{task_name}' from the build queue" +
251
+ " is stuck"
252
+ stuck = nil
253
+ details = get_details(task_name)
254
+ unless details.empty?
255
+ stuck = details["stuck"]
256
+ end
257
+ stuck
258
+ end
259
+
260
+ end
261
+ end
262
+ end
@@ -0,0 +1,84 @@
1
+ #
2
+ # Copyright (c) 2012-2013 Kannan Manickam <arangamani.kannan@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ require 'thor'
24
+ require 'thor/group'
25
+ require "#{File.dirname(__FILE__)}/node.rb"
26
+ require "#{File.dirname(__FILE__)}/job.rb"
27
+ require "#{File.dirname(__FILE__)}/system.rb"
28
+
29
+ module JenkinsApi
30
+ # This is the base module for all command line interface for Jenkins API.
31
+ #
32
+ module CLI
33
+ # This is the base class for the command line interface which adds other
34
+ # classes as subcommands to the CLI.
35
+ #
36
+ class Base < Thor
37
+
38
+ class_option :username, :aliases => "-u", :desc => "Name of Jenkins user"
39
+ class_option :password, :aliases => "-p",
40
+ :desc => "Password of Jenkins user"
41
+ class_option :password_base64, :aliases => "-b",
42
+ :desc => "Base 64 encoded password of Jenkins user"
43
+ class_option :server_ip, :aliases => "-s",
44
+ :desc => "Jenkins server IP address"
45
+ class_option :server_port, :aliases => "-o", :desc => "Jenkins port"
46
+ class_option :creds_file, :aliases => "-c",
47
+ :desc => "Credentials file for communicating with Jenkins server"
48
+
49
+
50
+ map "-v" => :version
51
+
52
+ desc "version", "Shows current version"
53
+ # CLI command that returns the version of Jenkins API Client
54
+ def version
55
+ puts JenkinsApi::Client::VERSION
56
+ end
57
+
58
+ # Register the CLI::Node class as "node" subcommand to CLI
59
+ register(
60
+ CLI::Node,
61
+ 'node',
62
+ 'node [subcommand]',
63
+ 'Provides functions to access the node interface of Jenkins CI server'
64
+ )
65
+
66
+ # Register the CLI::Job class as "job" subcommand to CLI
67
+ register(
68
+ CLI::Job,
69
+ 'job',
70
+ 'job [subcommand]',
71
+ 'Provides functions to access the job interface of Jenkins CI server'
72
+ )
73
+
74
+ # Register the CLI::System class as "system" subcommand to CLI
75
+ register(
76
+ CLI::System,
77
+ 'system',
78
+ 'system [subcommand]',
79
+ 'Provides functions to access system functions of the Jenkins CI server'
80
+ )
81
+
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,61 @@
1
+ #
2
+ # Copyright (c) 2012-2013 Kannan Manickam <arangamani.kannan@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ require 'fileutils'
24
+ require 'yaml'
25
+
26
+ module JenkinsApi
27
+ module CLI
28
+ # This is the helper class that sets up the credentials from the command
29
+ # line parameters given and initializes the Jenkins API Client.
30
+ class Helper
31
+ # Sets up the credentials and initializes the Jenkins API Client
32
+ #
33
+ # @param [Hash] options Options obtained from the command line
34
+ #
35
+ # @return [JenkinsApi::Client] A new Client object
36
+ #
37
+ def self.setup(options)
38
+ if options[:username] && options[:server_ip] && \
39
+ (options[:password] || options[:password_base64])
40
+ creds = options
41
+ elsif options[:creds_file]
42
+ creds = YAML.load_file(
43
+ File.expand_path(options[:creds_file], __FILE__)
44
+ )
45
+ elsif File.exist?("#{ENV['HOME']}/.improved_jenkins_client/login.yml")
46
+ creds = YAML.load_file(
47
+ File.expand_path(
48
+ "#{ENV['HOME']}/.improved_jenkins_client/login.yml", __FILE__
49
+ )
50
+ )
51
+ else
52
+ msg = "Credentials are not set. Please pass them as parameters or"
53
+ msg << " set them in the default credentials file"
54
+ puts msg
55
+ exit 1
56
+ end
57
+ JenkinsApi::Client.new(creds)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,133 @@
1
+ #
2
+ # Copyright (c) 2012-2013 Kannan Manickam <arangamani.kannan@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ require 'thor'
24
+ require 'thor/group'
25
+
26
+ module JenkinsApi
27
+ module CLI
28
+ # This class provides various command line operations related to jobs.
29
+ class Job < Thor
30
+ include Thor::Actions
31
+
32
+ desc "list", "List jobs"
33
+ method_option :status, :aliases => "-t", :desc => "Status to filter"
34
+ method_option :filter, :aliases => "-f",
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
38
+ def list
39
+ @client = Helper.setup(parent_options)
40
+ if options[:filter] && options[:status]
41
+ name_filtered = @client.job.list(options[:filter])
42
+ puts @client.job.list_by_status(options[:status], name_filtered)
43
+ elsif options[:filter]
44
+ puts @client.job.list(options[:filter])
45
+ elsif options[:status]
46
+ puts @client.job.list_by_status(options[:status])
47
+ else
48
+ puts @client.job.list_all
49
+ end
50
+ end
51
+
52
+ desc "recreate JOB", "Recreate a specified job"
53
+ # CLI command to recreate a job on Jenkins
54
+ def recreate(job)
55
+ @client = Helper.setup(parent_options)
56
+ @client.job.recreate(job)
57
+ end
58
+
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
+ #
64
+ option :params, :type => :hash, :default => {}
65
+ option :opts, :type => :hash, :default => {}
66
+ def build(job)
67
+ @client = Helper.setup(parent_options)
68
+ @client.job.build(job, options[:params], options[:opts])
69
+ end
70
+
71
+ desc "status JOB", "Get the current build status of a job"
72
+ # CLI command to get the status of a job
73
+ #
74
+ # @param [String] job Name of the job
75
+ #
76
+ def status(job)
77
+ @client = Helper.setup(parent_options)
78
+ puts @client.job.get_current_build_status(job)
79
+ end
80
+
81
+ desc "delete JOB", "Delete the job"
82
+ # CLI command to delete a job
83
+ #
84
+ # @param [String] job Name of the job
85
+ #
86
+ def delete(job)
87
+ @client = Helper.setup(parent_options)
88
+ puts @client.job.delete(job)
89
+ end
90
+
91
+ desc "console JOB", "Print the progressive console output of a job"
92
+ method_option :sleep, :aliases => "-z",
93
+ :desc => "Time to wait between querying the API for console output"
94
+ # CLI command to obtain console output for a job. Make sure the log
95
+ # location is set to something other than STDOUT. By default it is set to
96
+ # STDOUT. If the log messages are printed on the same console, the
97
+ # console output will get garbled.
98
+ #
99
+ # @param [String] job Name of the job
100
+ #
101
+ def console(job)
102
+ @client = Helper.setup(parent_options)
103
+ # Print progressive console output
104
+ response = @client.job.get_console_output(job)
105
+ puts response['output'] unless response['more']
106
+ while response['more']
107
+ size = response['size']
108
+ puts response['output'] unless response['output'].chomp.empty?
109
+ sleep options[:sleep].to_i if options[:sleep]
110
+ response = @client.job.get_console_output(job, 0, size)
111
+ end
112
+ # Print the last few lines
113
+ puts response['output'] unless response['output'].chomp.empty?
114
+ end
115
+
116
+ desc "restrict JOB", "Restricts a job to a specific node"
117
+ method_option :node, :aliases => "-n", :desc => "Node to be restricted to"
118
+ # CLI command to restrict a job to a node
119
+ #
120
+ # @param [String] job Name of the job
121
+ #
122
+ def restrict(job)
123
+ @client = Helper.setup(parent_options)
124
+ if options[:node]
125
+ @client.job.restrict_to_node(job, options[:node])
126
+ else
127
+ say "You need to specify the node to be restricted to.", :red
128
+ end
129
+ end
130
+
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,97 @@
1
+ #
2
+ # Copyright (c) 2012-2013 Kannan Manickam <arangamani.kannan@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ require 'thor'
24
+ require 'thor/group'
25
+ require 'terminal-table'
26
+
27
+ module JenkinsApi
28
+ module CLI
29
+ # This class provides various command line operations for the Node class.
30
+ class Node < Thor
31
+ include Thor::Actions
32
+ include Terminal
33
+
34
+ desc "list", "List all nodes"
35
+ method_option :filter, :aliases => "-f",
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
39
+ def list
40
+ @client = Helper.setup(parent_options)
41
+ if options[:filter]
42
+ puts @client.node.list(options[:filter])
43
+ else
44
+ puts @client.node.list
45
+ end
46
+ end
47
+
48
+ desc "print_general_attributes", "Prints general attributes of nodes"
49
+ # CLI command that prints the general attribtues of nodes
50
+ def print_general_attributes
51
+ @client = Helper.setup(parent_options)
52
+ general_attributes = Client::Node::GENERAL_ATTRIBUTES
53
+ rows = []
54
+ general_attributes.each do |attr|
55
+ rows << [attr, @client.node.method("get_#{attr}").call]
56
+ end
57
+ table = Table.new :headings => ['Attribute', 'Value'], :rows => rows
58
+ puts table
59
+ end
60
+
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
+ #
66
+ def print_node_attributes(node)
67
+ @client = Helper.setup(parent_options)
68
+ node_attributes = Client::Node::NODE_ATTRIBUTES
69
+ rows = []
70
+ node_attributes.each do |attr|
71
+ rows << [attr, @client.node.method("get_node_#{attr}").call(node)]
72
+ end
73
+ table = Table.new :headings => ['Attribute', 'Value'], :rows => rows
74
+ puts "Node: #{node}"
75
+ puts table
76
+ end
77
+
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
+ #
83
+ def print_node_properties(node)
84
+ @client = Helper.setup(parent_options)
85
+ node_properties = Client::Node::NODE_PROPERTIES
86
+ rows = []
87
+ node_properties.each do |property|
88
+ rows << [property, @client.node.method("is_#{property}?").call(node)]
89
+ end
90
+ table = Table.new :headings => ['Property', 'Value'], :rows => rows
91
+ puts "Node: #{node}"
92
+ puts table
93
+ end
94
+
95
+ end
96
+ end
97
+ end