sambot 0.1.117 → 0.1.118

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