nexus_cli 1.0.2 → 2.0.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.
Files changed (35) hide show
  1. data/.gitignore +4 -1
  2. data/.travis.yml +5 -0
  3. data/Gemfile +40 -0
  4. data/Guardfile +27 -0
  5. data/README.md +20 -23
  6. data/Thorfile +66 -0
  7. data/VERSION +1 -1
  8. data/{pro → features/pro}/nexus_custom_metadata.feature +0 -0
  9. data/{pro → features/pro}/nexus_pro.feature +0 -0
  10. data/features/support/env.rb +41 -32
  11. data/lib/nexus_cli.rb +26 -10
  12. data/lib/nexus_cli/base_remote.rb +32 -0
  13. data/lib/nexus_cli/configuration.rb +24 -5
  14. data/lib/nexus_cli/connection.rb +81 -0
  15. data/lib/nexus_cli/mixins/artifact_actions.rb +186 -0
  16. data/lib/nexus_cli/mixins/global_settings_actions.rb +64 -0
  17. data/lib/nexus_cli/mixins/logging_actions.rb +45 -0
  18. data/lib/nexus_cli/{nexus_pro_remote.rb → mixins/pro/custom_metadata_actions.rb} +5 -199
  19. data/lib/nexus_cli/mixins/pro/smart_proxy_actions.rb +214 -0
  20. data/lib/nexus_cli/mixins/repository_actions.rb +245 -0
  21. data/lib/nexus_cli/mixins/user_actions.rb +125 -0
  22. data/lib/nexus_cli/remote/oss_remote.rb +11 -0
  23. data/lib/nexus_cli/remote/pro_remote.rb +59 -0
  24. data/lib/nexus_cli/remote_factory.rb +24 -0
  25. data/lib/nexus_cli/tasks.rb +3 -3
  26. data/spec/fixtures/nexus.config +4 -0
  27. data/spec/spec_helper.rb +14 -2
  28. data/spec/{configuration_spec.rb → unit/nexus_cli/configuration_spec.rb} +0 -0
  29. data/spec/{oss_remote_spec.rb → unit/nexus_cli/oss_remote_spec.rb} +15 -5
  30. data/spec/{pro_remote_spec.rb → unit/nexus_cli/pro_remote_spec.rb} +6 -1
  31. metadata +32 -17
  32. data/Gemfile.lock +0 -65
  33. data/lib/nexus_cli/kernel.rb +0 -33
  34. data/lib/nexus_cli/nexus_oss_remote.rb +0 -636
  35. data/lib/nexus_cli/nexus_remote_factory.rb +0 -65
