jenkins2 1.0.0 → 1.1.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
2
  SHA1:
3
- metadata.gz: 89372ed31079640dc0d1e310f3cb279c209846f3
4
- data.tar.gz: 2ff0f1d37148a71cede4a61ffd9fb9dca76edaa5
3
+ metadata.gz: d1608986d87d4133655aed40daf7d52e89b27bfb
4
+ data.tar.gz: 948685475fb6f4bfed364db6d3692ca159c65ad9
5
5
  SHA512:
6
- metadata.gz: 28f396b6e2f8dbaf2f2e0f8ff6b222677d0e405b264af0f97c01d8ddd4ea34c3b53577ce555a31f5810b10b4ad47444c741a7a77db578caa773f69ed8f896461
7
- data.tar.gz: c53ee77163b15abe3cdc5bc14b24d408d6c51faf8d8b768e8e4f5f499b97db7d420c020a6c4c1bd874eed030568b60ffa6c2292a932bffe41a20bc0ee216b810
6
+ metadata.gz: eb1ea897fbea4233cf2120577532f96170e3e2dfad99bbba3812c8117757b818d1dc0b3aa6f12c8f8d25122f46204e57c80bb7813fdc2bde72f2f4a5960f8578
7
+ data.tar.gz: 3918162db471507a88b91718acf48460af711a13790a6211f50a8587900d507f7c57cd4d7f68cc44b32c84e93e4d740bc32f66e5b5df984086a1de121f660aba
@@ -1,13 +1,40 @@
1
1
  # Change Log
2
2
 
3
+ [jenkins]: https://jenkins.io/download/
4
+ [command-launcher]: https://plugins.jenkins.io/command-launcher
5
+ [cloudbees-folder]: https://plugins.jenkins.io/cloudbees-folder
6
+ [plain-credentials]: https://plugins.jenkins.io/plain-credentials
7
+ [role-strategy]: https://plugins.jenkins.io/role-strategy
8
+ [ssh-credentials]: https://plugins.jenkins.io/ssh-credentials
9
+
10
+ ## [v1.1.0](https://bitbucket.org/DracoAter/jenkins2/commits/tag/v1.1.0) (February 26, 2018)
11
+
12
+ ### Tested With
13
+
14
+ - [Jenkins][jenkins] 2.89.4
15
+ - [Command Agent Launcher][command-launcher] 1.2
16
+ - [Folders][cloudbees-folder] 6.3
17
+ - [Plain Credentials][plain-credentials] 1.4
18
+ - [Role-based Authorization Strategy][role-strategy] 2.7.0
19
+ - [SSH Credentials][ssh-credentials] 1.13
20
+
21
+ ### Enhancements
22
+
23
+ - Can manage folders with [Folders][cloudbees-folder] plugin.
24
+ - Can create/show/update/delete jobs inside nested folders.
25
+ - Can create/show/update/delete credentials inside nested folders.
26
+ - Can manage roles/users/permissions in [Role-based Authorization Strategy][role-strategy] plugin.
27
+ - Can list/create/delete roles.
28
+ - Can assign/unassign roles to/from users.
29
+
3
30
  ## [v1.0.0](https://bitbucket.org/DracoAter/jenkins2/commits/tag/v1.0.0) (February 19, 2018)
4
31
 
5
32
  ### Tested With
6
33
 
7
- - Jenkins 2.89.4
8
- - ssh-credentials 1.13
9
- - plain-credentials 1.4
10
- - command-launcher 1.2
34
+ - [Jenkins][jenkins] 2.89.4
35
+ - [Command Agent Launcher][command-launcher] 1.2
36
+ - [Plain Credentials][plain-credentials] 1.4
37
+ - [SSH Credentials][ssh-credentials] 1.13
11
38
 
12
39
  ### Enhancements
13
40
 
@@ -8,6 +8,7 @@ require_relative 'api/credentials'
8
8
  require_relative 'api/computer'
9
9
  require_relative 'api/job'
10
10
  require_relative 'api/plugins'
11
+ require_relative 'api/role_strategy'
11
12
  require_relative 'api/root'
12
13
  require_relative 'api/user'
13
14
  require_relative 'api/view'
@@ -18,6 +19,7 @@ module Jenkins2
18
19
  include Computer
19
20
  include Job
20
21
  include Plugins
22
+ include RoleStrategy
21
23
  include Root
22
24
  include User
23
25
  include View
@@ -4,7 +4,14 @@ require_relative 'rud'
4
4
 
5
5
  module Jenkins2
6
6
  class API
