rhc 0.96.9 → 0.97.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/README.md +1 -0
  2. data/bin/rhc +6 -18
  3. data/bin/rhc-app +3 -3
  4. data/bin/rhc-chk +2 -2
  5. data/bin/rhc-create-app +2 -2
  6. data/bin/rhc-create-domain +5 -2
  7. data/bin/rhc-ctl-app +2 -2
  8. data/bin/rhc-ctl-domain +5 -2
  9. data/bin/rhc-domain +6 -3
  10. data/bin/rhc-domain-info +6 -3
  11. data/bin/rhc-port-forward +9 -2
  12. data/bin/rhc-snapshot +2 -2
  13. data/bin/rhc-sshkey +2 -2
  14. data/bin/rhc-tail-files +2 -2
  15. data/features/lib/rhc_helper/app.rb +1 -1
  16. data/features/lib/rhc_helper/commandify.rb +32 -3
  17. data/features/lib/rhc_helper/domain.rb +46 -20
  18. data/features/step_definitions/cartridge_steps.rb +3 -3
  19. data/features/step_definitions/client_steps.rb +3 -1
  20. data/features/step_definitions/domain_steps.rb +45 -0
  21. data/features/verify.feature +36 -0
  22. data/lib/rhc-common.rb +6 -8
  23. data/lib/rhc-rest.rb +11 -2
  24. data/lib/rhc-rest/application.rb +20 -8
  25. data/lib/rhc-rest/cartridge.rb +18 -6
  26. data/lib/rhc-rest/client.rb +13 -37
  27. data/lib/rhc-rest/domain.rb +12 -4
  28. data/lib/rhc-rest/exceptions/exceptions.rb +1 -1
  29. data/lib/rhc-rest/key.rb +2 -2
  30. data/lib/rhc-rest/user.rb +2 -2
  31. data/lib/rhc/cli.rb +2 -3
  32. data/lib/rhc/commands.rb +154 -4
  33. data/lib/rhc/commands/base.rb +49 -12
  34. data/lib/rhc/commands/domain.rb +142 -0
  35. data/lib/rhc/commands/server.rb +1 -0
  36. data/lib/rhc/commands/setup.rb +3 -10
  37. data/lib/rhc/config.rb +20 -18
  38. data/lib/rhc/exceptions.rb +20 -0
  39. data/lib/rhc/help_formatter.rb +3 -22
  40. data/lib/rhc/helpers.rb +36 -5
  41. data/lib/rhc/json.rb +44 -44
  42. data/lib/rhc/targz.rb +3 -3
  43. data/lib/rhc/usage_templates/command_help.erb +26 -0
  44. data/lib/rhc/usage_templates/help.erb +27 -0
  45. data/lib/rhc/vendor/zliby.rb +563 -563
  46. data/lib/rhc/version.rb +2 -2
  47. data/lib/rhc/wizard.rb +10 -5
  48. data/spec/coverage_helper.rb +0 -1
  49. data/spec/rest_spec_helper.rb +95 -0
  50. data/spec/rhc/cli_spec.rb +7 -2
  51. data/spec/rhc/command_spec.rb +59 -13
  52. data/spec/rhc/commands/domain_spec.rb +225 -0
  53. data/spec/rhc/config_spec.rb +4 -4
  54. data/spec/rhc/helpers_spec.rb +27 -1
  55. data/spec/rhc/rest_application_spec.rb +6 -0
  56. data/spec/rhc/rest_client_spec.rb +32 -32
  57. data/spec/rhc/rest_spec.rb +2 -2
  58. data/spec/rhc/wizard_spec.rb +11 -4
  59. data/spec/spec_helper.rb +9 -9
  60. metadata +314 -312
data/lib/rhc/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module RHC
2
2
  module VERSION #:nocov:
3
3
  MAJOR = 0
4
- MINOR = 96
5
- MICRO = 9
4
+ MINOR = 97
5
+ MICRO = 17
6
6
  #PRE = ''
