sambot 0.1.117 → 0.1.118

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: 5410b3c608857a6491424bf29399106cf7023930
4
- data.tar.gz: 529645ac3268d9f87102f4e0311f1368d368d4c0
3
+ metadata.gz: 1805e2336fdd906d820e5745006354a299c3fb96
4
+ data.tar.gz: 2fabdabaa84f4c002b2bb7ef835d5d13c616ae68
5
5
  SHA512:
6
- metadata.gz: 1903dee501f46a5658f80a318e957ef75919d1799e65874b1fa99037c106825a4def5f509c38afcefaca9e03669dddb9b088ba29bb78747a2531c4d13f17a7b2
7
- data.tar.gz: f1960f6ebcb4b8b699f344da6314cb6ba10446d3357f80f1bb2b2e41f224124a440d82461996b0cba451934b7f744715f81a7836057b508f28840ddbfc65277d
6
+ metadata.gz: ee012bbfc56033cd20dbdc69779722631978284e964508e35bd9799bb6fcc1965925b9802601ec5b870d677316d969870e1b6a146ed749fed9ec7bcda3c868f3
7
+ data.tar.gz: 34b7a0cfafc6be639fb5d499d9c1b7dd7843253abe889cb6fc4a01a1077b6f14d83af44b724fda0bd6abb68f7e93bbf46fec9cb02bbfca5cfcb6c120292930f7
data/bin/slackbot ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'hashie'
4
+ require 'logger'
5
+ $VERBOSE = nil
6
+ Hashie.logger = Logger.new(nil)
7
+ ENV["SLACK_API_TOKEN"] = 'xoxb-204733805091-ZiZsfVnkiwJQSVyZy3mjaDvT'
8
+
9
+ require_relative '../lib/sambot'
10
+ Sambot::Slack::GusBot.run
@@ -25,6 +25,14 @@ class Thor
25
25
  end
26
26
  end
27
27
 
28
+ class Thor
29
+ module Shell
30
+ class Color < Basic
31
+ GRAY = "\e[90m"
32
+ end
33
+ end
34
+ end
35
+
28
36
 
29
37
  class Thor
30
38
  class << self
@@ -73,11 +81,11 @@ module Sambot
73
81
  ENV['SAMBOT_DEV_USERNAME'] = UI.ask("Please provide your DEV/QE AD username: ")
74
82
  end
75
83
  if need_dev_credentials && !ENV['SAMBOT_DEV_PASSWORD']
76
- ENV['SAMBOT_DEV_USERNAME'] = UI.ask_password("Please provide your DEV/QE AD password: ")
84
+ ENV['SAMBOT_DEV_PASSWORD'] = UI.ask_password("Please provide your DEV/QE AD password: ")
77
85
  puts "\n"
78
86
  end
79
87
  if need_sudo_password && !ENV['SAMBOT_SUDO_PASSWORD']
80
- ENV['SAMBOT_DEV_USERNAME'] = UI.ask_password("Please provide your sudo password - this is required for operations such as setting up your local SSH tunnels: ")
88
+ ENV['SAMBOT_SUDO_PASSWORD'] = UI.ask_password("Please provide your sudo password - this is required for operations such as setting up your local SSH tunnels: ")
81
89
  puts "\n"
82
90
  end
83
91
  Runtime.ensure_latest
@@ -19,12 +19,20 @@ module Sambot
19
19
  end
20
20
  end
21
21
 
22
- def self.sudo(command)
22
+ def self.sudo(command, flag_errors: true)
23
+ UI.warn("Running the command `sudo -S #{command}`")
24
+ output = ''
23
25
  Open4::popen4("sudo -S #{command}") do |pid, stdin, stdout, stderr|
24
26
  stdin.puts ENV['SAMBOT_SUDO_PASSWORD']
25
27
  stdin.close
26
- stdout.read
28
+ output = stdout.read
29
+ err = stderr.read
30
+ if flag_errors && err.strip.size > 0
31
+ UI.error(err)
32
+ exit -1
33
+ end
27
34
  end
35
+ output
28
36
  end
29
37
 
30
38
  end