7
+ # Allows manipulating jobs (projects). Supports cloudbees-folder plugin - i.e. nested jobs.
7
8
  module Job
9
+ # Step into proxy for managing jobs.
10
+ # ==== Parameters:
11
+ # +name+:: Job name
12
+ # +params+:: Key-value parameters. They will be added as URL parameters to request.
13
+ # ==== Returns:
14
+ # A Jenkins2::API::Job::Proxy object
8
15
  def job(name, **params)
9
16
  proxy = Proxy.new connection, 'job', params
10
17
  proxy.id = name
@@ -15,24 +22,45 @@ module Jenkins2
15
22
  attr_accessor :id
16
23
  include ::Jenkins2::API::RUD
17
24
 
25
+ # Create a new job from config.xml.
26
+ # ==== Parameters:
27
+ # +config_xml+:: config.xml of new job as string.
28
+ # ==== Returns:
29
+ # True on success
18
30
  def create(config_xml)
19
- connection.post('createItem', config_xml, name: id) do |req|
31
+ path = ::File.join(::File.dirname(@path), 'createItem')
32
+ connection.post(path, config_xml, name: id) do |req|
20
33
  req['Content-Type'] = 'text/xml'
21
34
  end.code == '200'
22
35
  end
23
36
 
37
+ # Create a new job by copying another one.
38
+ # ==== Parameters:
39
+ # +from+:: Job name to copy new job from.
40
+ # ==== Returns:
41
+ # True on success.
24
42
  def copy(from)
25
- connection.post('createItem', nil, name: id, from: from, mode: 'copy').code == '302'
43
+ path = ::File.join(::File.dirname(@path), 'createItem')
44
+ connection.post(path, nil, name: id, from: from, mode: 'copy').code == '302'
26
45
  end
27
46
 
47
+ # Disable a job, restrict all builds of the job from now on.
48
+ # ==== Returns:
49
+ # True on success.
28
50
  def disable
29
51
  connection.post(build_path('disable')).code == '302'
30
52
  end
31
53
 
54
+ # Enable job, allow building the job. Cancels previously issued "disable".
55
+ # ==== Returns:
56
+ # True on success.
32
57
  def enable
33
58
  connection.post(build_path('enable')).code == '302'
34
59
  end
35
60
 
61
+ # Schedule a job build. Allows to pass build parameters, if required.
62
+ # ==== Returns:
63
+ # True on success.
36
64
  def build(build_parameters={})
37
65
  if build_parameters.empty?
38
66
  connection.post(build_path('build'))
@@ -44,6 +72,29 @@ module Jenkins2
44
72
  def polling
45
73
  connection.post(build_path('polling')).code == '302'
46
74
  end
75
+
76
+ # cloudbees-folder plugin provides special type of job - folder. So now we can have
77
+ # nested jobs. This methods allows to go 1 job deeper.
78
+ # ==== Parameters:
79
+ # +name+:: Job name
80
+ # +params+:: Key-value parameters. They will be added as URL parameters to request.
81
+ # ==== Returns:
82
+ # A new Jenkins2::API::Job::Proxy object
83
+ def job(name, **params)
84
+ proxy = Proxy.new connection, build_path('job'), params
85
+ proxy.id = name
86
+ proxy
87
+ end
88
+
89
+ # cloudbees-folder plugin provides special type of job - folder. You can now create
90
+ # credentials inside particular folder.
91
+ # ==== Parameters:
92
+ # +params+:: Key-value parameters. They will be added as URL parameters to request.
93
+ # ==== Returns:
94
+ # A new Jenkins2::API::Credentials::Proxy object
95
+ def credentials(params={})
96
+ ::Jenkins2::API::Credentials::Proxy.new connection, build_path('credentials'), params
97
+ end
47
98
  end
48
99
  end