@@ -0,0 +1,214 @@
1
+ module NexusCli
2
+ # @author Kyle Allan <kallan@riotgames.com>
3
+ module SmartProxyActions
4
+
5
+ # Gets Smart Proxy related information about the
6
+ # given [repository_id].
7
+ #
8
+ # @param repository_id [String] the repository to get information about
9
+ #
10
+ # @return [String] a String of XML about the given repository
11
+ def get_pub_sub(repository_id)
12
+ response = nexus.get(nexus_url("service/local/smartproxy/pub-sub/#{repository_id}"))
13
+ case response.status
14
+ when 200
15
+ return response.content
16
+ else
17
+ raise UnexpectedStatusCodeException.new(response.status)
18
+ end
19
+ end
20
+
21
+ # Enables artifact publishing for the given [repository_id].
22
+ #
23
+ # @param repository_id [String] the repository to enable artifact publishing on
24
+ #
25
+ # @return [Boolean] true if the artifact is now publishing artifacts, false otherwise
26
+ def enable_artifact_publish(repository_id)
27
+ params = {:repositoryId => repository_id}
28
+ params[:publish] = true
29
+ artifact_publish(repository_id, params)
30
+ end
31
+
32
+ # Disables artifact publishing for the given [repository_id].
33
+ #
34
+ # @param repository_id [String] the repository to disable artifact publishing on
35
+ #
36
+ # @return [Boolean] true if the artifact is now disabled for publishing artifacts, false otherwise
37
+ def disable_artifact_publish(repository_id)
38
+ params = {:repositoryId => repository_id}
39
+ params[:publish] = false
40
+ artifact_publish(repository_id, params)
41
+ end
42
+
43
+ # Enables artifact subscribing for the given [repository_id].
44
+ #
45
+ # @param repository_id [String] the repository to enable artifact subscribe on
46
+ # @param preemptive_fetch [Boolean] true if the repository should prefetch artifacts, false otherwise
47
+ #
48
+ # @return [Boolean] true if the repository is now subscribing, false otherwise
49
+ def enable_artifact_subscribe(repository_id, preemptive_fetch)
50
+ raise NotProxyRepositoryException.new(repository_id) unless Nokogiri::XML(get_repository_info(repository_id)).xpath("/repository/data/repoType").first.content == "proxy"
51
+
52
+ params = {:repositoryId => repository_id}
53
+ params[:subscribe] = true
54
+ params[:preemptiveFetch] = preemptive_fetch
55
+ artifact_subscribe(repository_id, params)
56
+ end
57
+
58
+ # Disables artifact subscribing for the given [repository_id].
59
+ #
60
+ # @param repository_id [String] the repository to disable artifact subscribing on
61
+ #
62
+ # @return [Boolean] true if the repository is disabled, false otherwise
63
+ def disable_artifact_subscribe(repository_id)
64
+ raise NotProxyRepositoryException.new(repository_id) unless Nokogiri::XML(get_repository_info(repository_id)).xpath("/repository/data/repoType").first.content == "proxy"
65
+
66
+ params = {:repositoryId => repository_id}
67
+ params[:subscribe] = false
68
+ artifact_subscribe(repository_id, params)
69
+ end
70
+
71
+ # Enables Smart Proxy on the Nexus server.
72
+ #
73
+ # @param host=nil [String] an optional host to listen on for Smart Proxy
74
+ # @param port=nil [Fixnum] an optional port to listen on for Smart Proxy
75
+ #
76
+ # @return [Boolean] true if Smart Proxy is enabled, false otherwise
77
+ def enable_smart_proxy(host=nil, port=nil)
78
+ params = {:enabled => true}
79
+ params[:host] = host unless host.nil?
80
+ params[:port] = port unless port.nil?
81
+ smart_proxy(params)
82
+ end
83
+
84
+ # Disables Smart Proxy on the Nexus server.
85
+ #
86
+ #
87
+ # @return [Boolean] true if Smart Proxy is disabled, false otherwise
88
+ def disable_smart_proxy
89
+ params = {:enabled => false}
90
+ smart_proxy(params)
91
+ end
92
+
93
+
94
+ # Gets the current Smart Proxy settings of the Nexus server.
95
+ #
96
+ #
97
+ # @return [String] a String of JSON with information about Smart Proxy
98
+ def get_smart_proxy_settings
99
+ response = nexus.get(nexus_url("service/local/smartproxy/settings"), :header => DEFAULT_ACCEPT_HEADER)
100
+ case response.status
101
+ when 200
102
+ return response.content
103
+ else
104
+ raise UnexpectedStatusCodeException.new(response.status)
105
+ end
106
+ end
107
+
108
+ # @deprecated this method might not be used.
109
+ def get_smart_proxy_key
110
+ response = nexus.get(nexus_url("service/local/smartproxy/settings"), :header => DEFAULT_ACCEPT_HEADER)
111
+ case response.status
112
+ when 200
113
+ return response.content
114
+ else
115
+ raise UnexpectedStatusCodeException.new(response.status)
116
+ end
117
+ end
118
+
119
+ # Adds a trusted key to Nexus for use with Smart Proxy. By default,
120
+ # the [certificate] parameter will point to a path of a certificate file. As an
121
+ # alternative, call with path=false to pass a certificate in directly.
122
+ #
123
+ # @param certificate [String] a path to or the actual certificate String
124
+ # @param description [String] a brief description of the key; usually the name of the server the key belongs to
125
+ # @param path=true [Boolean] by default uses [certificate] as a path to a file, when false, [certificate] is treated as a String
126
+ #
127
+ # @return [Boolean] true when the certificate is added, false otherwise
128
+ def add_trusted_key(certificate, description, path=true)
129
+ params = {:description => description}
130
+ params[:certificate] = path ? File.read(File.expand_path(certificate)) : certificate
131
+ response = nexus.post(nexus_url("service/local/smartproxy/trusted-keys"), :body => create_add_trusted_key_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
132
+ case response.status
133
+ when 201
134
+ return true
135
+ else
136
+ raise UnexpectedStatusCodeException.new(response.status)
137
+ end
138
+ end
139
+
140
+ # Deletes a trusted key from the Nexus server.
141
+ #
142
+ # @param key_id [String] the key to delete
143
+ #
144
+ # @return [Boolean] true if the key has been deleted, false otherwise
145
+ def delete_trusted_key(key_id)
146
+ response = nexus.delete(nexus_url("service/local/smartproxy/trusted-keys/#{key_id}"))
147
+ case response.status
148
+ when 204
149
+ return true
150
+ else
151
+ raise UnexpectedStatusCodeException.new(response.status)
152
+ end
153
+ end
154
+
155
+ # Gets information about the current list of trusted keys
156
+ # in the Nexus server. A large amount of JSON will be printed
157
+ # because this resource returns the actual certificates.
158
+ #
159
+ # @return [String] a String of JSON from Nexus about the current list of trusted keys
160
+ def get_trusted_keys
161
+ response = nexus.get(nexus_url("service/local/smartproxy/trusted-keys"), :header => DEFAULT_ACCEPT_HEADER)
162
+ case response.status
163
+ when 200
164
+ return response.content
165
+ else
166
+ raise UnexpectedStatusCodeException.new(response.status)
167
+ end
168
+ end
169
+
170
+ private
171
+
172
+ def create_add_trusted_key_json(params)
173
+ JSON.dump(:data => params)
174
+ end
175
+
176
+ def create_smart_proxy_settings_json(params)
177
+ JSON.dump(:data => params)
178
+ end
179
+
180
+ def create_pub_sub_json(params)
181
+ JSON.dump(:data => params)
182
+ end
183
+
184
+ def artifact_subscribe(repository_id, params)
185
+ response = nexus.put(nexus_url("service/local/smartproxy/pub-sub/#{sanitize_for_id(repository_id)}"), :body => create_pub_sub_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
186
+ case response.status
187
+ when 200
188
+ return true
189
+ else
190
+ raise UnexpectedStatusCodeException.new(response.status)
191
+ end
192
+ end
193
+
194
+ def artifact_publish(repository_id, params)
195
+ response = nexus.put(nexus_url("service/local/smartproxy/pub-sub/#{sanitize_for_id(repository_id)}"), :body => create_pub_sub_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
196
+ case response.status
197
+ when 200
198
+ return true
199
+ else
200
+ raise UnexpectedStatusCodeException.new(response.status)
201
+ end
202
+ end
203
+
204
+ def smart_proxy(params)
205
+ response = nexus.put(nexus_url("service/local/smartproxy/settings"), :body => create_smart_proxy_settings_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
206
+ case response.status
207
+ when 200
208
+ return true
209
+ else
210
+ raise UnexpectedStatusCodeException.new(response.status)
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,245 @@
1
+ require 'json'
2
+
3
+ module NexusCli
4
+ # @author Kyle Allan <kallan@riotgames.com>
5
+ module RepositoryActions
6
+
7
+ # Creates a repository that the Nexus uses to hold artifacts.
8
+ #
9
+ # @param name [String] the name of the repository to create
10
+ # @param proxy [Boolean] true if this is a proxy repository
11
+ # @param url [String] the url for the proxy repository to point to
12
+ # @param id [String] the id of repository
13
+ # @param policy [String] repository policy (RELEASE|SNAPSHOT)
14
+ # @param provider [String] repo provider (maven2 by default)
15
+ #
16
+ # @return [Boolean] returns true on success
17
+ def create_repository(name, proxy, url, id, policy, provider)
18
+ json = if proxy
19
+ create_proxy_repository_json(name, url, id, policy, provider)
20
+ else
21
+ create_hosted_repository_json(name, id, policy, provider)
22
+ end
23
+ response = nexus.post(nexus_url("service/local/repositories"), :body => json, :header => DEFAULT_CONTENT_TYPE_HEADER)
24
+ case response.status
25
+ when 201
26
+ return true
27
+ when 400
28
+ raise CreateRepsitoryException.new(response.content)
29
+ else
30
+ raise UnexpectedStatusCodeException.new(response.status)
31
+ end
32
+ end
33
+
34
+ # Deletes the given repository
35
+ #
36
+ # @param name [String] the name of the repositroy to delete, transformed
37
+ # into an id.
38
+ #
39
+ # @return [Boolean] true if the repository is deleted, false otherwise.
40
+ def delete_repository(name)
41
+ response = nexus.delete(nexus_url("service/local/repositories/#{sanitize_for_id(name)}"))
42
+ case response.status
43
+ when 204
44
+ return true
45
+ when 404
46
+ raise RepositoryDoesNotExistException
47
+ else
48
+ raise UnexpectedStatusCodeException.new(response.status)
49
+ end
50
+ end
51
+
52
+ # Find information about the repository with the given
53
+ # [name].
54
+ #
55
+ # @param name [String] the name of the repository, transformed
56
+ # into an id.
57
+ #
58
+ # @return [String] A String of XML with information about the desired
59
+ # repository.
60
+ def get_repository_info(name)
61
+ response = nexus.get(nexus_url("service/local/repositories/#{sanitize_for_id(name)}"))
62
+ case response.status
63
+ when 200
64
+ return response.content
65
+ when 404
66
+ raise RepositoryNotFoundException
67
+ when 503
68
+ raise CouldNotConnectToNexusException
69
+ else
70
+ raise UnexpectedStatusCodeException.new(response.status)
71
+ end
72
+ end
73
+
74
+ # Creates a group repository with the given name.
75
+ #
76
+ # @param name [String] the name to give the new repository
77
+ # @param id [String] an alternative id to use for the new repository
78
+ # @param provider [String] the type of Maven provider for this repository
79
+ #
80
+ # @return [Boolean] true if the group repository is created, false otherwise
81
+ def create_group_repository(name, id, provider)
82
+ response = nexus.post(nexus_url("service/local/repo_groups"), :body => create_group_repository_json(name, id, provider), :header => DEFAULT_CONTENT_TYPE_HEADER)
83
+ case response.status
84
+ when 201
85
+ return true
86
+ when 400
87
+ raise CreateRepsitoryException.new(response.content)
88
+ else
89
+ raise UnexpectedStatusCodeException.new(response.status)
90
+ end
91
+ end
92
+
93
+ # Gets information about the given group repository with
94
+ # the given [group_id].
95
+ #
96
+ # @param group_id [String] the id of the group repository to find
97
+ #
98
+ # @return [String] a JSON String of information about the given group repository
99
+ def get_group_repository(group_id)
100
+ response = nexus.get(nexus_url("service/local/repo_groups/#{sanitize_for_id(group_id)}"), :header => DEFAULT_ACCEPT_HEADER)
101
+ case response.status
102
+ when 200
103
+ return response.content
104
+ when 404
105
+ raise RepositoryNotFoundException
106
+ else
107
+ raise UnexpectedStatusCodeException.new(response.status)
108
+ end
109
+ end
110
+
111
+ # Checks if a the given [repository_to_check] is a member
112
+ # of the given group repository - [group_ip].
113
+ #
114
+ # @param group_id [String] the group repository to look in
115
+ # @param repository_to_check [String] the repository that might be a member of the group
116
+ #
117
+ # @return [Boolean] true if the [repository_to_check] is a member of group repository, false otherwise
118
+ def repository_in_group?(group_id, repository_to_check)
119
+ group_repository = JSON.parse(get_group_repository(group_id))
120
+ repositories_in_group = group_repository["data"]["repositories"]
121
+
122
+ repositories_in_group.find{|repository| repository["id"] == sanitize_for_id(repository_to_check)}
123
+ end
124
+
125
+ # Adds the given [repository_to_add_id] to the given group repository,
126
+ # [group_id].
127
+ #
128
+ # @param group_id [String] the group repository to add to
129
+ # @param repository_to_add_id [String] the repository to added to the group
130
+ #
131
+ # @return [Boolean] true if the repository is successfully added, false otherwise
132
+ def add_to_group_repository(group_id, repository_to_add_id)
133
+ raise RepositoryInGroupException if repository_in_group?(group_id, repository_to_add_id)
134
+ response = nexus.put(nexus_url("service/local/repo_groups/#{sanitize_for_id(group_id)}"), :body => create_add_to_group_repository_json(group_id, repository_to_add_id), :header => DEFAULT_CONTENT_TYPE_HEADER)
135
+ case response.status
136
+ when 200
137
+ return true
138
+ when 400
139
+ raise RepositoryNotFoundException
140
+ else
141
+ raise UnexpectedStatusCodeException.new(response.status)
142
+ end
143
+ end
144
+
145
+ # Removes the given [repository_to_remove_id] from the group repository,
146
+ # [group_id].
147
+ #
148
+ # @param group_id [String] the group repository to remove from
149
+ # @param repository_to_remove_id [String] the repository to remove from the group
150
+ #
151
+ # @return [Boolean] true if the repisotory is successfully remove, false otherwise
152
+ def remove_from_group_repository(group_id, repository_to_remove_id)
153
+ raise RepositoryNotInGroupException unless repository_in_group?(group_id, repository_to_remove_id)
154
+ response = nexus.put(nexus_url("service/local/repo_groups/#{sanitize_for_id(group_id)}"), :body => create_remove_from_group_repository_json(group_id, repository_to_remove_id), :header => DEFAULT_CONTENT_TYPE_HEADER)
155
+ case response.status
156
+ when 200
157
+ return true
158
+ else
159
+ raise UnexpectedStatusCodeException.new(response.status)
160
+ end
161
+ end
162
+
163
+ # Deletes the given group repository.
164
+ #
165
+ # @param group_id [String] the group repository to delete
166
+ #
167
+ # @return [Boolean] true if the group repository is deleted, false otherwise
168
+ def delete_group_repository(group_id)
169
+ response = nexus.delete(nexus_url("service/local/repo_groups/#{sanitize_for_id(group_id)}"))
170
+ case response.status
171
+ when 204
172
+ return true
173
+ when 404
174
+ raise RepositoryNotFoundException
175
+ else
176
+ raise UnexpectedStatusCodeException.new(response.status)
177
+ end
178
+ end
179
+
180
+ private
181
+
182
+ def create_hosted_repository_json(name, id, policy, provider)
183
+ params = {:provider => provider.nil? ? "maven2": provider}
184
+ params[:providerRole] = "org.sonatype.nexus.proxy.repository.Repository"
185
+ params[:exposed] = true
186
+ params[:browseable] = true
187
+ params[:indexable] = true
188
+ params[:repoType] = "hosted"
189
+ params[:repoPolicy] = policy.nil? ? "RELEASE" : ["RELEASE", "SNAPSHOT"].include?(policy) ? policy : "RELEASE"
190
+ params[:name] = name
191
+ params[:id] = id.nil? ? sanitize_for_id(name) : sanitize_for_id(id)
192
+ params[:format] = "maven2"
193
+ JSON.dump(:data => params)
194
+ end
195
+
196
+ def create_proxy_repository_json(name, url, id, policy, provider)
197
+ params = {:provider => provider.nil? ? "maven2" : provider}
198
+ params[:providerRole] = "org.sonatype.nexus.proxy.repository.Repository"
199
+ params[:exposed] = true
200
+ params[:browseable] = true
201
+ params[:indexable] = true
202
+ params[:repoType] = "proxy"
203
+ params[:repoPolicy] = policy.nil? ? "RELEASE" : ["RELEASE", "SNAPSHOT"].include?(policy) ? policy : "RELEASE"
204
+ params[:checksumPolicy] = "WARN"
205
+ params[:writePolicy] = "READ_ONLY"
206
+ params[:downloadRemoteIndexes] = true
207
+ params[:autoBlockActive] = false
208
+ params[:name] = name
209
+ params[:id] = id.nil? ? sanitize_for_id(name) : sanitize_for_id(id)
210
+ params[:remoteStorage] = {:remoteStorageUrl => url.nil? ? "http://change-me.com/" : url}
211
+ JSON.dump(:data => params)
212
+ end
213
+
214
+ def create_group_repository_json(name, id, provider)
215
+ params = {:id => id.nil? ? sanitize_for_id(name) : sanitize_for_id(id)}
216
+ params[:name] = name
217
+ params[:provider] = provider.nil? ? "maven2" : provider
218
+ params[:exposed] = true
219
+ JSON.dump(:data => params)
220
+ end
221
+
222
+ def create_add_to_group_repository_json(group_id, repository_to_add_id)
223
+ group_repository_json = JSON.parse(get_group_repository(group_id))
224
+ repositories = group_repository_json["data"]["repositories"]
225
+ repositories << {:id => sanitize_for_id(repository_to_add_id)}
226
+ params = {:repositories => repositories}
227
+ params[:id] = group_repository_json["data"]["id"]
228
+ params[:name] = group_repository_json["data"]["name"]
229
+ params[:exposed] = group_repository_json["data"]["exposed"]
230
+ JSON.dump(:data => params)
231
+ end
232
+
233
+ def create_remove_from_group_repository_json(group_id, repository_to_remove_id)
234
+ group_repository_json = JSON.parse(get_group_repository(group_id))
235
+ repositories = group_repository_json["data"]["repositories"]
236
+
237
+ repositories.delete(repository_in_group?(group_id, repository_to_remove_id))
238
+
239
+ params = {:repositories => repositories}
240
+ params[:id] = group_repository_json["data"]["id"]
241
+ params[:name] = group_repository_json["data"]["name"]
242
+ JSON.dump(:data => params)
243
+ end
244
+ end
245
+ end