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 +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
|