-
Notifications
You must be signed in to change notification settings - Fork 8
/
cli.rb
230 lines (201 loc) · 9.13 KB
/
cli.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
require 'optparse'
require 'suse/connect'
module SUSE
module Connect
# Command line interface for interacting with SUSEConnect
class Cli # rubocop:disable ClassLength
include Logger
attr_reader :config, :options
def initialize(argv)
@options = {}
@argv = argv
extract_options
@config = Config.new.merge!(@options)
end
def execute! # rubocop:disable MethodLength, CyclomaticComplexity
# check for parameter dependencies
if @config.status
Status.new(@config).print_product_statuses(:json)
elsif @config.status_text
Status.new(@config).print_product_statuses(:text)
elsif @config.deregister
Client.new(@config).deregister!
elsif @config.cleanup
System.cleanup!
elsif @config.list_extensions
if Status.new(@config).activated_base_product?
Status.new(@config).print_extensions_list
else
log.error 'To list extensions, you must first register the base product, using: SUSEConnect -r <registration code>'
exit(1)
end
else
if @config.instance_data_file && @config.url_default?
log.error 'Please use --instance-data only in combination with --url pointing to your SMT server'
exit(1)
elsif @config.token && @config.instance_data_file
log.error 'Please use either --regcode or --instance-data'
exit(1)
elsif @config.url_default? && !@config.token && !Status.new(@config).activated_base_product?
log.error 'Please register your system using the --regcode parameter, or provide the --url parameter to register against SMT.'
exit(1)
else
Client.new(@config).register!
end
end
@config.write! if @config.write_config
rescue Errno::ECONNREFUSED
log.fatal "Error: Connection refused by server #{@config.url}"
exit 64
rescue Errno::EACCES => e
log.fatal "Error: Access error - #{e.message}"
exit 65
rescue JSON::ParserError
log.fatal complain_if_broken_smt || 'Error: Cannot parse response from server'
exit 66
rescue ApiError => e
if e.code == 401 && System.credentials?
log.fatal 'Error: Invalid system credentials, probably because the registered system was deleted in SUSE Customer Center.' \
" Check #{@options[:url] || 'https://scc.suse.com'} whether your system appears there." \
' If it does not, please call SUSEConnect --cleanup and re-register this system.'
else
log.fatal complain_if_broken_smt || "Error: SCC returned '#{e.message}' (#{e.code})"
end
exit 67
rescue FileError => e
log.fatal "FileError: '#{e.message}'"
exit 68
rescue ZypperError => e
# Zypper errors are in the range 1-7 and 100-105 (which connect will not cause)
log.fatal "Error: zypper returned (#{e.exitstatus}) with '#{e.output}'"
exit e.exitstatus
rescue SystemNotRegisteredError
log.fatal 'Deregistration failed. Check if the system has been '\
'registered using the --status-text option or use the '\
'--regcode parameter to register it.'
exit 69
rescue BaseProductDeactivationError
log.fatal 'Can not deregister base product. Use SUSEConnect -d to deactivate the whole system.'
exit 70
end
private
def complain_if_broken_smt
unless @config.url_default? || Client.new(@config).api.up_to_date?
return "Your Registration Proxy server doesn't support this function. Please update it and try again."
end
end
def extract_options # rubocop:disable MethodLength
@opts = OptionParser.new
@opts.separator 'Register SUSE Linux Enterprise installations with the SUSE Customer Center.'
@opts.separator 'Registration allows access to software repositories (including updates)'
@opts.separator 'and allows online management of subscriptions and organizations.'
@opts.separator ''
@opts.separator 'Manage subscriptions at https://scc.suse.com'
@opts.separator ''
@opts.on('-p', '--product [PRODUCT]', 'Activate PRODUCT. Defaults to the base SUSE Linux',
'Enterprise product on this system. ',
'Only one product can get activated at a time.',
'Product identifiers can be obtained with',
'\'--list-extensions\'.',
'Format: <internal name>/<version>/<architecture>') do |opt|
check_if_param(opt, 'Please provide a product identifier')
# rubocop:disable RegexpLiteral
check_if_param((opt =~ /\S+\/\S+\/\S+/), 'Please provide the product identifier in this format: ' \
'<internal name>/<version>/<architecture>. You can find these values by calling: ' \
'\'SUSEConnect --list-extensions\'. ')
identifier, version, arch = opt.split('/')
@options[:product] = Remote::Product.new(identifier: identifier, version: version, arch: arch)
end
@opts.on('-r', '--regcode [REGCODE]', 'Subscription registration code for the product to',
'be registered.',
'Relates that product to the specified subscription,',
'and enables software repositories for that product.') do |opt|
@options[:token] = opt
end
@opts.on('-d', '--de-register', 'De-registers a system and removes all services',
'installed by SUSEConnect. After de-registration,',
'the system no longer consumes a subscription slot',
'in SCC.') do |_opt|
@options[:deregister] = true
end
@opts.on('--instance-data [path to file]', 'Path to the XML file holding the public key and',
'instance data for cloud registration with SMT.') do |opt|
check_if_param(opt, 'Please provide the path to your instance data file')
@options[:instance_data_file] = opt
end
@opts.on('-e', '--email <email>', 'Email address for product registration.') do |opt|
check_if_param(opt, 'Please provide an email address')
@options[:email] = opt
end
@opts.on('--url [URL]', 'URL of registration server',
'(e.g. https://scc.suse.com).',
'Implies --write-config so that subsequent',
'invocations use the same registration server.') do |opt|
check_if_param(opt, 'Please provide registration server URL')
@options[:url] = opt
@options[:write_config] = true
end
@opts.on('--namespace [NAMESPACE]', 'Namespace option for use with SMT staging',
'environments.') do |opt|
check_if_param(opt, 'Please provide a namespace')
@options[:namespace] = opt
end
@opts.on('-s', '--status', 'Get current system registration status in json',
'format.') do |_opt|
@options[:status] = true
end
@opts.on('--status-text', 'Get current system registration status in text',
'format.') do |_opt|
@options[:status_text] = true
end
@opts.on('--list-extensions', 'List all extensions and modules available for',
'installation on this system.') do |_opt|
@options[:list_extensions] = true
end
@opts.on('--write-config', 'Write options to config file at /etc/SUSEConnect.') do |_opt|
@options[:write_config] = true
end
@opts.on('--cleanup', 'Remove old system credentials and all zypper',
'services installed by SUSEConnect.') do |_opt|
@options[:cleanup] = true
end
@opts.on('--rollback', 'Revert the registration state in case of a failed',
'migration.') do |_opt|
log.info('> Beginning registration rollback. This can take some time...')
SUSE::Connect::Migration.rollback
exit 0
end
@opts.separator ''
@opts.separator 'Common options:'
@opts.on('--root [PATH]', 'Path to the root folder, uses the same parameter',
'for zypper.') do |opt|
check_if_param(opt, 'Please provide path parameter')
@options[:filesystem_root] = opt
SUSE::Connect::System.filesystem_root = opt
end
@opts.on('--version', 'Print program version.') do
puts VERSION
exit
end
@opts.on('--debug', 'Provide debug output.') do |opt|
@options[:debug] = opt
SUSE::Connect::GlobalLogger.instance.log.level = ::Logger::DEBUG if opt
end
@opts.on_tail('-h', '--help', 'Show this message.') do
puts @opts
exit
end
@opts.set_summary_width(24)
@opts.parse(@argv)
@options[:language] = ENV['LANG'] if ENV['LANG']
log.debug("cmd options: '#{@options}'")
end
def check_if_param(opt, message)
unless opt
log.error message
exit 1
end
end
end
end
end