rhc 1.25.3 → 1.26.9

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.
@@ -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