49
100
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jenkins2
4
+ class API
5
+ # Provides support for role-strategy plugin.
6
+ # Allows creating, deleting, assigning, unassigning and listing roles.
7
+ module RoleStrategy
8
+ module RoleType
9
+ GLOBAL = 'globalRoles'
10
+ PROJECT = 'projectRoles'
11
+ SLAVE = 'slaveRoles'
12
+ end
13
+
14
+ # Step into proxy for managing roles in role-strategy.
15
+ # ==== Returns:
16
+ # A proxy object that enables different operations on roles.
17
+ def roles
18
+ Proxy.new connection, 'role-strategy/strategy'
19
+ end
20
+
21
+ class Proxy < ::Jenkins2::ResourceProxy
22
+ # Get existing roles and users assigned to them.
23
+ # *Returns*:: Hash where keys are roles, and values are arrays of users assigned to role.
24
+ def list
25
+ ::JSON.parse(connection.get(build_path('getAllRoles')).body,
26
+ object_class: ::OpenStruct).to_h
27
+ end
28
+
29
+ # Create a role in role-strategy
30
+ # ==== Parameters:
31
+ # +role+:: Role name.
32
+ # +type+:: Role type. Use RoleType enum values.
33
+ # +permissions+:: Array of permission ids. Default is - no permissions.
34
+ # +pattern+:: Slave or project pattern. Ignored for global roles.
35
+ # ==== Returns:
36
+ # True on success
37
+ def create(role:, type:, permissions: [], pattern: nil)
38
+ connection.post(build_path('addRole'), nil, roleName: role, type: type,
39
+ permissionIds: (permissions || []).join(','), pattern: pattern, overwrite: false).
40
+ code == '200'
41
+ end
42
+
43
+ # Delete role(s) in role-strategy
44
+ # ==== Parameters:
45
+ # +role+:: Role name or array of role names.
46
+ # +type+:: Role type. Use RoleType enum values.
47
+ # ==== Returns:
48
+ # True on success
49
+ def delete(role:, type:)
50
+ connection.post(build_path('removeRoles'), nil, roleNames: [role].flatten.join(','),
51
+ type: type).code == '200'
52
+ end
53
+
54
+ # Assign role to user in role-strategy
55
+ # ==== Parameters:
56
+ # +role+:: Role name.
57
+ # +type+:: Role type. Use RoleType enum values.
58
+ # +rsuser+:: Username.
59
+ # ==== Returns:
60
+ # True on success
61
+ def assign(role:, type:, rsuser:)
62
+ connection.post(build_path('assignRole'), nil, roleName: role, type: type, sid: rsuser).
63
+ code == '200'
64
+ end
65
+
66
+ # Unassign role from user in role-strategy
67
+ # ==== Parameters:
68
+ # +role+:: Role name.
69
+ # +type+:: Role type. Use RoleType enum values.
70
+ # +rsuser+:: Username.
71
+ # ==== Returns:
72
+ # True on success
73
+ def unassign(role:, type:, rsuser:)
74
+ connection.post(build_path('unassignRole'), nil, roleName: role, type: type, sid: rsuser).
75
+ code == '200'
76
+ end
77
+
78
+ # Unassign all roles from user in role-strategy
79
+ # ==== Parameters:
80
+ # +type+:: Role type. Use RoleType enum values.
81
+ # +rsuser+:: Username.
82
+ # ==== Returns:
83
+ # True on success
84
+ def unassign_all(type:, rsuser:)
85
+ connection.post(build_path('deleteSid'), nil, type: type, sid: rsuser).code == '200'
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -5,7 +5,9 @@ require 'yaml'
5
5
 
6
6
  require_relative 'version'
7
7
  require_relative 'cli/credentials'
8
+ require_relative 'cli/job'
8
9
  require_relative 'cli/nodes'
10
+ require_relative 'cli/role_strategy'
9
11
  require_relative 'cli/root'
10
12
  require_relative 'cli/plugins'
11
13
  require_relative 'cli/user'
@@ -153,7 +153,7 @@ module Jenkins2
153
153
 
154
154
  class ListCredentials < CLI
155
155
  def self.description
156
- 'Lists credentials in a specific store.'
156
+ 'List credentials in a specific store.'
157
157
  end
158
158
 
159
159
  def add_options
@@ -2,46 +2,190 @@
2
2
 
3
3
  module Jenkins2
4
4
  class CLI
5
- class ListJobs < CLI
5
+ # class Build < CLI
6
+ # # TODO: implement
7
+ # end
8
+
9
+ class CopyJob < CLI
6
10
  def self.description
7
- 'Lists all jobs in a specific view or item group.'
11
+ 'Copy a job.'
8
12
  end
9
13
 
10
14
  private
11
15
 
12
16
  def add_options
13
- parser.separator 'Optional arguments:'
14
- parser.on '-n', '--name NAME', 'Name of the view. Default - all' do |n|
17
+ parser.separator 'Mandatory arguments:'
18
+ parser.on '-f', '--from NAME', 'Name of the job to copy from.' do |f|
19
+ options[:from] = f
20
+ end
21
+ parser.on '-n', '--name NAME', 'Name of the new job.' do |n|
15
22
  options[:name] = n
16
23
  end
17
24
  end
18
25
 
