sambot 0.1.110 → 0.1.111

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