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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f232736b42afc8eb14ae4df636a3b7b6eccb7d0e
4
- data.tar.gz: f260940851ea03b9d2bfdfd863883468958cf8fc
3
+ metadata.gz: f8b43a40c66431c8282e710e49721519ae9cdd22
4
+ data.tar.gz: 6aab609acf080f4686b1ebceb016cd7162877579
5
5
  SHA512:
6
- metadata.gz: 02936421eec97fdeeddc3318adea9d7ae7e5b591164130f90b1ecf7a6e10a544374b260f047bc2309ce8087e4f5adec43b287d4c4b06af0057e0cb83f546492a
7
- data.tar.gz: bf8b6c1262e05bf9201538f4d8c478d09bae2248477c0338cd4df26471885640baf10626d9172fd09cdc6344913acaab99fd9feb02e49681eb462d8b136c8add
6
+ metadata.gz: f1583a06db19ab8874ce7b3b985e3366ff74dcfffe4a7162db5c502d3582ee1b1a5328dc9f061caf863ca38d74e913d38114c9f73804616c4cef8cce10321fc4
7
+ data.tar.gz: 8d671a6476db8a8ed65da10b25a0201da57d4c66ab270b75f5bb6a921d7351bdb1a2e27f2ffe317f2c7bd07f0fe96a9a7ce6d71e7b40ce554149c6a6baa2d95d
@@ -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 contexct
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
- > rsync
123
- - Rsync files to all selected resources.
124
- e.g. rsync 'localpath', 'remotepath'
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
- > scp
131
- - SCP files up to all selected resources
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
- > rsync
160
- - Rsync files.
161
- e.g. rsync 'localpath', 'remotepath'
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
- > scp
168
- - SCP files.
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
-
@@ -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 }
@@ -1,3 +1,3 @@
1
1
  module Bcome
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -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
@@ -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
@@ -1,7 +1,7 @@
1
1
  module ::Bcome::CommandHelper
2
2
 
3
- def run_local(command)
4
- puts "(local) > #{command}" if ::VERBOSE
3
+ def run_local(command, silent = false)
4
+ puts "(local) > #{command}" if !silent && ::VERBOSE
5
5
  system(command)
6
6
  end
7
7
  alias :local :run_local
@@ -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(files, remote_path, proxy, node)
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 rsync(local_path, remote_path)
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 scp(files, remote_path)
23
- @environment.execute_scp_upload(files, remote_path, self)
24
- return
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
@@ -22,29 +22,28 @@ module ::Bcome::Selections
22
22
  return
23
23
  end
24
24
 
25
- def rsync(local_path, remote_path)
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.rsync(local_path, remote_path)
32
+ object.put(local_path, remote_path)
32
33
  end
33
34
  return
34
35
  end
35
36
 
36
- def scp(files, remote_path)
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.scp(files, remote_path)
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)
@@ -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 => "Close the current context" },
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
  }
@@ -16,6 +16,10 @@ class String
16
16
  self.friendly
17
17
  end
18
18
 
19
+ def danger
20
+ self.colorize(:white).on_red
21
+ end
22
+
19
23
  def friendly
20
24
  self.colorize(:black).on_green
21
25
  end
data/lib/scp.rb CHANGED
@@ -1,18 +1,29 @@
1
1
  class ::Bcome::Scp
2
2
 
3
- def initialize(files, remote_path, proxy, node)
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 upload!
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
- @files.each do |local_path|
23
+ files = files.is_a?(Array) ? files : [files]
24
+ files.each do |local_path|
14
25
  name_old = ""
15
- scp.upload!(local_path, @remote_path, { :recursive => true }) do |ch, name, sent, total|
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}"
@@ -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 => "scp", :description => "SCP files up to all selected resources", :usage => "scp ['array','of', 'file', 'paths'], 'remote_path'" },
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
@@ -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 => "scp", :description => "SCP files.", :usage => "scp ['array','of', 'file', 'paths'], 'remote_path'" },
46
- { :command => "ssh", :description => "Initiate an SSH connection." }
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
@@ -1,19 +1,17 @@
1
- class ::Bcome::WorkspaceContext ## TODO Move to include
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.3
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-03 00:00:00.000000000 Z
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 discovery.
106
+ configuration, and is extensible. Integrates with AWS EC2 for dynamic network discover.
93
107
  email:
94
108
  - guillaume@webzakimbo.com
95
109
  executables: