startapp 0.1.6

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 (156) hide show
  1. checksums.yaml +7 -0
  2. data/COPYRIGHT +1 -0
  3. data/LICENSE +11 -0
  4. data/README.md +95 -0
  5. data/Rakefile +6 -0
  6. data/autocomplete/rhc_bash +1672 -0
  7. data/bin/app +37 -0
  8. data/conf/express.conf +8 -0
  9. data/features/assets/deploy.tar.gz +0 -0
  10. data/features/core_feature.rb +191 -0
  11. data/features/deployments_feature.rb +129 -0
  12. data/features/domains_feature.rb +58 -0
  13. data/features/keys_feature.rb +37 -0
  14. data/features/members_feature.rb +166 -0
  15. data/lib/rhc/auth/basic.rb +64 -0
  16. data/lib/rhc/auth/token.rb +102 -0
  17. data/lib/rhc/auth/token_store.rb +53 -0
  18. data/lib/rhc/auth.rb +5 -0
  19. data/lib/rhc/autocomplete.rb +66 -0
  20. data/lib/rhc/autocomplete_templates/bash.erb +39 -0
  21. data/lib/rhc/cartridge_helpers.rb +118 -0
  22. data/lib/rhc/cli.rb +40 -0
  23. data/lib/rhc/command_runner.rb +185 -0
  24. data/lib/rhc/commands/account.rb +25 -0
  25. data/lib/rhc/commands/alias.rb +124 -0
  26. data/lib/rhc/commands/app.rb +726 -0
  27. data/lib/rhc/commands/apps.rb +20 -0
  28. data/lib/rhc/commands/authorization.rb +115 -0
  29. data/lib/rhc/commands/base.rb +174 -0
  30. data/lib/rhc/commands/cartridge.rb +329 -0
  31. data/lib/rhc/commands/clone.rb +66 -0
  32. data/lib/rhc/commands/configure.rb +20 -0
  33. data/lib/rhc/commands/create.rb +100 -0
  34. data/lib/rhc/commands/delete.rb +19 -0
  35. data/lib/rhc/commands/deploy.rb +32 -0
  36. data/lib/rhc/commands/deployment.rb +82 -0
  37. data/lib/rhc/commands/domain.rb +172 -0
  38. data/lib/rhc/commands/env.rb +142 -0
  39. data/lib/rhc/commands/force_stop.rb +17 -0
  40. data/lib/rhc/commands/git_clone.rb +34 -0
  41. data/lib/rhc/commands/logout.rb +51 -0
  42. data/lib/rhc/commands/logs.rb +21 -0
  43. data/lib/rhc/commands/member.rb +148 -0
  44. data/lib/rhc/commands/port_forward.rb +197 -0
  45. data/lib/rhc/commands/reload.rb +17 -0
  46. data/lib/rhc/commands/restart.rb +17 -0
  47. data/lib/rhc/commands/scp.rb +54 -0
  48. data/lib/rhc/commands/server.rb +40 -0
  49. data/lib/rhc/commands/setup.rb +60 -0
  50. data/lib/rhc/commands/show.rb +43 -0
  51. data/lib/rhc/commands/snapshot.rb +137 -0
  52. data/lib/rhc/commands/ssh.rb +51 -0
  53. data/lib/rhc/commands/sshkey.rb +97 -0
  54. data/lib/rhc/commands/start.rb +17 -0
  55. data/lib/rhc/commands/stop.rb +17 -0
  56. data/lib/rhc/commands/tail.rb +47 -0
  57. data/lib/rhc/commands/threaddump.rb +14 -0
  58. data/lib/rhc/commands/tidy.rb +17 -0
  59. data/lib/rhc/commands.rb +396 -0
  60. data/lib/rhc/config.rb +321 -0
  61. data/lib/rhc/context_helper.rb +121 -0
  62. data/lib/rhc/core_ext.rb +202 -0
  63. data/lib/rhc/coverage_helper.rb +33 -0
  64. data/lib/rhc/deployment_helpers.rb +111 -0
  65. data/lib/rhc/exceptions.rb +256 -0
  66. data/lib/rhc/git_helpers.rb +106 -0
  67. data/lib/rhc/help_formatter.rb +55 -0
  68. data/lib/rhc/helpers.rb +481 -0
  69. data/lib/rhc/highline_extensions.rb +479 -0
  70. data/lib/rhc/json.rb +51 -0
  71. data/lib/rhc/output_helpers.rb +260 -0
  72. data/lib/rhc/rest/activation.rb +11 -0
  73. data/lib/rhc/rest/alias.rb +42 -0
  74. data/lib/rhc/rest/api.rb +87 -0
  75. data/lib/rhc/rest/application.rb +348 -0
  76. data/lib/rhc/rest/attributes.rb +36 -0
  77. data/lib/rhc/rest/authorization.rb +8 -0
  78. data/lib/rhc/rest/base.rb +79 -0
  79. data/lib/rhc/rest/cartridge.rb +162 -0
  80. data/lib/rhc/rest/client.rb +650 -0
  81. data/lib/rhc/rest/deployment.rb +18 -0
  82. data/lib/rhc/rest/domain.rb +98 -0
  83. data/lib/rhc/rest/environment_variable.rb +15 -0
  84. data/lib/rhc/rest/gear_group.rb +16 -0
  85. data/lib/rhc/rest/httpclient.rb +145 -0
  86. data/lib/rhc/rest/key.rb +44 -0
  87. data/lib/rhc/rest/membership.rb +105 -0
  88. data/lib/rhc/rest/mock.rb +1042 -0
  89. data/lib/rhc/rest/user.rb +32 -0
  90. data/lib/rhc/rest.rb +148 -0
  91. data/lib/rhc/scp_helpers.rb +27 -0
  92. data/lib/rhc/ssh_helpers.rb +380 -0
  93. data/lib/rhc/tar_gz.rb +51 -0
  94. data/lib/rhc/usage_templates/command_help.erb +51 -0
  95. data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
  96. data/lib/rhc/usage_templates/help.erb +61 -0
  97. data/lib/rhc/usage_templates/missing_help.erb +1 -0
  98. data/lib/rhc/usage_templates/options_help.erb +12 -0
  99. data/lib/rhc/vendor/okjson.rb +600 -0
  100. data/lib/rhc/vendor/parseconfig.rb +178 -0
  101. data/lib/rhc/vendor/sshkey.rb +253 -0
  102. data/lib/rhc/vendor/zliby.rb +628 -0
  103. data/lib/rhc/version.rb +5 -0
  104. data/lib/rhc/wizard.rb +637 -0
  105. data/lib/rhc.rb +34 -0
  106. data/spec/coverage_helper.rb +82 -0
  107. data/spec/direct_execution_helper.rb +339 -0
  108. data/spec/keys/example.pem +23 -0
  109. data/spec/keys/example_private.pem +27 -0
  110. data/spec/keys/server.pem +19 -0
  111. data/spec/rest_spec_helper.rb +31 -0
  112. data/spec/rhc/assets/cert.crt +22 -0
  113. data/spec/rhc/assets/cert_key_rsa +27 -0
  114. data/spec/rhc/assets/empty.txt +0 -0
  115. data/spec/rhc/assets/env_vars.txt +7 -0
  116. data/spec/rhc/assets/env_vars_2.txt +1 -0
  117. data/spec/rhc/assets/foo.txt +1 -0
  118. data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
  119. data/spec/rhc/assets/targz_sample.tar.gz +0 -0
  120. data/spec/rhc/auth_spec.rb +442 -0
  121. data/spec/rhc/cli_spec.rb +186 -0
  122. data/spec/rhc/command_spec.rb +435 -0
  123. data/spec/rhc/commands/account_spec.rb +42 -0
  124. data/spec/rhc/commands/alias_spec.rb +333 -0
  125. data/spec/rhc/commands/app_spec.rb +777 -0
  126. data/spec/rhc/commands/apps_spec.rb +39 -0
  127. data/spec/rhc/commands/authorization_spec.rb +157 -0
  128. data/spec/rhc/commands/cartridge_spec.rb +665 -0
  129. data/spec/rhc/commands/clone_spec.rb +41 -0
  130. data/spec/rhc/commands/deployment_spec.rb +327 -0
  131. data/spec/rhc/commands/domain_spec.rb +401 -0
  132. data/spec/rhc/commands/env_spec.rb +493 -0
  133. data/spec/rhc/commands/git_clone_spec.rb +102 -0
  134. data/spec/rhc/commands/logout_spec.rb +86 -0
  135. data/spec/rhc/commands/member_spec.rb +247 -0
  136. data/spec/rhc/commands/port_forward_spec.rb +217 -0
  137. data/spec/rhc/commands/scp_spec.rb +77 -0
  138. data/spec/rhc/commands/server_spec.rb +69 -0
  139. data/spec/rhc/commands/setup_spec.rb +118 -0
  140. data/spec/rhc/commands/snapshot_spec.rb +179 -0
  141. data/spec/rhc/commands/ssh_spec.rb +163 -0
  142. data/spec/rhc/commands/sshkey_spec.rb +188 -0
  143. data/spec/rhc/commands/tail_spec.rb +81 -0
  144. data/spec/rhc/commands/threaddump_spec.rb +84 -0
  145. data/spec/rhc/config_spec.rb +407 -0
  146. data/spec/rhc/helpers_spec.rb +531 -0
  147. data/spec/rhc/highline_extensions_spec.rb +314 -0
  148. data/spec/rhc/json_spec.rb +30 -0
  149. data/spec/rhc/rest_application_spec.rb +258 -0
  150. data/spec/rhc/rest_client_spec.rb +752 -0
  151. data/spec/rhc/rest_spec.rb +740 -0
  152. data/spec/rhc/targz_spec.rb +55 -0
  153. data/spec/rhc/wizard_spec.rb +756 -0
  154. data/spec/spec_helper.rb +575 -0
  155. data/spec/wizard_spec_helper.rb +330 -0
  156. metadata +469 -0