@@ -0,0 +1,13 @@
1
+ module Sambot
2
+ module Slack
3
+ class API
4
+
5
+ def self.connect
6
+ client_id = '3MVG99qusVZJwhsmVNpi.WqbGRUWtQC6srXMiq4QA.HjbH.jC.HsY24FyEzrtiGgfWTn7glS1Ni7P_xaUfyG3'
7
+ client_secret = '4690317352869892602'
8
+ Restforce.new(:client_id => client_id, :client_secret => client_secret, :username => 'olivier.kouame@gus.com', :password => 'Xamarin[2023]com99123')
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ require 'slack-ruby-bot'
2
+ require 'restforce'
3
+
4
+ module Sambot
5
+ module Slack
6
+ class Dispatcher
7
+
8
+ def self.backlog
9
+ api = Sambot::Slack::API.connect
10
+ work_items = Sambot::Slack::WorkItem.find_by_product_tag(api, 'AS-PE').map { |x| Formatter.format(x) }
11
+ Formatter.index + work_items
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ module Sambot
2
+ module Slack
3
+ class Formatter
4
+
5
+ COLUMNS = {
6
+ 'Blocked': {color: '#e85151', order: 1},
7
+ 'In Progress': {color: '#49d14b', order: 2},
8
+ 'Ready': {color: '#336334', order: 3},
9
+ 'Pending Prioritization': {color: '#5b7aa3', order: 4},
10
+ 'Icebox': {color: '#d1d1d1', order: 5}
11
+ }
12
+
13
+ def self.format(work_item)
14
+ {
15
+ fallback: "#{work_item.id_and_subject}",
16
+ title: "#{work_item.id_and_subject}",
17
+ text: "#{work_item.column} - #{work_item.assignee}",
18
+ color: "#{COLUMNS[work_item.column.to_sym] ? COLUMNS[work_item.column.to_sym][:color] : ''}"
19
+ }
20
+ end
21
+
22
+ def self.index
23
+ COLUMNS.keys.map do |key|
24
+ {fallback: key, title: key, color: COLUMNS[key][:color]}
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ require 'slack-ruby-bot'
2
+ require 'restforce'
3
+
4
+ module Sambot
5
+ module Slack
6
+ class GusBot < SlackRubyBot::Bot
7
+
8
+ command 'backlog' do |client, data, match|
9
+ client.web_client.chat_postMessage(channel: data.channel, attachments: Dispatcher.backlog)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module Sambot
2
+ module Slack
3
+
4
+ class ProductTag
5
+ attr_reader :id, :name
6
+
7
+ def initialize(id, name)
8
+ @id = id
9
+ @name = name
10
+ end
11
+
12
+ def self.find(client, name)
13
+ query = "SELECT Id, Name FROM ADM_Product_Tag__c WHERE Active__c = true AND Name = '#{name}'"
14
+ client.query(query).map {|x| ProductTag.new(x[:Id], x[:Name]) }[0]
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,105 @@
1
+ module Sambot
2
+ module Slack
3
+ class WorkItem
4
+
5
+ attr_reader :id, :name, :subject, :status, :product_tag
6
+
7
+ def initialize(s_object)
8
+ @s_object = s_object
9
+ end
10
+
11
+ def id; @s_object.Id; end
12
+
13
+ def name; @s_object.Name; end
14
+
15
+ def status; @s_object.Status__c; end
16
+
17
+ def product_tag; @s_object.Product_Tag__c; end
18
+
19
+ def subject; @s_object.Subject__c; end
20
+
21
+ def priority; @s_object.Priority__c; end
22
+
23
+ def product_owner; @s_object.Product_Owner__c; end
24
+
25
+ def qa_engineer; @s_object.QA_Engineer__c; end
26
+
27
+ def help_status; @s_object.Help_Status__c; end
28
+
29
+ def assignee; @s_object.Assignee__r.Name; end
30
+
31
+ def assigned_on; @s_object.Assigned_On__c; end
32
+
33
+ def last_activity_date; @s_object.LastActivityDate; end
34
+
35
+ def created_by_id; @s_object.CreatedById; end
36
+
37
+ def created_date; @s_object.CreatedDate; end
38
+
39
+ def record_type_id; @s_object.RecordTypeId; end
40
+
41
+ def owner_id; @s_object.OwnerId; end
42
+
43
+ def deleted?; @s_object.IsDeleted; end
44
+
45
+ def description; @s_object.Product_Owner__c; end
46
+
47
+ def story_points; @s_object.QA_Engineer__c; end
48
+
49
+ def closed_by; @s_object.Closed_By__c; end
50
+
51
+ def product_tag_name; @s_object.Product_Tag_Name__c; end
52
+
53
+ def epic; @s_object.Epic__c; end
54
+
55
+ def resolution; @s_object.Resolution__c; end
56
+
57
+ def column_rank; @s_object.Column_Rank__c || 0; end
58
+
59
+ def column; @s_object.Column__r ? @s_object.Column__r.Name : ''; end
60
+
61
+ def column_order
62
+ puts Formatter::COLUMNS[column.to_sym] ? Formatter::COLUMNS[column.to_sym][:order] : 100
63
+ column && Formatter::COLUMNS[column.to_sym] ? Formatter::COLUMNS[column.to_sym][:order] : 100
64
+ end
65
+
66
+ def id_and_subject; @s_object.WorkId_and_Subject__c; end
67
+
68
+ def self.find_by_product_tag(client, val)
69
+ product_tag = ProductTag.find(client, val)
70
+ query = "SELECT
71
+ Id,
72
+ Name,
73
+ Status__c,
74
+ Product_Tag__c,
75
+ Subject__c,
76
+ Priority__c,
77
+ Product_Owner__c,
78
+ QA_Engineer__c,
79
+ Help_Status__c,
80
+ Assignee__r.Name,
81
+ Assigned_On__c,
82
+ LastActivityDate,
83
+ CreatedById,
84
+ CreatedDate,
85
+ RecordTypeId,
86
+ OwnerId,
87
+ IsDeleted,
88
+ Description__c,
89
+ Story_Points__c,
90
+ Closed_By__c,
91
+ Product_Tag_Name__c,
92
+ Epic__c,
93
+ Resolution__c,
94
+ Column_Rank__c,
95
+ Column__r.Name,
96
+ WorkId_and_Subject__c
97
+ FROM ADM_Work__c \
98
+ WHERE Product_Tag__c = '#{product_tag.id}' AND (Status__c = 'New' OR Status__c = 'In Progress')"
99
+ results = client.query(query)
100
+ results.map {|x| WorkItem.new(x) }.sort_by {|x| [x.column_order, x.column_rank]}
101
+ end
102
+
103
+ end
104
+ end
105
+ end
@@ -32,3 +32,5 @@ metadata.rb
32
32
  chefignore