7
7
  STRING = [MAJOR,MINOR,MICRO].compact.join('.')
8
8
  end
data/lib/rhc/wizard.rb CHANGED
@@ -24,10 +24,11 @@ module RHC
24
24
  STAGES
25
25
  end
26
26
 
27
- def initialize(config_path)
28
- @config_path = config_path
27
+ def initialize(config)
28
+ @config = config
29
+ @config_path = config.config_path
29
30
  if @libra_server.nil?
30
- @libra_server = get_var('libra_server')
31
+ @libra_server = config['libra_server']
31
32
  # if not set, set to default
32
33
  @libra_server = @libra_server ? @libra_server : "openshift.redhat.com"
33
34
  end
@@ -51,6 +52,10 @@ module RHC
51
52
  true
52
53
  end
53
54
 
55
+ def needs_configuration?
56
+ not (@config.has_local_config? or @config.has_opts_config? or @config.noprompt?)
57
+ end
58
+
54
59
  private
55
60
 
56
61
  def greeting_stage
@@ -540,7 +545,7 @@ EOF
540
545
  end
541
546
 
542
547
  class RerunWizard < Wizard
543
- def initialize(config_path)
548
+ def initialize(config)
544
549
  super
545
550
  end
546
551
 
@@ -595,7 +600,7 @@ EOF
595
600
  def initialize(username, password)
596
601
  @username = username
597
602
  @password = password
598
- super("")
603
+ super RHC::Config
599
604
  end
600
605
  end
601
606
  end
@@ -35,7 +35,6 @@ unless RUBY_VERSION < '1.9'
35
35
  add_filter 'features/' # Don't report on the files that run the cucumber tests
36
36
  add_filter 'lib/rhc-feature-coverage-helper.rb'
37
37
  add_filter 'spec/' # Don't report on the files that run the spec tests
38
- add_filter 'lib/rhc/help_formatter.rb'
39
38
 
40
39
  # Groups - general categories of test areas
41
40
  add_group('Commands') { |src_file| src_file.filename.include?(File.join(%w[lib rhc commands])) }
@@ -1,4 +1,6 @@
1
1
  require 'webmock/rspec'
2
+ require 'rhc-rest'
3
+ require 'rhc/exceptions'
2
4
 
3
5
  Spec::Matchers.define :have_same_attributes_as do |expected|
4
6
  match do |actual|
@@ -110,4 +112,97 @@ module RestSpecHelper
110
112
  :status => 200
111
113
  }
112
114
  end
115
+
116
+ class MockRestClient < Rhc::Rest::Client
117
+ def initialize
118
+ Rhc::Rest::Client.stub(:new) { self }
119
+ @domains = []
120
+ end
121
+
122
+ def domains
123
+ @domains
124
+ end
125
+
126
+ def add_domain(id)
127
+ d = MockRestDomain.new(id, self)
128
+ @domains << d
129
+ d
130
+ end
131
+ end
132
+
133
+ class MockRestDomain
134
+ attr_reader :id
135
+
136
+ def initialize(id, client)
137
+ @id = id
138
+ @client = client
139
+ @applications = []
140
+ end
141
+
142
+ def update(id)
143
+ @id = id
144
+ self
145
+ end
146
+
147
+ def destroy
148
+ @client.domains.delete_if do |d|
149
+ match = (d.id == @id)
150
+ raise Rhc::Rest::ClientErrorException.new("Mock error. Trying to delete domain with apps.", 128) if match and not applications.empty?
151
+ match
152
+ end
153
+
154
+ @client = nil
155
+ @applications = nil
156
+ end
157
+
158
+ def add_application(name, type)
159
+ a = MockRestApplication.new(name, type, self)
160
+ @applications << a
161
+ a
162
+ end
163
+
164
+ def applications
165
+ @applications
166
+ end
167
+ end
168
+
169
+ class MockRestApplication
170
+ attr_reader :name, :uuid, :creation_time, :git_url, :app_url, :aliases
171
+
172
+ def initialize(name, type, domain)
173
+ @name = name
174
+ @domain = domain
175
+ @cartridges = []
176
+ @creation_time = "now"
177
+ @uuid = "fakeuuidfortests"
178
+ @git_url = "git:fake.foo/git/#{@name}.git"
179
+ @app_url = "https://#{@name}-#{@domain.id}.fake.foo/"
180
+ @aliases = []
181
+ add_cartridge(type, false)
182
+ end
183
+
184
+ def add_cartridge(name, embedded=true)
185
+ type = embedded ? "embedded" : "framework"
186
+ c = MockRestCartridge.new(name, type, self)
187
+ @cartridges << c
188
+ c
189
+ end
190
+
191
+ def cartridges
192
+ @cartridges
193
+ end
194
+ end
195
+
196
+ class MockRestCartridge < Rhc::Rest::Cartridge
197
+ attr_reader :name
198
+ attr_reader :type
199
+ attr_reader :properties
200
+
201
+ def initialize(name, type, app, properties={:cart_data => {:connection_url => {'value' => "http://fake.url" }}})
202
+ @name = name
203
+ @type = type
204
+ @app = app
205
+ @properties = properties
206
+ end
207
+ end
113
208
  end