19
- def run; end
26
+ def mandatory_arguments
27
+ super + %i[name from]
28
+ end
29
+
30
+ def run
31
+ jc.job(options[:name]).copy(options[:from])
32
+ end
20
33
  end
21
34
 
22
- class CopyJob < CLI
35
+ class CreateJob < CLI
23
36
  def self.description
24
- 'Copies a job.'
37
+ 'Create a new job by reading stdin as an XML configuration.'
25
38
  end
26
39
 
27
40
  private
28
41
 
29
42
  def add_options
30
43
  parser.separator 'Mandatory arguments:'
31
- parser.on '-f', '--from NAME', 'Name of the job to copy.' do |f|
32
- options[:from] = f
44
+ parser.on '-n', '--name NAME', 'Name of the new job.' do |n|
45
+ options[:name] = n
33
46
  end
34
- parser.on '-n', '--name NAME', 'Name of the new job, to be created.' do |n|
47
+ end
48
+
49
+ def mandatory_arguments
50
+ super + %i[name]
51
+ end
52
+
53
+ def run
54
+ jc.job(options[:name]).create($stdin.read)
55
+ end
56
+ end
57
+
58
+ class DeleteJob < CLI
59
+ def self.description
60
+ 'Delete a job.'
61
+ end
62
+
63
+ private
64
+
65
+ def add_options
66
+ parser.separator 'Mandatory arguments:'
67
+ parser.on '-n', '--name NAME', 'Name of the job.' do |n|
35
68
  options[:name] = n
36
69
  end
37
70
  end
38
71
 
39
72
  def mandatory_arguments
40
- super + %i[name from]
73
+ super + %i[name]
41
74
  end
42
75
 
43
76
  def run
44
- jc.job(options[:name]).copy(options[:from])
77
+ jc.job(options[:name]).delete
78
+ end
79
+ end
80
+
81
+ class DisableJob < CLI
82
+ def self.description
83
+ 'Disable a job, restrict all builds of the job from now on.'
84
+ end
85
+
86
+ private
87
+
88
+ def add_options
89
+ parser.separator 'Mandatory arguments:'
90
+ parser.on '-n', '--name NAME', 'Name of the job.' do |n|
91
+ options[:name] = n
92
+ end
93
+ end
94
+
95
+ def mandatory_arguments
96
+ super + %i[name]
97
+ end
98
+
99
+ def run
100
+ jc.job(options[:name]).disable
101
+ end
102
+ end
103
+
104
+ class EnableJob < CLI
105
+ def self.description
106
+ 'Enable job, allow building the job. Cancels previously issued "disable-job".'
107
+ end
108
+
109
+ private
110
+
111
+ def add_options
112
+ parser.separator 'Mandatory arguments:'
113
+ parser.on '-n', '--name NAME', 'Name of the job.' do |n|
114
+ options[:name] = n
115
+ end
116
+ end
117
+
118
+ def mandatory_arguments
119
+ super + %i[name]
120
+ end
121
+
122
+ def run
123
+ jc.job(options[:name]).enable
124
+ end
125
+ end
126
+
127
+ class GetJob < CLI
128
+ def self.description
129
+ 'Dump the job definition XML to stdout.'
130
+ end
131
+
132
+ private
133
+
134
+ def add_options
135
+ parser.separator 'Mandatory arguments:'
136
+ parser.on '-n', '--name NAME', 'Name of the job.' do |n|
137
+ options[:name] = n
138
+ end
139
+ end
140
+
141
+ def mandatory_arguments
142
+ super + %i[name]
143
+ end
144
+
145
+ def run
146
+ jc.job(options[:name]).config_xml
147
+ end
148
+ end
149
+
150
+ class ListJobs < CLI
151
+ def self.description
152
+ 'List all jobs in a specific view or item group.'
153
+ end
154
+
155
+ private
156
+
157
+ def add_options
158
+ parser.separator 'Optional arguments:'
159
+ parser.on '--view VIEW', 'Name of the view. Default - All.' do |v|
160
+ options[:view] = v
161
+ end
162
+ end
163
+
164
+ def run
165
+ jc.view(options[:view] || 'All').jobs.collect(&:name).join("\n")
166
+ end
167
+ end
168
+
169
+ class UpdateJob < CLI
170
+ def self.description
171
+ 'Update the job definition XML from stdin. The opposite of the "get-job" command.'
172
+ end
173
+
174
+ private
175
+
176
+ def add_options
177
+ parser.separator 'Mandatory arguments:'
178
+ parser.on '-n', '--name NAME', 'Name of the job.' do |n|
179
+ options[:name] = n
180
+ end
181
+ end
182
+
183
+ def mandatory_arguments
184
+ super + %i[name]
185
+ end
186
+
187
+ def run
188
+ jc.job(options[:name]).update($stdin.read)
45
189
  end