33
33
  teamcity.sh
34
34
  winrm_config
35
+ Vagrantfile.erb
36
+ bootstrap.sh
@@ -7,15 +7,52 @@ global
7
7
  defaults
8
8
  log global
9
9
  mode tcp
10
- option tcplog
11
10
  timeout connect 5000
12
11
  timeout client 50000
13
12
  timeout server 50000
14
13
 
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
14
+ <% @frontends.each do |x, services| %>
15
+ <% if x == 443 %>
16
+ <% services.each do |v| %>
17
+ backend <%= v[:name] %>-service
18
+ server <%= v[:name] %>-server 0.0.0.0:<%= v[:tunnel_port] %>
19
+
20
+ <% end %>
21
+ frontend ssl
22
+ bind 0.0.0.0:443
23
+ option socket-stats
24
+ tcp-request inspect-delay 5s
25
+ tcp-request content accept if { req_ssl_hello_type 1 }
26
+ <% services.each do |v| %>
27
+ use_backend <%= v[:name] %>-service if { req_ssl_sni -i <%= v[:name] %>.brighter.io }
28
+ <% end %>
29
+ <% elsif x == 8200%>
30
+ <% services.each do |v| %>
31
+ backend <%= v[:name] %>-service
32
+ server <%= v[:name] %>-server 0.0.0.0:<%= v[:tunnel_port] %>
33
+ <% end %>
34
+
35
+ frontend vault
36
+ bind 0.0.0.0:8200
37
+ option socket-stats
38
+ tcp-request inspect-delay 5s
39
+ tcp-request content accept if { req_ssl_hello_type 1 }
40
+ <% services.each do |v| %>
41
+ use_backend <%= v[:name] %>-service if { req_ssl_sni -i <%= v[:name] %>.brighter.io }
42
+ <% end %>
43
+ <% else %>
44
+ <% services.each do |v| %>
45
+ backend <%= v[:name] %>-service
46
+ server <%= v[:name] %>-server 0.0.0.0:<%= v[:tunnel_port] %>
47
+
48
+ <% end %>
49
+
50
+ frontend http
51
+ bind 0.0.0.0:80
52
+ <% services.each do |v| %>
53
+ acl host_<%= v[:name] %> hdr(host) -i <%= v[:name] %>.brighter.io
54
+ use_backend <%= v[:name] %>-service if host_<%= v[:name] %>
55
+ <% end %>
56
+ <% end %>
57
+
21
58
  <% end %>
