sambot 0.1.110 → 0.1.111

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: fa2109d02bfb359fefc1600cc8f153047e2392d0
4
- data.tar.gz: 86f6b773b656669841db39f6417f97e785782012
3
+ metadata.gz: 04cf2aa5575db3b8d682df8834ee8219bfbf7ebf
4
+ data.tar.gz: e664f1bfdb6988720af8966aa6bf9af92277502d
5
5
  SHA512:
6
- metadata.gz: 231c4161192aa3f385786557a446f316c525f6523d935636485406575c26f7f17a20f5eb0d67b75b0f29bfd7e9fdeee75063d451073847461fb142b99ea7e4db
7
- data.tar.gz: 5cfd929629ec2951d8e3f29cef1ed2b8c012c2ba0dbfa171ba7a0cce13b9e69f7c9e8004d48ff8d08f1c9c9388fa27b4732c22ff102d38b3d1e7ea9aa2d26e12
6
+ metadata.gz: 71f8344676808ea81f690b06891fb80820de093e37635b937613b8102e2f6b236d4f97b28d89d10ce5af5d6433340fd4a51d808d1c94e806cf97136f00244142
7
+ data.tar.gz: a4a9d08a9e08102507cddc15f060a2cb398752067481dbc823e53fc023703a39966235a1b50dab517984e900e5c49c36d5f6edd585a2a3296595f702e5df8082
data/lib/sambot.rb CHANGED
@@ -27,7 +27,9 @@ require_relative 'sambot/ssh/config_section'
27
27
  require_relative 'sambot/ssh/parser'
28
28
 
29
29
  require_relative 'sambot/developer_workflow/tunnel'
30
+ require_relative 'sambot/developer_workflow/tunnels'
30
31
  require_relative 'sambot/developer_workflow/brew'
32
+ require_relative 'sambot/developer_workflow/proxy'
31
33
  require_relative 'sambot/developer_workflow/networking'
32
34
  require_relative 'sambot/developer_workflow/dns'
33
35
  require_relative 'sambot/developer_workflow/session'
@@ -36,13 +38,8 @@ require_relative 'sambot/developer_workflow/workstation'
36
38
 
37
39
  require_relative 'sambot/commands/base_command'
38
40
  require_relative 'sambot/commands/cookbook'
39
- require_relative 'sambot/commands/rdp'
40
41
  require_relative 'sambot/commands/session'
41
42
  require_relative 'sambot/commands/workstation'
42
- require_relative 'sambot/commands/instance'
43
- require_relative 'sambot/commands/dns'
44
- require_relative 'sambot/commands/team'
45
- require_relative 'sambot/commands/report'
46
43
 
47
44
  require_relative 'sambot/cli'
48
45
 
@@ -7,6 +7,12 @@ module Sambot
7
7
  module Chef
8
8
  class Cookbook
9
9
 
10
+ def self.register(config)
11
+ name = config['name']
12
+ identifier = config['identifier']
13
+
14
+ end
15
+
10
16
  def self.build(config, essential_files, generated_files)
11
17
  validate_cookbook_structure(config['platforms'], essential_files, generated_files)
12
18
  setup_test_kitchen(config)
@@ -42,6 +48,7 @@ module Sambot
42
48
  'name' => name,
43
49
  'version' => '0.0.1',
44
50
  'platforms' => platforms,
