rhc 1.25.3 → 1.26.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,8 +11,7 @@ class RHC::Commands::Base
11
11
 
12
12
  attr_writer :options, :config
13
13
 
14
- def initialize(options=Commander::Command::Options.new,
15
- config=RHC::Config.new)
14
+ def initialize(options=Commander::Command::Options.new, config=RHC::Config.new)
16
15
  @options, @config = options, config
17
16
  end
18
17
 
@@ -87,12 +86,15 @@ class RHC::Commands::Base
87
86
  o = args.join(' ')
88
87
  options[:description] = o.strip_heredoc
89
88
  end
89
+
90
90
  def self.summary(value)
91
91
  options[:summary] = value
92
92
  end
93
+
93
94
  def self.syntax(value)
94
95
  options[:syntax] = value
95
96
  end
97
+
96
98
  #def self.deprecated(msg)
97
99
  # options[:deprecated] = msg
98
100
  #end
@@ -219,7 +219,7 @@ module RHC::Commands
219
219
 
220
220
  Examples
221
221
  rhc update-member -n mydomain --role view bob
222
- Adds or updates the user with login 'bob' to 'admin' role on mydomain
222
+ Adds or updates the user with login 'bob' to 'view' role on mydomain
223
223
 
224
224
  rhc update-member -n mydomain --role admin team1 --type team
225
225
  Updates the team member with name 'team1' to the 'admin' role on mydomain
@@ -1,16 +1,48 @@
1
+ require 'rhc/servers'
2
+
1
3
  module RHC::Commands
2
4
  class Server < Base
3
5
  suppress_wizard
4
6
 
5
- summary "Display information about the status of the OpenShift service"
7
+ summary "Manage your configured servers and check the status of services"
8
+ description <<-DESC
9
+ The 'rhc server' commands allow users to add multiple OpenShift
10
+ servers to interact with the rhc commands and easily switch between
11
+ them.
12
+
13
+ For example, if an user's company has installations of OpenShift Origin
14
+ (development) and Enterprise (production) and the user also has a personal
15
+ OpenShift Online account:
16
+
17
+ rhc server add openshift.redhat.com online -l personal@email.com
18
+ rhc server add origin.openshift.mycompany.com development -l user@company.com
19
+ rhc server add enterprise.openshift.mycompany.com production -l user@company.com
20
+
21
+ Then, to switch between the servers:
22
+
23
+ rhc server use online
24
+ rhc server use development
25
+ rhc server use production
26
+
27
+ To list all servers configured:
28
+
29
+ rhc servers
30
+ DESC
31
+ default_action :help
32
+
33
+ summary "Display information about the status of the OpenShift server"
34
+ syntax "<server>"
6
35
  description <<-DESC
7
36
  Retrieves any open issues or notices about the operation of the
8
37
  OpenShift service and displays them in the order they were opened.
9
38
 
10
- When connected to an OpenShift Enterprise server, will only display
39
+ When connected to an OpenShift Enterprise or Origin server, will only display
11
40
  the version of the API that it is connecting to.
12
41
  DESC
13
- def run
42
+ argument :server, "Server hostname or nickname to check. If not provided the default server will be used.", ["--server SERVER"], :optional => true
43
+ def status(server=nil)
44
+ options.server = server.hostname if server && server = (server_configs.find(server) rescue nil)
45
+
14
46
  say "Connected to #{openshift_server}"
15
47
 
16
48
  if openshift_online_server?
@@ -36,5 +68,159 @@ module RHC::Commands
36
68
  0
37
69
  end
38
70
  end
