improved_jenkins_client 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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