@@ -0,0 +1,82 @@
1
+ unless RUBY_VERSION < '1.9'
2
+ require 'simplecov'
3
+
4
+ # Patch to get correct coverage count, filed
5
+ # https://github.com/colszowka/simplecov/issues/146 upstream.
6
+ class SimpleCov::Result
7
+ def missed_lines
8
+ return @missed_lines if defined? @missed_lines
9
+ @missed_lines = 0
10
+ @files.each do |file|
11
+ @missed_lines += file.missed_lines.count
12
+ end
13
+ @missed_lines
14
+ end
15
+
16
+ def print_missed_lines
17
+ @files.each do |file|
18
+ file.missed_lines.each do |line|
19
+ STDERR.puts "MISSED #{file.filename}:#{line.number}"
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ unless SimpleCov.respond_to? :minimum_coverage=
26
+ module SimpleCov
27
+ def self.minimum_coverage=(value)
28
+ @minimum_coverage = value
29
+ end
30
+ def self.minimum_coverage
31
+ @minimum_coverage || -1
32
+ end
33
+ end
34
+
35
+ SimpleCov.at_exit do
36
+ begin
37
+ SimpleCov.result.format!
38
+ SimpleCov.result.print_missed_lines if SimpleCov.result.covered_percent.between?(98.0,99.9999999)
39
+ if SimpleCov.result.covered_percent < SimpleCov.minimum_coverage
40
+ STDERR.puts "Coverage not above #{SimpleCov.minimum_coverage}, build failed."
41
+ exit 1
42
+ end
43
+ rescue Exception => e
44
+ STDERR.puts "Exception at exit, #{e.message}"
45
+ end
46
+ end
47
+ else
48
+ SimpleCov.at_exit do
49
+ begin
50
+ SimpleCov.result.format!
51
+ SimpleCov.result.print_missed_lines if SimpleCov.result.covered_percent.between?(98.0,99.9999999)
52
+ rescue Exception => e
53
+ STDERR.puts "Exception at exit, #{e.message}"
54
+ end
55
+ end
56
+ end
57
+
58
+ SimpleCov.minimum_coverage = 100
59
+
60
+ SimpleCov.start do
61
+ coverage_dir 'coverage/spec/'
62
+
63
+ # Filters - these files will be ignored.
64
+ add_filter 'lib/rhc/vendor/' # vendored files should be taken directly and only
65
+ # namespaces changed
66
+ add_filter 'lib/rhc/rest/' # REST coverage is not yet 100%
67
+ add_filter 'lib/bin/' # This is just for safety; simplecov isn't picking these up.
68
+ add_filter 'features/' # Don't report on the files that run the cucumber tests
69
+ add_filter 'lib/rhc-feature-coverage-helper.rb'
70
+ add_filter 'spec/' # Don't report on the files that run the spec tests
71
+
72
+ # Groups - general categories of test areas
73
+ add_group('Commands') { |src_file| src_file.filename.include?(File.join(%w[lib rhc commands])) }
74
+ add_group('RHC Lib') { |src_file| src_file.filename.include?(File.join(%w[lib rhc])) }
75
+ add_group('REST') { |src_file| src_file.filename.include?(File.join(%w[lib rhc/rest])) }
76
+ add_group('Test') { |src_file| src_file.filename.include?(File.join(%w[features])) or
77
+ src_file.filename.include?(File.join(%w[spec])) }
78
+
79
+ # Note, the #:nocov: coverage exclusion should only be used on external functions
80
+ # that cannot be nondestructively tested in a developer environment.
81
+ end
82
+ end
@@ -0,0 +1,339 @@
1
+ require 'open4'
2
+ require 'rhc/helpers'
3
+
4
+ $source_bin_rhc = File.expand_path('bin/rhc')
5
+
6
+ SimpleCov.minimum_coverage = 0 # No coverage testing for features
7
+
8
+ #
9
+ # RHC_DEBUG=true TEST_INSECURE=1 TEST_USERNAME=test1 TEST_PASSWORD=password \
10
+ # RHC_SERVER=hostname \
11
+ # bundle exec rspec features/*_feature.rb
12
+ #
13
+
14
+ module RhcExecutionHelper
15
+ class Result < Struct.new(:args, :status, :stdout, :stderr)
16
+ def to_s
17
+ "Ran #{args.inspect} and got #{status}\n#{'-'*50}\n#{stdout}#{'-'*50}\n#{stderr}"
18
+ end
19
+ def successful?
20
+ status == 0
21
+ end
22
+ end
23
+
24
+ def when_running(*args)
25
+ subject{ rhc *args }
26
+ let(:output){ subject.stdout }
27
+ let(:status){ subject.status }
28
+ before{ standard_config }
29
+ end
30
+
31
+ def a_web_cartridge
32
+ if ENV['RHC_TARGET'] == 'rhel' || !File.exist?("/etc/fedora-release")
33
+ 'php-5.3'
34
+ else
35
+ 'php-5.5'
36
+ end
37
+ end
38
+
39
+ def a_random_cartridge(with_tags=nil, for_user=nil)
40
+ c = for_user ? for_user.client : client
41
+ c.cartridges.select{|cartridge| with_tags.nil? || (with_tags - cartridge.tags).empty?}.shuffle.first.name
42
+ end
43
+
44
+ def rhc(*args)
45
+ opts = args.pop if args.last.is_a? Hash
46
+ opts ||= {}
47
+ if user = opts[:as]
48
+ args << '--rhlogin'
49
+ args << user.login
50
+ if user.attributes.has_key? :token
51
+ args << '--token'
52
+ args << user.attributes[:token]
53
+ elsif user.attributes.has_key? :password
54
+ args << '--password'
55
+ args << user.attributes[:password]
56
+ end
57
+ elsif !server_supports_sessions?
58
+ args << '--password'
59
+ args << ENV['TEST_PASSWORD']
60
+ end
61
+ oldenv = if opts[:env]
62
+ old = ENV.to_hash
63
+ ENV.update(opts[:env])
64
+ old
65
+ end
66
+ execute_command(args.unshift(rhc_executable), opts[:with])
67
+ ensure
68
+ ENV.replace(oldenv) if oldenv
69
+ end
70
+
71
+ def execute_command(args, stdin="", tty=true)
72
+ stdin = stdin.join("\n") if stdin.is_a? Array
73
+ stdout, stderr =
74
+ if debug?
75
+ [debug, debug].map{ |t| RHC::Helpers::StringTee.new(t) }
76
+ else
77
+ [StringIO.new, StringIO.new]
78
+ end
79
+
80
+ args.map!(&:to_s)
81
+ status = Open4.spawn(args, 'stdout' => stdout, 'stderr' => stderr, 'stdin' => stdin, 'quiet' => true)
82
+ stdout, stderr = [stdout, stderr].map(&:string)
83
+ Result.new(args, status, stdout, stderr).tap do |r|
84
+ debug.puts "\n[#{example_description}] #{r}" if debug?
85
+ end
86
+ end
87
+
88
+ def rhc_executable
89
+ ENV['RHC_TEST_SYSTEM'] ? 'rhc' : $source_bin_rhc
90
+ end
91
+
92
+ def client
93
+ @client ||= (@environment && @environment[:client]) || begin
94
+ WebMock.allow_net_connect!
95
+ opts = {:server => ENV['RHC_SERVER']}
96
+ if token = RHC::Auth::TokenStore.new(File.expand_path("~/.openshift")).get(ENV['TEST_USERNAME'], ENV['RHC_SERVER'])
97
+ opts[:token] = token
98
+ else
99
+ opts[:user] = ENV['TEST_USERNAME']
100
+ opts[:password] = ENV['TEST_PASSWORD']
101
+ end
102
+ opts[:verify_mode] = OpenSSL::SSL::VERIFY_NONE if ENV['TEST_INSECURE'] == '1'
103
+ env = RHC::Rest::Client.new(opts)
104
+ @environment[:client] = env if @environment
105
+ env
106
+ end
107
+ end
108
+
109
+ def base_client(user, password)
110
+ opts = {:server => ENV['RHC_SERVER']}
111
+ opts[:user] = user
112
+ opts[:password] = password
113
+ opts[:verify_mode] = OpenSSL::SSL::VERIFY_NONE if ENV['TEST_INSECURE'] == '1'
114
+ RHC::Rest::Client.new(opts)
115
+ end
116
+
117
+ def no_applications(constraint=nil)
118
+ debug.puts "Removing applications that match #{constraint}" if debug?
119
+ apps = client.reset.applications
120
+ apps.each do |app|
121
+ next if constraint && !(app.name =~ constraint)
122
+ debug.puts " removing #{app.name}" if debug?
123
+ app.destroy
124
+ end
125
+ end
126
+
127
+ def other_users
128
+ $other_users ||= begin
129
+ (ENV['TEST_OTHER_USERS'] || "other1:a,other2:b,other3:c,other4:d").split(',').map{ |s| s.split(':') }.inject({}) do |h, (u, p)|
130
+ register_user(u,p) unless ENV['REGISTER_USER'].nil?
131
+ h[u] = base_client(u, p).user
132
+ h[u].attributes[:password] = p
133
+ h
134
+ end
135
+ end
136
+ end
137
+
138
+ def no_members(object)
139
+ object.delete_members
140
+ object.members.length.should == 1
141
+ end
142
+
143
+ def has_an_application(for_user=nil)
144
+ c = for_user ? for_user.client : client
145
+ debug.puts "Creating or reusing an app" if debug?
146
+ apps = c.applications
147
+ apps.find{|app| !app.scalable?} or begin
148
+ domain = has_a_domain(for_user)
149
+ debug.puts " creating a new application" if debug?
150
+ c.domains.first.add_application("test#{random}", :cartridges => [a_web_cartridge])
151
+ end
152
+ end
153
+
154
+ def has_a_scalable_application(for_user=nil)
155
+ c = for_user ? for_user.client : client
156
+ debug.puts "Creating or reusing a scalable app" if debug?
157
+ apps = c.applications
158
+ apps.find(&:scalable?) or begin
159
+ domain = has_a_domain(for_user)
160
+ debug.puts " creating a new scalable application" if debug?
161
+ c.domains.first.add_application("scalable#{random}", :cartridges => [a_web_cartridge], :scale => true)
162
+ end
163
+ end
164
+
165
+ def has_a_domain(for_user=nil)
166
+ c = for_user ? for_user.client : client
167
+ debug.puts "Creating or reusing a domain" if debug?
168
+ domain = c.domains.first or begin
169
+ debug.puts " creating a new domain" if debug?
170
+ c.add_domain("test#{random}")
171
+ end
172
+ end
173
+
174
+ def setup_args(opts={})
175
+ c = opts[:client] || client
176
+ args = []
177
+ args << 'yes' if (ENV['TEST_INSECURE'] == '1' || false)
178
+ args << (opts[:login] || ENV['TEST_USERNAME'])
179
+ args << (opts[:password] || ENV['TEST_PASSWORD'])
180
+ args << 'yes' if server_supports_sessions?(c)
181
+ args << 'yes' # generate a key, temp dir will never have one
182
+ args << (opts[:login] || ENV['TEST_USERNAME']) if (c.find_key('default').present? rescue false) # same key name as username
183
+ args << (opts[:domain_name] || "d#{random}") if (c.domains.empty? rescue true)
184
+ args
185
+ end
186
+
187
+ def has_local_ssh_key(user)
188
+ with_environment(user) do
189
+ r = rhc :setup, :with => setup_args(:login => user.login, :password => user.attributes[:password], :domain_name => "\n")
190
+ r.status.should == 0
191
+ user
192
+ end
193
+ end
194
+
195
+ def ssh_exec_for_env
196
+ @environment[:ssh_exec]
197
+ end
198
+
199
+ def use_clean_config
200
+ environment
201
+ FileUtils.rm_rf(File.join(@environment[:dir], ".openshift"))
202
+ client.reset
203
+ end
204
+
205
+ def standard_config
206
+ environment(:standard) do
207
+ r = rhc :setup, :with => setup_args
208
+ raise "Unable to configure standard config" if r.status != 0
209
+ end
210
+ client.reset
211
+ end
212
+
213
+ def debug?
214
+ @debug ||= !!ENV['RHC_DEBUG']
215
+ end
216
+
217
+ def debug (*args)
218
+ @debug_stream ||= begin
219
+ if debug?
220
+ if ENV['RHC_DEBUG'] == 'true'
221
+ STDERR
222
+ else
223
+ File.open(ENV['RHC_DEBUG'], 'w')
224
+ end
225
+ else
226
+ StringIO.new
227
+ end
228
+ end
229
+ end
230
+
231
+ def random
232
+ @environment[:id]
233
+ end
234
+
235
+ def server_supports_sessions?(c=client)
236
+ @environment && c.supports_sessions?
237
+ end
238
+
239
+ def with_environment(user, &block)
240
+ previous = @environment
241
+ @environment, @client = nil
242
+ env = ENV.to_hash
243
+ ENV['TEST_RANDOM_USER'] = nil
244
+ ENV['TEST_USERNAME'] = user.login
245
+ ENV['TEST_PASSWORD'] = user.attributes[:password]
246
+ environment("custom_#{user.login}")
247
+ yield
248
+ ensure
249
+ @environment = previous
250
+ ENV.replace(env)
251
+ end
252
+
253
+ private
254
+ def example_description
255
+ if respond_to?(:example) && example
256
+ example.metadata[:full_description]
257
+ else
258
+ self.class.example.metadata[:full_description]
259
+ end
260
+ end
261
+
262
+ def environment(id=nil)
263
+ unless @environment
264
+ is_new = false
265
+ e = Environments.get(id){ is_new = true}
266
+ update_env(e)
267
+
268
+ dir = Dir.mktmpdir('rhc_features_test')
269
+ at_exit{ FileUtils.rm_rf(dir) } unless ENV['RHC_DEBUG_DIRS']
270
+ Dir.chdir(dir)
271
+
272
+ @client = e[:client]
273
+ @environment = e
274
+ yield if block_given? && is_new
275
+ end
276
+ @environment
277
+ end
278
+
279
+ def update_env(config)
280
+ ENV['HOME'] = config[:dir]
281
+ ENV['RHC_SERVER'] ||= 'openshift.redhat.com'
282
+ if ENV['TEST_RANDOM_USER']
283
+ {
284
+ 'TEST_USERNAME' => "test_user_#{config[:id]}",
285
+ 'TEST_PASSWORD' => "password",
286
+ }.each_pair{ |k,v| ENV[k] = v }
287
+ else
288
+ ENV['TEST_USERNAME'] or raise "No TEST_USERNAME set"
289
+ ENV['TEST_PASSWORD'] or raise "No TEST_PASSWORD set"
290
+ end
291
+
292
+ register_user(ENV['TEST_USERNAME'],ENV['TEST_PASSWORD']) unless ENV['REGISTER_USER'].nil?
293
+ ENV['GIT_SSH'] = config[:ssh_exec]
294
+ end
295
+
296
+ def register_user(user,password)
297
+ if File.exists?("/etc/openshift/plugins.d/openshift-origin-auth-mongo.conf")
298
+ command = "bash -c 'unset GEM_HOME; unset GEM_PATH; oo-register-user -l admin -p admin --username #{user} --userpass #{password}'"
299
+ if Object.const_defined?('Bundler')
300
+ Bundler::with_clean_env do
301
+ system command
302
+ end
303
+ else
304
+ system command
305
+ end
306
+ elsif File.exists?("/etc/openshift/plugins.d/openshift-origin-auth-remote-user.conf")
307
+ system "/usr/bin/htpasswd -b /etc/openshift/htpasswd #{user} #{password}"
308
+ else
309
+ #ignore
310
+ print "Unknown auth plugin. Not registering user #{user}/#{password}."
311
+ print "Modify #{__FILE__}:239 if user registration is required."
312
+ cmd = nil
313
+ end
314
+ end
315
+ end
316
+
317
+ module Environments
318
+ def self.get(id, &block)
319
+ (@environments ||= {})[id] ||= begin
320
+ dir = Dir.mktmpdir('rhc_features')
321
+ at_exit{ FileUtils.rm_rf(dir) } unless ENV['RHC_DEBUG_DIRS']
322
+ id = Random.rand(1000000)
323
+ ssh_exec = create_ssh_exec(dir)
324
+ yield if block_given?
325
+ {:dir => dir, :id => id, :ssh_exec => ssh_exec}
326
+ end
327
+ end
328
+ def self.create_ssh_exec(dir, for_user=nil)
329
+ ssh_exec = File.join(dir, "ssh_exec#{for_user ? "_#{for_user}" : ""}")
330
+ IO.write(ssh_exec, "#!/bin/sh\nssh -o StrictHostKeyChecking=no -i #{dir}/.ssh/id_rsa \"$@\"")
331
+ FileUtils.chmod("u+x", ssh_exec)
332
+ ssh_exec
333
+ end
334
+ end
335
+
336
+ RSpec.configure do |config|
337
+ config.include(RhcExecutionHelper)
338
+ config.extend(RhcExecutionHelper)
339
+ end
@@ -0,0 +1,23 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIID4DCCAsgCCQDLI3UAX4mf4DANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC
3
+ VVMxFzAVBgNVBAgMDk5vcnRoIENhcm9saW5hMRAwDgYDVQQHDAdSYWxlaWdoMRAw
4
+ DgYDVQQKDAdSZWQgSGF0MRcwFQYDVQQLDA5PcGVuU2hpZnQgVGVzdDEiMCAGA1UE
5
+ AwwZdGVzdC5vcGVuc2hpZnQucmVkaGF0LmNvbTEoMCYGCSqGSIb3DQEJARYZdGVz
6
+ dEBvcGVuc2hpZnQucmVkaGF0LmNvbTAeFw0xMjEyMjIyMTI1MDFaFw0xMzEyMjIy
7
+ MTI1MDFaMIGxMQswCQYDVQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmEx
8
+ EDAOBgNVBAcMB1JhbGVpZ2gxEDAOBgNVBAoMB1JlZCBIYXQxFzAVBgNVBAsMDk9w
9
+ ZW5TaGlmdCBUZXN0MSIwIAYDVQQDDBl0ZXN0Lm9wZW5zaGlmdC5yZWRoYXQuY29t
10
+ MSgwJgYJKoZIhvcNAQkBFhl0ZXN0QG9wZW5zaGlmdC5yZWRoYXQuY29tMIIBIjAN
11
+ BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA08M8AZMgpYY+BJ6Of2LVf+vGKCmP
12
+ 0nMSGe9ESy2LDlgF5TRhg38XyryvkzBI1IBc/0+VuDxh5IbxGFUkBNsdVz9xfKKB
13
+ b1LBxVI9QuhlKyY0V+VsUAwMLOQGh7YnThBrLlSE4+oWha5mnfnC4qRaeI3LOOYe
14
+ jCaVH3ee/+gzcGKf5IW+cSbF97/++38AHHIW8x87sBfZBkP05ZiVKW1zsMS1HZMa
15
+ wc2JfvZaJZZqzezphwzfPxS11MbucceZEIqj1u47qT6957dZ/uDpmS+uPZBMS/FZ
16
+ xsnHpUIiAAP1Dm4jQXON62NfrR54Jr0O7/Z4XV42GF6R0Z2xEuoP1CDUmwIDAQAB
17
+ MA0GCSqGSIb3DQEBBQUAA4IBAQBx9MAVgYBSWGlc1Ja5vJYeYOc1eRUAGljWQN1Y
18
+ t3/iEenIu8ZLEYKqUQEFzDvjUhaVOyW4XpoLR6SQdcvOGt54aYQ5a5sRPmXtaJjm
19
+ 9ic3lJuZ+c4He4APl7j0xQ0IQPNwbqkIe6MFxISq0/4+iJDQgOTmoXm5WKKP1b48
20
+ 8s3xyJaky2LEKoUvng81/TjvOE6i7MPSGBaT64kGm1DwYjLGm8C7Q8e6fDpTAR9H
21
+ ukfpcIRls7mrqtP4vvhf5+NngJ6Ubo7hrcrWLijGub1+QAo8XlXxp9258sED+Vyx
22
+ 0596NONiYyu3h7eyD4BcawfSE0dPm0bNcq+XTMnhK3tVriTB
23
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpAIBAAKCAQEA08M8AZMgpYY+BJ6Of2LVf+vGKCmP0nMSGe9ESy2LDlgF5TRh
3
+ g38XyryvkzBI1IBc/0+VuDxh5IbxGFUkBNsdVz9xfKKBb1LBxVI9QuhlKyY0V+Vs
4
+ UAwMLOQGh7YnThBrLlSE4+oWha5mnfnC4qRaeI3LOOYejCaVH3ee/+gzcGKf5IW+
5
+ cSbF97/++38AHHIW8x87sBfZBkP05ZiVKW1zsMS1HZMawc2JfvZaJZZqzezphwzf
6
+ PxS11MbucceZEIqj1u47qT6957dZ/uDpmS+uPZBMS/FZxsnHpUIiAAP1Dm4jQXON
7
+ 62NfrR54Jr0O7/Z4XV42GF6R0Z2xEuoP1CDUmwIDAQABAoIBAQCrb/ani7Y1a13Q
8
+ HZFdneUcwANXxnYSOWihKGzQtBlMzoRPUD3V2FGpp2I5NjDwIM+pPoQGeJQEEB8l
9
+ xN/5Mm8pkEpPTbyeJJCNMAw6m6wz56Uet7UdhPNicGS9AAIIGBC9nF1Nqtj69vtK
10
+ z8Yv+EDqMlkhQmPesOmvZQeLRDBIvYUdKFMc2tvBBqAkVUbcpRICUmHbAjyGs3qi
11
+ +K3eBym9Hhv5ICLNAsvSHUwb/vVN0uvr5qMrcl8kFWBsNgCac6dj3eAMU90olV4x
12
+ BjmRBln30RlwbVbUKownVqpyCi+JCEENQ74Dcg9eQkpyTC/csL+7E1IeaLoz8aKA
13
+ uAGhF6SRAoGBAP5jtNY70HHPDjyB4ySkuaJKvt316MASqOp79Q4vvrAPVAuX2LlX
14
+ ce0WzFid5ZssfTBQ5QnX3gDGnJ+daZS3QwgquDEfyR8rdkxnhfcjrl79+vLom394
15
+ vUMA8dS/ctk2lN7UQq3qXkqg2cBkJ2sd0FkjYgRmdWcVysKEOrxiCi7DAoGBANUa
16
+ cSEoLfluI4XPfeXe6IYlfdnQkk+0uyUD+XnKPj3Sh8YEh0xx/24fAIY9gEtTSiXK
17
+ E+a0iVoRcF6Kr/1jj4BYoZTG67RqsJWDr8ISnMES+dfQoKOWQg4GTPbCvMlluBwH
18
+ dPCgDS3xgXw7MmJTsnvn69nVQTIzFZFZ5GAJ1pVJAoGAGpvFQ49YGz9kJtITNzb/
19
+ r8kPs9nP8Z9CCdzTYht+X54K1XeZlLFf2kPDNhW1+YgqxA4CFwh8USp1IYDulT6i
20
+ BU2qnIDNobQDGLTPX21dBNSeFiBce3Xeng6QPQeVdMDvy2r6WoSkPjwa6rPPJ7Yj
21
+ n99ClmE9MH4oCjaYijHbDM8CgYBb3mtY7PZs6oNb42iWGbPKaQ1JQnZg8DwhqAX7
22
+ 8ClHA6TOxBMD7L0+XxUdyhOt5Xk4s1ZDBh+UeaIkz8sxBKPPo+X8uojQnZIE0uGJ
23
+ W/bB8YlN9b3a6CMP4r15P9idRkHJq5lJRuaHoO6+fNKquwReEEyH+zyBBK7Om58t
24
+ m/ArKQKBgQCcamRni3FOi6kK8YT/cv4Tobx4e8qwOJcX+93E8DdrB2UP3MLfkwA5
25
+ thThxl4Lub50bgtUJ5yfNDS0nCZed/Ax/SqzizvCCJbw7BqSOBbJv/BSsql3k1FD
26
+ hoBg8a1zkB8dDQNoKj2Om5NM7U+rL1Ujp9uW/qcLaejuks3C441FGw==
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDKzCCApSgAwIBAgICOcMwDQYJKoZIhvcNAQEFBQAwgbExCzAJBgNVBAYTAi0t
3
+ MRIwEAYDVQQIDAlTb21lU3RhdGUxETAPBgNVBAcMCFNvbWVDaXR5MRkwFwYDVQQK
4
+ DBBTb21lT3JnYW5pemF0aW9uMR8wHQYDVQQLDBZTb21lT3JnYW5pemF0aW9uYWxV
5
+ bml0MRkwFwYDVQQDDBBpcC0xMC0xMi0xMjMtMjI5MSQwIgYJKoZIhvcNAQkBFhVy
6
+ b290QGlwLTEwLTEyLTEyMy0yMjkwHhcNMTIxMjE2MDUyNzA3WhcNMTMxMjE2MDUy
7
+ NzA3WjCBsTELMAkGA1UEBhMCLS0xEjAQBgNVBAgMCVNvbWVTdGF0ZTERMA8GA1UE
8
+ BwwIU29tZUNpdHkxGTAXBgNVBAoMEFNvbWVPcmdhbml6YXRpb24xHzAdBgNVBAsM
9
+ FlNvbWVPcmdhbml6YXRpb25hbFVuaXQxGTAXBgNVBAMMEGlwLTEwLTEyLTEyMy0y
10
+ MjkxJDAiBgkqhkiG9w0BCQEWFXJvb3RAaXAtMTAtMTItMTIzLTIyOTCBnzANBgkq
11
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEA5yEY0irLovUbcFoCnhon8zo4yp68+UBBtJ3A
12
+ 0apkSHhU+P29/YgKTbMoSu0xGTiDnih77KY3jq5SS3O7kKMrqA8otqp96Hl4iB+X
13
+ KNa9njZIP5FS3RmS2nOzrlNQvSwOjK4cHJYkzH6ozIBOgz3qaCNC8skmNCdb0LmZ
14
+ TX9lYssCAwEAAaNQME4wHQYDVR0OBBYEFIoxHQJuFHsreItT4b6Vx9XB5rrtMB8G
15
+ A1UdIwQYMBaAFIoxHQJuFHsreItT4b6Vx9XB5rrtMAwGA1UdEwQFMAMBAf8wDQYJ
16
+ KoZIhvcNAQEFBQADgYEAHDAQGgA5PmauN0GKJuUbHkH/L7cBgxs6B2Rnbx8r+zJM
17
+ a3OdnEhJRwhfXEsw47Uo7Uo78auCPNO5VQCMxmSwejJ7BbsWuqpKpKL/UsZv3qeJ
18
+ pyXCQnzYnYsuTe1b72AZ7ek6S4s5Utc5L+sqWOM+WcKODC5yxrEQPrtMjXKNXZY=
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,31 @@
1
+ require 'webmock/rspec'
2
+ require 'rhc/rest'
3
+ require 'rhc/rest/mock'
4
+ require 'rhc/exceptions'
5
+ require 'base64'
6
+
7
+ RSpec::Matchers.define :have_same_attributes_as do |expected|
8
+ match do |actual|
9
+ (actual.instance_variables == expected.instance_variables) &&
10
+ (actual.instance_variables.map { |i| instance_variable_get(i) } ==
11
+ expected.instance_variables.map { |i| instance_variable_get(i) })
12
+ end
13
+ end
14
+
15
+ # ruby 1.8 does not have strict_encode
16
+ if RUBY_VERSION.to_f == 1.8
17
+ module Base64
18
+ def strict_encode64(value)
19
+ encode64(value).delete("\n")
20
+ end
21
+ end
22
+ end
23
+
24
+ module RestSpecHelper
25
+ include RHC::Rest::Mock::Helpers
26
+ include RHC::Rest::Mock
27
+ end
28
+
29
+ RSpec.configure do |configuration|
30
+ include(RestSpecHelper)
31
+ end
@@ -0,0 +1,22 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDoDCCAogCCQDzF8AJCHnrbjANBgkqhkiG9w0BAQUFADCBkTELMAkGA1UEBhMC
3
+ VVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxDzANBgNVBAoMBnJl
4
+ ZGhhdDESMBAGA1UECwwJb3BlbnNoaWZ0MRIwEAYDVQQDDAlvcGVuc2hpZnQxKDAm
5
+ BgkqhkiG9w0BCQEWGWluZm9Ab3BlbnNoaWZ0LnJlZGhhdC5jb20wHhcNMTMwMjE5
6
+ MjExMTQ4WhcNMTQwMjE5MjExMTQ4WjCBkTELMAkGA1UEBhMCVVMxCzAJBgNVBAgM
7
+ AkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxDzANBgNVBAoMBnJlZGhhdDESMBAGA1UE
8
+ CwwJb3BlbnNoaWZ0MRIwEAYDVQQDDAlvcGVuc2hpZnQxKDAmBgkqhkiG9w0BCQEW
9
+ GWluZm9Ab3BlbnNoaWZ0LnJlZGhhdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
10
+ DwAwggEKAoIBAQDAEbH4MCi3iIDP1HS+/Xwu8SjdSc5WJX6htV7hJpmFZ8HohV/8
11
+ ba0v6aM9IJIIt+sIe2J62t/9G3leOdIHBxeACN4fV2l/iA/fvxvlnFKeD7sHm9Oc
12
+ Yj1H6YYJ57sIOf/oLDpJl6l3Rw8VC3+3W0/lzlVpA8qt7fpkiW7XQJCPplUSrdVC
13
+ 3okQ2T5NAod5+wVIOqELgE5bLX1LRs5VPsjytHkJ7rKXs55FHR3kpsoImn5xD0Ky
14
+ 6lRn8cIMolQoyN5HIGr8f5P+07hrHibve8jje/DKTssb5yEUAEmh6iGHQsRAnsUW
15
+ QoIEUOLqQCu9re2No4G52Kl2xQIjyJF7rCfxAgMBAAEwDQYJKoZIhvcNAQEFBQAD
16
+ ggEBAGHrya/ZkiAje2kHsOajXMlO2+y1iLfUDcRLuEWpUa8sI5EM4YtemQrsupFp
17
+ 8lVYG5C4Vh8476oF9t8Wex5eH3ocwbSvPIUqE07hdmrubiMq4wxFVRYq7g9lHAnx
18
+ l+bABuN/orbAcPcGAGg7AkXVoAc3Fza/ZcgMcw7NOtDTEss70V9OdgCfQUJL0KdO
19
+ hCO8bQ1EaEiq6zEh8RpZe8mu+f/GYATX1I+eJUc6F6cn83oJjE9bqAVzk7TzTHeK
20
+ EBKN50C14wWtXeG7n2+ugaVO+0xnvHeUrQBLHSRyOHqxXrQQ5XmzcaBiyI0f2IQM
21
+ Hst1BVXyX0n/L/ZoYYsv5juJmDo=
22
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEogIBAAKCAQEAwBGx+DAot4iAz9R0vv18LvEo3UnOViV+obVe4SaZhWfB6IVf
3
+ /G2tL+mjPSCSCLfrCHtietrf/Rt5XjnSBwcXgAjeH1dpf4gP378b5ZxSng+7B5vT
4
+ nGI9R+mGCee7CDn/6Cw6SZepd0cPFQt/t1tP5c5VaQPKre36ZIlu10CQj6ZVEq3V
5
+ Qt6JENk+TQKHefsFSDqhC4BOWy19S0bOVT7I8rR5Ce6yl7OeRR0d5KbKCJp+cQ9C
6
+ supUZ/HCDKJUKMjeRyBq/H+T/tO4ax4m73vI43vwyk7LG+chFABJoeohh0LEQJ7F
7
+ FkKCBFDi6kArva3tjaOBudipdsUCI8iRe6wn8QIDAQABAoIBAG/on4JVRRQSw8LU
8
+ LiWt+jI7ryyoOUH2XL8JtzuGSwLwvomlVJT2rmbxQXx3Qr8zsgziHzIn30RRQrkF
9
+ BXu0xRuDjzBBtSVqeJ1Mc4uoNncEAVxgjb5bewswZDnXPCGB8bosMtX4OPRXgdEo
10
+ PwTtfjMOsrMaU3hd5Xu4m81tQA2BvwOlx8aYDyH0jeTnervc5uRGbeTBQG4Bu40E
11
+ rWNmXvgNq2EzTAwbbN6Ma97gw9KgXnM4Nlh29Fxb5TBeUU9lkzuTZAZIDXKIm7AG
12
+ UwMbj/A038yAumYQtThTE/3e4W3rn7F2Vko900bC4aAC1KQOAzjIeQqzqkVxWTWq
13
+ 4SUFQAECgYEA/ODwifOTuI6hdZK6JRgc4wp6Rc0fkqHuxLzABXoIGuSVlWyimqIN
14
+ ZySAkpo5EW6DNraRJxNCOBmWeGPEhHGrea+JPiPEwCK0F7SxvSmg3jzNzw3Es31T
15
+ ecET7eDwuSOY9v4XDzLyiXXkEUUReD7Ng2hEYL+HaQrl5jWj4lxgq/ECgYEAwnCb
16
+ Krz7FwX8AqtFAEi6uUrc12k1xYKQfrwSxbfdK2vBBUpgB71Iq/fqP+1BittEljDG
17
+ 8f4jEtMBFfEPhLzGIHaI3UiHUHXS4GetA77TRgR8lnKKpj1FcMIY2iKU479707O5
18
+ Q08pgWRUDQ8BVg2ePgbo5QjLMc/rv7UF3AHvPAECgYB/auAIwqDGN6gHU/1TP4ke
19
+ pWLi1O55tfpXSzv+BnUbB96PQgPUop7aP7xBIlBrBiI7aVZOOBf/qHT3CF421geu
20
+ 8tHWa7NxlIrl/vgn9lfGYyDYmXlpb1amXLEsBVGGF/e1TGZWFDe9J5fZU9HvosVu
21
+ 1xTNIvSZ6xHYI2MGZcGYIQKBgEYeebaV5C7PV6xWu1F46O19U9rS9DM//H/XryVi
22
+ Qv4vo7IWuj7QQe7SPsXC98ntfPR0rqoCLf/R3ChfgGsr8H8wf/bc+v9HHj8S5E/f
23
+ dy1e3Nccg2ej3PDm7jNsGSlwmmUkAQGHAL7KwYzcBm1UB+bycvZ1j2FtS+UckPpg
24
+ MDgBAoGALD8PkxHb4U4DtbNFSYRrUdvS9heav/yph3lTMfifNkOir36io6v8RPgb
25
+ D2bHKKZgmYlTgJrxD45Er9agC5jclJO35QRU/OfGf3GcnABkBI7vlvUKADAo65Sq
26
+ weZkdJnbrIadcvLOHOzkKC9m+rxFTC9VoN1dwK2zwYvUXfa1VJA=
27
+ -----END RSA PRIVATE KEY-----
File without changes
@@ -0,0 +1,7 @@
1
+ FOO=123
2
+ BAR=456
3
+ MY_OPENSHIFT_ENV_VAR=mongodb://user:pass@host:port/
4
+ MY_EMPTY_ENV_VAR=
5
+ ZEE
6
+ LOL
7
+ MUST NOT BE INCLUDED
@@ -0,0 +1 @@
1
+ AND=123
@@ -0,0 +1 @@
1
+ foo
@@ -0,0 +1 @@
1
+ foo
Binary file