46
190
  end
47
191
  end
@@ -24,7 +24,7 @@ module Jenkins2
24
24
 
25
25
  class CreateNode < CLI
26
26
  def self.description
27
- 'Creates a new node by reading stdin for an XML configuration.'
27
+ 'Create a new node by reading stdin for an XML configuration.'
28
28
  end
29
29
 
30
30
  def add_options
@@ -42,7 +42,7 @@ module Jenkins2
42
42
 
43
43
  class DeleteNode < CLI
44
44
  def self.description
45
- 'Deletes node(s).'
45
+ 'Delete node(s).'
46
46
  end
47
47
 
48
48
  def add_options
@@ -61,7 +61,7 @@ module Jenkins2
61
61
 
62
62
  class DisconnectNode < CLI
63
63
  def self.description
64
- 'Disconnects node(s).'
64
+ 'Disconnect node(s).'
65
65
  end
66
66
 
67
67
  def add_options
@@ -86,7 +86,7 @@ module Jenkins2
86
86
 
87
87
  class GetNode < CLI
88
88
  def self.description
89
- 'Dumps the node definition XML to stdout.'
89
+ 'Dump the node definition XML to stdout.'
90
90
  end
91
91
 
92
92
  def add_options
@@ -103,7 +103,7 @@ module Jenkins2
103
103
 
104
104
  class ListNode < CLI
105
105
  def self.description
106
- 'Outputs the node list.'
106
+ 'Output the node list.'
107
107
  end
108
108
 
109
109
  def run
@@ -113,7 +113,7 @@ module Jenkins2
113
113
 
114
114
  class ListOnlineNode < CLI
115
115
  def self.description
116
- 'Outputs the online node list.'
116
+ 'Output the online node list.'
117
117
  end
118
118
 
119
119
  def run
@@ -167,7 +167,7 @@ module Jenkins2
167
167
 
168
168
  class UpdateNode < CLI
169
169
  def self.description
170
- 'Updates the node definition XML from stdin. The opposite of the get-node command.'
170
+ 'Update the node definition XML from stdin. The opposite of the get-node command.'
171
171
  end
172
172
 
173
173
  def add_options
@@ -6,7 +6,7 @@ module Jenkins2
6
6
  class CLI
7
7
  class InstallPlugin < CLI
8
8
  def self.description
9
- 'Installs a plugin either from a file, an URL, standard input or from update center.'
9
+ 'Install a plugin either from a file, an URL, standard input or from update center.'
10
10
  end
11
11
 
12
12
  private
@@ -39,7 +39,7 @@ module Jenkins2
39
39
 
40
40
  class ListPlugins < CLI
41
41
  def self.description
42
- 'Lists all installed plugins.'
42
+ 'List all installed plugins.'
43
43
  end
44
44
 
45
45
  private
@@ -53,7 +53,7 @@ module Jenkins2
53
53
 
54
54
  class UninstallPlugin < CLI
55
55
  def self.description
56
- 'Uninstalls a plugin.'
56
+ 'Uninstall a plugin.'
57
57
  end
58
58
 
