jenkins2 1.0.0 → 1.1.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 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