71
+
72
+ summary "Add a new server"
73
+ description <<-DESC
74
+ Add and configure a new OpenShift server that will be available to
75
+ use through rhc commands.
76
+ When adding a new server users can optionally provide a 'nickname'
77
+ that will allow to easily switch between servers.
78
+ DESC
79
+ syntax "<hostname> [<nickname>] [--rhlogin LOGIN] [--[no-]use-authorization-tokens] [--[no-]insecure]"
80
+ argument :hostname, "Hostname of the server you are adding", ["--server HOSTNAME"]
81
+ argument :nickname, "Optionally provide a nickname to the server you are adding (e.g. 'development', 'production', 'online')", ["--nickname NICKNAME"], :optional => true
82
+ option ["-l", "--rhlogin LOGIN"], "Change the default OpenShift login used on this server"
83
+ option ["--[no-]use-authorization-tokens"], "Server will attempt to create and use authorization tokens to connect to the server"
84
+ option ["--[no-]insecure"], "If true, certificate errors will be ignored"
85
+ option ["--use"], "If provided, the server being added will be set as default (same as 'rhc server use')"
86
+ option ["--skip-wizard"], "If provided, the wizard will be skipped and a session token will not be estabilished"
87
+ def add(hostname, nickname)
88
+ raise ArgumentError, "The --use and --skip-wizard options cannot be used together." if options.use && options.skip_wizard
89
+
90
+ attrs = [:login, :use_authorization_tokens, :insecure, :timeout, :ssl_version, :ssl_client_cert_file, :ssl_ca_file]
91
+
92
+ server = server_configs.add(hostname,
93
+ attrs.inject({:nickname => nickname}){ |h, (k, v)| h[k] = options[k == :login ? :rhlogin : k]; h })
94
+
95
+ unless options.skip_wizard
96
+ (wizard_to_server(server.hostname, options.use, attrs.inject({}){ |h, (k, v)| h[k] = server.send(k); h }) ? 0 : 1).tap do |r|
97
+ paragraph { success "Now using '#{server.hostname}'" } if options.use && r == 0
98
+ end
99
+ else
100
+ say "Saving server configuration to #{system_path(server_configs.path)} ... "
101
+ server_configs.save!
102
+ success "done"
103
+ 0
104
+ end
105
+ end
106
+
107
+ summary "List all configured servers"
108
+ alias_action :"servers", :root_command => true
109
+ def list
110
+ servers = config.has_configs_from_files? ? server_configs.list : []
111
+
112
+ servers.sort.each do |server|
113
+ say display_server(server)
114
+ end
115
+
116
+ paragraph do
117
+ case servers.length
118
+ when 0
119
+ warn "You don't have any servers configured. Use 'rhc setup' to configure your OpenShift server."
120
+ when 1
121
+ say "You have 1 server configured. Use 'rhc server add' to add a new server."
122
+ else
123
+ say "You have #{servers.length} servers configured. Use 'rhc server use <hostname|nickname>' to switch between them."
124
+ end
125
+ end
126
+ 0
127
+ end
128
+
129
+ summary "Change the default server"
130
+ syntax "<server>"
131
+ argument :server, "Server hostname or nickname to use", ["--server SERVER"]
132
+ def use(server)
133
+ server = server_configs.find(server)
134
+
135
+ if wizard_to_server(server.hostname, true, :login => server.login, :use_authorization_tokens => server.use_authorization_tokens, :insecure => server.insecure)
136
+ paragraph { success "Now using '#{server.hostname}'" }
137
+ 0
138
+ else
139
+ 1
140
+ end
141
+ end
142
+
143
+ summary "Remove a server"
144
+ syntax "<server>"
145
+ argument :server, "Server hostname or nickname to be removed", ["--server SERVER"]
146
+ def remove(server)
147
+ server = server_configs.find(server)
148
+
149
+ say "Removing '#{server.hostname}' ... "
150
+
151
+ if server.default?
152
+ raise RHC::ServerInUseException.new("The '#{server.designation}' server is in use. Please switch to another server before removing it.")
153
+ else
154
+ server_configs.remove(server.hostname)
155
+ server_configs.save!
156
+ end
157
+
158
+ success "done"
159
+ 0
160
+ end
161
+
162
+ summary "Update server attributes"
163
+ syntax "<server> [--hostname HOSTNAME] [--nickname NICKNAME] [--rhlogin LOGIN] [--[no-]use-authorization-tokens] [--[no-]insecure]"
164
+ argument :server, "Server hostname or nickname to be configured", ["--server SERVER"]
165
+ option ["--hostname HOSTNAME"], "Change the hostname of this server"
166
+ option ["--nickname NICKNAME"], "Change the nickname of this server"
167
+ option ["-l", "--rhlogin LOGIN"], "Change the default OpenShift login used on this server"
168
+ option ["--[no-]use-authorization-tokens"], "Server will attempt to create and use authorization tokens to connect to the server"
169
+ option ["--[no-]insecure"], "If true, certificate errors will be ignored"
170
+ option ["--use"], "If provided, the server being configured will be set as default (same as 'rhc server use')"
171
+ option ["--skip-wizard"], "If provided, the wizard will be skipped and a session token will not be estabilished"
172
+ def configure(server)
173
+ raise ArgumentError, "The --use and --skip-wizard options cannot be used together." if options.use && options.skip_wizard
174
+
175
+ server = server_configs.find(server)
176
+
177
+ attrs = [:hostname, :nickname, :login, :use_authorization_tokens, :insecure, :timeout, :ssl_version, :ssl_client_cert_file, :ssl_ca_file].inject({}){ |h, (k, v)| v = options[k == :login ? :rhlogin : k]; h[k] = (v.nil? ? server.send(k) : v); h }
178
+
179
+ raise RHC::ServerNicknameExistsException.new(options.nickname) if options.nickname &&
180
+ server_configs.nickname_exists?(options.nickname) &&
181
+ server_configs.find(options.nickname).hostname != server.hostname
182
+
183
+ server = server_configs.update(server.hostname, attrs)
184
+
185
+ unless options.skip_wizard
186
+ wizard_to_server(attrs[:hostname], options.use, attrs.reject{|k, v| k == :hostname || k == :nickname})
187
+ else
188
+ say "Saving server configuration to #{system_path(server_configs.path)} ... "
189
+ server_configs.save!
190
+ success "done"
191
+ 0
192
+ end
193
+
194
+ paragraph{ say display_server(server) }
195
+ paragraph { success "Now using '#{server.hostname}'" } if options.use
196
+ 0
197
+ end
198
+
199
+ summary "Display the configuration of the given server"
200
+ syntax "<server>"
201
+ argument :server, "Server hostname or nickname to be displayed", ["--server SERVER"]
202
+ def show(server)
203
+ server = server_configs.find(server)
204
+ say display_server(server)
205
+ paragraph{ say "Use 'rhc servers' to display all your servers." } if server_configs.list.length > 1
206
+ 0
207
+ end
208
+
209
+ protected
210
+ def wizard_to_server(hostname, set_default, args)
211
+ options['server'] = hostname
212
+ options['rhlogin'] = args[:login] if args[:login]
213
+ options['use_authorization_tokens'] = args[:use_authorization_tokens] unless args[:use_authorization_tokens].nil?
214
+ options['insecure'] = args[:insecure] unless args[:insecure].nil?
215
+ options['timeout'] = args[:timeout] unless args[:timeout].nil?
216
+ options['ssl_version'] = args[:ssl_version] unless args[:ssl_version].nil?
217
+ options['ssl_client_cert_file'] = args[:ssl_client_cert_file] unless args[:ssl_client_cert_file].nil?
218
+ options['ssl_ca_file'] = args[:ssl_ca_file] unless args[:ssl_ca_file].nil?
219
+ RHC::ServerWizard.new(config, options, server_configs, set_default).run
220
+ end
221
+
222
+ def server_configs
223
+ @servers ||= RHC::Servers.new(config)
224
+ end
39
225
  end