59
59
  private
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jenkins2
4
+ class CLI
5
+ # Provides list-roles command in CLI. Requires role-strategy plugin enabled.
6
+ class ListRoles < CLI
7
+ def self.description
8
+ 'List all global roles in role-strategy plugin.'
9
+ end
10
+
11
+ def run
12
+ jc.roles.list.collect do |role, users|
13
+ "#{role}: #{users.join(',')}"
14
+ end.join("\n")
15
+ end
16
+ end
17
+
18
+ # Provides create-role command in CLI. Requires role-strategy plugin enabled.
19
+ class CreateRole < CLI
20
+ def self.description
21
+ 'Create a role in role-strategy plugin.'
22
+ end
23
+
24
+ def add_options
25
+ parser.separator 'Mandatory arguments:'
26
+ parser.on '--role ROLE', 'Role name.' do |r|
27
+ options[:role] = r
28
+ end
29
+ parser.on '--type TYPE', 'Role type. One of: globalRoles, projectRoles, slaveRoles.' do |t|
30
+ options[:type] = t
31
+ end
32
+ parser.separator 'Optional arguments:'
33
+ parser.on '--permissions X,Y,..', Array, 'Comma-separated list of permissions.' do |p|
34
+ options[:permissions] = p
35
+ end
36
+ parser.on '--pattern PATTERN', 'Slave or project pattern. Ignored for global roles.' do |p|
37
+ options[:pattern] = p
38
+ end
39
+ end
40
+
41
+ def mandatory_arguments
42
+ super + %i[role type]
43
+ end
44
+
45
+ def run
46
+ jc.roles.create(role: options[:role], type: options[:type],
47
+ permissions: options[:permissions], pattern: options[:pattern])
48
+ end
49
+ end
50
+
51
+ # Provides delete-role command in CLI. Requires role-strategy plugin enabled.
52
+ class DeleteRoles < CLI
53
+ def self.description
54
+ 'Delete role(s) in role-strategy plugin.'
55
+ end
56
+
57
+ def add_options
58
+ parser.separator 'Mandatory arguments:'
59
+ parser.on '--role X,Y,..', Array, 'Role names.' do |r|
60
+ options[:role] = r
61
+ end
62
+ parser.on '--type TYPE', 'Role type. One of: globalRoles, projectRoles, slaveRoles.' do |t|
63
+ options[:type] = t
64
+ end
65
+ end
66
+
67
+ def mandatory_arguments
68
+ super + %i[role type]
69
+ end
70
+
71
+ def run
72
+ jc.roles.delete(role: options[:role], type: options[:type])
73
+ end
74
+ end
75
+
76
+ # Provides assign-role command in CLI. Requires role-strategy plugin enabled.
77
+ class AssignRole < CLI
78
+ def self.description
79
+ 'Assign role to user in role-strategy plugin.'
80
+ end
81
+
82
+ def add_options
83
+ parser.separator 'Mandatory arguments:'
84
+ parser.on '--role ROLE', 'Role name.' do |r|
85
+ options[:role] = r
86
+ end
87
+ parser.on '--type TYPE', 'Role type. One of: globalRoles, projectRoles, slaveRoles.' do |t|
88
+ options[:type] = t
89
+ end
90
+ parser.on '--rsuser USER', 'Username.' do |u|
91
+ options[:rsuser] = u
92
+ end
93
+ end
94
+
95
+ def mandatory_arguments
96
+ super + %i[role type rsuser]
97
+ end
98
+
99
+ def run
100
+ jc.roles.assign(role: options[:role], type: options[:type], rsuser: options[:rsuser])
101
+ end
102
+ end
103
+
104
+ # Provides unassign-role command in CLI. Requires role-strategy plugin enabled.
105
+ class UnassignRole < CLI
106
+ def self.description
107
+ 'Unassign role from user in role-strategy plugin.'
108
+ end
109
+
110
+ def add_options
111
+ parser.separator 'Mandatory arguments:'
112
+ parser.on '--role ROLE', 'Role name.' do |r|
113
+ options[:role] = r
114
+ end
115
+ parser.on '--type TYPE', 'Role type. One of: globalRoles, projectRoles, slaveRoles.' do |t|
116
+ options[:type] = t
117
+ end
118
+ parser.on '--rsuser USER', 'Username.' do |u|
119
+ options[:rsuser] = u
120
+ end
121
+ end
122
+
123
+ def mandatory_arguments
124
+ super + %i[role type rsuser]
125
+ end
126
+
127
+ def run
128
+ jc.roles.unassign(role: options[:role], type: options[:type], rsuser: options[:rsuser])
129
+ end
130
+ end
131
+
132
+ # Provides unassign-all-roles command in CLI. Requires role-strategy plugin enabled.
133
+ class UnassignAllRoles < CLI
134
+ def self.description
135
+ 'Unassign all roles from user in role-strategy plugin.'
136
+ end
137
+
138
+ def add_options
139
+ parser.separator 'Mandatory arguments:'
140
+ parser.on '--type TYPE', 'Role type. One of: globalRoles, projectRoles, slaveRoles.' do |t|
141
+ options[:type] = t
142
+ end
143
+ parser.on '--rsuser USER', 'Username.' do |u|
144
+ options[:rsuser] = u
145
+ end
146
+ end
147
+
148
+ def mandatory_arguments
149
+ super + %i[type rsuser]
150
+ end
151
+
152
+ def run
153
+ jc.roles.unassign_all(type: options[:type], rsuser: options[:rsuser])
154
+ end
155
+ end
156
+ end
157
+ end
@@ -4,7 +4,7 @@ module Jenkins2
4
4
  class CLI
5
5
  class WhoAmI < CLI
6
6
  def self.description
7
- 'Reports your credentials.'
7
+ 'Report your credentials.'
8
8
  end