data/spec/rhc/cli_spec.rb CHANGED
@@ -5,7 +5,7 @@ describe RHC::CLI do
5
5
  shared_examples_for 'a help page' do
6
6
  let(:arguments) { @arguments or raise "no arguments" }
7
7
  it('should contain the program description') { run_output.should =~ /Command line interface for OpenShift/ }
8
- it('should contain the global options') { run_output.should =~ /Global Options:/ }
8
+ it('should contain the global options') { run_output.should =~ /Global Options/ }
9
9
  it('should provide a --config switch') { run_output.should =~ /\-\-config FILE/ }
10
10
  end
11
11
 
@@ -16,11 +16,16 @@ describe RHC::CLI do
16
16
  it('should provide a message about --help') { run_output.should =~ /\-\-help/ }
17
17
  end
18
18
 
19
+ context 'with help and invalid command' do
20
+ let(:arguments) { ['invalidcommand', 'help'] }
21
+ it { expect { run }.should exit_with_code(1) }
22
+ end
23
+
19
24
  context 'with --help' do
20
25
  before(:each){ @arguments = ['--help'] }
21
26
  it_should_behave_like 'a help page'
22
27
  end
23
-
28
+
24
29
  context 'with -h' do
25
30
  before(:each){ @arguments = ['-h'] }
26
31
  it_should_behave_like 'a help page'
@@ -2,13 +2,12 @@ require 'spec_helper'
2
2
  require 'rhc/commands/base'
3
3
 
4
4
  describe RHC::Commands::Base do
5
-
6
5
  describe '#object_name' do
7
6
  subject { described_class }
8
7
  its(:object_name) { should == 'base' }
9
8
 
10
9
  context 'when the class is at the root' do
11
- subject do
10
+ subject do
12
11
  Kernel.module_eval do
13
12
  class StaticRootClass < RHC::Commands::Base; def run; 1; end; end
14
13
  end
@@ -34,16 +33,32 @@ describe RHC::Commands::Base do
34
33
 
35
34
  context 'when dynamically instantiating without an object name' do
36
35
  subject { const_for(Class.new(RHC::Commands::Base) { def run; 1; end }) }
37
-
36
+
38
37
  it("should raise") { expect { subject }.to raise_exception( RHC::Commands::Base::InvalidCommand, /object_name/i ) }
39
38
  end
40
39
 
41
40
  context 'when dynamically instantiating with object_name' do
42
41
  subject { const_for(Class.new(RHC::Commands::Base) { object_name :test; def run(args, options); 1; end }) }
43
-
42
+
44
43
  it("should register itself") { expect { subject }.to change(commands, :length).by(1) }
45
44
  it("should have an object name") { subject.object_name.should == 'test' }
