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 +4 -4
- data/CHANGELOG.md +31 -4
- data/lib/jenkins2/api.rb +2 -0
- data/lib/jenkins2/api/job.rb +53 -2
- data/lib/jenkins2/api/role_strategy.rb +90 -0
- data/lib/jenkins2/cli.rb +2 -0
- data/lib/jenkins2/cli/credentials.rb +1 -1
- data/lib/jenkins2/cli/job.rb +156 -12
- data/lib/jenkins2/cli/nodes.rb +7 -7
- data/lib/jenkins2/cli/plugins.rb +3 -3
- data/lib/jenkins2/cli/role_strategy.rb +157 -0
- data/lib/jenkins2/cli/user.rb +1 -1
- data/lib/jenkins2/cli/view.rb +5 -5
- data/lib/jenkins2/connection.rb +60 -5
- data/lib/jenkins2/errors.rb +11 -0
- data/lib/jenkins2/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1608986d87d4133655aed40daf7d52e89b27bfb
|
4
|
+
data.tar.gz: 948685475fb6f4bfed364db6d3692ca159c65ad9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb1ea897fbea4233cf2120577532f96170e3e2dfad99bbba3812c8117757b818d1dc0b3aa6f12c8f8d25122f46204e57c80bb7813fdc2bde72f2f4a5960f8578
|
7
|
+
data.tar.gz: 3918162db471507a88b91718acf48460af711a13790a6211f50a8587900d507f7c57cd4d7f68cc44b32c84e93e4d740bc32f66e5b5df984086a1de121f660aba
|
data/CHANGELOG.md
CHANGED
@@ -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
|
-
-
|
9
|
-
- plain-credentials 1.4
|
10
|
-
-
|
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
|
|
data/lib/jenkins2/api.rb
CHANGED
@@ -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
|
data/lib/jenkins2/api/job.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
data/lib/jenkins2/cli.rb
CHANGED
@@ -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'
|
data/lib/jenkins2/cli/job.rb
CHANGED
@@ -2,46 +2,190 @@
|
|
2
2
|
|
3
3
|
module Jenkins2
|
4
4
|
class CLI
|
5
|
-
class
|
5
|
+
# class Build < CLI
|
6
|
+
# # TODO: implement
|
7
|
+
# end
|
8
|
+
|
9
|
+
class CopyJob < CLI
|
6
10
|
def self.description
|
7
|
-
'
|
11
|
+
'Copy a job.'
|
8
12
|
end
|
9
13
|
|
10
14
|
private
|
11
15
|
|
12
16
|
def add_options
|
13
|
-
parser.separator '
|
14
|
-
parser.on '-
|
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
|
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
|
35
|
+
class CreateJob < CLI
|
23
36
|
def self.description
|
24
|
-
'
|
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 '-
|
32
|
-
options[:
|
44
|
+
parser.on '-n', '--name NAME', 'Name of the new job.' do |n|
|
45
|
+
options[:name] = n
|
33
46
|
end
|
34
|
-
|
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
|
73
|
+
super + %i[name]
|
41
74
|
end
|
42
75
|
|
43
76
|
def run
|
44
|
-
jc.job(options[:name]).
|
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
|
data/lib/jenkins2/cli/nodes.rb
CHANGED
@@ -24,7 +24,7 @@ module Jenkins2
|
|
24
24
|
|
25
25
|
class CreateNode < CLI
|
26
26
|
def self.description
|
27
|
-
'
|
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
|
-
'
|
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
|
-
'
|
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
|
-
'
|
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
|
-
'
|
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
|
-
'
|
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
|
-
'
|
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
|
data/lib/jenkins2/cli/plugins.rb
CHANGED
@@ -6,7 +6,7 @@ module Jenkins2
|
|
6
6
|
class CLI
|
7
7
|
class InstallPlugin < CLI
|
8
8
|
def self.description
|
9
|
-
'
|
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
|
-
'
|
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
|
-
'
|
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
|
data/lib/jenkins2/cli/user.rb
CHANGED
data/lib/jenkins2/cli/view.rb
CHANGED
@@ -4,7 +4,7 @@ module Jenkins2
|
|
4
4
|
class CLI
|
5
5
|
class CreateView < CLI
|
6
6
|
def self.description
|
7
|
-
'
|
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
|
-
'
|
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
|
-
'
|
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
|
-
'
|
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
|
-
'
|
129
|
+
'Remove jobs from view.'
|
130
130
|
end
|
131
131
|
|
132
132
|
private
|
data/lib/jenkins2/connection.rb
CHANGED
@@ -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
|
-
#
|
10
|
-
# Parameter:
|
10
|
+
# ==== Parameters:
|
11
11
|
# +server+:: Jenkins Server URL.
|
12
|
-
def initialize(
|
13
|
-
@server =
|
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
|
data/lib/jenkins2/errors.rb
CHANGED
@@ -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"'
|
data/lib/jenkins2/version.rb
CHANGED
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.
|
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-
|
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
|