40
226
  end
@@ -27,7 +27,7 @@ module RHC::Commands
27
27
  If you would like to enable tab-completion in Bash shells, pass
28
28
  --autocomplete for more information.
29
29
  DESC
30
- option ["--server NAME"], "Hostname of an OpenShift server", :default => :server_context, :required => true
30
+ option ["--server HOSTNAME"], "Hostname of an OpenShift server", :default => :server_context, :required => true
31
31
  option ['--clean'], "Ignore any saved configuration options"
32
32
  option ['--[no-]create-token'], "Create an authorization token for this server"
33
33
  option ['--autocomplete'], "Instructions for enabling tab-completion"
@@ -1,5 +1,8 @@
1
+ require 'fileutils'
1
2
  require 'rhc/vendor/parseconfig'
2
3
  require 'rhc/core_ext'
4
+ require 'rhc/servers'
5
+ require 'rhc/server_helpers'
3
6
 
4
7
  module RHC
5
8
 
@@ -45,24 +48,24 @@ module RHC
45
48
  #
46
49
  class Config
47
50
  include ConfigEnv
51
+ include RHC::ServerHelpers
48
52
 
49
53
  # Option name [config_key type comment_string_for_config]
50
54
  # if nil, == key nil == string won't be written to file if nil
51
55
  OPTIONS = {
52
- :server => ['libra_server', nil, 'The OpenShift server to connect to'],
53
- :rhlogin => ['default_rhlogin', nil, 'Your OpenShift login name'],
54
- :password => nil,
55
- :use_authorization_tokens =>
56
- [nil, :boolean, 'If true, the server will attempt to create and use authorization tokens to connect to the server'],
57
- :timeout => [nil, :integer, 'The default timeout for network operations'],
58
- :insecure => [nil, :boolean, "If true, certificate errors will be ignored.\nWARNING: This may allow others to eavesdrop on your communication with OpenShift."],
59
- :ssl_version => [nil, nil, 'The SSL protocol version to use when connecting to this server'],
60
- :ssl_client_cert_file => [nil, :path_to_file, 'A client certificate file for use with your server'],
61
- :ssl_ca_file => [nil, :path_to_file, 'A file containing CA one or more certificates'],
56
+ :server => ['libra_server', nil, 'The default OpenShift server to connect to'],
57
+ :rhlogin => ['default_rhlogin', nil, 'Your OpenShift login name'],
58
+ :password => nil,
59
+ :use_authorization_tokens => [nil, :boolean, 'If true, the server will attempt to create and use authorization tokens to connect to the server'],
60
+ :timeout => [nil, :integer, 'The default timeout for network operations'],
61
+ :insecure => [nil, :boolean, "If true, certificate errors will be ignored.\nWARNING: This may allow others to eavesdrop on your communication with OpenShift."],
62
+ :ssl_version => [nil, nil, 'The SSL protocol version to use when connecting to this server'],
63
+ :ssl_client_cert_file => [nil, :path_to_file, 'A client certificate file for use with your server'],
64
+ :ssl_ca_file => [nil, :path_to_file, 'A file containing CA one or more certificates'],
62
65
  }
