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.
- checksums.yaml +7 -0
- data/COPYRIGHT +1 -0
- data/LICENSE +11 -0
- data/README.md +95 -0
- data/Rakefile +6 -0
- data/autocomplete/rhc_bash +1672 -0
- data/bin/app +37 -0
- data/conf/express.conf +8 -0
- data/features/assets/deploy.tar.gz +0 -0
- data/features/core_feature.rb +191 -0
- data/features/deployments_feature.rb +129 -0
- data/features/domains_feature.rb +58 -0
- data/features/keys_feature.rb +37 -0
- data/features/members_feature.rb +166 -0
- data/lib/rhc/auth/basic.rb +64 -0
- data/lib/rhc/auth/token.rb +102 -0
- data/lib/rhc/auth/token_store.rb +53 -0
- data/lib/rhc/auth.rb +5 -0
- data/lib/rhc/autocomplete.rb +66 -0
- data/lib/rhc/autocomplete_templates/bash.erb +39 -0
- data/lib/rhc/cartridge_helpers.rb +118 -0
- data/lib/rhc/cli.rb +40 -0
- data/lib/rhc/command_runner.rb +185 -0
- data/lib/rhc/commands/account.rb +25 -0
- data/lib/rhc/commands/alias.rb +124 -0
- data/lib/rhc/commands/app.rb +726 -0
- data/lib/rhc/commands/apps.rb +20 -0
- data/lib/rhc/commands/authorization.rb +115 -0
- data/lib/rhc/commands/base.rb +174 -0
- data/lib/rhc/commands/cartridge.rb +329 -0
- data/lib/rhc/commands/clone.rb +66 -0
- data/lib/rhc/commands/configure.rb +20 -0
- data/lib/rhc/commands/create.rb +100 -0
- data/lib/rhc/commands/delete.rb +19 -0
- data/lib/rhc/commands/deploy.rb +32 -0
- data/lib/rhc/commands/deployment.rb +82 -0
- data/lib/rhc/commands/domain.rb +172 -0
- data/lib/rhc/commands/env.rb +142 -0
- data/lib/rhc/commands/force_stop.rb +17 -0
- data/lib/rhc/commands/git_clone.rb +34 -0
- data/lib/rhc/commands/logout.rb +51 -0
- data/lib/rhc/commands/logs.rb +21 -0
- data/lib/rhc/commands/member.rb +148 -0
- data/lib/rhc/commands/port_forward.rb +197 -0
- data/lib/rhc/commands/reload.rb +17 -0
- data/lib/rhc/commands/restart.rb +17 -0
- data/lib/rhc/commands/scp.rb +54 -0
- data/lib/rhc/commands/server.rb +40 -0
- data/lib/rhc/commands/setup.rb +60 -0
- data/lib/rhc/commands/show.rb +43 -0
- data/lib/rhc/commands/snapshot.rb +137 -0
- data/lib/rhc/commands/ssh.rb +51 -0
- data/lib/rhc/commands/sshkey.rb +97 -0
- data/lib/rhc/commands/start.rb +17 -0
- data/lib/rhc/commands/stop.rb +17 -0
- data/lib/rhc/commands/tail.rb +47 -0
- data/lib/rhc/commands/threaddump.rb +14 -0
- data/lib/rhc/commands/tidy.rb +17 -0
- data/lib/rhc/commands.rb +396 -0
- data/lib/rhc/config.rb +321 -0
- data/lib/rhc/context_helper.rb +121 -0
- data/lib/rhc/core_ext.rb +202 -0
- data/lib/rhc/coverage_helper.rb +33 -0
- data/lib/rhc/deployment_helpers.rb +111 -0
- data/lib/rhc/exceptions.rb +256 -0
- data/lib/rhc/git_helpers.rb +106 -0
- data/lib/rhc/help_formatter.rb +55 -0
- data/lib/rhc/helpers.rb +481 -0
- data/lib/rhc/highline_extensions.rb +479 -0
- data/lib/rhc/json.rb +51 -0
- data/lib/rhc/output_helpers.rb +260 -0
- data/lib/rhc/rest/activation.rb +11 -0
- data/lib/rhc/rest/alias.rb +42 -0
- data/lib/rhc/rest/api.rb +87 -0
- data/lib/rhc/rest/application.rb +348 -0
- data/lib/rhc/rest/attributes.rb +36 -0
- data/lib/rhc/rest/authorization.rb +8 -0
- data/lib/rhc/rest/base.rb +79 -0
- data/lib/rhc/rest/cartridge.rb +162 -0
- data/lib/rhc/rest/client.rb +650 -0
- data/lib/rhc/rest/deployment.rb +18 -0
- data/lib/rhc/rest/domain.rb +98 -0
- data/lib/rhc/rest/environment_variable.rb +15 -0
- data/lib/rhc/rest/gear_group.rb +16 -0
- data/lib/rhc/rest/httpclient.rb +145 -0
- data/lib/rhc/rest/key.rb +44 -0
- data/lib/rhc/rest/membership.rb +105 -0
- data/lib/rhc/rest/mock.rb +1042 -0
- data/lib/rhc/rest/user.rb +32 -0
- data/lib/rhc/rest.rb +148 -0
- data/lib/rhc/scp_helpers.rb +27 -0
- data/lib/rhc/ssh_helpers.rb +380 -0
- data/lib/rhc/tar_gz.rb +51 -0
- data/lib/rhc/usage_templates/command_help.erb +51 -0
- data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
- data/lib/rhc/usage_templates/help.erb +61 -0
- data/lib/rhc/usage_templates/missing_help.erb +1 -0
- data/lib/rhc/usage_templates/options_help.erb +12 -0
- data/lib/rhc/vendor/okjson.rb +600 -0
- data/lib/rhc/vendor/parseconfig.rb +178 -0
- data/lib/rhc/vendor/sshkey.rb +253 -0
- data/lib/rhc/vendor/zliby.rb +628 -0
- data/lib/rhc/version.rb +5 -0
- data/lib/rhc/wizard.rb +637 -0
- data/lib/rhc.rb +34 -0
- data/spec/coverage_helper.rb +82 -0
- data/spec/direct_execution_helper.rb +339 -0
- data/spec/keys/example.pem +23 -0
- data/spec/keys/example_private.pem +27 -0
- data/spec/keys/server.pem +19 -0
- data/spec/rest_spec_helper.rb +31 -0
- data/spec/rhc/assets/cert.crt +22 -0
- data/spec/rhc/assets/cert_key_rsa +27 -0
- data/spec/rhc/assets/empty.txt +0 -0
- data/spec/rhc/assets/env_vars.txt +7 -0
- data/spec/rhc/assets/env_vars_2.txt +1 -0
- data/spec/rhc/assets/foo.txt +1 -0
- data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
- data/spec/rhc/assets/targz_sample.tar.gz +0 -0
- data/spec/rhc/auth_spec.rb +442 -0
- data/spec/rhc/cli_spec.rb +186 -0
- data/spec/rhc/command_spec.rb +435 -0
- data/spec/rhc/commands/account_spec.rb +42 -0
- data/spec/rhc/commands/alias_spec.rb +333 -0
- data/spec/rhc/commands/app_spec.rb +777 -0
- data/spec/rhc/commands/apps_spec.rb +39 -0
- data/spec/rhc/commands/authorization_spec.rb +157 -0
- data/spec/rhc/commands/cartridge_spec.rb +665 -0
- data/spec/rhc/commands/clone_spec.rb +41 -0
- data/spec/rhc/commands/deployment_spec.rb +327 -0
- data/spec/rhc/commands/domain_spec.rb +401 -0
- data/spec/rhc/commands/env_spec.rb +493 -0
- data/spec/rhc/commands/git_clone_spec.rb +102 -0
- data/spec/rhc/commands/logout_spec.rb +86 -0
- data/spec/rhc/commands/member_spec.rb +247 -0
- data/spec/rhc/commands/port_forward_spec.rb +217 -0
- data/spec/rhc/commands/scp_spec.rb +77 -0
- data/spec/rhc/commands/server_spec.rb +69 -0
- data/spec/rhc/commands/setup_spec.rb +118 -0
- data/spec/rhc/commands/snapshot_spec.rb +179 -0
- data/spec/rhc/commands/ssh_spec.rb +163 -0
- data/spec/rhc/commands/sshkey_spec.rb +188 -0
- data/spec/rhc/commands/tail_spec.rb +81 -0
- data/spec/rhc/commands/threaddump_spec.rb +84 -0
- data/spec/rhc/config_spec.rb +407 -0
- data/spec/rhc/helpers_spec.rb +531 -0
- data/spec/rhc/highline_extensions_spec.rb +314 -0
- data/spec/rhc/json_spec.rb +30 -0
- data/spec/rhc/rest_application_spec.rb +258 -0
- data/spec/rhc/rest_client_spec.rb +752 -0
- data/spec/rhc/rest_spec.rb +740 -0
- data/spec/rhc/targz_spec.rb +55 -0
- data/spec/rhc/wizard_spec.rb +756 -0
- data/spec/spec_helper.rb +575 -0
- data/spec/wizard_spec_helper.rb +330 -0
- metadata +469 -0
data/bin/app
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'rhc/coverage_helper'
|
|
3
|
+
|
|
4
|
+
def get_args
|
|
5
|
+
ARGV.shift
|
|
6
|
+
args = ""
|
|
7
|
+
ARGV.each do|a|
|
|
8
|
+
if ( a.to_s.strip.length == 0 || a.to_s.strip.match(/\s/) ); a = "'#{a}'" end
|
|
9
|
+
args += " #{a}"
|
|
10
|
+
end
|
|
11
|
+
args
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
begin
|
|
15
|
+
Signal.trap("PIPE", "EXIT") if Signal.list["PIPE"]
|
|
16
|
+
|
|
17
|
+
retcode = begin
|
|
18
|
+
require 'rhc/cli'
|
|
19
|
+
RHC::CLI.set_terminal
|
|
20
|
+
RHC::CLI.start(ARGV)
|
|
21
|
+
rescue Interrupt
|
|
22
|
+
puts "Interrupted"
|
|
23
|
+
128 + 2
|
|
24
|
+
rescue SystemExit => e
|
|
25
|
+
puts
|
|
26
|
+
e.status
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if retcode == nil
|
|
30
|
+
retcode = 1
|
|
31
|
+
|
|
32
|
+
# return codes for uncaught signals are 128 + the signal code
|
|
33
|
+
retcode = 128 + $?.termsig if $?.signaled? and !$?.termsig.nil?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
exit retcode
|
|
37
|
+
end
|
data/conf/express.conf
ADDED
|
Binary file
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'direct_execution_helper'
|
|
3
|
+
|
|
4
|
+
describe "rhc core scenarios" do
|
|
5
|
+
|
|
6
|
+
it "reports a version" do
|
|
7
|
+
r = rhc '--version'
|
|
8
|
+
r.status.should == 0
|
|
9
|
+
r.stdout.should match /rhc \d+\.\d+\.\d+\b/
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "displays help" do
|
|
13
|
+
r = rhc 'help'
|
|
14
|
+
r.status.should == 0
|
|
15
|
+
r.stdout.should match "Command line interface for OpenShift"
|
|
16
|
+
r.stdout.should match "Usage: rhc"
|
|
17
|
+
r.stdout.should match "Getting started"
|
|
18
|
+
r.stdout.should match "See 'rhc help options' for a list"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "with a clean configuration" do
|
|
22
|
+
before{ use_clean_config }
|
|
23
|
+
|
|
24
|
+
it "walks through a configuration" do
|
|
25
|
+
r = rhc :setup, :with => setup_args
|
|
26
|
+
r.stdout.should match 'OpenShift Client Tools'
|
|
27
|
+
r.stdout.should match 'Checking for git ...'
|
|
28
|
+
r.stdout.should match 'Checking for applications ...'
|
|
29
|
+
r.stdout.should match 'Your client tools are now configured.'
|
|
30
|
+
r.status.should == 0
|
|
31
|
+
|
|
32
|
+
r = rhc :account
|
|
33
|
+
r.stdout.should match "on #{ENV['RHC_SERVER']}"
|
|
34
|
+
r.stdout.should match 'Gears Allowed'
|
|
35
|
+
r.stdout.should match 'Allowed Gear Sizes'
|
|
36
|
+
r.stdout.should match 'Gears Used'
|
|
37
|
+
r.stdout.should match 'SSL Certificates'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "displays help on default invocation" do
|
|
41
|
+
r = rhc
|
|
42
|
+
r.status.should == 0
|
|
43
|
+
r.stdout.should match "Command line interface for OpenShift"
|
|
44
|
+
r.stdout.should match "Usage: rhc"
|
|
45
|
+
r.stdout.should match "Getting started"
|
|
46
|
+
r.stdout.should match "See 'rhc help options' for a list"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "when creating an app" do
|
|
51
|
+
when_running 'create-app', 'test1', a_web_cartridge
|
|
52
|
+
before{ no_applications }
|
|
53
|
+
it "returns the proper info and is in the rest api" do
|
|
54
|
+
status.should == 0
|
|
55
|
+
output.should match "Your application 'test1' is now available"
|
|
56
|
+
output.should match /Gear Size: .*default/
|
|
57
|
+
output.should match /Scaling: .*no/
|
|
58
|
+
output.should match %r(URL: .*http://test1-)
|
|
59
|
+
output.should match "Cloned to"
|
|
60
|
+
|
|
61
|
+
apps = client.applications
|
|
62
|
+
apps.should_not be_empty
|
|
63
|
+
apps.should include{ |app| app.name == 'test1' }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context "with an existing app" do
|
|
68
|
+
before(:all) do
|
|
69
|
+
standard_config
|
|
70
|
+
@app = has_an_application
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
let(:app){ @app }
|
|
74
|
+
|
|
75
|
+
it "should display domain list" do
|
|
76
|
+
r = rhc 'domains'
|
|
77
|
+
r.status.should == 0
|
|
78
|
+
r.stdout.should match "Domain #{app.domain_id}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should show app state" do
|
|
82
|
+
r = rhc 'app-show', app.name, '--state'
|
|
83
|
+
r.status.should == 0
|
|
84
|
+
r.stdout.should match "Cartridge #{a_web_cartridge} is started"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should stop and start the app" do
|
|
88
|
+
r = rhc 'stop-app', app.name
|
|
89
|
+
r.status.should == 0
|
|
90
|
+
r.stdout.should match "#{app.name} stopped"
|
|
91
|
+
r = rhc 'start-app', app.name
|
|
92
|
+
r.status.should == 0
|
|
93
|
+
r.stdout.should match "#{app.name} started"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should show gear status" do
|
|
97
|
+
r = rhc 'app-show', app.name, '--gears'
|
|
98
|
+
r.status.should == 0
|
|
99
|
+
r.stdout.lines.to_a.length.should == 3
|
|
100
|
+
r.stdout.should match app.ssh_string
|
|
101
|
+
app.cartridges.map(&:name).each do |c|
|
|
102
|
+
r.stdout.should match c
|
|
103
|
+
end
|
|
104
|
+
r.stdout.should match "started"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should show gear ssh strings" do
|
|
108
|
+
r = rhc 'app-show', app.name, '--gears', 'ssh'
|
|
109
|
+
r.status.should == 0
|
|
110
|
+
r.stdout.lines.to_a.length.should == 1
|
|
111
|
+
r.stdout.chomp.should == app.ssh_string
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context "when the app is cloned" do
|
|
115
|
+
before(:all) do
|
|
116
|
+
rhc('git-clone', @app.name).status.should == 0
|
|
117
|
+
Dir.exists?(@app.name).should be_true
|
|
118
|
+
Dir.chdir @app.name
|
|
119
|
+
end
|
|
120
|
+
let(:git_config){ `git config --list` }
|
|
121
|
+
let(:git_remotes){ `git remote -v` }
|
|
122
|
+
|
|
123
|
+
it "will set Git config values" do
|
|
124
|
+
git_config.should match "rhc.app-id=#{app.id}"
|
|
125
|
+
git_config.should match "rhc.app-name=#{app.name}"
|
|
126
|
+
git_config.should match "rhc.domain-name=#{app.domain_name}"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "will set remote branches correctly" do
|
|
130
|
+
git_remotes.should match "origin"
|
|
131
|
+
git_remotes.should_not match "upstream"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "will infer the current app from the git repository" do
|
|
135
|
+
r = rhc 'show-app'
|
|
136
|
+
r.stdout.should match app.name
|
|
137
|
+
r.stdout.should match app.id
|
|
138
|
+
r.stdout.should match app.ssh_string
|
|
139
|
+
r.stdout.should match app.app_url
|
|
140
|
+
(app.cartridges.map(&:name) + app.cartridges.map(&:display_name)).each{ |n| r.stdout.should match n }
|
|
141
|
+
r.status.should == 0
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "will fetch the quotas from the app" do
|
|
145
|
+
r = rhc 'show-app', '--gears', 'quota'
|
|
146
|
+
r.stdout.chomp.lines.count.should == (app.gear_count + 2)
|
|
147
|
+
app.cartridges.map(&:name).each{ |n| r.stdout.should match n }
|
|
148
|
+
app.cartridges.map(&:gear_storage).each{ |n| r.stdout.should match(RHC::Helpers.human_size(n)) }
|
|
149
|
+
r.status.should == 0
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "will ssh to the app and run a command" do
|
|
153
|
+
r = rhc 'ssh', '--', '--ssh', ENV['GIT_SSH'], 'echo $OPENSHIFT_APP_NAME'
|
|
154
|
+
r.stdout.should match app.name
|
|
155
|
+
r.status.should == 0
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
context "when adding a cartridge" do
|
|
161
|
+
context "with a scalable app" do
|
|
162
|
+
before(:all) do
|
|
163
|
+
standard_config
|
|
164
|
+
@app = has_a_scalable_application
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
after(:all) do
|
|
168
|
+
debug.puts "cleaning up scalable app" if debug?
|
|
169
|
+
@app.destroy
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
let(:app){ @app }
|
|
173
|
+
|
|
174
|
+
it "should add a cartridge with small gear size" do
|
|
175
|
+
cartridge = a_random_cartridge(['embedded', 'service', 'database'])
|
|
176
|
+
r = rhc 'add-cartridge', cartridge, '-a', app.name, '--gear-size', 'small'
|
|
177
|
+
r.stdout.should match /#{cartridge}/
|
|
178
|
+
r.stdout.should match /Gears:\s+1 small/
|
|
179
|
+
r.status.should == 0
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should fail for a cartridge with not allowed gear size" do
|
|
183
|
+
cartridge = a_random_cartridge(['embedded', 'service', 'database'])
|
|
184
|
+
r = rhc 'add-cartridge', cartridge, '-a', app.name, '--gear-size', 'medium'
|
|
185
|
+
r.stdout.should match "The gear size 'medium' is not valid for this domain. Allowed sizes: small."
|
|
186
|
+
r.status.should_not == 0
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'direct_execution_helper'
|
|
3
|
+
require 'httpclient'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
DEPLOYMENT_LIST_ITEM = /([0-2]?[0-9]:[0-5][0-9] (AM|PM), deployment [a-f0-9]{8})/
|
|
7
|
+
|
|
8
|
+
describe "rhc deployment scenarios" do
|
|
9
|
+
context "with an existing app" do
|
|
10
|
+
before(:all) do
|
|
11
|
+
standard_config
|
|
12
|
+
@app = has_an_application
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
let(:app){ @app }
|
|
16
|
+
|
|
17
|
+
it "should display deployment list" do
|
|
18
|
+
r = list_deployments
|
|
19
|
+
r.stdout.should match DEPLOYMENT_LIST_ITEM
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should configure the app for a git ref deployment" do
|
|
23
|
+
r = configure_app_for_manual_git_deployment
|
|
24
|
+
r.stdout.should match /Deployment:\s+manual/
|
|
25
|
+
r.stdout.should match /Keep Deployments:\s+10/
|
|
26
|
+
r.stdout.should match /Deployment Type:\s+git/
|
|
27
|
+
r.stdout.should match /Deployment Branch:\s+master/
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should configure the app for a binary deployment" do
|
|
31
|
+
r = configure_app_for_manual_binary_deployment
|
|
32
|
+
r.stdout.should match /Deployment:\s+manual/
|
|
33
|
+
r.stdout.should match /Keep Deployments:\s+10/
|
|
34
|
+
r.stdout.should match /Deployment Type:\s+binary/
|
|
35
|
+
r.stdout.should match /Deployment Branch:\s+master/
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should deploy a git ref" do
|
|
39
|
+
configure_app_for_manual_git_deployment
|
|
40
|
+
r = deploy_master
|
|
41
|
+
r.stdout.should match /Deployment of git ref 'master' in progress for application #{app.name}/
|
|
42
|
+
r.stdout.should match /Success/
|
|
43
|
+
r = list_deployments
|
|
44
|
+
r.stdout.should match DEPLOYMENT_LIST_ITEM
|
|
45
|
+
r.stdout.scan(DEPLOYMENT_LIST_ITEM).length.should > 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should perform a complete deploy workflow" do
|
|
49
|
+
configure_app_for_manual_git_deployment
|
|
50
|
+
edit_simple_change 'Bienvenido a'
|
|
51
|
+
app_page_content.should match /Welcome to/
|
|
52
|
+
app_page_content.should_not match /Bienvenido a/
|
|
53
|
+
deploy_master
|
|
54
|
+
app_page_content.should match /Bienvenido a/
|
|
55
|
+
app_page_content.should_not match /Welcome to/
|
|
56
|
+
deployment_id = find_inactive_deployment
|
|
57
|
+
deployment_id.should_not be_nil
|
|
58
|
+
activate deployment_id
|
|
59
|
+
app_page_content.should match /Welcome to/
|
|
60
|
+
app_page_content.should_not match /Bienvenido a/
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
def configure_app_for_manual_git_deployment
|
|
65
|
+
ensure_command 'configure-app', app.name, '--no-auto-deploy', '--keep-deployments', 10, '--deployment-type', 'git'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def configure_app_for_manual_binary_deployment
|
|
69
|
+
ensure_command 'configure-app', app.name, '--no-auto-deploy', '--keep-deployments', 10, '--deployment-type', 'binary'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def list_deployments
|
|
73
|
+
ensure_command 'deployments', app.name
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def deploy(ref)
|
|
77
|
+
ensure_command 'deploy', ref, '-a', app.name
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def deploy_master
|
|
81
|
+
deploy 'master'
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def activate(deployment_id)
|
|
85
|
+
ensure_command 'activate-deployment', deployment_id, '-a', app.name
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def snapshot_deployment
|
|
89
|
+
ensure_command 'save-snapshot', app.name, '--deployment'
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def git_clone
|
|
93
|
+
ensure_command 'git-clone', app.name, '-r', git_directory
|
|
94
|
+
Dir.exists?(git_directory).should be_true
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def edit_simple_change(content)
|
|
98
|
+
FileUtils.rm_rf git_directory
|
|
99
|
+
git_clone
|
|
100
|
+
Dir.chdir git_directory
|
|
101
|
+
`git config user.email "you@example.com"`
|
|
102
|
+
`git config user.name "Your Name"`
|
|
103
|
+
`sed -i "s/Welcome/#{content}/" index.php`
|
|
104
|
+
`git commit -a -m "Commit from Feature Tests"`
|
|
105
|
+
`git push origin master`
|
|
106
|
+
Dir.chdir '../'
|
|
107
|
+
FileUtils.rm_rf git_directory
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def app_page_content
|
|
111
|
+
HTTPClient.new.get_content(app.app_url)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def git_directory
|
|
115
|
+
"#{app.name}_feature_tests_repo"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def find_inactive_deployment
|
|
119
|
+
r = list_deployments
|
|
120
|
+
r.stdout.match(/deployment ([a-f0-9]{8})/)[1]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def ensure_command(*args)
|
|
124
|
+
r = rhc *args
|
|
125
|
+
r.status.should == 0
|
|
126
|
+
r
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'direct_execution_helper'
|
|
3
|
+
|
|
4
|
+
describe "rhc domain scenarios" do
|
|
5
|
+
context "with an existing domain" do
|
|
6
|
+
before(:all) do
|
|
7
|
+
standard_config
|
|
8
|
+
@domain = has_a_domain
|
|
9
|
+
end
|
|
10
|
+
let(:domain){ @domain }
|
|
11
|
+
|
|
12
|
+
it "should display the domain configuration" do
|
|
13
|
+
r = rhc 'configure-domain', domain.name
|
|
14
|
+
r.status.should == 0
|
|
15
|
+
if domain.allowed_gear_sizes
|
|
16
|
+
r.stdout.should match "Allowed Gear Sizes:\s+#{domain.allowed_gear_sizes.join(", ")}"
|
|
17
|
+
else
|
|
18
|
+
r.stdout.should_not match "Allowed Gear Sizes:"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should change the domain configuration" do
|
|
23
|
+
r = rhc 'configure-domain', domain.name, '--no-allowed-gear-sizes'
|
|
24
|
+
r.status.should == 0
|
|
25
|
+
r.stdout.should match "Allowed Gear Sizes:\s+<none>$"
|
|
26
|
+
client.reset.find_domain(domain.name).allowed_gear_sizes.should == []
|
|
27
|
+
|
|
28
|
+
all_sizes = client.user.capabilities.gear_sizes
|
|
29
|
+
r = rhc 'configure-domain', domain.name, '--allowed-gear-sizes', all_sizes.join(',')
|
|
30
|
+
r.status.should == 0
|
|
31
|
+
r.stdout.should match "Allowed Gear Sizes:\s+#{all_sizes.join(', ')}$"
|
|
32
|
+
client.reset.find_domain(domain.name).allowed_gear_sizes.should == all_sizes
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should reject invalid gear size configuration changes" do
|
|
36
|
+
all_sizes = client.user.capabilities.gear_sizes
|
|
37
|
+
valid_sizes = client.api.links['ADD_DOMAIN']['optional_params'].inject([]) {|sizes, p| sizes += p['valid_options'] if p['name'] == 'allowed_gear_sizes' } rescue []
|
|
38
|
+
disallowed_sizes = valid_sizes - all_sizes
|
|
39
|
+
|
|
40
|
+
r = rhc 'configure-domain', domain.name, '--allowed-gear-sizes', '_not_a_size_'
|
|
41
|
+
r.status.should_not == 1
|
|
42
|
+
r.stdout.should match "Updating domain configuration.*The following gear sizes are invalid: _not_a_size_"
|
|
43
|
+
client.reset.find_domain(domain.name).allowed_gear_sizes.should == all_sizes
|
|
44
|
+
|
|
45
|
+
if disallowed_sizes.first
|
|
46
|
+
r = rhc 'configure-domain', domain.name, '--allowed-gear-sizes', disallowed_sizes.first
|
|
47
|
+
r.status.should_not == 1
|
|
48
|
+
r.stdout.should match "Updating domain configuration.*The following gear sizes are not available.*: #{disallowed_sizes.first}"
|
|
49
|
+
client.reset.find_domain(domain.name).allowed_gear_sizes.should == all_sizes
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
r = rhc 'configure-domain', domain.name, '--allowed-gear-sizes'
|
|
53
|
+
r.status.should_not == 1
|
|
54
|
+
r.stdout.should match "invalid option: Provide a comma delimited .* --allowed-gear-sizes"
|
|
55
|
+
client.reset.find_domain(domain.name).allowed_gear_sizes.should == all_sizes
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'direct_execution_helper'
|
|
3
|
+
|
|
4
|
+
describe "rhc sshkey scenarios" do
|
|
5
|
+
context "with an existing domain" do
|
|
6
|
+
before(:all) do
|
|
7
|
+
standard_config
|
|
8
|
+
@domain = has_a_domain
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:domain){ @domain }
|
|
12
|
+
|
|
13
|
+
context "with an application" do
|
|
14
|
+
before{ has_an_application }
|
|
15
|
+
|
|
16
|
+
it "should add and remove kerberos keys on gear" do
|
|
17
|
+
app = @domain.applications.first
|
|
18
|
+
keyname = "key#{rand(1000000000000)}"
|
|
19
|
+
keycontent = "principal#{rand(1000000000000)}"
|
|
20
|
+
|
|
21
|
+
r = rhc 'sshkey', 'add', keyname, '--type', 'krb5-principal', '--content', keycontent
|
|
22
|
+
r.status.should == 0
|
|
23
|
+
|
|
24
|
+
r = rhc 'ssh', app.name, '-n', domain.name, '--ssh', ssh_exec_for_env, '--', 'if [ -f .k5login ]; then cat .k5login; fi'
|
|
25
|
+
r.status.should == 0
|
|
26
|
+
r.stdout.should match(Regexp.new("#{keyname}\n#{keycontent}"))
|
|
27
|
+
|
|
28
|
+
r = rhc 'sshkey', 'remove', keyname
|
|
29
|
+
r.status.should == 0
|
|
30
|
+
|
|
31
|
+
r = rhc 'ssh', app.name, '-n', domain.name, '--ssh', ssh_exec_for_env, '--', 'if [ -f .k5login ]; then cat .k5login; fi'
|
|
32
|
+
r.status.should == 0
|
|
33
|
+
r.stdout.should_not match(Regexp.new("#{keyname}\n#{keycontent}"))
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'direct_execution_helper'
|
|
3
|
+
|
|
4
|
+
describe "rhc member scenarios" do
|
|
5
|
+
context "with an existing domain" do
|
|
6
|
+
before(:all) do
|
|
7
|
+
standard_config
|
|
8
|
+
@domain = has_a_domain
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:domain){ @domain }
|
|
12
|
+
|
|
13
|
+
context "with no users" do
|
|
14
|
+
before{ no_members(domain) }
|
|
15
|
+
|
|
16
|
+
it "should not show members in the domain" do
|
|
17
|
+
r = rhc 'show-domain', domain.name
|
|
18
|
+
r.status.should == 0
|
|
19
|
+
r.stdout.should_not match "Members:"
|
|
20
|
+
r.stdout.should match "owned by #{domain.owner}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should prevent leaving the domain for the owner" do
|
|
24
|
+
r = rhc 'leave-domain', domain.name
|
|
25
|
+
r.status.should_not == 1
|
|
26
|
+
r.stdout.should match "Leaving domain.*You are the owner of this domain and cannot leave"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should add and remove a member" do
|
|
30
|
+
user = other_users.keys.take(1).first
|
|
31
|
+
r = rhc 'add-member', user, '-n', domain.name
|
|
32
|
+
r.status.should == 0
|
|
33
|
+
r.stdout.should match "Adding 1 editor to domain"
|
|
34
|
+
r.stdout.should match "done"
|
|
35
|
+
client.find_domain(domain.name).members.any?{ |m| m.id == other_users[user].id && m.editor? }.should be_true
|
|
36
|
+
|
|
37
|
+
r = rhc 'show-domain', domain.name
|
|
38
|
+
r.status.should == 0
|
|
39
|
+
r.stdout.should match "Members:"
|
|
40
|
+
r.stdout.should match "#{user} \\(edit\\)"
|
|
41
|
+
|
|
42
|
+
r = rhc 'remove-member', user, '-n', domain.name
|
|
43
|
+
r.status.should == 0
|
|
44
|
+
r.stdout.should match "Removing 1 member from domain"
|
|
45
|
+
client.find_domain(domain.name).members.none?{ |m| m.id == other_users[user].id }.should be_true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should add and remove two members" do
|
|
49
|
+
user1, user2 = other_users.keys.take(2)
|
|
50
|
+
r = rhc 'add-member', user1, user2, '-n', domain.name
|
|
51
|
+
r.status.should == 0
|
|
52
|
+
r.stdout.should match "Adding 2 editors to domain"
|
|
53
|
+
r.stdout.should match "done"
|
|
54
|
+
members = client.find_domain(domain.name).members
|
|
55
|
+
members.any?{ |m| m.id == other_users[user1].id && m.editor? }.should be_true
|
|
56
|
+
members.any?{ |m| m.id == other_users[user2].id && m.editor? }.should be_true
|
|
57
|
+
|
|
58
|
+
r = rhc 'show-domain', domain.name
|
|
59
|
+
r.status.should == 0
|
|
60
|
+
r.stdout.should match "Members:"
|
|
61
|
+
r.stdout.should match "#{user1} \\(edit\\)"
|
|
62
|
+
r.stdout.should match "#{user2} \\(edit\\)"
|
|
63
|
+
|
|
64
|
+
r = rhc 'remove-member', user1, user2, '-n', domain.name
|
|
65
|
+
r.status.should == 0
|
|
66
|
+
r.stdout.should match "Removing 2 members from domain"
|
|
67
|
+
client.find_domain(domain.name).members.none?{ |m| m.id == other_users[user1].id }.should be_true
|
|
68
|
+
client.find_domain(domain.name).members.none?{ |m| m.id == other_users[user2].id }.should be_true
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should add a view and an admin member. and allow users to leave the domain" do
|
|
72
|
+
user1, user2 = other_users.keys.take(2)
|
|
73
|
+
|
|
74
|
+
r = rhc 'add-member', user1, '--role', 'admin', '-n', domain.name
|
|
75
|
+
r.status.should == 0
|
|
76
|
+
r.stdout.should match "Adding 1 administrator to domain"
|
|
77
|
+
r.stdout.should match "done"
|
|
78
|
+
client.find_domain(domain.name).members.any?{ |m| m.id == other_users[user1].id && m.admin? }.should be_true
|
|
79
|
+
|
|
80
|
+
r = rhc 'add-member', user2, '--role', 'view', '-n', domain.name
|
|
81
|
+
r.status.should == 0
|
|
82
|
+
r.stdout.should match "Adding 1 viewer to domain"
|
|
83
|
+
r.stdout.should match "done"
|
|
84
|
+
client.find_domain(domain.name).members.any?{ |m| m.id == other_users[user2].id && m.viewer? }.should be_true
|
|
85
|
+
|
|
86
|
+
r = rhc 'show-domain', domain.name
|
|
87
|
+
r.status.should == 0
|
|
88
|
+
r.stdout.should match "Members:"
|
|
89
|
+
r.stdout.should match "#{user1} \\(admin\\)"
|
|
90
|
+
r.stdout.should match "#{user2} \\(view\\)"
|
|
91
|
+
|
|
92
|
+
r = rhc 'leave-domain', domain.name, :as => other_users[user2]
|
|
93
|
+
r.status.should == 0
|
|
94
|
+
r.stdout.should match "Leaving domain.*done"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should remove all non owners" do
|
|
98
|
+
user1, user2 = other_users.keys.take(2)
|
|
99
|
+
r = rhc 'add-member', user1, user2, '-n', domain.name
|
|
100
|
+
r.status.should == 0
|
|
101
|
+
r.stdout.should match "Adding 2 editors to domain"
|
|
102
|
+
r.stdout.should match "done"
|
|
103
|
+
members = client.find_domain(domain.name).members
|
|
104
|
+
members.any?{ |m| m.id == other_users[user1].id && m.editor? }.should be_true
|
|
105
|
+
members.any?{ |m| m.id == other_users[user2].id && m.editor? }.should be_true
|
|
106
|
+
|
|
107
|
+
r = rhc 'remove-member', domain.name, '--all'
|
|
108
|
+
r.status.should == 0
|
|
109
|
+
r.stdout.should match "Removing all members from domain.*done"
|
|
110
|
+
members = client.find_domain(domain.name).members
|
|
111
|
+
members.select(&:owner).should == members
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should reject a non-existent user" do
|
|
115
|
+
r = rhc 'add-member', 'not-a-user', '-n', domain.name
|
|
116
|
+
r.status.to_i.should == 256
|
|
117
|
+
r.stdout.should match "There is no account with login not-a-user."
|
|
118
|
+
client.find_domain(domain.name).members.length.should == 1
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "should add a user by id" do
|
|
122
|
+
user = other_users.values.take(1).first
|
|
123
|
+
r = rhc 'add-member', user.id, '--ids', '-n', domain.name
|
|
124
|
+
r.status.should == 0
|
|
125
|
+
r.stdout.should match "Adding 1 editor to domain"
|
|
126
|
+
r.stdout.should match "done"
|
|
127
|
+
client.find_domain(domain.name).members.any?{ |m| m.id == user.id && m.editor? }.should be_true
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "with an application" do
|
|
132
|
+
let(:other_user){ other_users.values.first }
|
|
133
|
+
before{ has_an_application }
|
|
134
|
+
before{ has_local_ssh_key(other_user) }
|
|
135
|
+
|
|
136
|
+
it "should allow SSH only for admin and edit roles" do
|
|
137
|
+
user = other_user.login
|
|
138
|
+
name = @domain.applications.first.name
|
|
139
|
+
|
|
140
|
+
r = rhc 'add-member', user, '--role', 'admin', '-n', domain.name
|
|
141
|
+
r.status.should == 0
|
|
142
|
+
|
|
143
|
+
with_environment(other_user) do
|
|
144
|
+
r = rhc 'ssh', name, '-n', domain.name, '--ssh', ssh_exec_for_env
|
|
145
|
+
r.status.should == 0
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
r = rhc 'add-member', user, '--role', 'view', '-n', domain.name
|
|
149
|
+
r.status.should == 0
|
|
150
|
+
|
|
151
|
+
with_environment(other_user) do
|
|
152
|
+
r = rhc 'ssh', name, '-n', domain.name, '--ssh', ssh_exec_for_env
|
|
153
|
+
r.status.to_i.should_not == 0
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
r = rhc 'add-member', user, '--role', 'edit', '-n', domain.name
|
|
157
|
+
r.status.should == 0
|
|
158
|
+
|
|
159
|
+
with_environment(other_user) do
|
|
160
|
+
r = rhc 'ssh', name, '-n', domain.name, '--ssh', ssh_exec_for_env
|
|
161
|
+
r.status.should == 0
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|