46
- it { expects_running('test').should call(:run).on(instance).with(no_args) }
45
+ it("should run with wizard") do
46
+ FakeFS.activate!
47
+
48
+ wizard_run = false
49
+ RHC::Wizard.stub!(:new) do |config|
50
+ RHC::Wizard.unstub!(:new)
51
+ w = RHC::Wizard.new(config)
52
+ w.stub!(:run) { wizard_run = true }
53
+ w
54
+ end
55
+
56
+ expects_running('test').should call(:run).on(instance).with(no_args)
57
+ wizard_run.should be_true
58
+
59
+ FakeFS::FileSystem.clear
60
+ FakeFS.deactivate!
61
+ end
47
62
  end
48
63
 
49
64
  context 'when statically defined' do
@@ -51,37 +66,68 @@ describe RHC::Commands::Base do
51
66
  Kernel.module_eval do
52
67
  module Nested
53
68
  class Static < RHC::Commands::Base
69
+ suppress_wizard
54
70
  def run(args, options); 1; end
55
71
  end
56
72
  end
57
73
  end
58
74
  Nested::Static
59
75
  end
60
-
76
+
61
77
  it("should register itself") { expect { subject }.to change(commands, :length).by(1) }
62
78
  it("should have an object name of the class") { subject.object_name.should == 'static' }
63
79
  it("invokes the right method") { expects_running('static').should call(:run).on(instance).with(no_args) }
64
80
  end
65
81
 
66
82
  context 'when statically defined with no default method' do
67
- subject do
68
- Kernel.module_eval do
83
+ subject do
84
+ Kernel.module_eval do
69
85
  class Static < RHC::Commands::Base
86
+ suppress_wizard
87
+
70
88
  def test; 1; end
89
+
90
+ argument :testarg, "Test arg", "--testarg testarg"
91
+ summary "Test command execute"
71
92
  def execute; 1; end
93
+ def raise_exception
94
+ raise Exception.new("test exception")
95
+ end
72
96
  end
73
97
  end
74
98
  Static
75
99
  end
76
-
77
- it("should register itself") { expect { subject }.to change(commands, :length).by(2) }
100
+
101
+ it("should register itself") { expect { subject }.to change(commands, :length).by(3) }
78
102
  it("should have an object name of the class") { subject.object_name.should == 'static' }
79
-
103
+
80
104
  context 'and when test is called' do
81
105
  it { expects_running('static', 'test').should call(:test).on(instance).with(no_args) }
82
106
  end
83
- context 'and when test is called' do
84
- it { expects_running('static', 'execute').should call(:execute).on(instance).with(no_args) }
107
+ context 'and when execute is called with argument' do
108
+ it { expects_running('static', 'execute', 'simplearg').should call(:execute).on(instance).with('simplearg') }
109
+ end
110
+ context 'and when execute is called with argument switch' do
111
+ it { expects_running('static', 'execute', '--testarg', 'switcharg').should call(:execute).on(instance).with('switcharg') }
112
+ end
113
+ context 'and when execute is called with same argument and switch' do
114
+ it { expects_running('statis', 'execute', 'duparg', '--testarg', 'duparg2').should exit_with_code(1) }
115
+ end
116
+
117
+ context 'and when execute is called with too many arguments' do
118
+ it { expects_running('static', 'execute', 'arg1', 'arg2').should exit_with_code(1) }
119
+ end
120
+
121
+ context 'and when execute is called with a missing argument' do
122
+ it { expects_running('static', 'execute').should exit_with_code(1) }
123
+ end
124
+
125
+ context 'and when an exception is raised in a call' do
126
+ it { expects_running('static', 'raise_exception').should exit_with_code(128) }
127
+ end
128
+
129
+ context 'and when an exception is raised in a call with --trace option' do
130
+ it { expects_running('static', 'raise_exception', "--trace").should raise_error(Exception, "test exception") }
85
131
  end
86
132
  end
87
133
  end