63
66
 
64
- def self.options_to_config(options)
65
- OPTIONS.inject([]) do |arr, (name, opts)|
67
+ def self.options_to_config(options, args=OPTIONS.keys)
68
+ OPTIONS.select{|k,v| args ? args.include?(k) : true}.inject([]) do |arr, (name, opts)|
66
69
  opts ||= []
67
70
  next arr unless opts[2]
68
71
  value = options[name]
@@ -70,7 +73,8 @@ module RHC
70
73
  arr << "#{value.nil? ? '#' : ''}#{opts[0] || name}=#{self.type_to_config(opts[1], value)}"
71
74
  arr << ""
72
75
  arr
73
- end.join("\n")
76
+ end.unshift(!args.nil? && args.length < OPTIONS.length ?
77
+ ["# Check servers.yml for detailed server configuration", ""] : nil).flatten.compact.join("\n")
74
78
  end
75
79
 
76
80
  def self.type_to_config(type, value)
@@ -121,56 +125,83 @@ module RHC
121
125
  @global_config = nil
122
126
  @local_config = nil
123
127
  @opts_config = nil # config file passed in the options
128
+ @additional_config = nil
124
129
 
125
130
  @default_proxy = nil
126
131
 
127
- @defaults.add('libra_server', 'openshift.redhat.com')
128
- @env_config.add('libra_server', ENV['LIBRA_SERVER']) if ENV['LIBRA_SERVER']
129
- @env_config.add('libra_server', ENV['RHC_SERVER']) if ENV['RHC_SERVER']
132
+ @defaults.add('insecure', false)
133
+ @defaults.add('libra_server', openshift_online_server)
134
+
135
+ @env_config.add('libra_server', libra_server_env) if libra_server_env
136
+ @env_config.add('libra_server', rhc_server_env) if rhc_server_env
130
137
 
131
138
  @opts_config_path = nil
132
139
  end
133
140
 
134
141
  def to_options
135
142
  OPTIONS.inject({}) do |h, (name, opts)|
136
- opts = Array(opts)
137
- value = self[opts[0] || name.to_s]
138
- if value
139
- value = case opts[1]
140
- when :integer
141
- Integer(value)
142
- when :boolean
143
- !!(value =~ /^\s*(y|yes|1|t|true)\s*$/i)
144
- else
145
- value unless value.blank?
146
- end
147
- h[name] = value unless value.nil?
148
- end
149
- h
143
+ opts = Array(opts)
144
+ value = self[opts[0] || name.to_s]
145
+ unless value.nil?
146
+ value = case opts[1]
147
+ when :integer
148
+ Integer(value)
149
+ when :boolean
150
+ value.is_a?(TrueClass) || !!(value =~ /^\s*(y|yes|1|t|true)\s*$/i)
151
+ else
152
+ value unless value.blank?
153
+ end
154
+ h[name] = value
150
155
  end
