nexus_cli_nx 4.1.2
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 +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +23 -0
- data/Gemfile +41 -0
- data/Guardfile +27 -0
- data/LICENSE +15 -0
- data/README.md +123 -0
- data/Rakefile +1 -0
- data/Thorfile +66 -0
- data/VERSION +1 -0
- data/bin/nexus-cli +10 -0
- data/data/pom.xml.erb +13 -0
- data/features/nexus_oss.feature +259 -0
- data/features/pro/nexus_custom_metadata.feature +116 -0
- data/features/pro/nexus_pro.feature +101 -0
- data/features/step_definitions/cli_steps.rb +105 -0
- data/features/support/env.rb +64 -0
- data/lib/nexus_cli.rb +44 -0
- data/lib/nexus_cli/artifact.rb +44 -0
- data/lib/nexus_cli/base_remote.rb +16 -0
- data/lib/nexus_cli/cli.rb +7 -0
- data/lib/nexus_cli/configuration.rb +101 -0
- data/lib/nexus_cli/connection.rb +84 -0
- data/lib/nexus_cli/errors.rb +259 -0
- data/lib/nexus_cli/mixins/artifact_actions.rb +239 -0
- data/lib/nexus_cli/mixins/global_settings_actions.rb +64 -0
- data/lib/nexus_cli/mixins/logging_actions.rb +45 -0
- data/lib/nexus_cli/mixins/pro/custom_metadata_actions.rb +176 -0
- data/lib/nexus_cli/mixins/pro/smart_proxy_actions.rb +219 -0
- data/lib/nexus_cli/mixins/repository_actions.rb +245 -0
- data/lib/nexus_cli/mixins/user_actions.rb +125 -0
- data/lib/nexus_cli/n3_metadata.rb +77 -0
- data/lib/nexus_cli/remote/oss_remote.rb +11 -0
- data/lib/nexus_cli/remote/pro_remote.rb +59 -0
- data/lib/nexus_cli/remote_factory.rb +30 -0
- data/lib/nexus_cli/tasks.rb +507 -0
- data/lib/nexus_cli/version.rb +6 -0
- data/nexus_cli_nx.gemspec +32 -0
- data/spec/fixtures/metadata_search.xml +10 -0
- data/spec/fixtures/nexus.config +4 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/unit/nexus_cli/artifact_spec.rb +82 -0
- data/spec/unit/nexus_cli/configuration_spec.rb +159 -0
- data/spec/unit/nexus_cli/mixins/pro/custom_metadata_actions_spec.rb +21 -0
- data/spec/unit/nexus_cli/oss_remote_spec.rb +83 -0
- data/spec/unit/nexus_cli/pro_remote_spec.rb +110 -0
- data/spec/unit/nexus_cli/remote_factory_spec.rb +42 -0
- metadata +263 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'jsonpath'
|
3
|
+
|
4
|
+
module NexusCli
|
5
|
+
# @author Kyle Allan <kallan@riotgames.com>
|
6
|
+
module UserActions
|
7
|
+
|
8
|
+
|
9
|
+
# Gets information about the current Nexus users.
|
10
|
+
#
|
11
|
+
# @return [String] a String of XML with data about Nexus users
|
12
|
+
def get_users
|
13
|
+
response = nexus.get(nexus_url("service/local/users"))
|
14
|
+
case response.status
|
15
|
+
when 200
|
16
|
+
return response.content
|
17
|
+
else
|
18
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a User.
|
23
|
+
#
|
24
|
+
# @param params [Hash] a Hash of parameters to use during user creation
|
25
|
+
#
|
26
|
+
# @return [Boolean] true if the user is created, false otherwise
|
27
|
+
def create_user(params)
|
28
|
+
response = nexus.post(nexus_url("service/local/users"), :body => create_user_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
|
29
|
+
case response.status
|
30
|
+
when 201
|
31
|
+
return true
|
32
|
+
when 400
|
33
|
+
raise CreateUserException.new(response.content)
|
34
|
+
else
|
35
|
+
raise UnexpectedStatusCodeException.new(reponse.code)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Updates a user by changing parts of that user's data.
|
40
|
+
#
|
41
|
+
# @param params [Hash] a Hash of parameters to update
|
42
|
+
#
|
43
|
+
# @return [Boolean] true if the user is updated, false otherwise
|
44
|
+
def update_user(params)
|
45
|
+
params[:roles] = [] if params[:roles] == [""]
|
46
|
+
user_json = get_user(params[:userId])
|
47
|
+
|
48
|
+
modified_json = JsonPath.for(user_json)
|
49
|
+
params.each do |key, value|
|
50
|
+
modified_json.gsub!("$..#{key}"){|v| value} unless key == "userId" || value.blank?
|
51
|
+
end
|
52
|
+
|
53
|
+
response = nexus.put(nexus_url("service/local/users/#{params[:userId]}"), :body => JSON.dump(modified_json.to_hash), :header => DEFAULT_CONTENT_TYPE_HEADER)
|
54
|
+
case response.status
|
55
|
+
when 200
|
56
|
+
return true
|
57
|
+
when 400
|
58
|
+
raise UpdateUserException.new(response.content)
|
59
|
+
else
|
60
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Gets a user
|
65
|
+
#
|
66
|
+
# @param user [String] the name of the user to get
|
67
|
+
#
|
68
|
+
# @return [Hash] a parsed Ruby object representing the user's JSON
|
69
|
+
def get_user(user)
|
70
|
+
response = nexus.get(nexus_url("service/local/users/#{user}"), :header => DEFAULT_ACCEPT_HEADER)
|
71
|
+
case response.status
|
72
|
+
when 200
|
73
|
+
return JSON.parse(response.content)
|
74
|
+
when 404
|
75
|
+
raise UserNotFoundException.new(user)
|
76
|
+
else
|
77
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Changes the password of a user
|
82
|
+
#
|
83
|
+
# @param params [Hash] a hash given to update the users password
|
84
|
+
#
|
85
|
+
# @return [type] [description]
|
86
|
+
def change_password(params)
|
87
|
+
response = nexus.post(nexus_url("service/local/users_changepw"), :body => create_change_password_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
|
88
|
+
case response.status
|
89
|
+
when 202
|
90
|
+
return true
|
91
|
+
when 400
|
92
|
+
raise InvalidCredentialsException
|
93
|
+
else
|
94
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Deletes the Nexus user with the given id.
|
99
|
+
#
|
100
|
+
# @param user_id [String] the Nexus user to delete
|
101
|
+
#
|
102
|
+
# @return [Boolean] true if the user is deleted, false otherwise
|
103
|
+
def delete_user(user_id)
|
104
|
+
response = nexus.delete(nexus_url("service/local/users/#{user_id}"))
|
105
|
+
case response.status
|
106
|
+
when 204
|
107
|
+
return true
|
108
|
+
when 404
|
109
|
+
raise UserNotFoundException.new(user_id)
|
110
|
+
else
|
111
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def create_user_json(params)
|
118
|
+
JSON.dump(:data => params)
|
119
|
+
end
|
120
|
+
|
121
|
+
def create_change_password_json(params)
|
122
|
+
JSON.dump(:data => params)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module NexusCli
|
4
|
+
module N3Metadata
|
5
|
+
class << self
|
6
|
+
# Checks if the custom metadata key is valid.
|
7
|
+
# Valid characters are alphanumeric with no special characeters.
|
8
|
+
def valid_n3_key?(element)
|
9
|
+
return !element.nil? && !element.match(/^[a-zA-Z0-9]+$/).nil? ? true : false
|
10
|
+
end
|
11
|
+
|
12
|
+
# Checks if the custom metadata value is valid.
|
13
|
+
# Valid characters are anything but quotes.
|
14
|
+
def valid_n3_value?(element)
|
15
|
+
return !element.nil? && !element.match(/^[^"'\\]*$/).nil? ? true : false
|
16
|
+
end
|
17
|
+
|
18
|
+
# Check if the custom metadata search type is valid.
|
19
|
+
def valid_n3_search_type?(element)
|
20
|
+
return !element.nil? && ["equal", "notequal", "matches", "bounded"].include?(element)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Creates a custom metadata subject for HTTP requests.
|
24
|
+
def create_base64_subject(artifact)
|
25
|
+
return Base64.urlsafe_encode64("urn:maven/artifact##{artifact.group_id}:#{artifact.artifact_id}:#{artifact.version}::#{artifact.extension}")
|
26
|
+
end
|
27
|
+
|
28
|
+
# Parses the regular custom metadata xml into a simpler format containing only the custom metadata.
|
29
|
+
def convert_result_to_simple_xml(custom_metadata)
|
30
|
+
request = []
|
31
|
+
document = REXML::Document.new(custom_metadata)
|
32
|
+
REXML::XPath.each(document, "//customMetadataResponse/data/customMetadata[namespace=\"urn:nexus/user#\"]") do |row|
|
33
|
+
request.push(create_tag(row.elements["key"].text.strip, row.elements["value"].text.strip))
|
34
|
+
end
|
35
|
+
formatter = REXML::Formatters::Pretty.new(4)
|
36
|
+
formatter.compact = true
|
37
|
+
document = REXML::Document.new("<artifact-resolution><data>#{request.join}</data></artifact-resolution>")
|
38
|
+
out = ""
|
39
|
+
formatter.write(document, out)
|
40
|
+
out
|
41
|
+
end
|
42
|
+
|
43
|
+
# Parses the regular custom metadata xml into a hash containing only the custom metadata.
|
44
|
+
def convert_result_to_hash(custom_metadata)
|
45
|
+
request = {}
|
46
|
+
document = REXML::Document.new(custom_metadata)
|
47
|
+
REXML::XPath.each(document, "//customMetadataResponse/data/customMetadata[namespace=\"urn:nexus/user#\"]") do |row|
|
48
|
+
request[row.elements["key"].text.strip] = row.elements["value"].text.strip
|
49
|
+
end
|
50
|
+
request
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create the request from the specified list of custom metadata key:value pairs
|
54
|
+
# @info If the target hash contains empty values for a key that exist in source, the metadata will be deleted
|
55
|
+
# @param [Hash] source The source hash of custom metadata key:value pairs
|
56
|
+
# @param [Hash] target The target hash to merge with the source hash (optional)
|
57
|
+
# @result [Hash] The resulting merge of the source and target hashes
|
58
|
+
def create_metadata_hash(source, target={})
|
59
|
+
request = []
|
60
|
+
source.merge(target).each do |key, value|
|
61
|
+
request.push({:namespace => "urn:nexus/user#", :key => key, :value => value, :readOnly => false}) unless value.empty?
|
62
|
+
end
|
63
|
+
return request
|
64
|
+
end
|
65
|
+
|
66
|
+
def missing_custom_metadata?(custom_metadata)
|
67
|
+
return !custom_metadata.match(/<data[ ]*\/>/).nil? ? true : false
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def create_tag(tag, value)
|
73
|
+
"<#{tag}>#{value}</#{tag}>"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module NexusCli
|
2
|
+
class ProRemote < BaseRemote
|
3
|
+
|
4
|
+
include ArtifactActions
|
5
|
+
include CustomMetadataActions
|
6
|
+
include GlobalSettingsActions
|
7
|
+
include LoggingActions
|
8
|
+
include RepositoryActions
|
9
|
+
include SmartProxyActions
|
10
|
+
include UserActions
|
11
|
+
|
12
|
+
def get_license_info
|
13
|
+
response = nexus.get(nexus_url("service/local/licensing"), :header => DEFAULT_ACCEPT_HEADER)
|
14
|
+
case response.status
|
15
|
+
when 200
|
16
|
+
return response.content
|
17
|
+
else
|
18
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def install_license(license_file)
|
23
|
+
file = File.read(File.expand_path(license_file))
|
24
|
+
response = nexus.post(nexus_url("service/local/licensing/upload"), :body => file, :header => {"Content-Type" => "application/octet-stream"})
|
25
|
+
case response.status
|
26
|
+
when 201
|
27
|
+
return true
|
28
|
+
when 403
|
29
|
+
raise LicenseInstallFailure
|
30
|
+
else
|
31
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def install_license_bytes(bytes)
|
36
|
+
response = nexus.post(nexus_url("service/local/licensing/upload"), :body => bytes, :header => {"Content-Type" => "application/octet-stream"})
|
37
|
+
case response.status
|
38
|
+
when 201
|
39
|
+
return true
|
40
|
+
when 403
|
41
|
+
raise LicenseInstallFailure
|
42
|
+
else
|
43
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def transfer_artifact(artifact, from_repository, to_repository)
|
48
|
+
do_transfer_artifact(artifact, from_repository, to_repository)
|
49
|
+
|
50
|
+
configuration["repository"] = sanitize_for_id(from_repository)
|
51
|
+
from_artifact_metadata = get_custom_metadata_hash(artifact)
|
52
|
+
|
53
|
+
configuration["repository"] = sanitize_for_id(to_repository)
|
54
|
+
to_artifact_metadata = get_custom_metadata_hash(artifact)
|
55
|
+
|
56
|
+
do_update_custom_metadata(artifact, from_artifact_metadata, to_artifact_metadata)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module NexusCli
|
5
|
+
class RemoteFactory
|
6
|
+
class << self
|
7
|
+
attr_reader :configuration
|
8
|
+
attr_reader :connection
|
9
|
+
|
10
|
+
# Creates a new Nexus Remote that can connect to and communicate with
|
11
|
+
# the Nexus server.
|
12
|
+
#
|
13
|
+
# @param [Hash] overrides
|
14
|
+
# @param [Boolean] ssl_verify
|
15
|
+
#
|
16
|
+
# @return [NexusCli::ProRemote, NexusCli::OSSRemote]
|
17
|
+
def create(overrides, ssl_verify=true)
|
18
|
+
@configuration = overrides ? Configuration.from_overrides(overrides) : Configuration.from_file
|
19
|
+
@connection = Connection.new(configuration, ssl_verify)
|
20
|
+
running_nexus_pro? ? ProRemote.new(overrides, ssl_verify) : OSSRemote.new(overrides, ssl_verify)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def running_nexus_pro?
|
26
|
+
return connection.status['edition_long'] == "Professional" ? true : false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,507 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'highline'
|
3
|
+
|
4
|
+
module NexusCli
|
5
|
+
module Tasks
|
6
|
+
def self.included(base)
|
7
|
+
base.send :include, ::Thor::Actions
|
8
|
+
base.class_eval do
|
9
|
+
|
10
|
+
map 'pull' => :pull_artifact
|
11
|
+
map 'push' => :push_artifact
|
12
|
+
map 'info' => :get_artifact_info
|
13
|
+
map 'custom' => :get_artifact_custom_info
|
14
|
+
map 'config' => :get_nexus_configuration
|
15
|
+
map 'status' => :get_nexus_status
|
16
|
+
map 'search' => :search_for_artifacts
|
17
|
+
map 'search_lucene' => :search_artifacts_lucene
|
18
|
+
map 'search_custom' => :search_artifacts_custom
|
19
|
+
map 'transfer' => :transfer_artifact
|
20
|
+
|
21
|
+
class_option :overrides,
|
22
|
+
:type => :hash,
|
23
|
+
:default => nil,
|
24
|
+
:desc => "A hashed list of overrides. Available options are 'url', 'repository', 'username', and 'password'."
|
25
|
+
|
26
|
+
class_option :ssl_verify,
|
27
|
+
:type => :boolean,
|
28
|
+
:default => true,
|
29
|
+
:desc => "Set to false to disable SSL Verification."
|
30
|
+
|
31
|
+
method_option :destination,
|
32
|
+
:type => :string,
|
33
|
+
:default => nil,
|
34
|
+
:desc => "A different folder other than the current working directory."
|
35
|
+
desc "pull_artifact coordinates", "Pulls an artifact from Nexus and places it on your machine."
|
36
|
+
def pull_artifact(coordinates)
|
37
|
+
pull_artifact_response = nexus_remote.pull_artifact(coordinates, options[:destination])
|
38
|
+
say "Artifact has been retrieved and can be found at path: #{pull_artifact_response[:file_path]}", :green
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "push_artifact coordinates file", "Pushes an artifact from your machine onto the Nexus."
|
42
|
+
def push_artifact(coordinates, file)
|
43
|
+
nexus_remote.push_artifact(coordinates, file)
|
44
|
+
say "Artifact #{coordinates} has been successfully pushed to Nexus.", :green
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "get_artifact_info coordinates", "Gets and returns the metadata in XML format about a particular artifact."
|
48
|
+
def get_artifact_info(coordinates)
|
49
|
+
say nexus_remote.get_artifact_info(coordinates), :green
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "search_for_artifacts", "Searches for all the versions of a particular artifact and prints it to the screen."
|
53
|
+
def search_for_artifacts(coordinates)
|
54
|
+
say nexus_remote.search_for_artifacts(coordinates), :green
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "search_artifacts_lucene", "Searches all repositiories with a gaecv maven search using wildcards"
|
58
|
+
def search_artifacts_lucene(coordinates)
|
59
|
+
say nexus_remote.search_artifacts_lucene(coordinates), :green
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "get_artifact_custom_info coordinates", "Gets and returns the custom metadata in XML format about a particular artifact."
|
63
|
+
def get_artifact_custom_info(coordinates)
|
64
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
65
|
+
say nexus_remote.get_artifact_custom_info(coordinates), :green
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "update_artifact_custom_info coordinates param1 param2 ...", "Updates the artifact custom metadata with the given key-value pairs."
|
69
|
+
def update_artifact_custom_info(coordinates, *params)
|
70
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
71
|
+
nexus_remote.update_artifact_custom_info(coordinates, *params)
|
72
|
+
say "Custom metadata for artifact #{coordinates} has been successfully pushed to Nexus.", :green
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "clear_artifact_custom_info coordinates", "Clears the artifact custom metadata."
|
76
|
+
def clear_artifact_custom_info(coordinates)
|
77
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
78
|
+
nexus_remote.clear_artifact_custom_info(coordinates)
|
79
|
+
say "Custom metadata for artifact #{coordinates} has been successfully cleared.", :green
|
80
|
+
end
|
81
|
+
|
82
|
+
desc "search_artifacts_custom param1 param2 ... ", "Searches for artifacts using artifact metadata and returns the result as a list with items in XML format."
|
83
|
+
def search_artifacts_custom(*params)
|
84
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
85
|
+
say (s = nexus_remote.search_artifacts_custom(*params)) == "" ? "No search results." : s, :green
|
86
|
+
end
|
87
|
+
|
88
|
+
desc "get_nexus_configuration", "Prints out configuration from the .nexus_cli file that helps inform where artifacts will be uploaded."
|
89
|
+
def get_nexus_configuration
|
90
|
+
config = nexus_remote.configuration
|
91
|
+
say "********* Reading CLI configuration from #{File.expand_path('~/.nexus_cli')} *********", :blue
|
92
|
+
say "Nexus URL: #{config['url']}", :blue
|
93
|
+
say "Nexus Repository: #{config['repository']}", :blue
|
94
|
+
end
|
95
|
+
|
96
|
+
desc "get_nexus_status", "Prints out information about the Nexus instance."
|
97
|
+
def get_nexus_status
|
98
|
+
data = nexus_remote.status
|
99
|
+
say "********* Getting Nexus status from #{data['base_url']} *********", :blue
|
100
|
+
say "Application Name: #{data['app_name']}", :blue
|
101
|
+
say "Version: #{data['version']}", :blue
|
102
|
+
say "Edition: #{data['edition_long']}", :blue
|
103
|
+
say "State: #{data['state']}", :blue
|
104
|
+
say "Started At: #{data['started_at']}", :blue
|
105
|
+
say "Base URL: #{data['base_url']}", :blue
|
106
|
+
end
|
107
|
+
|
108
|
+
desc "get_global_settings", "Prints out your Nexus' current setttings and saves them to a file."
|
109
|
+
def get_global_settings
|
110
|
+
nexus_remote.get_global_settings
|
111
|
+
say "Your current Nexus global settings have been written to the file: ~/.nexus/global_settings.json", :blue
|
112
|
+
end
|
113
|
+
|
114
|
+
method_option :json,
|
115
|
+
:type => :string,
|
116
|
+
:default => nil,
|
117
|
+
:desc => "A String of the JSON you wish to upload."
|
118
|
+
desc "upload_global_settings", "Uploads a global_settings.json file to your Nexus to update its settings."
|
119
|
+
def upload_global_settings
|
120
|
+
nexus_remote.upload_global_settings(options[:json])
|
121
|
+
say "Your global_settings.json file has been uploaded to Nexus", :blue
|
122
|
+
end
|
123
|
+
|
124
|
+
desc "reset_global_settings", "Resets your Nexus global_settings to their out-of-the-box defaults."
|
125
|
+
def reset_global_settings
|
126
|
+
nexus_remote.reset_global_settings
|
127
|
+
say "Your Nexus global settings have been reset to their default values", :blue
|
128
|
+
end
|
129
|
+
|
130
|
+
method_option :id,
|
131
|
+
:type => :string,
|
132
|
+
:desc => "The id of the repository to use."
|
133
|
+
method_option :policy,
|
134
|
+
:type => :string,
|
135
|
+
:desc => "Repo policy [RELEASE|SNAPSHOT], RELEASE by default"
|
136
|
+
method_option :provider,
|
137
|
+
:type => :string,
|
138
|
+
:desc => "Repo provider (maven2 by default)"
|
139
|
+
method_option :proxy,
|
140
|
+
:type => :boolean,
|
141
|
+
:desc => "True if the new repository should be a proxy repository"
|
142
|
+
method_option :url,
|
143
|
+
:type => :string,
|
144
|
+
:desc => "The url of the actual repository for the proxy repository to use."
|
145
|
+
desc "create_repository name", "Creates a new Repository with the provided name."
|
146
|
+
def create_repository(name)
|
147
|
+
if nexus_remote.create_repository(name, options[:proxy], options[:url], options[:id], options[:policy], options[:provider])
|
148
|
+
say "A new Repository named #{name} has been created.", :blue
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
desc "delete_repository name", "Deletes a Repository with the provided name."
|
153
|
+
def delete_repository(name)
|
154
|
+
if nexus_remote.delete_repository(name)
|
155
|
+
say "The Repository named #{name} has been deleted.", :blue
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
desc "get_repository_info name", "Finds and returns information about the provided Repository."
|
160
|
+
def get_repository_info(name)
|
161
|
+
say nexus_remote.get_repository_info(name), :green
|
162
|
+
end
|
163
|
+
|
164
|
+
desc "get_users", "Returns XML representing the users in Nexus."
|
165
|
+
def get_users
|
166
|
+
say nexus_remote.get_users, :green
|
167
|
+
end
|
168
|
+
|
169
|
+
method_option :username,
|
170
|
+
:type => :string,
|
171
|
+
:default => nil,
|
172
|
+
:desc => "The username."
|
173
|
+
method_option :first_name,
|
174
|
+
:type => :string,
|
175
|
+
:default => nil,
|
176
|
+
:desc => "The first name."
|
177
|
+
method_option :last_name,
|
178
|
+
:type => :string,
|
179
|
+
:default => nil,
|
180
|
+
:desc => "The last name."
|
181
|
+
method_option :email,
|
182
|
+
:type => :string,
|
183
|
+
:default => nil,
|
184
|
+
:desc => "The email."
|
185
|
+
method_option :password,
|
186
|
+
:type => :string,
|
187
|
+
:default => nil,
|
188
|
+
:desc => "The password."
|
189
|
+
method_option :enabled,
|
190
|
+
:type => :boolean,
|
191
|
+
:default => nil,
|
192
|
+
:desc => "Whether this new user is enabled or disabled."
|
193
|
+
method_option :roles,
|
194
|
+
:type => :array,
|
195
|
+
:default => [],
|
196
|
+
:require => false,
|
197
|
+
:desc => "An array of roles."
|
198
|
+
desc "create_user", "Creates a new user"
|
199
|
+
def create_user
|
200
|
+
params = ask_user(options)
|
201
|
+
|
202
|
+
if nexus_remote.create_user(params)
|
203
|
+
say "A user with the ID of #{params[:userId]} has been created.", :blue
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
method_option :username,
|
208
|
+
:type => :string,
|
209
|
+
:default => nil,
|
210
|
+
:desc => "The username."
|
211
|
+
method_option :first_name,
|
212
|
+
:type => :string,
|
213
|
+
:default => nil,
|
214
|
+
:desc => "The first name."
|
215
|
+
method_option :last_name,
|
216
|
+
:type => :string,
|
217
|
+
:default => nil,
|
218
|
+
:desc => "The last name."
|
219
|
+
method_option :email,
|
220
|
+
:type => :string,
|
221
|
+
:default => nil,
|
222
|
+
:desc => "The email."
|
223
|
+
method_option :enabled,
|
224
|
+
:type => :boolean,
|
225
|
+
:default => nil,
|
226
|
+
:desc => "Whether this new user is enabled or disabled."
|
227
|
+
method_option :roles,
|
228
|
+
:type => :array,
|
229
|
+
:default => [],
|
230
|
+
:require => false,
|
231
|
+
:desc => "An array of roles."
|
232
|
+
desc "update_user user_id", "Updates a user's details. Leave fields blank for them to remain their current values."
|
233
|
+
def update_user(user_id)
|
234
|
+
params = ask_user(options, false, false)
|
235
|
+
params[:userId] = user_id
|
236
|
+
|
237
|
+
if nexus_remote.update_user(params)
|
238
|
+
say "User #{user_id} has been updated.", :blue
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
desc "delete_user user_id", "Deletes the user with the given id."
|
243
|
+
def delete_user(user_id)
|
244
|
+
if nexus_remote.delete_user(user_id)
|
245
|
+
say "User #{user_id} has been deleted.", :blue
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
method_option :oldPassword,
|
250
|
+
:type => :string,
|
251
|
+
:default => nil,
|
252
|
+
:desc => ""
|
253
|
+
method_option :newPassword,
|
254
|
+
:type => :string,
|
255
|
+
:default => nil,
|
256
|
+
:desc => ""
|
257
|
+
desc "change_password user_id", "Changes the given user's passwords to a new one."
|
258
|
+
def change_password(user_id)
|
259
|
+
|
260
|
+
oldPassword = options[:oldPassword]
|
261
|
+
newPassword = options[:newPassword]
|
262
|
+
|
263
|
+
if oldPassword.nil?
|
264
|
+
oldPassword = ask_password("Please enter your old password:")
|
265
|
+
end
|
266
|
+
if newPassword.nil?
|
267
|
+
newPassword = ask_password("Please enter your new password:")
|
268
|
+
end
|
269
|
+
|
270
|
+
params = {:userId => user_id}
|
271
|
+
params[:oldPassword] = oldPassword
|
272
|
+
params[:newPassword] = newPassword
|
273
|
+
if nexus_remote.change_password(params)
|
274
|
+
say "The password for user #{user_id} has been updated.", :blue
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
desc "get_pub_sub repository_id", "Returns the publish/subscribe status of the given repository."
|
279
|
+
def get_pub_sub(repository_id)
|
280
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
281
|
+
say nexus_remote.get_pub_sub(repository_id), :green
|
282
|
+
end
|
283
|
+
|
284
|
+
desc "enable_artifact_publish repository_id", "Sets a repository to enable the publishing of updates about its artifacts."
|
285
|
+
def enable_artifact_publish(repository_id)
|
286
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
287
|
+
if nexus_remote.enable_artifact_publish(repository_id)
|
288
|
+
say "The repository #{repository_id} will now publish updates.", :blue
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
desc "disable_artifact_publish repository_id", "Sets a repository to disable the publishing of updates about its artifacts."
|
293
|
+
def disable_artifact_publish(repository_id)
|
294
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
295
|
+
if nexus_remote.disable_artifact_publish(repository_id)
|
296
|
+
say "The repository #{repository_id} is no longer publishing updates.", :blue
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
method_option :preemptive_fetch,
|
301
|
+
:type => :boolean,
|
302
|
+
:default => false,
|
303
|
+
:desc => "Subscribing repositories that preemtively fetch will grab artifacts as updates are received."
|
304
|
+
desc "enable_artifact_subscribe repository_id", "Sets a repository to subscribe to updates about artifacts."
|
305
|
+
def enable_artifact_subscribe(repository_id)
|
306
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
307
|
+
if nexus_remote.enable_artifact_subscribe(repository_id, options[:preemptive_fetch])
|
308
|
+
say "The repository #{repository_id} is now subscribed for artifact updates.", :blue
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
desc "disable_artifact_subscribe repository_id", "Sets a repository to stop subscribing to updates about artifacts."
|
313
|
+
def disable_artifact_subscribe(repository_id)
|
314
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
315
|
+
if nexus_remote.disable_artifact_subscribe(repository_id)
|
316
|
+
say "The repository #{repository_id} is no longer subscribed for artifact updates.", :blue
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
method_option :host,
|
321
|
+
:type => :string,
|
322
|
+
:desc => "An IP address for the Nexus server at which publishing will be available."
|
323
|
+
method_option :port,
|
324
|
+
:type => :numeric,
|
325
|
+
:desc => "An available port that will be used for Smart Proxy connections."
|
326
|
+
desc "enable_smart_proxy", "Enables Smart Proxy on the server."
|
327
|
+
def enable_smart_proxy
|
328
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
329
|
+
say nexus_remote.enable_smart_proxy(options[:host], options[:port])
|
330
|
+
end
|
331
|
+
|
332
|
+
desc "disable_smart_proxy", "Disables Smart Proxy on the server."
|
333
|
+
def disable_smart_proxy
|
334
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
335
|
+
say nexus_remote.disable_smart_proxy
|
336
|
+
end
|
337
|
+
|
338
|
+
desc "get_smart_proxy_settings", "Returns the Smart Proxy settings of the server."
|
339
|
+
def get_smart_proxy_settings
|
340
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
341
|
+
say JSON.pretty_generate(JSON.parse(nexus_remote.get_smart_proxy_settings)), :green
|
342
|
+
end
|
343
|
+
|
344
|
+
method_option :certificate,
|
345
|
+
:type => :string,
|
346
|
+
:required => :true,
|
347
|
+
:desc => "A path to a file containing a certificate."
|
348
|
+
method_option :description,
|
349
|
+
:type => :string,
|
350
|
+
:required => true,
|
351
|
+
:desc => "A description to give to the trusted key. It is probably best to make this meaningful."
|
352
|
+
desc "add_trusted_key", "Adds a new trusted key to the Smart Proxy configuration."
|
353
|
+
def add_trusted_key
|
354
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
355
|
+
if nexus_remote.add_trusted_key(options[:certificate], options[:description])
|
356
|
+
say "A new trusted key has been added to the nexus.", :blue
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
desc "delete_trusted_key key_id", "Deletes a trusted key using the given key_id."
|
361
|
+
def delete_trusted_key(key_id)
|
362
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
363
|
+
if nexus_remote.delete_trusted_key(key_id)
|
364
|
+
say "The trusted key with an id of #{key_id} has been deleted.", :blue
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
desc "get_trusted_keys", "Returns the trusted keys of the server."
|
369
|
+
def get_trusted_keys
|
370
|
+
raise NotNexusProException unless nexus_remote.kind_of? ProRemote
|
371
|
+
say JSON.pretty_generate(JSON.parse(nexus_remote.get_trusted_keys)), :green
|
372
|
+
end
|
373
|
+
|
374
|
+
desc "get_license_info", "Returns the license information of the server."
|
375
|
+
def get_license_info
|
376
|
+
say nexus_remote.get_license_info, :green
|
377
|
+
end
|
378
|
+
|
379
|
+
desc "install_license license_file", "Installs a license file into the server."
|
380
|
+
def install_license(license_file)
|
381
|
+
nexus_remote.install_license(license_file)
|
382
|
+
end
|
383
|
+
|
384
|
+
desc "get_logging_info", "Gets the log4j Settings of the Nexus server."
|
385
|
+
def get_logging_info
|
386
|
+
say nexus_remote.get_logging_info, :green
|
387
|
+
end
|
388
|
+
|
389
|
+
desc "set_logger_level level", "Updates the log4j logging level to a new value."
|
390
|
+
def set_logger_level(level)
|
391
|
+
if nexus_remote.set_logger_level(level)
|
392
|
+
say "The logging level of Nexus has been set to #{level.upcase}", :blue
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
desc "create_group_repository name", "Creates a new repository group with the given name."
|
397
|
+
method_option :id,
|
398
|
+
:type => :string,
|
399
|
+
:desc => "The id of the group repository to use (calculated from name by default)."
|
400
|
+
method_option :provider,
|
401
|
+
:type => :string,
|
402
|
+
:desc => "Group repo provider (maven2 by default)."
|
403
|
+
def create_group_repository(name)
|
404
|
+
if nexus_remote.create_group_repository(name, options[:id], options[:provider])
|
405
|
+
say "A new group repository named #{name} has been created.", :blue
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
desc "get_group_repository group_id", "Gets information about the given group repository."
|
410
|
+
def get_group_repository(group_id)
|
411
|
+
say nexus_remote.get_group_repository(group_id), :green
|
412
|
+
end
|
413
|
+
|
414
|
+
desc "add_to_group_repository group_id repository_to_add_id", "Adds a repository with the given id into the group repository."
|
415
|
+
def add_to_group_repository(group_id, repository_to_add_id)
|
416
|
+
if nexus_remote.add_to_group_repository(group_id, repository_to_add_id)
|
417
|
+
say "The repository #{repository_to_add_id} has been added to the repository group #{group_id}", :blue
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
desc "remove_from_group_repository group_id repository_to_remove_id", "Remove a repository with the given id from the group repository."
|
422
|
+
def remove_from_group_repository(group_id, repository_to_remove_id)
|
423
|
+
if nexus_remote.remove_from_group_repository(group_id, repository_to_remove_id)
|
424
|
+
say "The repository with an id of #{repository_to_remove_id} has been removed from the group repository, #{group_id}.", :blue
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
desc "delete_group_repository group_id","Deletes a group repository based on the given id."
|
429
|
+
def delete_group_repository(group_id)
|
430
|
+
if nexus_remote.delete_group_repository(group_id)
|
431
|
+
say "The group repository, #{group_id} has been deleted.", :blue
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
desc "transfer_artifact coordinates from_repository to_repository", "Transfers a given artifact from one repository to another."
|
436
|
+
def transfer_artifact(coordinates, from_repository, to_repository)
|
437
|
+
if nexus_remote.transfer_artifact(coordinates, from_repository, to_repository)
|
438
|
+
say "The artifact #{coordinates} has been transferred from #{from_repository} to #{to_repository}.", :blue
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
desc "get_artifact_download_url coordinates", "Gets the Nexus download URL for the given artifact."
|
443
|
+
def get_artifact_download_url(coordinates)
|
444
|
+
say nexus_remote.get_artifact_download_url(coordinates), :green
|
445
|
+
end
|
446
|
+
|
447
|
+
private
|
448
|
+
|
449
|
+
def nexus_remote
|
450
|
+
begin
|
451
|
+
nexus_remote ||= RemoteFactory.create(options[:overrides], options[:ssl_verify])
|
452
|
+
rescue NexusCliError => e
|
453
|
+
say e.message, :red
|
454
|
+
exit e.status_code
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def ask_user(params, ask_username=true, ask_password=true)
|
459
|
+
username = params[:username]
|
460
|
+
first_name = params[:first_name]
|
461
|
+
last_name = params[:last_name]
|
462
|
+
email = params[:email]
|
463
|
+
enabled = params[:enabled]
|
464
|
+
password = params[:password]
|
465
|
+
roles = params[:roles]
|
466
|
+
status = enabled
|
467
|
+
|
468
|
+
if username.nil? && ask_username
|
469
|
+
username = ask "Please enter the username:"
|
470
|
+
end
|
471
|
+
if first_name.nil?
|
472
|
+
first_name = ask "Please enter the first name:"
|
473
|
+
end
|
474
|
+
if last_name.nil?
|
475
|
+
last_name = ask "Please enter the last name:"
|
476
|
+
end
|
477
|
+
if email.nil?
|
478
|
+
email = ask "Please enter the email:"
|
479
|
+
end
|
480
|
+
if enabled.nil?
|
481
|
+
status = ask "Is this user enabled for use?", :limited_to => ["true", "false"]
|
482
|
+
end
|
483
|
+
if password.nil? && ask_password
|
484
|
+
password = ask_password("Please enter a password:")
|
485
|
+
end
|
486
|
+
if roles.size == 0
|
487
|
+
roles = ask "Please enter the roles:"
|
488
|
+
end
|
489
|
+
params = {:userId => username}
|
490
|
+
params[:firstName] = first_name
|
491
|
+
params[:lastName] = last_name
|
492
|
+
params[:email] = email
|
493
|
+
params[:status] = status == true ? "active" : "disabled"
|
494
|
+
params[:password] = password
|
495
|
+
params[:roles] = roles.kind_of?(Array) ? roles : roles.split(' ')
|
496
|
+
params
|
497
|
+
end
|
498
|
+
|
499
|
+
def ask_password(message)
|
500
|
+
HighLine.new.ask(message) do |q|
|
501
|
+
q.echo = false
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
end
|