data/lib/sambot/ui.rb CHANGED
@@ -11,9 +11,14 @@ module Sambot
11
11
  Thor.new.ask(msg, :echo => false)
12
12
  end
13
13
 
14
+ def self.warn(msg)
15
+ date_format = DateTime.now.strftime("%Y-%m-%d %H:%M:%S")
16
+ Thor.new.say("#{date_format} [W] #{msg}", :yellow)
17
+ end
18
+
14
19
  def self.debug(msg)
15
20
  date_format = DateTime.now.strftime("%Y-%m-%d %H:%M:%S")
16
- Thor.new.say("#{date_format} [D] #{msg}", :yellow)
21
+ Thor.new.say("#{date_format} [D] #{msg}", :gray)
17
22
  end
18
23
 
19
24
  def self.info(msg)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sambot
4
- VERSION = '0.1.117'.freeze
4
+ VERSION = '0.1.118'.freeze
5
5
  end
@@ -9,8 +9,8 @@ module Sambot
9
9
  def self.update_hosts(forwards, src = '/etc/hosts', dest = nil)
10
10
  UI.info('Updating your hosts file to allow access to Advertising Studio services through local SSH tunnels')
11
11
  modify_hosts(forwards, src, dest) do |entries, key, value|
12
- UI.debug("Adding hosts entry #{key} #{value[:ip]}")
13
- entries << Hosts::Entry.new(value[:ip], key)
12
+ UI.debug("Adding hosts entry #{key} 127.0.0.1")
13
+ entries << Hosts::Entry.new("127.0.0.1", key)
14
14
  end
15
15
  end
16
16
 
@@ -7,27 +7,27 @@ module Sambot
7
7
  CONFIG_PATH = '/tmp/haproxy.conf'
8
8
 
9
9
  def self.start(forwards)
10
- template_path = FileManagement::TemplateProvider.get_path('haproxy.conf.erb')
11
- input = File.read(template_path)
12
- eruby = Erubis::Eruby.new(input)
10
+ template = Sambot::Template.new('haproxy.conf.erb')
13
11
  services = forwards.map do |key, value|
12
+ name = key.to_s.split('.')[0]
13
+ UI.debug("Proxying #{name}.brighter.io:#{value[:proxy_port]} to 0.0.0.0:#{value[:tunnel_port]}")
14
14
  {
15
- name: key.to_s.split('.')[0],
16
- ip: value[:ip],
17
- tunnel_port: value[:local_port],
18
- local_port: value[:port]
15
+ name: name,
16
+ tunnel_port: value[:tunnel_port],
17
+ local_port: value[:proxy_port]
19
18
  }
20
19
  end
20
+ frontends = {}
21
+ services.map {|x| x[:local_port]}.uniq.each { |a| frontends[a] = [] }
21
22
  services.each do |service|
22
- UI.debug("Proxying #{service[:name]}.brighter.io:#{service[:local_port]} to #{service[:ip]}:#{service[:tunnel_port]}")
23
+ frontends[service[:local_port]] << service
23
24
  end
24
- contents = eruby.evaluate({services: services})
25
- File.write(CONFIG_PATH, contents)
26
- Runtime.sudo("haproxy -f #{CONFIG_PATH}")
25
+ template.write({frontends: frontends}, CONFIG_PATH)
26
+ Runtime.sudo("haproxy -f #{CONFIG_PATH}", flag_errors: true)
27
27
  end
28
28
 
29
29
  def self.stop
30
- Runtime.sudo("killall haproxy")
30
+ Runtime.sudo("killall haproxy", flag_errors: false)
31
31
  end
32
32
 
33
33
  end
@@ -19,24 +19,33 @@ module Sambot
19
19
  BASTION_HOST_IP = '146.177.10.174'
20
20
 