@@ -0,0 +1,225 @@
1
+ require 'spec_helper'
2
+ require 'rest_spec_helper'
3
+ require 'rhc/commands/domain'
4
+ require 'rhc/config'
5
+
6
+ describe RHC::Commands::Domain do
7
+ before(:each) do
8
+ RHC::Config.set_defaults
9
+ end
10
+
11
+ describe 'run' do
12
+ let(:arguments) { ['domain', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
13
+
14
+ context 'when run with no domains' do
15
+ before(:each) do
16
+ @rc = MockRestClient.new
17
+ end
18
+ it { expect { run }.should exit_with_code(0) }
19
+ it { run_output.should match("Namespace: No namespaces found") }
20
+ end
21
+
22
+ context 'when run with one domain no apps' do
23
+ before(:each) do
24
+ @rc = MockRestClient.new
25
+ @rc.add_domain("onedomain")
26
+ end
27
+ it { expect { run }.should exit_with_code(0) }
28
+ it "should match output" do
29
+ output = run_output
30
+ output.should match("Namespace onedomain's Applications")
31
+ output.should match("No applications found")
32
+ end
33
+ end
34
+
35
+ context 'when run with multiple domain no apps' do
36
+ before(:each) do
37
+ @rc = MockRestClient.new
38
+ @rc.add_domain("firstdomain")
39
+ @rc.add_domain("seconddomain")
40
+ end
41
+ it { expect { run }.should exit_with_code(0) }
42
+ it "should match output" do
43
+ output = run_output
44
+ output.should match("Namespace\\(0\\): firstdomain")
45
+ output.should match("Namespace\\(1\\): seconddomain")
46
+ output.should match("Namespace firstdomain's Applications")
47
+ output.should match("Namespace seconddomain's Applications")
48
+ end
49
+ end
50
+
51
+ context 'when run with one domain multiple apps' do
52
+ before(:each) do
53
+ @rc = MockRestClient.new
54
+ d = @rc.add_domain("appdomain")
55
+ a = d.add_application("app_no_carts", "testframework-1.0")
56
+ a = d.add_application("app_multi_carts", "testframework-1.0")
57
+ a.add_cartridge("testcart-1")
58
+ a.add_cartridge("testcart-2")
59
+ a.add_cartridge("testcart-3")
60
+ end
61
+ it { expect { run }.should exit_with_code(0) }
62
+ it "should match output" do
63
+ output = run_output
64
+ output.should match("app_no_carts")
65
+ output.should match("None")
66
+ output.should match("app_multi_carts")
67
+ output.should match("testframework-1.0")
68
+ output.should match("testcart-1")
69
+ output.should match("testcart-2")
70
+ output.should match("testcart-3")
71
+ end
72
+ end
73
+ end
74
+
75
+ describe 'create' do
76
+ let(:arguments) { ['domain', 'create', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'testnamespace'] }
77
+
78
+ context 'when no issues with ' do
79
+ before(:each) do
80
+ @rc = MockRestClient.new
81
+ end
82
+
83
+ it "should create a domain" do
84
+ expect { run }.should exit_with_code(0)
85
+ @rc.domains[0].id.should == 'testnamespace'
86
+ end
87
+ it { run_output.should match(/'testnamespace'\n\nRESULT:\n.*Success/m) }
88
+ end
89
+ end
90
+
91
+ describe 'update' do
92
+ let(:arguments) { ['domain', 'update', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'alterednamespace'] }
93
+
94
+ context 'when no issues with ' do
95
+ before(:each) do
96
+ @rc = MockRestClient.new
97
+ @rc.add_domain("olddomain")
98
+ end
99
+
100
+ it "should update a domain" do
101
+ expect { run }.should exit_with_code(0)
102
+ @rc.domains[0].id.should == 'alterednamespace'
103
+ end
104
+ it { run_output.should match(/Updating domain 'olddomain' to namespace 'alterednamespace'\n\nRESULT:\n.*Success/m) }
105
+ end
106
+
107
+ context 'when there is no domain' do
108
+ before(:each) do
109
+ @rc = MockRestClient.new
110
+ end
111
+
112
+ it "should not create a domain" do
113
+ expect { run }.should exit_with_code(127)
114
+ @rc.domains.empty?.should be_true
115
+ end
116
+ it { run_output.should match("No domains are registered to the user test@test.foo") }
117
+ end
118
+ end
119
+
120
+ describe 'alter alias' do
121
+ let(:arguments) { ['domain', 'alter', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'alterednamespace'] }
122
+
123
+ context 'when no issues with ' do
124
+ before(:each) do
125
+ @rc = MockRestClient.new
126
+ @rc.add_domain("olddomain")
127
+ end
128
+
129
+ it "should update a domain" do
130
+ expect { run }.should exit_with_code(0)
131
+ @rc.domains[0].id.should == 'alterednamespace'
132
+ end
133
+ it { run_output.should match(/Updating domain 'olddomain' to namespace 'alterednamespace'\n\nRESULT:\n.*Success/m) }
134
+ end
135
+ end
136
+
137
+ describe 'delete' do
138
+ let(:arguments) { ['domain', 'delete', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'deleteme'] }
139
+
140
+ context 'when no issues with ' do
141
+ before(:each) do
142
+ @rc = MockRestClient.new
143
+ @rc.add_domain("deleteme")
144
+ end
145
+
146
+ it "should delete a domain" do
147
+ expect { run }.should exit_with_code(0)
148
+ @rc.domains.empty?.should be_true
149
+ end
150
+ end
151
+
152
+ context 'when there is a different domain' do
153
+ before(:each) do
154
+ @rc = MockRestClient.new
155
+ @rc.add_domain("dontdelete")
156
+ end
157
+
158
+ it "should error out" do
159
+ expect { run }.should exit_with_code(127)
160
+ @rc.domains[0].id.should == 'dontdelete'
161
+ end
162
+ it { run_output.should match("Domain deleteme does not exist") }
163
+ end
164
+ end
165
+
166
+ describe 'alias destroy' do
167
+ let(:arguments) { ['domain', 'destroy', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'deleteme'] }
168
+
169
+ context 'when no issues with ' do
170
+ before(:each) do
171
+ @rc = MockRestClient.new
172
+ @rc.add_domain("deleteme")
173
+ end
174
+
175
+ it "should delete a domain" do
176
+ expect { run }.should exit_with_code(0)
177
+ @rc.domains.empty?.should be_true
178
+ end
179
+ end
180
+
181
+ context 'when domain contains app' do
182
+ before(:each) do
183
+ @rc = MockRestClient.new
184
+ d = @rc.add_domain("deleteme")
185
+ d.add_application("app1", "testframework-1.0")
186
+ end
187
+
188
+ it "should fail to delete domain" do
189
+ expect { run }.should exit_with_code(128)
190
+ @rc.domains.empty?.should be_false
191
+ end
192
+ end
193
+ end
194
+
195
+ describe 'status' do
196
+ let(:arguments) { ['domain', 'status', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
197
+
198
+ before(:each) do
199
+ Kernel.stub!(:system) do |cmd|
200
+ @cmd = cmd
201
+ # run the true command to get $?.exitstatus == 0
202
+ system("true")
203
+ end
204
+ end
205
+
206
+ context 'rhc-chk should be executed' do
207
+ it "runs" do
208
+ expect { run }.should exit_with_code(0)
209
+ # check lengths here because different versions of ruby output the switches in different order
210
+ @cmd.length.should == "rhc-chk --noprompt true --config test.conf --rhlogin test@test.foo --password password 2>&1".length
211
+ end
212
+ end
213
+ end
214
+
215
+ describe 'help' do
216
+ let(:arguments) { ['domain', 'help'] }
217
+
218
+ context 'help is run' do
219
+ it "should display help" do
220
+ expect { run }.should exit_with_code(0)
221
+ end
222
+ it('should output usage') { run_output.should match("Usage: rhc domain") }
223
+ end
224
+ end
225
+ end