rhc 0.96.9 → 0.97.17

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 (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