21
21
  FORWARDS = {
22
- 'chef.brighter.io': { ip: '127.0.0.13', port: 443, local_port: 9013 },
23
- 'teamcity.brighter.io': { ip: '127.0.0.14', port: 80, local_port: 9014 },
24
- 'splunk.brighter.io': { ip: '127.0.0.15', port: 80, local_port: 9015 },
25
- 'jenkins.brighter.io': { ip: '127.0.0.16', port: 80, local_port: 9016 },
26
- 'vault.brighter.io': { ip: '127.0.0.1', port: 8200, local_port: 9017 }
22
+ 'chef.brighter.io': {
23
+ tunnel_port: 9000, dest_port: 443, proxy_port: 443
24
+ },
25
+ 'teamcity.brighter.io': {
26
+ tunnel_port: 9001, dest_port: 8111, proxy_port: 443
27
+ },
28
+ 'splunk.brighter.io': {
29
+ tunnel_port: 9002, dest_port: 8000, proxy_port: 443
30
+ },
31
+ 'vault.brighter.io': {
32
+ tunnel_port: 9003, dest_port: 8200, proxy_port: 8200
33
+ }
27
34
  }
28
35
 
29
- def start(username, password, sudo_password)
30
- Tunnels.stop
31
- unless verify_credentials(username, password)
36
+ def start(user, pass, sudo_password)
37
+ stop
38
+ unless verify_credentials(user, pass)
32
39
  UI.error 'The session could not be started'
33
40
  exit
34
41
  end
35
42
  DNS.update_hosts(FORWARDS)
36
43
  Proxy.start(FORWARDS)
37
- Networking.configure(FORWARDS)
38
- Tunnels.start(username, password, BASTION_HOST_IP, FORWARDS)
39
- setup_secrets_management(username, password)
44
+ Runtime.sudo("ifconfig lo0 -alias 127.0.0.1")
45
+ Runtime.sudo("ifconfig lo0 alias 127.0.0.1 up")
46
+ Tunnels.start(user, pass, BASTION_HOST_IP, FORWARDS)
47
+ run_connectivity_checks()
48
+ setup_secrets_management(user, pass)
40
49
  UI.info("Your session has now started - run `sambot session stop` to close it")
41
50
  end
42
51
 
@@ -44,10 +53,24 @@ module Sambot
44
53
  Tunnels.stop
45
54
  DNS.reset_hosts(FORWARDS)
46
55
  Proxy.stop
56
+ release_ports
47
57
  end
48
58
 
49
59
  private
50
60
 
61
+ def release_ports
62
+ FORWARDS.each do |k, v|
63
+ output = Runtime.sudo("lsof -wni tcp:#{v[:tunnel_port]}", flag_errors: true)
64
+ if output.strip.size > 0
65
+ line = output.strip.lines[1]
66
+ pid = line.split[1]
67
+ UI.debug(line)
68
+ Runtime.sudo("kill -9 #{pid}")
69
+ end
70
+ end
71
+ #TODO RELEASE PROXY PORTS
72
+ end
73
+
51
74
  def verify_credentials(username, password)
52
75
  full_username = "DEV\\#{username}"
53
76
  begin
@@ -65,6 +88,10 @@ module Sambot
65
88
  return false
66
89
  end
67
90
 
91
+ def run_connectivity_checks
92
+ #TODO
93
+ end
94
+
68
95
  def setup_secrets_management(username, password)
69
96
  unless Vault.has_environment_variables?(FORWARDS)
70
97
  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")
@@ -5,9 +5,9 @@ module Sambot
5
5
  module Workflow
6
6
  class Tunnel
7
7
 
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)
8
+ def self.create(session, host, port, local_port)
9
+ UI.debug "Creating a tunnel from 0.0.0.0:#{local_port} to #{host}:#{port}"
10
+ session.forward.local("0.0.0.0", local_port, host, port)
11
11
  end
12
12
 
13
13
  end
@@ -11,7 +11,7 @@ module Sambot
11
11
 
12
12
  def self.start(username, password, bastion_host_ip, forwards)
13
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
14
+ Dante::Runner.new(SESSION_ID).execute(daemonize: true, pid_path: PID_PATH, log_path: LOG_PATH) do
15
15
  setup_ssh_tunnels(username, password, bastion_host_ip, forwards)
16
16
  end