156
+ h
157
+ end
151
158
  end
152
159
 
153
- def save!(options)
154
- File.open(path, 'w'){ |f| f.puts self.class.options_to_config(options) }
155
- @opts, @opts_config, @local_config, @global_config = nil
160
+ def backup
161
+ if File.exists? path
162
+ backup = "#{path}.bak"
163
+ FileUtils.cp(path, backup)
164
+ end
165
+ end
166
+
167
+ def save!(options, fields=nil)
168
+ File.open(path, 'w') do |f|
169
+ f.puts self.class.options_to_config(
170
+ options,
171
+ fields
172
+ )
173
+ end
174
+ @opts, @opts_config, @env_config, @additional_config, @local_config, @global_config = nil
156
175
  load_config_files
157
176
  self
158
177
  end
159
178
 
160
179
  def [](key)
161
180
  lazy_init
162
-
163
- # evaluate in cascading order
164
- configs = [@opts, @opts_config, @env_config, @local_config, @global_config, @defaults]
181
+ configs = configs_cascade
165
182
  result = nil
166
- configs.each do |conf|
183
+ c = nil
184
+ configs.each_with_index do |conf, i|
167
185
  result = conf[key] if !conf.nil?
186
+ c = conf
168
187
  break if !result.nil?
169
188
  end
170
-
171
189
  result
172
190
  end
173
191
 
192
+ # individual configs will be evaluated in the following cascading order
193
+ def configs_cascade
194
+ [
195
+ @opts,
196
+ @opts_config,
197
+ @env_config,
198
+ @additional_config,
199
+ @local_config,
200
+ @global_config,
201
+ @defaults
202
+ ]
203
+ end
204
+
174
205
  # DEPRECATED - will be removed when old commands are gone
175
206
  def get_value(key)
176
207
  self[key]
@@ -238,6 +269,15 @@ module RHC
238
269
  !@opts_config.nil?
239
270
  end
240
271
 
272
+ def has_additional_config?
273
+ lazy_init
274
+ !@additional_config.nil?
275
+ end
276
+
277
+ def has_configs_from_files?
278
+ has_local_config? || has_opts_config? || has_additional_config?
279
+ end
280
+
241
281
  # DEPRECATED - should be moved to Helpers
242
282
  def should_run_ssh_wizard?
243
283
  not File.exists? ssh_priv_key_file_path
@@ -252,6 +292,7 @@ module RHC
252
292
  def config_path
253
293
  @config_path ||= local_config_path
254
294
  end
295
+
255
296
  def path
256
297
  config_path
257
298
  end
@@ -294,10 +335,18 @@ module RHC
294
335
  # DEPRECATED - will be removed when old commands are gone
295
336
  def proxy_vars
296
337
  Hash[[:address,:user,:pass,:port].map do |x|
297
- [x,default_proxy.instance_variable_get("@proxy_#{x}")]
338
+ [x, default_proxy.instance_variable_get("@proxy_#{x}")]
298
339
  end]
299
340
  end
300
341
 
342
+ def servers
343
+ @servers
344
+ end
345
+
346
+ def sync_additional_config
347
+ @additional_config = servers_config
348
+ end
349
+
301
350
  private
302
351
  # Allow mocking of the home dir
303
352
  def self.home_dir
@@ -311,9 +360,19 @@ module RHC
311
360
  raise Errno::EACCES.new("Could not open config file: #{e.message}")
312
361
  end
313
362
 
363
+ def load_servers
364
+ @servers ||= RHC::Servers.new
365
+ end
366
+
367
+ def servers_config
368
+ lazy_init
369
+ (servers.find(self['libra_server']).to_config rescue nil) || (servers.list.first.to_config rescue nil)
370
+ end
371
+
314
372
  def lazy_init
315
373
  unless @loaded
316
374
  load_config_files
375
+ load_servers
317
376
  @loaded = true
318
377
  end
319
378
  end