bcome 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/documentation/usage.md +21 -21
- data/lib/bcome.rb +4 -1
- data/lib/bcome/version.rb +1 -1
- data/lib/become_object.rb +9 -0
- data/lib/boot.rb +8 -0
- data/lib/helpers/command_helper.rb +2 -2
- data/lib/helpers/environment_ssh.rb +12 -2
- data/lib/helpers/instance_command.rb +21 -6
- data/lib/helpers/selections.rb +7 -8
- data/lib/object.rb +17 -3
- data/lib/patches/string.rb +4 -0
- data/lib/scp.rb +17 -6
- data/lib/stack/environment.rb +7 -2
- data/lib/stack/instance.rb +17 -4
- data/lib/workspace_context.rb +7 -4
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8b43a40c66431c8282e710e49721519ae9cdd22
|
4
|
+
data.tar.gz: 6aab609acf080f4686b1ebceb016cd7162877579
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1583a06db19ab8874ce7b3b985e3366ff74dcfffe4a7162db5c502d3582ee1b1a5328dc9f061caf863ca38d74e913d38114c9f73804616c4cef8cce10321fc4
|
7
|
+
data.tar.gz: 8d671a6476db8a8ed65da10b25a0201da57d4c66ab270b75f5bb6a921d7351bdb1a2e27f2ffe317f2c7bd07f0fe96a9a7ce6d71e7b40ce554149c6a6baa2d95d
|
data/documentation/usage.md
CHANGED
@@ -16,7 +16,7 @@ or, if with bundler
|
|
16
16
|
> bundle exec bcome
|
17
17
|
```
|
18
18
|
|
19
|
-
### Entering the shell and jumping to a quick link
|
19
|
+
### Entering the shell and jumping to a quick link context
|
20
20
|
|
21
21
|
```
|
22
22
|
> cd /your/installed/bcome/application/directory
|
@@ -119,17 +119,21 @@ e.g. remove 'identifier', OR remove ['array', 'of','identifiers']
|
|
119
119
|
> selections
|
120
120
|
- Show all added resources.
|
121
121
|
|
122
|
-
>
|
123
|
-
-
|
124
|
-
e.g.
|
122
|
+
> put
|
123
|
+
- Uploads files to all selected resources. Uses Rsync, and so copies recursively
|
124
|
+
e.g. put 'localpath', 'remotepath'
|
125
|
+
|
126
|
+
> get
|
127
|
+
- Downloads files from all remote resources down to local. Does so using Rsync, and so is recursive.
|
128
|
+
- A 'downloads' directory will be created in your project directory, within which downloaded files are stored.
|
129
|
+
e.g. get 'remotepath'
|
125
130
|
|
126
131
|
> run
|
127
132
|
- Execute a command on all selected resources
|
128
133
|
e.g. run 'command'
|
129
134
|
|
130
|
-
>
|
131
|
-
-
|
132
|
-
e.g. scp ['array','of', 'file', 'paths'], 'remote_path'
|
135
|
+
> sudo
|
136
|
+
- Enters 'sudo' mode, resulting in 'get' or 'put' commands being execute remotely using 'sudo'. This assumes that you have passwordless sudo setup on each respective remote host.
|
133
137
|
|
134
138
|
### Instance level commands
|
135
139
|
|
@@ -156,26 +160,22 @@ e.g. workon 'identifier'
|
|
156
160
|
- Execute a shell command on your local machine.
|
157
161
|
e.g. local "command"
|
158
162
|
|
159
|
-
>
|
160
|
-
-
|
161
|
-
e.g.
|
163
|
+
> put
|
164
|
+
- Uploads files. Uses Rsync, and so copies recursively
|
165
|
+
e.g. put 'localpath', 'remotepath'
|
166
|
+
|
167
|
+
> get
|
168
|
+
- Downloads files to local. Does so using Rsync, and so is recursive.
|
169
|
+
- A 'downloads' directory will be created in your project directory, within which downloaded files are stored.
|
170
|
+
e.g. get 'remotepath'
|
162
171
|
|
163
172
|
> run
|
164
173
|
- Execute a command.
|
165
174
|
e.g. run 'command'
|
166
175
|
|
167
|
-
>
|
168
|
-
-
|
169
|
-
e.g. scp ['array','of', 'file', 'paths'], 'remote_path'
|
176
|
+
> sudo
|
177
|
+
- Enters 'sudo' mode, resulting in 'get' or 'put' commands being execute remotely using 'sudo'. This assumes that you have passwordless sudo setup on the remote host.
|
170
178
|
|
171
179
|
> ssh
|
172
180
|
- Initiate an SSH connection.
|
173
181
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
data/lib/bcome.rb
CHANGED
@@ -5,5 +5,8 @@ require 'aws-sdk'
|
|
5
5
|
require 'net/scp'
|
6
6
|
require 'net/ssh/proxy/command'
|
7
7
|
require 'fog'
|
8
|
+
require 'require_all'
|
9
|
+
|
10
|
+
require_all "#{File.dirname(__FILE__)}/../lib"
|
11
|
+
require_all "#{File.dirname(__FILE__)}/../filters"
|
8
12
|
|
9
|
-
Dir[File.dirname(__FILE__) + "/**/*.rb"].each {|file| require file }
|
data/lib/bcome/version.rb
CHANGED
data/lib/become_object.rb
CHANGED
@@ -12,6 +12,15 @@ module ::Bcome::BecomeObject
|
|
12
12
|
"#{previous_workspace_object.send(:become_identifier)}> #{identifier}"
|
13
13
|
end
|
14
14
|
|
15
|
+
|
16
|
+
def local_download_path
|
17
|
+
"#{Dir.pwd}/downloads#{namespace}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def namespace
|
21
|
+
"#{previous_workspace_object.send(:namespace)}/#{identifier}"
|
22
|
+
end
|
23
|
+
|
15
24
|
def previous_workspace_object=(object)
|
16
25
|
@previous_workspace_object = object
|
17
26
|
end
|
data/lib/boot.rb
CHANGED
@@ -22,4 +22,12 @@ class ::Bcome::Boot
|
|
22
22
|
::START_PROMPT
|
23
23
|
end
|
24
24
|
|
25
|
+
def namespace
|
26
|
+
starting_namespace
|
27
|
+
end
|
28
|
+
|
29
|
+
def starting_namespace
|
30
|
+
"" # Used to determine where to store downloaded file - this is the start point directory, relative to the bcome install directory
|
31
|
+
end
|
32
|
+
|
25
33
|
end
|
@@ -31,8 +31,8 @@ module ::Bcome::EnvironmentSSH
|
|
31
31
|
|
32
32
|
def execute_scp_upload(files, remote_path, node)
|
33
33
|
begin
|
34
|
-
scp = ::Bcome::Scp.new(
|
35
|
-
scp.upload!
|
34
|
+
scp = ::Bcome::Scp.new(proxy, node)
|
35
|
+
scp.upload!(files, remote_path)
|
36
36
|
rescue Net::SSH::AuthenticationFailed
|
37
37
|
raise "Could not authenticate connection to #{node.identifier}".failure
|
38
38
|
rescue Net::SSH::Disconnect
|
@@ -40,5 +40,15 @@ module ::Bcome::EnvironmentSSH
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
def execute_scp_download(remote_path, local_path, node)
|
44
|
+
begin
|
45
|
+
scp = ::Bcome::Scp.new(proxy, node)
|
46
|
+
scp.download!(remote_path, local_path)
|
47
|
+
rescue Net::SSH::AuthenticationFailed
|
48
|
+
raise "Could not authenticate connection to #{node.identifier}".failure
|
49
|
+
rescue Net::SSH::Disconnect
|
50
|
+
raise "SSH connection to #{node.identifier} was disconnected".failure
|
51
|
+
end
|
52
|
+
end
|
43
53
|
|
44
54
|
end
|
@@ -9,19 +9,34 @@ module ::Bcome::InstanceCommand
|
|
9
9
|
@environment.execute_command(commands, self)
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def put(local_path, remote_path)
|
13
13
|
puts "rsync> #{self.identifier}".informational
|
14
14
|
if @environment.ssh_mode_type == ::SSH_DIRECT_MODE_IDENTIFIER
|
15
|
-
rsync_command = "rsync -av #{local_path} #{self.ssh_user}@#{self.ip_address}:#{remote_path}"
|
15
|
+
rsync_command = "rsync #{rsync_is_sudo}-av #{local_path} #{self.ssh_user}@#{self.ip_address}:#{remote_path}"
|
16
16
|
else
|
17
|
-
rsync_command = "rsync -av -e \"ssh -A #{self.ssh_user}@#{@environment.bastion_ip_address} ssh -o StrictHostKeyChecking=no\" #{local_path} #{self.ssh_user}@#{self.ip_address}:#{remote_path}"
|
17
|
+
rsync_command = "rsync -av -e \"ssh -A #{self.ssh_user}@#{@environment.bastion_ip_address} ssh -o StrictHostKeyChecking=no\" #{rsync_is_sudo}#{local_path} #{self.ssh_user}@#{self.ip_address}:#{remote_path}"
|
18
18
|
end
|
19
19
|
run_local(rsync_command)
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
22
|
+
def get(remote_path, local_path = local_download_path)
|
23
|
+
raise "No local path specified" unless local_path
|
24
|
+
raise "No remote_path specified" unless remote_path
|
25
|
+
|
26
|
+
if @environment.ssh_mode_type == ::SSH_DIRECT_MODE_IDENTIFIER
|
27
|
+
rsync_command = "rsync #{rsync_is_sudo} -chavzP #{self.ssh_user}@#{self.ip_address}:#{remote_path} #{local_path}"
|
28
|
+
else
|
29
|
+
rsync_command = "rsync -chavzP -av -e \"ssh -A #{self.ssh_user}@#{@environment.bastion_ip_address} ssh -o StrictHostKeyChecking=no\" #{rsync_is_sudo}#{self.ssh_user}@#{self.ip_address}:#{remote_path} #{local_path}"
|
30
|
+
end
|
31
|
+
|
32
|
+
silent = true
|
33
|
+
local("mkdir -p #{local_path}", silent)
|
34
|
+
run_local(rsync_command)
|
35
|
+
puts "done: files copied to #{local_path}".informational
|
36
|
+
end
|
37
|
+
|
38
|
+
def rsync_is_sudo
|
39
|
+
is_sudo? ? " --rsync-path=\"sudo rsync\" " : ""
|
25
40
|
end
|
26
41
|
|
27
42
|
end
|
data/lib/helpers/selections.rb
CHANGED
@@ -22,29 +22,28 @@ module ::Bcome::Selections
|
|
22
22
|
return
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def put(local_path, remote_path)
|
26
26
|
if !@objects || @objects.empty?
|
27
27
|
no_selections_error
|
28
28
|
return
|
29
29
|
end
|
30
|
+
|
30
31
|
@objects.each do |object|
|
31
|
-
object.
|
32
|
+
object.put(local_path, remote_path)
|
32
33
|
end
|
33
34
|
return
|
34
35
|
end
|
35
36
|
|
36
|
-
def
|
37
|
+
def get(remote_path)
|
37
38
|
if !@objects || @objects.empty?
|
38
39
|
no_selections_error
|
39
40
|
return
|
40
41
|
end
|
41
|
-
|
42
|
-
return unless @objects
|
43
42
|
@objects.each do |object|
|
44
|
-
object.
|
45
|
-
end
|
43
|
+
object.get(remote_path)
|
44
|
+
end
|
46
45
|
return
|
47
|
-
end
|
46
|
+
end
|
48
47
|
|
49
48
|
def add(resource_identifier = nil)
|
50
49
|
if resource_identifier.is_a?(Array)
|
data/lib/object.rb
CHANGED
@@ -14,7 +14,21 @@ class Object
|
|
14
14
|
def become(object)
|
15
15
|
BECOME.set(object, self)
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
|
+
def toggle_sudo
|
19
|
+
@sudo = @sudo.nil? ? true : (@sudo ? false : true)
|
20
|
+
puts "sudo #{sudo_state.informational}"
|
21
|
+
return
|
22
|
+
end
|
23
|
+
|
24
|
+
def is_sudo?
|
25
|
+
@sudo
|
26
|
+
end
|
27
|
+
|
28
|
+
def sudo_state
|
29
|
+
is_sudo? ? "on" : "off"
|
30
|
+
end
|
31
|
+
|
18
32
|
def workon(identifier)
|
19
33
|
resource = resource_for_identifier(identifier)
|
20
34
|
|
@@ -32,7 +46,7 @@ class Object
|
|
32
46
|
{ :command => "list / ls", :description => "List all available resources at the current context." },
|
33
47
|
{ :command => "describe", :description => "Describe the resource object at the current context." },
|
34
48
|
{ :command => "workon' / w", :description => "Select a resource object, and switch to its context.", :usage => "workon 'identifier'" },
|
35
|
-
{ :command => "exit", :description => "
|
49
|
+
{ :command => "exit", :description => "Return to the previous context" },
|
36
50
|
{ :command => "exit!", :description => "Close all contexts, and exit Become."},
|
37
51
|
{ :command => "local", :description => "Execute a shell command on your local machine.", :usage => 'local "command"'}
|
38
52
|
]
|
@@ -62,7 +76,7 @@ class Object
|
|
62
76
|
def set_irb_prompt(conf)
|
63
77
|
conf[:PROMPT][:CUSTOM] = {
|
64
78
|
:PROMPT_N => "\e[1m:\e[m ",
|
65
|
-
:PROMPT_I => "\e[1m#{BECOME.irb_prompt} >\e[m ",
|
79
|
+
:PROMPT_I => "\e[1m#{BECOME.irb_prompt} #{is_sudo? ? " sudo ".danger : ""}>\e[m ", # high voltage
|
66
80
|
:PROMPT_C => "\e[1m#{BECOME.irb_prompt} >\e[m ",
|
67
81
|
:RETURN => ::VERBOSE ? "%s \n" : "\n"
|
68
82
|
}
|
data/lib/patches/string.rb
CHANGED
data/lib/scp.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
class ::Bcome::Scp
|
2
2
|
|
3
|
-
|
4
|
-
@files = files
|
3
|
+
def initialize(proxy, node)
|
5
4
|
@proxy = proxy
|
6
5
|
@node = node
|
7
|
-
@remote_path = remote_path
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
8
|
+
def download!(remote_path, local_path = @node.local_download_path)
|
9
|
+
local("mkdir -p #{local_path}", true)
|
10
|
+
::Net::SCP.start(@node.ip_address, @node.ssh_user, { :proxy => @proxy, :keys => @node.keys, :paranoid => false }) do |scp|
|
11
|
+
scp.download!(remote_path, local_path, { :recursive => true, :preserve => true, :verbose => true }) do |cha, name, received, total|
|
12
|
+
pct = received / total.to_f
|
13
|
+
cnt = ( 72 * pct ).ceil
|
14
|
+
print "%-72s %.2f%%\r" % [ ("#" * cnt), ( pct * 100 ) ]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
puts "done: files copied to #{local_path}".informational
|
18
|
+
end
|
19
|
+
|
20
|
+
def upload!(files, remote_path)
|
11
21
|
puts "scp> #{@node.identifier}".informational
|
12
22
|
::Net::SCP.start(@node.ip_address, @node.ssh_user, { :proxy => @proxy, :keys => @node.keys, :paranoid => false }) do |scp|
|
13
|
-
|
23
|
+
files = files.is_a?(Array) ? files : [files]
|
24
|
+
files.each do |local_path|
|
14
25
|
name_old = ""
|
15
|
-
scp.upload!(local_path,
|
26
|
+
scp.upload!(local_path, remote_path, { :recursive => true }) do |ch, name, sent, total|
|
16
27
|
log_string = "#{name}: #{sent}/#{total}"
|
17
28
|
if name_old == name
|
18
29
|
STDOUT.write "\r#{log_string}"
|
data/lib/stack/environment.rb
CHANGED
@@ -31,9 +31,10 @@ module ::Bcome::Stack
|
|
31
31
|
{ :command => "remove", :description => "Remove a resource you no longer with to work on.", :usage => "remove 'identifier', OR remove ['array', 'of','identifiers']" },
|
32
32
|
{ :command => "clear!", :description => "Remove all selected resources." },
|
33
33
|
{ :command => "selections", :description => "Show all added resources." },
|
34
|
-
{ :command => "rsync", :description => "Rsync files to all selected resources.", :usage => "rsync 'localpath', 'remotepath'" },
|
35
34
|
{ :command => "run", :description => "Execute a command on all selected resources", :usage => "run 'command'" },
|
36
|
-
{ :command => "
|
35
|
+
{ :command => "get", :description => "Download from remote from all selected resources (recursive - uses rsync)", :usage => "get 'remote_path'" },
|
36
|
+
{ :command => "put", :description => "Copy files up to all selected resources (recursive - uses rsync)", :usage => "put 'local_path', 'remote_path'" },
|
37
|
+
{ :command => "sudo", :description => "Run 'get' and 'put' in sudo mode (assumes you have passwordless sudo setup)" }
|
37
38
|
]
|
38
39
|
end
|
39
40
|
|
@@ -51,6 +52,10 @@ module ::Bcome::Stack
|
|
51
52
|
return @meta_data[:ssh_mode][:ssh_user]
|
52
53
|
end
|
53
54
|
|
55
|
+
def sudo
|
56
|
+
toggle_sudo
|
57
|
+
end
|
58
|
+
|
54
59
|
def valid_ssh_modes
|
55
60
|
[::SSH_JUMP_MODE_IDENTIFIER, ::SSH_DIRECT_MODE_IDENTIFIER]
|
56
61
|
end
|
data/lib/stack/instance.rb
CHANGED
@@ -40,10 +40,11 @@ module ::Bcome::Stack
|
|
40
40
|
|
41
41
|
def menu_items
|
42
42
|
super + [
|
43
|
-
{ :command => "rsync", :description => "Rsync files.", :usage => "rsync 'localpath', 'remotepath'" },
|
44
43
|
{ :command => "run", :description => "Execute a command.", :usage => "run 'command'" },
|
45
|
-
{ :command => "
|
46
|
-
{ :command => "
|
44
|
+
{ :command => "put", :description => "Copy files to remote (recursive - uses rsync)", :usage => "put 'local_path', 'remote_path'" },
|
45
|
+
{ :command => "get", :description => "Download from remote (recursive - uses rsync).", :usage => "get 'remote_path'"},
|
46
|
+
{ :command => "ssh", :description => "Initiate an SSH connection." },
|
47
|
+
{ :command => "sudo", :description => "Run 'get' and 'put' in sudo mode (assumes you have passwordless sudo setup)" }
|
47
48
|
]
|
48
49
|
end
|
49
50
|
|
@@ -51,6 +52,18 @@ module ::Bcome::Stack
|
|
51
52
|
@environment.platform
|
52
53
|
end
|
53
54
|
|
55
|
+
def sudo
|
56
|
+
toggle_sudo
|
57
|
+
end
|
58
|
+
|
59
|
+
def namespace
|
60
|
+
"#{@environment.namespace}/#{identifier}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def is_sudo?
|
64
|
+
super || @environment.is_sudo?
|
65
|
+
end
|
66
|
+
|
54
67
|
def responds_to_list?
|
55
68
|
false
|
56
69
|
end
|
@@ -80,7 +93,7 @@ module ::Bcome::Stack
|
|
80
93
|
end
|
81
94
|
|
82
95
|
def do_describe
|
83
|
-
description = "#{identifier}"
|
96
|
+
description = "#{identifier}#{ is_sudo? ? " MODE: sudo " : "" }"
|
84
97
|
description += "\n\t* Internal IP #{@meta_data[:external_network_interface_address]}"
|
85
98
|
description += "\n\t* External IP #{public_ip_address}" if public_ip_address
|
86
99
|
description += "\n\t* #{role}" if role
|
data/lib/workspace_context.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
|
-
class ::Bcome::WorkspaceContext
|
1
|
+
class ::Bcome::WorkspaceContext
|
2
2
|
|
3
3
|
attr_reader :object
|
4
4
|
|
5
5
|
def set(object, current_object, spawn = true)
|
6
|
-
|
7
6
|
@object = object
|
8
7
|
main_context = IRB.conf[:MAIN_CONTEXT]
|
9
8
|
@object.main_context = main_context.workspace if main_context
|
10
9
|
@object.previous_workspace_object = current_object if current_object
|
11
10
|
|
12
|
-
irb = IRB::Irb.new(IRB::WorkSpace.new(@object))
|
13
|
-
|
14
11
|
# Spawn is initiated when a user wants to shift workspace context.
|
15
12
|
# We don't spawn whilst setting up the hierarchy for quick contexts
|
16
13
|
spawn_for_object(@object) if spawn
|
14
|
+
return
|
17
15
|
end
|
18
16
|
|
19
17
|
def spawn_for_object(object)
|
@@ -33,4 +31,9 @@ class ::Bcome::WorkspaceContext ## TODO Move to include
|
|
33
31
|
def irb_prompt
|
34
32
|
@object ? @object.send(:become_identifier) : start_prompt
|
35
33
|
end
|
34
|
+
|
35
|
+
def is_sudo?
|
36
|
+
@object.is_sudo?
|
37
|
+
end
|
38
|
+
|
36
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bcome
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume Roderick (Webzakimbo)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -86,10 +86,24 @@ dependencies:
|
|
86
86
|
- - '='
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: 1.33.0
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: require_all
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 1.3.3
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - '='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 1.3.3
|
89
103
|
description: Provides a console interface for traversing a hierarchy of platforms
|
90
104
|
-> environment -> servers, and exposes common administration tools for the managemenent
|
91
105
|
either of individual servers, or groups or servers. System is driven from simple
|
92
|
-
configuration, and is extensible. Integrates with AWS EC2 for dynamic network
|
106
|
+
configuration, and is extensible. Integrates with AWS EC2 for dynamic network discover.
|
93
107
|
email:
|
94
108
|
- guillaume@webzakimbo.com
|
95
109
|
executables:
|