17
17
  sleep(2)
@@ -21,7 +21,7 @@ module Sambot
21
21
  end
22
22
 
23
23
  def self.stop
24
- Dante::Runner.new(SESSION_ID).execute(:kill => true, :pid_path => PID_PATH)
24
+ Dante::Runner.new(SESSION_ID).execute(kill: true, pid_path: PID_PATH)
25
25
  UI.debug("All active sessions have been closed")
26
26
  File.delete(LOG_PATH) if File.exist?(LOG_PATH)
27
27
  end
@@ -29,8 +29,8 @@ module Sambot
29
29
  def self.setup_ssh_tunnels(username, password, bastion_host_ip, forwards)
30
30
  full_username = "DEV\\#{username}"
31
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]) }
32
+ Net::SSH.start(bastion_host_ip, full_username, password: password) do |session|
33
+ forwards.each { |key, value| Tunnel.create(session, key, value[:dest_port], value[:tunnel_port]) }
34
34
  session.loop {true}
35
35
  end
36
36
  end
@@ -27,13 +27,15 @@ module Sambot
27
27
  end
28
28
 
29
29
  def self.build_vault_address(forwards)
30
- "https://vault.brighter.io:#{forwards[:'vault.brighter.io'][:local_port]}"
30
+ "https://vault.brighter.io:#{forwards[:'vault.brighter.io'][:proxy_port]}"
31
31
  end
32
32
 
33
33
  def self.save_environment_variable(key, value, target = File.expand_path('~/.bash_profile'))
34
34
  contents = File.read(target)