9
9
 
10
10
  def run
@@ -4,7 +4,7 @@ module Jenkins2
4
4
  class CLI
5
5
  class CreateView < CLI
6
6
  def self.description
7
- 'Creates a new view by reading stdin as a XML configuration.'
7
+ 'Create a new view by reading stdin as an XML configuration.'
8
8
  end
9
9
 
10
10
  private
@@ -52,7 +52,7 @@ module Jenkins2
52
52
 
53
53
  class GetView < CLI
54
54
  def self.description
55
- 'Dumps the view definition XML to stdout.'
55
+ 'Dump the view definition XML to stdout.'
56
56
  end
57
57
 
58
58
  private
@@ -75,7 +75,7 @@ module Jenkins2
75
75
 
76
76
  class UpdateView < CLI
77
77
  def self.description
78
- 'Updates the view definition XML from stdin. The opposite of the get-view command.'
78
+ 'Update the view definition XML from stdin. The opposite of the get-view command.'
79
79
  end
80
80
 
81
81
  private
@@ -98,7 +98,7 @@ module Jenkins2
98
98
 
99
99
  class AddJobToView < CLI
100
100
  def self.description
101
- 'Adds jobs to view.'
101
+ 'Add jobs to view.'
102
102
  end
103
103
 
104
104
  private
@@ -126,7 +126,7 @@ module Jenkins2
126
126
 
127
127
  class RemoveJobFromView < CLI
128
128
  def self.description
129
- 'Removes jobs from view.'
129
+ 'Remove jobs from view.'
130
130
  end
131
131
 
132
132
  private
@@ -5,17 +5,17 @@ require 'openssl'
5
5
  require 'json'
6
6
 
7
7
  module Jenkins2
8
+ # Creates a "connection" to Jenkins and makes all the HTTP requests.
8
9
  class Connection
9
- # Creates a "connection" to Jenkins.
10
- # Parameter:
10
+ # ==== Parameters:
11
11
  # +server+:: Jenkins Server URL.
12
- def initialize(url)
13
- @server = url
12
+ def initialize(server)
13
+ @server = server
14
14
  @crumb = nil
15
15
  end
16
16
 
17
17
  # Add basic auth to existing connection. Returns self.
18
- # Parameters:
18
+ # ==== Parameters:
19
19
  # +user+:: Jenkins API user.
20
20
  # +key+:: Jenkins API key.
21
21
  def basic_auth(user, key)
@@ -23,23 +23,58 @@ module Jenkins2
23
23
  self
24
24
  end
25
25
 
26
+ # Appends api/json to passed +path+ and makes GET request. Yields request, if block given.
27
+ # ==== Parameters:
28
+ # +path+:: Path to make request to. "api/json" will be appened to the end.
29
+ # +params+:: Parameter hash. It will be converted to URL parameters.
30
+ # +&block+:: Yields Net::HTTP::Get request.
31
+ # ==== Returns:
32
+ # Net::HTTP::Response
26
33
  def get_json(path, params={}, &block)
27
34
  get(::File.join(path, 'api/json'), params, &block)
28
35
  end
29
36
 
37
+ # Makes GET request. Yields request, if block given.
38
+ # ==== Parameters:
39
+ # +path+:: Path to make request to.
40
+ # +params+:: Parameter hash. It will be converted to URL parameters.
41
+ # +&block+:: Yields Net::HTTP::Get request.
42
+ # ==== Returns:
43
+ # Net::HTTP::Response
30
44
  def get(path, params={}, &block)
31
45
  api_request(Net::HTTP::Get, build_uri(path, params), &block)
32
46
  end
33
47
 
48
+ # Makes HEAD request. Yields request, if block given.
49
+ # ==== Parameters:
50
+ # +path+:: Path to make request to.
51
+ # +params+:: Parameter hash. It will be converted to URL parameters.
52
+ # +&block+:: Yields Net::HTTP::Head request.
53
+ # ==== Returns:
54
+ # Net::HTTP::Response
34
55
  def head(path, params={}, &block)
35
56
  api_request(Net::HTTP::Head, build_uri(path, params), &block)
36
57
  end
37
58
 
59
+ # Makes POST request. Yields request, if block given.
60
+ # ==== Parameters:
61
+ # +path+:: Path to make request to.
62
+ # +body+:: Post request body.
63
+ # +params+:: Parameter hash. It will be converted to URL parameters.
64
+ # +&block+:: Yields Net::HTTP::Post request.
65
+ # ==== Returns:
66
+ # Net::HTTP::Response
38
67
  def post(path, body=nil, params={}, &block)
