rhc 1.19.5 → 1.20.3
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.
- data/README.md +2 -2
- data/features/keys_feature.rb +1 -1
- data/lib/rhc/commands/cartridge.rb +6 -3
- data/lib/rhc/commands/scp.rb +54 -0
- data/lib/rhc/exceptions.rb +18 -0
- data/lib/rhc/rest/cartridge.rb +9 -1
- data/lib/rhc/rest/key.rb +1 -1
- data/lib/rhc/rest/membership.rb +2 -2
- data/lib/rhc/rest/mock.rb +2 -0
- data/lib/rhc/scp_helpers.rb +27 -0
- data/lib/rhc/ssh_helpers.rb +3 -1
- data/spec/rhc/commands/domain_spec.rb +1 -1
- data/spec/rhc/commands/member_spec.rb +23 -4
- data/spec/rhc/commands/scp_spec.rb +77 -0
- data/spec/rhc/commands/sshkey_spec.rb +9 -9
- data/spec/rhc/helpers_spec.rb +2 -0
- data/spec/rhc/highline_extensions_spec.rb +1 -1
- metadata +51 -31
data/README.md
CHANGED
|
@@ -7,8 +7,8 @@ info on installing the tool on each supported operating system.
|
|
|
7
7
|
|
|
8
8
|
Please stop by #openshift on irc.freenode.net if you have any questions or
|
|
9
9
|
comments. For more information about OpenShift, visit https://openshift.redhat.com
|
|
10
|
-
or the OpenShift
|
|
11
|
-
https://openshift.redhat.com/
|
|
10
|
+
or the OpenShift support page
|
|
11
|
+
https://openshift.redhat.com/support.
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
## Using RHC to create an application
|
data/features/keys_feature.rb
CHANGED
|
@@ -17,7 +17,7 @@ describe "rhc sshkey scenarios" do
|
|
|
17
17
|
app = @domain.applications.first
|
|
18
18
|
keyname = "key#{rand(1000000000000)}"
|
|
19
19
|
keycontent = "principal#{rand(1000000000000)}"
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
r = rhc 'sshkey', 'add', keyname, '--type', 'krb5-principal', '--content', keycontent
|
|
22
22
|
r.status.should == 0
|
|
23
23
|
|
|
@@ -52,18 +52,21 @@ module RHC::Commands
|
|
|
52
52
|
say c.description
|
|
53
53
|
paragraph{ say "Tagged with: #{tags.sort.join(', ')}" } if tags.present?
|
|
54
54
|
paragraph{ say format_usage_message(c) } if c.usage_rate?
|
|
55
|
+
paragraph{ warn "Does not receive automatic security updates" } unless c.automatic_updates?
|
|
55
56
|
end
|
|
56
57
|
end
|
|
57
58
|
else
|
|
58
59
|
say table(carts.collect do |c|
|
|
59
|
-
[c.usage_rate? ? "
|
|
60
|
+
[[c.name, c.usage_rate? ? " (*)" : "", c.automatic_updates? ? '' : ' (!)'].join(''),
|
|
60
61
|
c.display_name,
|
|
61
|
-
c.only_in_existing? ? 'addon' : 'web'
|
|
62
|
+
c.only_in_existing? ? 'addon' : 'web',
|
|
63
|
+
]
|
|
62
64
|
end)
|
|
63
65
|
end
|
|
64
66
|
|
|
65
67
|
paragraph{ say "Note: Web cartridges can only be added to new applications." }
|
|
66
|
-
paragraph{ say "(*) denotes a cartridge with additional usage costs." } if carts.any?
|
|
68
|
+
paragraph{ say "(*) denotes a cartridge with additional usage costs." } if carts.any?(&:usage_rate?)
|
|
69
|
+
paragraph{ say "(!) denotes a cartridge that will not receive automatic security updates." } unless options.verbose || carts.none?(&:automatic_updates?)
|
|
67
70
|
|
|
68
71
|
0
|
|
69
72
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'rhc/commands/base'
|
|
2
|
+
require 'rhc/scp_helpers'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
module RHC::Commands
|
|
6
|
+
class Scp < Base
|
|
7
|
+
suppress_wizard
|
|
8
|
+
|
|
9
|
+
summary "SCP a file to or from your application"
|
|
10
|
+
description <<-DESC
|
|
11
|
+
Transfer files to and from your applications using SCP. This will transfer
|
|
12
|
+
files to and from your primary gear (the one with the Git repository and web
|
|
13
|
+
cartridge) by default.
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
Uploading a file from your workding directory to your app-root/data directory
|
|
17
|
+
rhc scp myapp upload somefile.txt app-root/data
|
|
18
|
+
|
|
19
|
+
Downloading a file from your app-root/data directory to your working directory
|
|
20
|
+
rhc scp myapp download ./ app-root/data/somebigarchive.tar.gz
|
|
21
|
+
DESC
|
|
22
|
+
syntax "[<app> --] <action> <local_path> <remote_path>"
|
|
23
|
+
takes_application :argument => true
|
|
24
|
+
argument :action, "Transfer direction: upload|download", ["-t", "--transfer_direction upload|download"], :optional => false
|
|
25
|
+
argument :local_path, "Local filesystem path", ["-l", "--local_path file_path"], :optional => false
|
|
26
|
+
argument :remote_path, "Remote filesystem path", ["-r", "--remote_path file_path"], :optional => false
|
|
27
|
+
alias_action 'app scp', :root_command => true
|
|
28
|
+
def run(_, action, local_path, remote_path)
|
|
29
|
+
rest_app = find_app
|
|
30
|
+
ssh_opts = rest_app.ssh_url.gsub("ssh://","").split("@")
|
|
31
|
+
|
|
32
|
+
raise RHC::ArgumentNotValid.new("'#{action}' is not a valid argument for this command. Please use upload or download.") unless action == 'download' || action == 'upload'
|
|
33
|
+
raise RHC::FileOrPathNotFound.new("Local file, file_path, or directory could not be found.") unless File.exist?(local_path)
|
|
34
|
+
|
|
35
|
+
begin
|
|
36
|
+
start_time = Time.now
|
|
37
|
+
Net::SCP.send("#{action}!".to_sym, ssh_opts[1], ssh_opts[0], (action == 'upload' ? local_path : remote_path), (action == 'upload' ? remote_path : local_path)) do |ch, name, sent, total|
|
|
38
|
+
#:nocov:
|
|
39
|
+
$stderr.print "\r #{action}ing #{name}: #{((sent.to_f/total.to_f)*100).to_i}% complete. #{sent}/#{total} bytes transferred " + (sent == total ? "in #{Time.now - start_time} seconds \n" : "")
|
|
40
|
+
#:nocov:
|
|
41
|
+
end
|
|
42
|
+
rescue Errno::ECONNREFUSED
|
|
43
|
+
raise RHC::SSHConnectionRefused.new(ssh_opts[0], ssh_opts[1])
|
|
44
|
+
rescue SocketError => e
|
|
45
|
+
raise RHC::ConnectionFailed, "The connection to #{ssh_opts[1]} failed: #{e.message}"
|
|
46
|
+
rescue Net::SCP::Error => e
|
|
47
|
+
raise RHC::RemoteFileOrPathNotFound.new("Remote file, file_path, or directory could not be found.")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
protected
|
|
52
|
+
include RHC::SCPHelpers
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/rhc/exceptions.rb
CHANGED
|
@@ -230,6 +230,24 @@ module RHC
|
|
|
230
230
|
end
|
|
231
231
|
end
|
|
232
232
|
|
|
233
|
+
class FileOrPathNotFound < Exception
|
|
234
|
+
def initialize(message="File, file path, or directory could not be found")
|
|
235
|
+
super message
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
class RemoteFileOrPathNotFound < FileOrPathNotFound
|
|
240
|
+
def initialize(message="Remote File, file path, or directory could not be found")
|
|
241
|
+
super message
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
class ArgumentNotValid < Exception
|
|
246
|
+
def initialize(message="Argument is not valid for this command")
|
|
247
|
+
super message
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
233
251
|
class NoDomainsForUser < Exception
|
|
234
252
|
def initialize(message="In order to deploy applications, you must create a domain with 'rhc setup' or 'rhc create-domain'.")
|
|
235
253
|
super message, 1
|
data/lib/rhc/rest/cartridge.rb
CHANGED
|
@@ -5,7 +5,7 @@ module RHC
|
|
|
5
5
|
|
|
6
6
|
define_attr :type, :name, :display_name, :properties, :gear_profile, :status_messages, :scales_to, :scales_from, :scales_with,
|
|
7
7
|
:current_scale, :supported_scales_to, :supported_scales_from, :tags, :description, :collocated_with, :base_gear_storage,
|
|
8
|
-
:additional_gear_storage, :url, :environment_variables, :gear_size
|
|
8
|
+
:additional_gear_storage, :url, :environment_variables, :gear_size, :automatic_updates
|
|
9
9
|
|
|
10
10
|
def scalable?
|
|
11
11
|
supported_scales_to != supported_scales_from
|
|
@@ -23,6 +23,14 @@ module RHC
|
|
|
23
23
|
type == 'embedded'
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def automatic_updates?
|
|
27
|
+
v = attribute(:automatic_updates)
|
|
28
|
+
if v.nil?
|
|
29
|
+
v = !(tags.include?('no_updates') || custom?)
|
|
30
|
+
end
|
|
31
|
+
v
|
|
32
|
+
end
|
|
33
|
+
|
|
26
34
|
def shares_gears?
|
|
27
35
|
Array(collocated_with).present?
|
|
28
36
|
end
|
data/lib/rhc/rest/key.rb
CHANGED
|
@@ -30,7 +30,7 @@ module RHC
|
|
|
30
30
|
@fingerprint ||= begin
|
|
31
31
|
public_key = Net::SSH::KeyFactory.load_data_public_key("#{type} #{content}")
|
|
32
32
|
public_key.fingerprint
|
|
33
|
-
rescue NotImplementedError, OpenSSL::PKey::PKeyError
|
|
33
|
+
rescue NotImplementedError, Net::SSH::Exception, OpenSSL::PKey::PKeyError
|
|
34
34
|
'Invalid key'
|
|
35
35
|
end if is_ssh?
|
|
36
36
|
end
|
data/lib/rhc/rest/membership.rb
CHANGED
|
@@ -61,7 +61,7 @@ module RHC::Rest
|
|
|
61
61
|
def compact_members
|
|
62
62
|
arr = members.reject(&:owner?) rescue []
|
|
63
63
|
if arr.length > 5
|
|
64
|
-
arr.sort_by
|
|
64
|
+
arr = arr.sort_by(&:name)
|
|
65
65
|
admin, arr = arr.partition(&:admin?)
|
|
66
66
|
edit, arr = arr.partition(&:editor?)
|
|
67
67
|
view, arr = arr.partition(&:viewer?)
|
|
@@ -97,7 +97,7 @@ module RHC::Rest
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def owner
|
|
100
|
-
if o = Array(
|
|
100
|
+
if o = Array(attributes['members']).find{ |m| m['owner'] == true }
|
|
101
101
|
o['name'] || o['login']
|
|
102
102
|
end
|
|
103
103
|
end
|
data/lib/rhc/rest/mock.rb
CHANGED
|
@@ -697,6 +697,7 @@ module RHC::Rest::Mock
|
|
|
697
697
|
|
|
698
698
|
def add_member(member)
|
|
699
699
|
(@members ||= []) << member
|
|
700
|
+
(attributes['members'] ||= []) << member.attributes
|
|
700
701
|
self
|
|
701
702
|
end
|
|
702
703
|
end
|
|
@@ -902,6 +903,7 @@ module RHC::Rest::Mock
|
|
|
902
903
|
|
|
903
904
|
def add_member(member)
|
|
904
905
|
(@members ||= []) << member
|
|
906
|
+
(attributes['members'] ||= []) << member.attributes
|
|
905
907
|
self
|
|
906
908
|
end
|
|
907
909
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
###
|
|
2
|
+
# ssh_key_helpers.rb - methods to help manipulate ssh keys
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2012 Red Hat, Inc. and/or its affiliates.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
|
|
18
|
+
require 'net/ssh'
|
|
19
|
+
require 'net/scp'
|
|
20
|
+
require 'rhc/ssh_helpers'
|
|
21
|
+
require 'rhc/vendor/sshkey'
|
|
22
|
+
|
|
23
|
+
module RHC
|
|
24
|
+
module SCPHelpers
|
|
25
|
+
include SSHHelpers
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/rhc/ssh_helpers.rb
CHANGED
|
@@ -169,7 +169,9 @@ module RHC
|
|
|
169
169
|
def ssh_ruby(host, username, command, compression=false, request_pty=false, &block)
|
|
170
170
|
debug "Opening Net::SSH connection to #{host}, #{username}, #{command}"
|
|
171
171
|
exit_status = 0
|
|
172
|
-
|
|
172
|
+
options = {:compression => compression}
|
|
173
|
+
options[:verbose] = :debug if debug?
|
|
174
|
+
Net::SSH.start(host, username, options) do |session|
|
|
173
175
|
#:nocov:
|
|
174
176
|
channel = session.open_channel do |channel|
|
|
175
177
|
if request_pty
|
|
@@ -37,8 +37,27 @@ describe RHC::Commands::Member do
|
|
|
37
37
|
|
|
38
38
|
let(:owner){ RHC::Rest::Membership::Member.new(:id => '1', :role => 'admin', :owner => true, :login => 'alice') }
|
|
39
39
|
let(:other_admin){ RHC::Rest::Membership::Member.new(:id => '2', :role => 'admin', :login => 'Bob') }
|
|
40
|
-
let(:other_editor){ RHC::Rest::Membership::Member.new(:id => '3', :role => '
|
|
41
|
-
let(:other_viewer){ RHC::Rest::Membership::Member.new(:id => '4', :role => '
|
|
40
|
+
let(:other_editor){ RHC::Rest::Membership::Member.new(:id => '3', :role => 'edit', :name => 'Carol', :login => 'carol') }
|
|
41
|
+
let(:other_viewer){ RHC::Rest::Membership::Member.new(:id => '4', :role => 'view', :name => 'Doug', :login => 'doug@doug.com') }
|
|
42
|
+
let(:other_viewer2){ RHC::Rest::Membership::Member.new(:id => '5', :role => 'view', :name => 'ViewerC', :login => 'viewerc@viewer.com') }
|
|
43
|
+
let(:other_viewer3){ RHC::Rest::Membership::Member.new(:id => '6', :role => 'view', :name => 'ViewerB', :login => 'viewerb@viewer.com') }
|
|
44
|
+
let(:other_viewer4){ RHC::Rest::Membership::Member.new(:id => '7', :role => 'view', :name => 'ViewerA', :login => 'viewera@viewer.com') }
|
|
45
|
+
|
|
46
|
+
describe 'show-domain' do
|
|
47
|
+
context 'with members' do
|
|
48
|
+
let(:arguments) { ['domain', 'show', 'mock-domain-0'] }
|
|
49
|
+
let(:supports_members){ true }
|
|
50
|
+
|
|
51
|
+
before{ with_mock_domain.add_member(owner).add_member(other_editor).add_member(other_admin).add_member(other_viewer).add_member(other_viewer2).add_member(other_viewer3).add_member(other_viewer4) }
|
|
52
|
+
it { expect { run }.to exit_with_code(0) }
|
|
53
|
+
it { run_output.should =~ /owned by alice/ }
|
|
54
|
+
it { run_output.should =~ /Bob\s+\(admin\)/ }
|
|
55
|
+
it { run_output.should =~ /<carol>\s+\(edit\)/ }
|
|
56
|
+
it { run_output.should =~ /<doug@doug\.com>\s+\(view\)/ }
|
|
57
|
+
it("should order the members by role then by name") { run_output.should =~ /Bob.*admin.*Admins.*Carol.*Editors.*ViewerA.*ViewerB.*ViewerC.*Viewers/m }
|
|
58
|
+
it("should include the login value") { run_output.should =~ /alice.*Bob.*carol.*doug@doug\.com/m }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
42
61
|
|
|
43
62
|
describe 'list-member' do
|
|
44
63
|
context 'on a domain' do
|
|
@@ -79,8 +98,8 @@ describe RHC::Commands::Member do
|
|
|
79
98
|
it { expect { run }.to exit_with_code(0) }
|
|
80
99
|
it { run_output.should =~ /alice\s+admin \(owner\)/ }
|
|
81
100
|
it { run_output.should =~ /Bob\s+admin/ }
|
|
82
|
-
it { run_output.should =~ /carol\s+
|
|
83
|
-
it { run_output.should =~ /doug\.com\s+
|
|
101
|
+
it { run_output.should =~ /carol\s+edit/ }
|
|
102
|
+
it { run_output.should =~ /doug\.com\s+view/ }
|
|
84
103
|
it("should order the members by role") { run_output.should =~ /admin.*owner.*admin.*edit.*view/m }
|
|
85
104
|
it("should include the login value") { run_output.should =~ /alice.*Bob.*carol.*doug@doug\.com/m }
|
|
86
105
|
it("should show the name column") { run_output.should =~ /^Name\s+Login\s+Role$/ }
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/commands/scp'
|
|
4
|
+
|
|
5
|
+
describe RHC::Commands::Scp do
|
|
6
|
+
let!(:rest_client){ MockRestClient.new }
|
|
7
|
+
let!(:config){ user_config }
|
|
8
|
+
before{ RHC::Config.stub(:home_dir).and_return('/home/mock_user') }
|
|
9
|
+
before{ Kernel.stub(:exec).and_raise(RuntimeError) }
|
|
10
|
+
|
|
11
|
+
describe 'scp default' do
|
|
12
|
+
context 'scp' do
|
|
13
|
+
let(:arguments) { ['scp'] }
|
|
14
|
+
it { run_output.should match('Usage:') }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe 'scp with invalid option' do
|
|
19
|
+
let (:arguments) {['app', 'scp', 'app1', 'invalid_command', 'file.txt', 'app-root/data']}
|
|
20
|
+
|
|
21
|
+
context 'when run' do
|
|
22
|
+
before(:each) do
|
|
23
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
24
|
+
@domain.add_application("app1", "mock_type")
|
|
25
|
+
end
|
|
26
|
+
it { run_output.should match("'invalid_command' is not a valid argument for this command. Please use upload or download.") }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'local file or path does not exist' do
|
|
31
|
+
let (:arguments) {['app', 'scp', 'app1', 'upload', 'file.txt', 'app-root/data']}
|
|
32
|
+
|
|
33
|
+
context 'when run' do
|
|
34
|
+
before(:each) do
|
|
35
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
36
|
+
@domain.add_application("app1", "mock_type")
|
|
37
|
+
File.should_receive(:exist?).with("file.txt").once.and_return(false)
|
|
38
|
+
end
|
|
39
|
+
it { run_output.should match("Local file, file_path, or directory could not be found.") }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe 'scp connections' do
|
|
44
|
+
let (:arguments) {['app', 'scp', 'app1', 'upload', 'file.txt', 'app-root/data']}
|
|
45
|
+
|
|
46
|
+
context 'connection refused' do
|
|
47
|
+
before(:each) do
|
|
48
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
49
|
+
@domain.add_application("app1", "mock_type")
|
|
50
|
+
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
|
51
|
+
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(Errno::ECONNREFUSED)
|
|
52
|
+
end
|
|
53
|
+
it { run_output.should match("The server fakeuuidfortestsapp1 refused a connection with user 127.0.0.1. The application may be unavailable.") }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context 'socket error' do
|
|
57
|
+
before(:each) do
|
|
58
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
59
|
+
@domain.add_application("app1", "mock_type")
|
|
60
|
+
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
|
61
|
+
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(SocketError)
|
|
62
|
+
end
|
|
63
|
+
it { run_output.should match("The connection to 127.0.0.1 failed: SocketError") }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context 'remote file not found' do
|
|
67
|
+
before(:each) do
|
|
68
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
69
|
+
@domain.add_application("app1", "mock_type")
|
|
70
|
+
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
|
71
|
+
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(Net::SCP::Error)
|
|
72
|
+
end
|
|
73
|
+
it { run_output.should match("Remote file, file_path, or directory could not be found.") }
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
@@ -14,13 +14,13 @@ describe RHC::Commands::Sshkey do
|
|
|
14
14
|
let(:arguments) { %w[sshkey list --noprompt --config test.conf -l test@test.foo -p password --trace] }
|
|
15
15
|
|
|
16
16
|
it { expect { run }.to exit_with_code(0) }
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
it { run_output.should match(/mockkey1 \(type: ssh-rsa\)/) }
|
|
19
19
|
it { run_output.should match(/Fingerprint:.*0f:ce:86:80:df:a0:81:ca:db:f1:a7:0c:70:85:ce:00/) }
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
it { run_output.should match(/mockkey3 \(type: krb5-principal\)/) }
|
|
22
22
|
it { run_output.should match(/Principal:.* mockuser@mockdomain/) }
|
|
23
|
-
it { run_output.
|
|
23
|
+
# it { run_output.should match(/Fingerprint:.*Invalid key/) }
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -127,25 +127,25 @@ describe RHC::Commands::Sshkey do
|
|
|
127
127
|
|
|
128
128
|
context "when adding a nonexistent key" do
|
|
129
129
|
let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
it "exits with status code Errno::ENOENT::Errno" do
|
|
132
132
|
expect { run }.to exit_with_code(128)
|
|
133
133
|
end
|
|
134
134
|
end
|
|
135
|
-
|
|
135
|
+
|
|
136
136
|
context "when attempting to add an existing but inaccessible key" do
|
|
137
137
|
let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar inaccessible_key.pub] }
|
|
138
|
-
|
|
138
|
+
|
|
139
139
|
#before :all do
|
|
140
140
|
# @inaccessible_key = 'inaccessible_key.pub'
|
|
141
141
|
# File.new(@inaccessible_key, 'w+')
|
|
142
142
|
# File.chmod(0000, @inaccessible_key)
|
|
143
143
|
#end
|
|
144
|
-
|
|
144
|
+
|
|
145
145
|
#after :all do
|
|
146
146
|
# File.delete @inaccessible_key
|
|
147
147
|
#end
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
it "exits with status code Errno::EACCES::Errno" do
|
|
150
150
|
IO.should_receive(:read).and_raise(Errno::EACCES)
|
|
151
151
|
expect { run }.to exit_with_code(128)
|
|
@@ -155,7 +155,7 @@ describe RHC::Commands::Sshkey do
|
|
|
155
155
|
|
|
156
156
|
context "when adding a key without correct arguments" do
|
|
157
157
|
let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar] }
|
|
158
|
-
|
|
158
|
+
|
|
159
159
|
it "exits with argument error" do
|
|
160
160
|
expect { run }.to exit_with_code(1)
|
|
161
161
|
end
|
data/spec/rhc/helpers_spec.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'rhc'
|
|
3
3
|
require 'rhc/ssh_helpers'
|
|
4
|
+
require 'rhc/scp_helpers'
|
|
4
5
|
require 'rhc/cartridge_helpers'
|
|
5
6
|
require 'rhc/git_helpers'
|
|
6
7
|
require 'rhc/core_ext'
|
|
@@ -13,6 +14,7 @@ require 'ostruct'
|
|
|
13
14
|
class AllRhcHelpers
|
|
14
15
|
include RHC::Helpers
|
|
15
16
|
include RHC::SSHHelpers
|
|
17
|
+
include RHC::SCPHelpers
|
|
16
18
|
include RHC::CartridgeHelpers
|
|
17
19
|
|
|
18
20
|
def config
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rhc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 65
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 1
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
version: 1.
|
|
8
|
+
- 20
|
|
9
|
+
- 3
|
|
10
|
+
version: 1.20.3
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Red Hat
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2014-
|
|
18
|
+
date: 2014-02-24 00:00:00 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
name: net-ssh
|
|
@@ -34,9 +34,25 @@ dependencies:
|
|
|
34
34
|
type: :runtime
|
|
35
35
|
version_requirements: *id001
|
|
36
36
|
- !ruby/object:Gem::Dependency
|
|
37
|
-
name: net-
|
|
37
|
+
name: net-scp
|
|
38
38
|
prerelease: false
|
|
39
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
|
40
|
+
none: false
|
|
41
|
+
requirements:
|
|
42
|
+
- - ">="
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
hash: 23
|
|
45
|
+
segments:
|
|
46
|
+
- 1
|
|
47
|
+
- 1
|
|
48
|
+
- 2
|
|
49
|
+
version: 1.1.2
|
|
50
|
+
type: :runtime
|
|
51
|
+
version_requirements: *id002
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: net-ssh-multi
|
|
54
|
+
prerelease: false
|
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
40
56
|
none: false
|
|
41
57
|
requirements:
|
|
42
58
|
- - ">="
|
|
@@ -48,11 +64,11 @@ dependencies:
|
|
|
48
64
|
- 0
|
|
49
65
|
version: 1.2.0
|
|
50
66
|
type: :runtime
|
|
51
|
-
version_requirements: *
|
|
67
|
+
version_requirements: *id003
|
|
52
68
|
- !ruby/object:Gem::Dependency
|
|
53
69
|
name: archive-tar-minitar
|
|
54
70
|
prerelease: false
|
|
55
|
-
requirement: &
|
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
56
72
|
none: false
|
|
57
73
|
requirements:
|
|
58
74
|
- - ">="
|
|
@@ -62,11 +78,11 @@ dependencies:
|
|
|
62
78
|
- 0
|
|
63
79
|
version: "0"
|
|
64
80
|
type: :runtime
|
|
65
|
-
version_requirements: *
|
|
81
|
+
version_requirements: *id004
|
|
66
82
|
- !ruby/object:Gem::Dependency
|
|
67
83
|
name: commander
|
|
68
84
|
prerelease: false
|
|
69
|
-
requirement: &
|
|
85
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
|
70
86
|
none: false
|
|
71
87
|
requirements:
|
|
72
88
|
- - ">="
|
|
@@ -77,11 +93,11 @@ dependencies:
|
|
|
77
93
|
- 0
|
|
78
94
|
version: "4.0"
|
|
79
95
|
type: :runtime
|
|
80
|
-
version_requirements: *
|
|
96
|
+
version_requirements: *id005
|
|
81
97
|
- !ruby/object:Gem::Dependency
|
|
82
98
|
name: highline
|
|
83
99
|
prerelease: false
|
|
84
|
-
requirement: &
|
|
100
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
|
85
101
|
none: false
|
|
86
102
|
requirements:
|
|
87
103
|
- - ~>
|
|
@@ -93,11 +109,11 @@ dependencies:
|
|
|
93
109
|
- 11
|
|
94
110
|
version: 1.6.11
|
|
95
111
|
type: :runtime
|
|
96
|
-
version_requirements: *
|
|
112
|
+
version_requirements: *id006
|
|
97
113
|
- !ruby/object:Gem::Dependency
|
|
98
114
|
name: httpclient
|
|
99
115
|
prerelease: false
|
|
100
|
-
requirement: &
|
|
116
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
|
101
117
|
none: false
|
|
102
118
|
requirements:
|
|
103
119
|
- - ">="
|
|
@@ -108,11 +124,11 @@ dependencies:
|
|
|
108
124
|
- 2
|
|
109
125
|
version: "2.2"
|
|
110
126
|
type: :runtime
|
|
111
|
-
version_requirements: *
|
|
127
|
+
version_requirements: *id007
|
|
112
128
|
- !ruby/object:Gem::Dependency
|
|
113
129
|
name: open4
|
|
114
130
|
prerelease: false
|
|
115
|
-
requirement: &
|
|
131
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
|
116
132
|
none: false
|
|
117
133
|
requirements:
|
|
118
134
|
- - ">="
|
|
@@ -122,11 +138,11 @@ dependencies:
|
|
|
122
138
|
- 0
|
|
123
139
|
version: "0"
|
|
124
140
|
type: :runtime
|
|
125
|
-
version_requirements: *
|
|
141
|
+
version_requirements: *id008
|
|
126
142
|
- !ruby/object:Gem::Dependency
|
|
127
143
|
name: rake
|
|
128
144
|
prerelease: false
|
|
129
|
-
requirement: &
|
|
145
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
|
130
146
|
none: false
|
|
131
147
|
requirements:
|
|
132
148
|
- - ">="
|
|
@@ -138,11 +154,11 @@ dependencies:
|
|
|
138
154
|
- 7
|
|
139
155
|
version: 0.8.7
|
|
140
156
|
type: :development
|
|
141
|
-
version_requirements: *
|
|
157
|
+
version_requirements: *id009
|
|
142
158
|
- !ruby/object:Gem::Dependency
|
|
143
159
|
name: webmock
|
|
144
160
|
prerelease: false
|
|
145
|
-
requirement: &
|
|
161
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
|
146
162
|
none: false
|
|
147
163
|
requirements:
|
|
148
164
|
- - <
|
|
@@ -153,11 +169,11 @@ dependencies:
|
|
|
153
169
|
- 12
|
|
154
170
|
version: "1.12"
|
|
155
171
|
type: :development
|
|
156
|
-
version_requirements: *
|
|
172
|
+
version_requirements: *id010
|
|
157
173
|
- !ruby/object:Gem::Dependency
|
|
158
174
|
name: rspec
|
|
159
175
|
prerelease: false
|
|
160
|
-
requirement: &
|
|
176
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
|
161
177
|
none: false
|
|
162
178
|
requirements:
|
|
163
179
|
- - ">="
|
|
@@ -169,11 +185,11 @@ dependencies:
|
|
|
169
185
|
- 0
|
|
170
186
|
version: 2.8.0
|
|
171
187
|
type: :development
|
|
172
|
-
version_requirements: *
|
|
188
|
+
version_requirements: *id011
|
|
173
189
|
- !ruby/object:Gem::Dependency
|
|
174
190
|
name: fakefs
|
|
175
191
|
prerelease: false
|
|
176
|
-
requirement: &
|
|
192
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
|
177
193
|
none: false
|
|
178
194
|
requirements:
|
|
179
195
|
- - ">="
|
|
@@ -184,11 +200,11 @@ dependencies:
|
|
|
184
200
|
- 4
|
|
185
201
|
version: "0.4"
|
|
186
202
|
type: :development
|
|
187
|
-
version_requirements: *
|
|
203
|
+
version_requirements: *id012
|
|
188
204
|
- !ruby/object:Gem::Dependency
|
|
189
205
|
name: thor
|
|
190
206
|
prerelease: false
|
|
191
|
-
requirement: &
|
|
207
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
|
192
208
|
none: false
|
|
193
209
|
requirements:
|
|
194
210
|
- - ">="
|
|
@@ -198,11 +214,11 @@ dependencies:
|
|
|
198
214
|
- 0
|
|
199
215
|
version: "0"
|
|
200
216
|
type: :development
|
|
201
|
-
version_requirements: *
|
|
217
|
+
version_requirements: *id013
|
|
202
218
|
- !ruby/object:Gem::Dependency
|
|
203
219
|
name: cucumber
|
|
204
220
|
prerelease: false
|
|
205
|
-
requirement: &
|
|
221
|
+
requirement: &id014 !ruby/object:Gem::Requirement
|
|
206
222
|
none: false
|
|
207
223
|
requirements:
|
|
208
224
|
- - ">="
|
|
@@ -212,11 +228,11 @@ dependencies:
|
|
|
212
228
|
- 0
|
|
213
229
|
version: "0"
|
|
214
230
|
type: :development
|
|
215
|
-
version_requirements: *
|
|
231
|
+
version_requirements: *id014
|
|
216
232
|
- !ruby/object:Gem::Dependency
|
|
217
233
|
name: activesupport
|
|
218
234
|
prerelease: false
|
|
219
|
-
requirement: &
|
|
235
|
+
requirement: &id015 !ruby/object:Gem::Requirement
|
|
220
236
|
none: false
|
|
221
237
|
requirements:
|
|
222
238
|
- - ~>
|
|
@@ -227,7 +243,7 @@ dependencies:
|
|
|
227
243
|
- 0
|
|
228
244
|
version: "3.0"
|
|
229
245
|
type: :development
|
|
230
|
-
version_requirements: *
|
|
246
|
+
version_requirements: *id015
|
|
231
247
|
description: The client tools for the OpenShift platform that allow for application management.
|
|
232
248
|
email: dev@lists.openshift.redhat.com
|
|
233
249
|
executables:
|
|
@@ -243,6 +259,7 @@ files:
|
|
|
243
259
|
- lib/rhc/core_ext.rb
|
|
244
260
|
- lib/rhc/json.rb
|
|
245
261
|
- lib/rhc/wizard.rb
|
|
262
|
+
- lib/rhc/scp_helpers.rb
|
|
246
263
|
- lib/rhc/rest.rb
|
|
247
264
|
- lib/rhc/autocomplete.rb
|
|
248
265
|
- lib/rhc/git_helpers.rb
|
|
@@ -258,6 +275,7 @@ files:
|
|
|
258
275
|
- lib/rhc/commands/setup.rb
|
|
259
276
|
- lib/rhc/commands/deployment.rb
|
|
260
277
|
- lib/rhc/commands/tail.rb
|
|
278
|
+
- lib/rhc/commands/scp.rb
|
|
261
279
|
- lib/rhc/commands/server.rb
|
|
262
280
|
- lib/rhc/commands/ssh.rb
|
|
263
281
|
- lib/rhc/commands/apps.rb
|
|
@@ -344,6 +362,7 @@ files:
|
|
|
344
362
|
- spec/rhc/commands/tail_spec.rb
|
|
345
363
|
- spec/rhc/commands/setup_spec.rb
|
|
346
364
|
- spec/rhc/commands/alias_spec.rb
|
|
365
|
+
- spec/rhc/commands/scp_spec.rb
|
|
347
366
|
- spec/rhc/commands/env_spec.rb
|
|
348
367
|
- spec/rhc/commands/port_forward_spec.rb
|
|
349
368
|
- spec/rhc/commands/git_clone_spec.rb
|
|
@@ -438,6 +457,7 @@ test_files:
|
|
|
438
457
|
- spec/rhc/commands/tail_spec.rb
|
|
439
458
|
- spec/rhc/commands/setup_spec.rb
|
|
440
459
|
- spec/rhc/commands/alias_spec.rb
|
|
460
|
+
- spec/rhc/commands/scp_spec.rb
|
|
441
461
|
- spec/rhc/commands/env_spec.rb
|
|
442
462
|
- spec/rhc/commands/port_forward_spec.rb
|
|
443
463
|
- spec/rhc/commands/git_clone_spec.rb
|