35
35
  contents = contents.gsub(/export #{key}=#{value}/, '') if has_environment_variable?(key, value, target)
36
- contents << "export #{key}=#{value.to_s}\n"
36
+ new_line = "export #{key}=#{value.to_s}\n"
37
+ UI.debug("Adding `#{new_line}` to your ~/.bash_profile")
38
+ contents << new_line
37
39
  File.write(target, contents)
38
40
  ENV[key] = value.to_s
39
41
  end
data/lib/sambot.rb CHANGED
@@ -26,12 +26,18 @@ require_relative 'sambot/workflow/tunnel'
26
26
  require_relative 'sambot/workflow/tunnels'
27
27
  require_relative 'sambot/workflow/brew'
28
28
  require_relative 'sambot/workflow/proxy'
29
- require_relative 'sambot/workflow/networking'
30
29
  require_relative 'sambot/workflow/dns'
31
30
  require_relative 'sambot/workflow/session'
32
31
  require_relative 'sambot/workflow/vault'
33
32
  require_relative 'sambot/workflow/workstation'
34
33
 
34
+ require_relative 'sambot/slack/product_tag'
35
+ require_relative 'sambot/slack/work_item'
36
+ require_relative 'sambot/slack/api'
37
+ require_relative 'sambot/slack/formatter'
38
+ require_relative 'sambot/slack/gus_bot'
39
+ require_relative 'sambot/slack/dispatcher'
40
+
35
41
  require_relative 'sambot/cli'
36
42
 
37
43
  module Sambot
data/sambot.gemspec CHANGED
@@ -21,15 +21,21 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_dependency 'thor-hollaback'
23
23
  spec.add_dependency 'git'
24
+ spec.add_dependency 'slack-ruby-bot'
25
+ spec.add_dependency 'celluloid-io'
24
26
  spec.add_dependency 'process_exists'
25
27
  spec.add_dependency 'climate_control'
26
28
  spec.add_dependency 'vault'
27
29
  spec.add_dependency 'hosts'
28
30
  spec.add_dependency 'fog'
31
+ spec.add_dependency 'databasedotcom'
29
32
  spec.add_dependency 'rhcl'
33
+ spec.add_dependency 'restforce'
30
34
  spec.add_dependency 'ridley'
31
35
  spec.add_dependency 'dante'
32
36
  spec.add_dependency 'net-ssh'
37
+ spec.add_dependency 'eventmachine'
38
+ spec.add_dependency 'faye-websocket'
33
39
  spec.add_dependency 'titan'
34
40
  spec.add_dependency 'open4'
35
41
  spec.add_dependency 'haproxy-tools'
@@ -39,6 +45,7 @@ Gem::Specification.new do |spec|
39
45
  spec.add_dependency 'gems', '~> 1.0', '>= 1.0.0'
40
46
  spec.add_development_dependency 'aruba'
41
47
  spec.add_dependency 'awesome_print'
48
+ spec.add_development_dependency 'pry'
42
49
  spec.add_development_dependency 'fuubar'
43
50
  spec.add_development_dependency 'rubocop', '~> 0.49'
44
51
  spec.add_development_dependency 'gem-release', '~> 1.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.117
4
+ version: 0.1.118
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-28 00:00:00.000000000 Z
11
+ date: 2017-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor-hollaback
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: slack-ruby-bot
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: celluloid-io
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: process_exists
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +136,20 @@ dependencies:
108
136
  - - ">="
109
137
  - !ruby/object:Gem::Version
110
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: databasedotcom
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: rhcl
113
155
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +164,20 @@ dependencies:
122
164
  - - ">="
123
165
  - !ruby/object:Gem::Version
124
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: restforce
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
125
181
  - !ruby/object:Gem::Dependency
126
182
  name: ridley
127
183
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +220,34 @@ dependencies:
164
220
  - - ">="
165
221
  - !ruby/object:Gem::Version
166
222
  version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: eventmachine
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: faye-websocket
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
167
251
  - !ruby/object:Gem::Dependency
168
252
  name: titan
169
253
  requirement: !ruby/object:Gem::Requirement
@@ -302,6 +386,20 @@ dependencies:
302
386
  - - ">="
303
387
  - !ruby/object:Gem::Version
304
388
  version: '0'
389
+ - !ruby/object:Gem::Dependency
390
+ name: pry
391
+ requirement: !ruby/object:Gem::Requirement
392
+ requirements:
393
+ - - ">="
394
+ - !ruby/object:Gem::Version
395
+ version: '0'
396
+ type: :development
397
+ prerelease: false
398
+ version_requirements: !ruby/object:Gem::Requirement
399
+ requirements:
400
+ - - ">="
401
+ - !ruby/object:Gem::Version
402
+ version: '0'
305
403
  - !ruby/object:Gem::Dependency
306
404
  name: fuubar
307
405
  requirement: !ruby/object:Gem::Requirement
@@ -440,6 +538,7 @@ files:
440
538
  - README.md
441
539
  - bin/sambot
442
540
  - bin/setup
541
+ - bin/slackbot
443
542
  - lib/sambot.rb
444
543
  - lib/sambot/application_error.rb
445
544
  - lib/sambot/chef/cookbook.rb
@@ -468,6 +567,12 @@ files:
468
567
  - lib/sambot/rackspace/images.rb
469
568
  - lib/sambot/rackspace/instances.rb
470
569
  - lib/sambot/runtime.rb
570
+ - lib/sambot/slack/api.rb
571
+ - lib/sambot/slack/dispatcher.rb
572
+ - lib/sambot/slack/formatter.rb
573
+ - lib/sambot/slack/gus_bot.rb
574
+ - lib/sambot/slack/product_tag.rb
575
+ - lib/sambot/slack/work_item.rb
471
576
  - lib/sambot/template.rb
472
577
  - lib/sambot/templates/.config.yml.erb
473
578
  - lib/sambot/templates/.gitignore.sample
@@ -490,7 +595,6 @@ files:
490
595
  - lib/sambot/version.rb
491
596
  - lib/sambot/workflow/brew.rb
492
597
  - lib/sambot/workflow/dns.rb
493
- - lib/sambot/workflow/networking.rb
494
598
  - lib/sambot/workflow/proxy.rb
495
599
  - lib/sambot/workflow/session.rb
496
600
  - lib/sambot/workflow/tunnel.rb
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'socket'
3
-
4
- module Sambot
5
- module Workflow
6
- class Networking
7
-
8
- attr_reader :local_addresses
9
-
10
- def self.local_addresses
11
- return @local_addresses if @local_addresses
12
- addr_infos = Socket.getifaddrs
13
- @local_addresses = []
14
- addr_infos.each do |addr_info|
15
- if addr_info.addr && addr_info.name == 'lo0' && addr_info.addr.ipv4?
16
- @local_addresses << addr_info.addr.ip_address
17
- end
18
- end
19
- @local_addresses
20
- end
21
-
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")
31
- end
32
- end
33
-
34
- end
35
- end
36
- end