39
68
  headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
40
69
  api_request(Net::HTTP::Post, build_uri(path, params), body, headers, &block)
41
70
  end
42
71
 
72
+ # Builds URI. Appends parameters.
73
+ # ==== Parameters:
74
+ # +relative_or_absolute+:: Absolute URI or URI path. If path, Jenkins server will be prepended.
75
+ # +params+:: Parameter hash. It will be converted to URL parameters.
76
+ # ==== Returns:
77
+ # Absolute URI with parameters
43
78
  def build_uri(relative_or_absolute, params={})
44
79
  result = ::URI.parse relative_or_absolute
45
80
  result = ::URI.parse ::File.join(@server.to_s, relative_or_absolute) unless result.absolute?
@@ -47,6 +82,15 @@ module Jenkins2
47
82
  result
48
83
  end
49
84
 
85
+ # Makes request, using +method+ provided. Yields request, if block given. Retries request with
86
+ # updated crumbs, if "No valid crumbs" error received.
87
+ # ==== Parameters:
88
+ # +method+:: Net:HTTP class to instantiate (e.g. Net::HTTP::Post, Net::HTTP::Get)
89
+ # +url+:: Absolute URI to make request to.
90
+ # +body+:: Request body if applicable.
91
+ # +headers+:: Request headers.
92
+ # ==== Returns:
93
+ # Net::HTTP::Response
50
94
  def api_request(method, uri, body=nil, headers=nil)
51
95
  req = method.new(URI(uri), headers)
52
96
  req.basic_auth @user, @key if @user and @key
@@ -67,10 +111,19 @@ module Jenkins2
67
111
  end
68
112
  end
69
113
 
114
+ # Updates crumbs for current connection. These crumbs will be submitted with all requests.
115
+ # ==== Returns:
116
+ # Crumbs as hash
70
117
  def update_crumbs
71
118
  @crumb = JSON.parse(get_json('/crumbIssuer').body)
72
119
  end
73
120
 
121
+ # Handles Jenkins response. Tries parsing error messages in some cases, then reraises
122
+ # exception from Jenkins2 namespace.
123
+ # ==== Returns:
124
+ # HTTPResponse
125
+ # ==== Raises:
126
+ # Different Net::HTTP and Jenkins2 errors.
74
127
  def handle_response(response)
75
128
  Log.debug{ "Response: #{response.code}, #{response.body}" }
76
129
  case response
@@ -80,6 +133,8 @@ module Jenkins2
80
133
  raise Jenkins2::BadRequestError, response
81
134
  when Net::HTTPServiceUnavailable
82
135
  raise Jenkins2::ServiceUnavailableError, response
136
+ when Net::HTTPInternalServerError
137
+ raise Jenkins2::InternalServerError, response
83
138
  when Net::HTTPClientError, Net::HTTPServerError # 4XX, 5XX
84
139
  response.value
85
140
  else
@@ -29,6 +29,17 @@ module Jenkins2
29
29
  end
30
30
  end
31
31
 
32
+ class InternalServerError < Net::HTTPError
33
+ def initialize(res)
34
+ case res.body
35
+ when %r{<div id="error-description">(.+)</div>}m
36
+ super(Regexp.last_match(1), res)
37
+ else
38
+ res.value
39
+ end
40
+ end
41
+ end
42
+
32
43
  class NoValidCrumbMatcher
33
44
  def self.===(exception)
34
45
  exception.message == '403 "No valid crumb was included in the request"'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jenkins2
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jenkins2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juri Timošin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-19 00:00:00.000000000 Z
11
+ date: 2018-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ci_reporter_minitest
@@ -98,6 +98,7 @@ files:
98
98
  - lib/jenkins2/api/credentials.rb
99
99
  - lib/jenkins2/api/job.rb
100
100
  - lib/jenkins2/api/plugins.rb
101
+ - lib/jenkins2/api/role_strategy.rb
101
102
  - lib/jenkins2/api/root.rb
102
103
  - lib/jenkins2/api/rud.rb
103
104
  - lib/jenkins2/api/user.rb
@@ -107,6 +108,7 @@ files:
107
108
  - lib/jenkins2/cli/job.rb
108
109
  - lib/jenkins2/cli/nodes.rb
109
110
  - lib/jenkins2/cli/plugins.rb
111
+ - lib/jenkins2/cli/role_strategy.rb
110
112
  - lib/jenkins2/cli/root.rb
111
113
  - lib/jenkins2/cli/user.rb
112
114
  - lib/jenkins2/cli/view.rb