51
+ 'identifier' => '',
45
52
  'suites' => [{
46
53
  'name' => 'default',
47
54
  'run_list' => [
data/lib/sambot/cli.rb CHANGED
@@ -12,8 +12,5 @@ module Sambot
12
12
  desc 'workstation', 'Manage engineer workstations'
13
13
  subcommand 'workstation', Sambot::Commands::Workstation
14
14
 
15
- desc 'dns', 'Manage DEV/QE DNS'
16
- subcommand 'dns', Sambot::Commands::DNS
17
-
18
15
  end
19
16
  end
@@ -60,11 +60,15 @@ module Sambot
60
60
 
61
61
  no_commands do
62
62
 
63
- def execute(access = :standard)
64
- if access == :sudo
65
- ensure_running_as_sudo
66
- else
67
- ensure_not_running_as_sudo
63
+ def execute(need_dev_credentials: false, need_sudo_password: false)
64
+ if need_dev_credentials && !ENV['SAMBOT_DEV_USERNAME']
65
+ raise ApplicationError, 'Your DEV/QE username needs to be set in the environment variable SAMBOT_DEV_USERNAME before this command can be run.'
66
+ end
67
+ if need_dev_credentials && !ENV['SAMBOT_DEV_PASSWORD']
68
+ raise ApplicationError, 'Your DEV/QE password needs to be set in the environment variable SAMBOT_DEV_PASSWORD before this command can be run.'
69
+ end
70
+ if need_sudo_password && !ENV['SAMBOT_SUDO_PASSWORD']
71
+ raise ApplicationError, 'Your local password needs to be set in the environment variable SAMBOT_SUDO_PASSWORD before this command can be run.'
68
72
  end
69
73
  Runtime.ensure_latest
70
74
  yield
@@ -72,14 +76,6 @@ module Sambot
72
76
  UI.error(e.message)
73
77
  end
74
78
 
75
- def ensure_not_running_as_sudo
76
- #raise ApplicationError, "This command should not be run as sudo" unless ENV['USER'] != 'root'
77
- end
78
-
79
- def ensure_running_as_sudo
80
- #raise ApplicationError, "This command needs to be run as sudo" unless ENV['USER'] == 'root'
81
- end
82
-
83
79
  def config
84
80
  Config.new.read
85
81
  end
@@ -37,6 +37,11 @@ module Sambot
37
37
  execute { puts "##teamcity[buildNumber '#{config['version'].to_s}']" }
38
38
  end
39
39
 
40
+ desc 'register', 'Registers the cookbook short name in Consul for use with Rundeck machine creation jobs'
41
+ def register
42
+ execute { Chef::Cookbook.register(config) }
43
+ end
44
+
40
45
  end
41
46
  end
42
47
  end
@@ -6,23 +6,21 @@ module Sambot
6
6
 
7
7
  namespace 'session'
8
8
 
9
- desc 'start', 'Start a new DEV/QE session'
9
+ desc 'start', 'Start a new Sambot session'
10
10
  def start
11
- execute(:sudo) do
12
- username = ENV['SAMBOT_SESSION_USERNAME']
13
- password = ENV['SAMBOT_SESSION_PASSWORD']
14
- unless username && password
15
- username = ask(' What is your DEV/QE username i.e. jsmith? ')
16
- password = ask(' What is your DEV/QE password? ', :echo => false)
17
- say('')
18
- end
19
- DeveloperWorkflow::Session.new.start(username, password)
11
+ execute(need_dev_credentials: true, need_sudo_password: true) do
12
+ DeveloperWorkflow::Session.new.start(ENV['SAMBOT_DEV_USERNAME'], ENV['SAMBOT_DEV_PASSWORD'], ENV['SAMBOT_SUDO_PASSWORD'])
20
13
  end
21
14
  end
22
15
 
23
- desc 'stop', 'Stop the DEV/QE session'
16
+ desc 'stop', 'Stop any active Sambot session'
24
17
  def stop
25
- execute(:sudo) { DeveloperWorkflow::Session.new.stop }
18
+ execute(need_sudo_password: true) { DeveloperWorkflow::Session.new.stop }
19
+ end
20
+
21
+ desc 'status', 'Show the status of your Sambot session'
22
+ def status
23
+ execute(need_sudo_password: true) { DeveloperWorkflow::Session.new.show }
26
24
  end
27
25
 
28
26
  end
@@ -8,9 +8,8 @@ module Sambot
8
8
 
9
9
  desc 'configure', 'Sets up an engineering workstation'
10
10
  def configure
11
- execute do
12
- username = ask(' What is your DEV/QE Active Directory username i.e. john.smith? ')
13
- DeveloperWorkflow::Workstation.configure(username)
11
+ execute(need_dev_credentials: true, need_sudo_password: true) do
12
+ DeveloperWorkflow::Workstation.configure(ENV['SAMBOT_DEV_PASSWORD'])
14
13
  end
15
14
  end
16
15
 
@@ -5,25 +5,40 @@ module Sambot
5
5
  class Brew
6
6
 
7
7
  def configure
8
+ UI.debug("Updating Homebrew formulas and casks")
8
9
  update
9
10
  tap('caskroom/cask')
10
11
  update
11
12
  end
12
13
 
13
14
  def update
14
- `brew update`
15
+ Bundler.with_clean_env do
16
+ `brew update`
17
+ end
15
18
  end
16
19
 
17
20
  def tap(name)
18
- `brew tap #{name}`
21
+ Bundler.with_clean_env do
22
+ `brew tap #{name}`
23
+ end
19
24
  end
20
25
 
21
- def list_casks
22
- `brew cask list`.split
26
+ def install_cask(cask, binary)
27
+ result = `which #{binary}`
28
+ if result
29
+ UI.info("Not installing the Homebrew cask #{cask} as the corresponding binary is already available")
30
+ else
31
+ `brew cask install #{cask}`
32
+ end
23
33
  end
24
34
 
25
- def list_formulas
26
- `brew list`.split
35
+ def install_formula(formula, binary)
36
+ result = `which #{binary}`
37
+ if result
38
+ UI.info("Not installing the Homebrew formula #{formula} as the corresponding binary is already available")
39
+ else
40
+ `brew install #{formula}`
41
+ end
27
42
  end
28
43
 
29
44
  end
@@ -6,27 +6,36 @@ module Sambot
6
6
  module DeveloperWorkflow
7
7
  class DNS
8
8
 
9
- def self.update_hosts(forwards, src = '/etc/hosts')
10
- modify_hosts(forwards, src) do |entries, key, value|
9
+ def self.update_hosts(forwards, src = '/etc/hosts', dest = nil)
10
+ UI.info('Updating your hosts file to allow access to Advertising Studio services through local SSH tunnels')
11
+ modify_hosts(forwards, src, dest) do |entries, key, value|
12
+ UI.debug("Adding hosts entry #{key} #{value[:ip]}")
11
13
  entries << Hosts::Entry.new(value[:ip], key)
12
14
  end
13
15
  end
14
16
 
15
- def self.reset_hosts(forwards, src = '/etc/hosts')
16
- modify_hosts(forwards, src)
17
+ def self.reset_hosts(forwards, src = '/etc/hosts', dest = nil)
18
+ UI.info('Removing extra entries in hosts file')
19
+ modify_hosts(forwards, src, dest)
17
20
  end
18
21
 
19
22
  private
20
23
 
21
- def self.modify_hosts(forwards, src)
22
- UI.debug('Updating your hosts file.')
24
+ def self.modify_hosts(forwards, src, dest)
23
25
  hosts = Hosts::File.read(src)
24
26
  entries = hosts.elements
25
27
  forwards.each do |key, value|
26
28
  entries.delete_if { |entry| entry.is_a?(Aef::Hosts::Entry) && entry.name == key.to_s}
27
29
  yield(entries, key, value) if block_given?
28
30
  end
29
- hosts.write
31
+ if dest
32
+ hosts.write(:path => dest)
33
+ else
34
+ tempfile = Tempfile.new
35
+ hosts.write(:path => tempfile.path)
36
+ Runtime.sudo("cp #{tempfile.path} /etc/hosts")
37
+ end
38
+
30
39
  end
31
40
 
32
41
  end
@@ -7,7 +7,8 @@ module Sambot
7
7
 
8
8
  attr_reader :local_addresses
9
9
 
10
- def initialize
10
+ def self.local_addresses
11
+ return @local_addresses if @local_addresses
11
12
  addr_infos = Socket.getifaddrs
12
13
  @local_addresses = []
13
14
  addr_infos.each do |addr_info|
@@ -15,14 +16,19 @@ module Sambot
15
16
  @local_addresses << addr_info.addr.ip_address
16
17
  end
17
18
  end
19
+ @local_addresses
18
20
  end
19
21
 
20
- def configure(ip)
21
- if local_addresses.include?(ip)
22
- `sudo ifconfig lo0 -alias #{ip}`
22
+ def self.configure(forwards)
23
+ network = Networking.new
24
+ forwards.each do |key, value|
25
+ ip = value[:ip]
26
+ if local_addresses.include?(ip)
27
+ Runtime.sudo("ifconfig lo0 -alias #{ip}")
28
+ end
29
+ UI.debug "Setting up the local IP #{ip} for accessing #{key}"
30
+ Runtime.sudo("ifconfig lo0 alias #{ip} up")
23
31
  end
24
- UI.debug "Setting up the local IP #{ip} for SSH tunneling purposes."
25
- `sudo ifconfig lo0 alias #{ip} up`
26
32
  end
27
33
 
28
34
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sambot
4
+ module DeveloperWorkflow
5
+ class Proxy
6
+
7
+ def self.start(forwards)
8
+ template_path = FileManagement::TemplateProvider.get_path('haproxy.conf.erb')
9
+ input = File.read(template_path)
10
+ eruby = Erubis::Eruby.new(input)
11
+ services = forwards.map do |key, value|
12
+ {
13
+ name: key.to_s.split('.')[0],
14
+ ip: value[:ip],
15
+ tunnel_port: value[:local_port],
16
+ local_port: value[:port]
17
+ }
18
+ end
19
+ services.each do |service|
20
+ UI.debug("Proxying #{service[:name]}.brighter.io:#{service[:local_port]} to #{service[:ip]}:#{service[:tunnel_port]}")
21
+ end
22
+ contents = eruby.evaluate({services: services})
23
+ temp_config = Tempfile.new
24
+ File.write(temp_config.path, contents)
25
+ Runtime.sudo("haproxy -f #{temp_config.path}")
26
+ end
27
+
28
+ def self.stop
29
+
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -2,6 +2,7 @@
2
2
  require 'titan'
3
3
  require 'net/ssh'
4
4
  require 'dante'
5
+ require 'haproxy-tools'
5
6
 
6
7
  module Dante
7
8
  class Runner
@@ -18,37 +19,34 @@ module Sambot
18
19
  BASTION_HOST_IP = '146.177.10.174'
19
20
 
20
21
  FORWARDS = {
21
- 'chef.brighter.io': { ip: '127.0.0.13', port: 443 },
22
- 'teamcity.brighter.io': { ip: '127.0.0.14', port: 443 },
23
- 'splunk.brighter.io': { ip: '127.0.0.15', port: 443 },
24
- 'jenkins.brighter.io': { ip: '127.0.0.16', port: 443 },
25
- 'vault.brighter.io': { ip: '127.0.0.17', port: 8200 }
22
+ 'chef.brighter.io': { ip: '127.0.0.13', port: 443, local_port: 9013 },
23
+ 'teamcity.brighter.io': { ip: '127.0.0.14', port: 443, local_port: 9014 },
24
+ 'splunk.brighter.io': { ip: '127.0.0.15', port: 443, local_port: 9015 },
25
+ 'jenkins.brighter.io': { ip: '127.0.0.16', port: 443, local_port: 9016 },
26
+ 'vault.brighter.io': { ip: '127.0.0.17', port: 8200, local_port: 9017 }
26
27
  }
27
28
 
28
- def start(username, password)
29
- kill_active_sessions
29
+ def start(username, password, sudo_password)
30
+ Tunnels.stop
30
31
  unless verify_credentials(username, password)
31
- UI.error 'The session could not be started.'
32
+ UI.error 'The session could not be started'
32
33
  exit
33
34
  end
34
- setup_networking
35
- start_daemon_for_tunneling(username, password)
36
- setup_secrets_management(username, password)
37
- UI.info("Your session has now started. Run `sambot session stop` to close it.")
35
+ DNS.update_hosts(FORWARDS)
36
+ Proxy.start(FORWARDS)
37
+ Networking.configure(FORWARDS)
38
+ Tunnels.start(username, password, BASTION_HOST_IP, FORWARDS)
39
+ #setup_secrets_management(username, password)
40
+ UI.info("Your session has now started - run `sambot session stop` to close it")
38
41
  end
39
42
 
40
43
  def stop
41
- kill_active_sessions
44
+ Tunnels.stop
42
45
  DNS.reset_hosts(FORWARDS)
43
46
  end
44
47
 
45
48
  private
46
49
 
47
- def kill_active_sessions
48
- Dante::Runner.new('sambot-session').execute(:kill => true)
49
- UI.debug("All active Sambot sessions have been closed.")
50
- end
51
-
52
50
  def verify_credentials(username, password)
53
51
  full_username = "DEV\\#{username}"
54
52
  begin
@@ -61,44 +59,21 @@ module Sambot
61
59
  rescue Errno::ECONNREFUSED
62
60
  puts " Connection refused"
63
61
  rescue Net::SSH::Disconnect
64
- UI.error "Invalid username or password provided."
62
+ UI.error "Invalid username or password provided"
65
63
  end
66
64
  return false
67
65
  end
68
66
 
69
- def start_daemon_for_tunneling(username, password)
70
- Dante::Runner.new('sambot-session').execute(:daemonize => true, :log_path => 'sambot-session.log') do
71
- setup_ssh_tunnels(username, password)
72
- end
73
- end
74
-
75
67
  def setup_secrets_management(username, password)
76
- Vault.setup_environment('vault.brighter.io', FORWARDS['vault.brighter.io'.to_sym][:port], '/etc/profile.d/')
77
68
  unless Vault.has_environment_variables?('/etc/profile.d/')
78
- Vault.dump_environment('sambot.env')
79
- UI.info("Because this is the first time you have created a session, environment variables need to be set. Run `source sambot.env` to add them this session - future sessions won't need this step.")
69
+ UI.info("You have either not configured your workstation or you have not opened up a new shell to pick up the changes applied during configuration")
80
70
  end
81
- UI.debug "Authenticating with Hashicorp Vault in Rackspace DEV/QE..."
71
+ UI.debug "Authenticating with Hashicorp Vault in Rackspace DEV/QE"
82
72
  token = Vault.authenticate(username, password)
83
- UI.debug "Saving your Vault authentication token to ~/.vault-token..."
73
+ UI.debug "Saving your Vault authentication token to ~/.vault-token"
84
74
  Vault.save_token(token)
85
75
  end
86
76
 
87
- def setup_ssh_tunnels(username, password)
88
- full_username = "DEV\\#{username}"
89
- UI.debug "Opening a connection to the Rackspace DEV/QE environment..."
90
- Net::SSH.start(BASTION_HOST_IP, full_username, :password => password) do |session|
91
- FORWARDS.each { |key, value| Tunnel.create(session, key, value[:ip], value[:port]) }
92
- session.loop {true}
93
- end
94
- end
95
-
96
- def setup_networking
97
- DNS.update_hosts(FORWARDS)
98
- network = Networking.new
99
- FORWARDS.each { |key, value| network.configure(value[:ip]) }
100
- end
101
-
102
77
  end
103
78
  end
104
79
  end
@@ -5,9 +5,9 @@ module Sambot
5
5
  module DeveloperWorkflow
6
6
  class Tunnel
7
7
 
8
- def self.create(session, host, ip, port)
9
- UI.debug "Creating a tunnel from #{ip}:#{port} to #{host}:#{port}."
10
- session.forward.local(ip, port, host, port)
8
+ def self.create(session, host, ip, port, local_port)
9
+ UI.debug "Creating a tunnel from #{ip}:#{local_port} to #{host}:#{port}"
10
+ session.forward.local(ip, local_port, host, port)
11
11
  end
12
12
 
13
13
  end
@@ -0,0 +1,40 @@
1
+ module Sambot
2
+ module DeveloperWorkflow
3
+
4
+ class Tunnels
5
+
6
+ PID_PATH = '/tmp/sambot-session.pid'
7
+
8
+ LOG_PATH = '/tmp/sambot-session.log'
9
+
10
+ SESSION_ID = 'sambot'
11
+
12
+ def self.start(username, password, bastion_host_ip, forwards)
13
+ UI.info("Starting daemon for tunneling - log is available at #{LOG_PATH}")
14
+ Dante::Runner.new(SESSION_ID).execute(:daemonize => true, :pid_path => PID_PATH, :log_path => LOG_PATH) do
15
+ setup_ssh_tunnels(username, password, bastion_host_ip, forwards)
16
+ end
17
+ sleep(2)
18
+ puts "----- Background Daemon Log -----"
19
+ puts File.read(LOG_PATH)
20
+ puts "---------------------------------"
21
+ end
22
+
23
+ def self.stop
24
+ Dante::Runner.new(SESSION_ID).execute(:kill => true, :pid_path => PID_PATH)
25
+ UI.debug("All active sessions have been closed")
26
+ File.delete(LOG_PATH) if File.exist?(LOG_PATH)
27
+ end
28
+
29
+ def self.setup_ssh_tunnels(username, password, bastion_host_ip, forwards)
30
+ full_username = "DEV\\#{username}"
31
+ UI.debug "Opening a connection to the Rackspace DEV/QE environment"
32
+ Net::SSH.start(bastion_host_ip, full_username, :password => password) do |session|
33
+ forwards.each { |key, value| Tunnel.create(session, key, value[:ip], value[:port], value[:local_port]) }
34
+ session.loop {true}
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'vault'
4
+ require 'open4'
4
5
 
5
6
  module Sambot
6
7
  module DeveloperWorkflow
@@ -19,14 +20,16 @@ module Sambot
19
20
  secret.auth.client_token
20
21
  end
21
22
 
22
- def self.setup_environment(host, port, root = '/etc/profile.d/')
23
+ def self.setup_environment(root = '/etc/profile.d/')
23
24
  save_environment_variable('VAULT_SKIP_VERIFY', true)
24
25
  save_environment_variable('VAULT_ADDR', TARGET)
25
26
  end
26
27
 
27
28
  def self.save_environment_variable(key, value, path = '/etc/profile.d/')
28
29
  path = File.join(path, "#{key}.sh")
29
- File.write(path, "export #{key}=#{value}")
30
+ file = Tempfile.new('foo')
31
+ file.write("export #{key}=#{value}")
32
+ Runtime.sudo("cp #{file.path} #{path}")
30
33
  ENV[key] = value.to_s
31
34
  end
32
35
 
@@ -4,45 +4,52 @@ module Sambot
4
4
  module DeveloperWorkflow
5
5
  class Workstation
6
6
 
7
- FORMULAS = %w{golang git}
8
-
9
- CASKS = %w{virtualbox vagrant vagrant-manager chefdk}
7
+ FORMULAS = {
8
+ 'git': 'git',
9
+ 'vault': 'vault',
10
+ 'haproxy': 'haproxy'
11
+ }
12
+
13
+ CASKS = {
14
+ 'virtualbox': 'virtualbox',
15
+ 'vagrant': 'vagrant',
16
+ 'chefdk': 'chef'
17
+ }
10
18
 
11
19
  XCODE_INSTALLATION_SCRIPT = 'xcode-select --install'
12
20
 
13
21
  def self.configure(username)
14
- UI.debug('Updating your environment variables.')
15
22
  update_environment_variables
16
23
  install_native_binaries
17
- UI.info('Your workstation is now ready for use. Please close this shell and open up a new one to start making use of your new environment.')
24
+ UI.info('Your workstation is now ready for use - please close this shell and open up a new one to start making use of your new environment')
18
25
  end
19
26
 
20
27
  def self.install_native_binaries
21
- system(XCODE_INSTALLATION_SCRIPT)
28
+ if `xcode-select version`
29
+ UI.info("Not installing XCode Developer Tools as they are already")
30
+ else
31
+ system(XCODE_INSTALLATION_SCRIPT)
32
+ end
22
33
  brew = Brew.new
23
34
  brew.configure
24
35
  install_formulas(brew)
25
36
  install_casks(brew)
26
37
  end
27
38
 
28
- def self.install_formulas(brew)
29
- CASKS.each do |formula|
30
- brew.install_cask(formula) unless brew.list_formulas.include?(formula)
39
+ def self.install_casks(brew)
40
+ CASKS.each do |formula, binary|
41
+ brew.install_cask(formula, binary)
31
42
  end
32
43
  end
33
44
 
34
45
  def self.install_formulas(brew)
35
- FORMULAS.each do |formula|
36
- brew.install_formula(formula) unless brew.list_formulas.include?(formula)
46
+ FORMULAS.each do |formula, binary|
47
+ brew.install_formula(formula, binary)
37
48
  end
38
49
  end
39
50
 
40
- def self.update_ssh_configuration(username)
41
- config = Ssh::Parser.new.update('DEV\\' + username)
42
- config.save
43
- end
44
-
45
51
  def self.update_environment_variables
52
+ UI.debug('Updating your Vault environment variables')
46
53
  Vault.setup_environment
47
54
  end
48
55
 
@@ -12,10 +12,18 @@ module Sambot
12
12
 
13
13
  def self.ensure_latest
14
14
  latest_version = Gems.new.versions('sambot')[0]["number"]
15
- UI.debug("Current Sambot version is #{Sambot::VERSION}.")
16
- UI.debug("Latest Sambot version is #{latest_version}.")
15
+ UI.debug("Current version is #{Sambot::VERSION}")
16
+ UI.debug("Latest version is #{latest_version}")
17
17
  if is_obsolete
18
- UI.info('A newer version of the sambot gem exists. Please update the gem before continuing.')
18
+ UI.info('A newer version of this gem exists - please update the gem before continuing')
19
+ end
20
+ end
21
+
22
+ def self.sudo(command)
23
+ Open4::popen4("sudo -S #{command}") do |pid, stdin, stdout, stderr|
24
+ stdin.puts ENV['SAMBOT_SUDO_PASSWORD']
25
+ stdin.close
26
+ stdout.read
19
27
  end
20
28
  end
21
29
 
@@ -0,0 +1,21 @@
1
+ global
2
+ chroot /var/lib/haproxy
3
+ stats socket /run/haproxy/admin.sock mode 660 level admin
4
+ stats timeout 30s
5
+ daemon
6
+
7
+ defaults
8
+ log global
9
+ mode tcp
10
+ option tcplog
11
+ timeout connect 5000
12
+ timeout client 50000
13
+ timeout server 50000
14
+
15
+ <% @services.each do |service| %>
16
+ backend <%= service[:name] %>-service
17
+ server <%= service[:name] %>-server <%= service[:ip] %>:<%= service[:tunnel_port] %>
18
+ frontend <%= service[:name] %>
19
+ bind <%= service[:ip] %>:<%= service[:local_port] %>
20
+ default_backend <%= service[:name] %>-service
21
+ <% end %>
data/lib/sambot/ui.rb CHANGED
@@ -4,15 +4,18 @@ module Sambot
4
4
  module UI
5
5
 
6
6
  def self.debug(msg)
7
- Thor.new.say("debug: #{msg}", :yellow)
7
+ date_format = DateTime.now.strftime("%Y-%m-%d %H:%M:%S")
8
+ Thor.new.say("#{date_format} [D] #{msg}", :yellow)
8
9
  end
9
10
 
10
11
  def self.info(msg)
11
- Thor.new.say(" info: #{msg}", :green)
12
+ date_format = DateTime.now.strftime("%Y-%m-%d %H:%M:%S")
13
+ Thor.new.say("#{date_format} [I] #{msg}", :green)
12
14
  end
13
15
 
14
16
  def self.error(msg)
15
- Thor.new.say("error: #{msg}", :red)
17
+ date_format = DateTime.now.strftime("%Y-%m-%d %H:%M:%S")
18
+ Thor.new.say("#{date_format} [E] #{msg}", :red)
16
19
  end
17
20
 
18
21
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sambot
4
- VERSION = '0.1.110'.freeze
4
+ VERSION = '0.1.111'.freeze
5
5
  end
data/sambot.gemspec CHANGED
@@ -31,6 +31,8 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency 'dante'
32
32
  spec.add_dependency 'net-ssh'
33
33
  spec.add_dependency 'titan'
34
+ spec.add_dependency 'open4'
35
+ spec.add_dependency 'haproxy-tools'
34
36
  spec.add_dependency 'chef', '~> 12.18'
35
37
  spec.add_dependency 'thor', '~> 0.19'
36
38
  spec.add_dependency 'erubis', '~> 2.7', '>= 2.7.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sambot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.110
4
+ version: 0.1.111
5
5
  platform: ruby
6
6
  authors:
7
7
  - Olivier Kouame
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-21 00:00:00.000000000 Z
11
+ date: 2017-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor-hollaback
@@ -178,6 +178,34 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: open4
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: haproxy-tools
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
181
209
  - !ruby/object:Gem::Dependency
182
210
  name: chef
183
211
  requirement: !ruby/object:Gem::Requirement
@@ -410,7 +438,6 @@ files:
410
438
  - ".ruby-version"
411
439
  - Gemfile
412
440
  - README.md
413
- - Rakefile
414
441
  - bin/sambot
415
442
  - bin/setup
416
443
  - lib/sambot.rb
@@ -422,19 +449,16 @@ files:
422
449
  - lib/sambot/cli.rb
423
450
  - lib/sambot/commands/base_command.rb
424
451
  - lib/sambot/commands/cookbook.rb
425
- - lib/sambot/commands/dns.rb
426
- - lib/sambot/commands/instance.rb
427
- - lib/sambot/commands/rdp.rb
428
- - lib/sambot/commands/report.rb
429
452
  - lib/sambot/commands/session.rb
430
- - lib/sambot/commands/team.rb
431
453
  - lib/sambot/commands/workstation.rb
432
454
  - lib/sambot/config.rb
433
455
  - lib/sambot/developer_workflow/brew.rb
434
456
  - lib/sambot/developer_workflow/dns.rb
435
457
  - lib/sambot/developer_workflow/networking.rb
458
+ - lib/sambot/developer_workflow/proxy.rb
436
459
  - lib/sambot/developer_workflow/session.rb
437
460
  - lib/sambot/developer_workflow/tunnel.rb
461
+ - lib/sambot/developer_workflow/tunnels.rb
438
462
  - lib/sambot/developer_workflow/vault.rb
439
463
  - lib/sambot/developer_workflow/workstation.rb
440
464
  - lib/sambot/dns/records.rb
@@ -471,6 +495,7 @@ files:
471
495
  - lib/sambot/templates/.rubocop.yml
472
496
  - lib/sambot/templates/Berksfile
473
497
  - lib/sambot/templates/chefignore
498
+ - lib/sambot/templates/haproxy.conf.erb
474
499
  - lib/sambot/templates/metadata.rb.erb
475
500
  - lib/sambot/templates/pre-push
476
501
  - lib/sambot/templates/startup-script.ps1
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task default: :spec
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'git'
4
-
5
- module Sambot
6
- module Commands
7
- class DNS < BaseCommand
8
-
9
- namespace 'dns'
10
-
11
- desc 'remove', 'Removes the given DNS entry'
12
- option :hostname, :required => true, :desc => 'The DNS name for the A record'
13
- def remove
14
- execute(:sudo) do
15
- Sambot::DNS::Repository.new.records.remove(options[:hostname])
16
- end
17
- end
18
-
19
- desc 'list', 'Shows all DNS entries'
20
- def list
21
- execute do
22
- records = Sambot::DNS::Repository.new.list_records
23
- say
24
- print_table(records)
25
- end
26
- end
27
-
28
- desc 'show', 'Shows a given DNS entry'
29
- def show
30
- rescue ApplicationError => e
31
- UI.error(e.message)
32
- end
33
-
34
- desc 'add', 'Adds or modify a DNS entry'
35
- option :address, :required => true, :desc => 'The internal IP address for the A record'
36
- option :hostname, :required => true, :desc => 'The DNS name for the A record'
37
- option :team, :desc => 'The team owning the instance pointed to. Leave blank if the hostname contains stable, patch or unstable i.e. stable-api'
38
- long_desc docs('cookbook/clean')
39
- def add
40
- execute(:sudo) { Sambot::DNS::Repository.new.records.add(options[:hostname], options[:address], options[:team]) }
41
- end
42
-
43
- end
44
- end
45
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sambot
4
- module Commands
5
-
6
- class Instance < BaseCommand
7
-
8
- namespace 'instance'
9
-
10
- desc 'generate', 'Generate a name for an instance based on the instance characteristics supplied'
11
- def generate
12
- execute {}
13
- end
14
-
15
- end
16
- end
17
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sambot
4
- module Commands
5
- class RDP < BaseCommand
6
-
7
- namespace 'rdp'
8
-
9
- desc 'config', 'Get a configuration file for Remote Desktop Manager Free'
10
- def config
11
- execute do
12
-
13
- end
14
- end
15
-
16
- end
17
- end
18
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sambot
4
- module Commands
5
- class Report < BaseCommand
6
-
7
- namespace 'report'
8
-
9
- desc 'consistency', 'Checks the build pipeline is consistent'
10
- def consistency
11
- execute {}
12
- end
13
-
14
- end
15
- end
16
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sambot
4
- module Commands
5
- class Team < BaseCommand
6
-
7
- namespace 'team'
8
-
9
- desc 'list', 'Display the names and symbols of all Advertising Studio engineering teams'
10
- def list
11
- execute {}
12
- end
13
-
14
- end
15
- end
16
- end