sambot 0.1.175 → 0.1.176
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 +4 -4
- data/lib/sambot/chef/cookbook.rb +7 -10
- data/lib/sambot/chef/kitchen.rb +6 -6
- data/lib/sambot/templates/Vagrantfile.erb +1 -1
- data/lib/sambot/templates/bootstrap_scripts/local/sidecar_vault/bootstrap.sh.erb +23 -27
- data/lib/sambot/templates/test_kitchen/local.yml.erb +4 -1
- data/lib/sambot/version.rb +1 -1
- data/lib/sambot.rb +0 -9
- metadata +1 -15
- data/lib/sambot/rackspace/client.rb +0 -41
- data/lib/sambot/rackspace/flavors.rb +0 -19
- data/lib/sambot/rackspace/images.rb +0 -27
- data/lib/sambot/rackspace/instances.rb +0 -86
- data/lib/sambot/slack/api.rb +0 -13
- data/lib/sambot/slack/dispatcher.rb +0 -16
- data/lib/sambot/slack/formatter.rb +0 -30
- data/lib/sambot/slack/gus_bot.rb +0 -14
- data/lib/sambot/slack/product_tag.rb +0 -19
- data/lib/sambot/slack/work_item.rb +0 -105
- data/lib/sambot/templates/consul_helper.rb +0 -0
- data/lib/sambot/workflow/brew.rb +0 -46
- data/lib/sambot/workflow/vault.rb +0 -60
- data/lib/sambot/workflow/workstation.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eab59e5f0e0b8c2ad376fce691f5a5648a86d661
|
4
|
+
data.tar.gz: 034017c58ab37062840f06fcea9fcbaad5162630
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ef1cdc040babdc5e217561b7fc4e559526f354f6cfc73243c5efadfad09834b8a4efcfc77ece4c2cdc0d55810f06e1733be546f6328c82ec19de2df3347ef1c
|
7
|
+
data.tar.gz: f8fd14fd310eb21a9b47e0a6026c29709c09bd14d92ff92690bdf673258a922f8b6eeec259daa81d5262a375dde459454b1302956ca8e34911ef7918f0dc55d2
|
data/lib/sambot/chef/cookbook.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'yaml'
|
4
|
-
require 'git'
|
5
4
|
|
6
5
|
module Sambot
|
7
6
|
module Chef
|
@@ -20,9 +19,9 @@ module Sambot
|
|
20
19
|
class << self
|
21
20
|
|
22
21
|
def build(config, cloud, vault_setup = nil)
|
23
|
-
create_files(config)
|
22
|
+
create_files(config, true)
|
24
23
|
Generator.from_templates(config, cloud, vault_setup, GENERATED_FILES)
|
25
|
-
Kitchen.setup(cloud, config)
|
24
|
+
Kitchen.setup(cloud, config, vault_setup)
|
26
25
|
Metadata.generate(config)
|
27
26
|
Hooks.copy()
|
28
27
|
UI.info('The cookbook has been successfully built.')
|
@@ -45,6 +44,7 @@ module Sambot
|
|
45
44
|
end
|
46
45
|
|
47
46
|
def create(config)
|
47
|
+
require 'git'
|
48
48
|
Git.init(config.name)
|
49
49
|
Dir.chdir(config.name) do
|
50
50
|
create_files(config)
|
@@ -54,17 +54,14 @@ module Sambot
|
|
54
54
|
|
55
55
|
private
|
56
56
|
|
57
|
-
def create_files(config)
|
57
|
+
def create_files(config, build_phase = false)
|
58
58
|
['.vault.yml', '.consul.yml', 'README.md'].each { |resource| FS.copy(resource) unless FS.exist?(resource) }
|
59
59
|
['spec', 'test', 'attributes', 'vault'].each { |resource| FS.mkdir(resource) unless FS.exist?(resource) }
|
60
|
-
Dir.chdir('attributes') { FileUtils.touch('default.rb') }
|
61
|
-
Dir.chdir('spec') { FS.copy('spec_helper.rb') unless FS.exist?('spec_helper.rb') }
|
60
|
+
Dir.chdir('attributes') { FileUtils.touch('default.rb') unless build_phase }
|
61
|
+
Dir.chdir('spec') { FS.copy('spec_helper.rb') unless FS.exist?('spec_helper.rb') unless build_phase }
|
62
62
|
['recipes', 'libraries', 'resources', 'files', 'templates'].each { |target| FS.mkdir(target) unless FS.exist?(target) }
|
63
63
|
Dir.chdir('recipes') do
|
64
|
-
|
65
|
-
FileUtils.touch('install.rb') unless FS.exist?('install.rb')
|
66
|
-
FileUtils.touch('configure.rb') unless FS.exist?('configure.rb')
|
67
|
-
FileUtils.touch('default.rb') unless FS.exist?('default.rb')
|
64
|
+
FileUtils.touch('default.rb') unless FS.exist?('default.rb') && !build_phase
|
68
65
|
end
|
69
66
|
unless FS.exist?('.config.yml')
|
70
67
|
Template.new('.config.yml.erb').write({config: config}, '.config.yml')
|
data/lib/sambot/chef/kitchen.rb
CHANGED
@@ -8,8 +8,8 @@ module Sambot
|
|
8
8
|
|
9
9
|
GENERATED_FILE = '.kitchen.yml'
|
10
10
|
|
11
|
-
def setup(cloud, config)
|
12
|
-
contents = generate_yml(cloud, config.name, config.available_platforms, config.suites)
|
11
|
+
def setup(cloud, config, vault_setup)
|
12
|
+
contents = generate_yml(cloud, config.name, config.available_platforms, config.suites, vault_setup)
|
13
13
|
File.write(GENERATED_FILE, contents)
|
14
14
|
UI.debug("#{GENERATED_FILE} has been added to the cookbook.")
|
15
15
|
end
|
@@ -18,10 +18,10 @@ module Sambot
|
|
18
18
|
FS.delete(GENERATED_FILE)
|
19
19
|
end
|
20
20
|
|
21
|
-
def generate_yml(cloud, cookbook_name, platforms, suites = nil)
|
21
|
+
def generate_yml(cloud, cookbook_name, platforms, suites = nil, vault_setup = nil)
|
22
22
|
raise ApplicationError, 'Missing platforms when trying to generate Test-Kitchen YAML.' unless platforms
|
23
23
|
raise ApplicationError, 'Missing cookbook name when trying to generate Test-Kitchen YAML.' unless cookbook_name
|
24
|
-
template = read_template(cloud, cookbook_name, platforms)
|
24
|
+
template = read_template(cloud, cookbook_name, platforms, vault_setup)
|
25
25
|
if suites
|
26
26
|
template['suites'] = Marshal.load(Marshal.dump(suites))
|
27
27
|
add_platform_identifier(template, cloud)
|
@@ -57,8 +57,8 @@ module Sambot
|
|
57
57
|
platform == 'local' ? runlist['local'] : runlist['dev']
|
58
58
|
end
|
59
59
|
|
60
|
-
def read_template(cloud, cookbook_name, platforms)
|
61
|
-
ctx = {platforms: platforms, name: cookbook_name}
|
60
|
+
def read_template(cloud, cookbook_name, platforms, vault_setup)
|
61
|
+
ctx = {platforms: platforms, name: cookbook_name, vault_setup: vault_setup}
|
62
62
|
result = Template.new("test_kitchen/#{cloud}.yml.erb").evaluate(ctx, {:pattern => '<!--% %-->'})
|
63
63
|
YAML.load(result)
|
64
64
|
end
|
@@ -1,30 +1,35 @@
|
|
1
1
|
#!/bin/bash -e
|
2
2
|
|
3
|
-
|
3
|
+
echo "Install required tools"
|
4
|
+
sudo yum install -y unzip wget epel-release zlib-devel bzip2 openssl-devel libyaml-devel libffi-devel readline-devel gdbm-devel ncurses-devel gcc gcc-c++ make
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
echo "Download and install Hashicorp Vault"
|
7
|
+
if [ ! -f /usr/bin/vault ]; then
|
8
|
+
curl --fail -sSO "https://releases.hashicorp.com/vault/0.6.5/vault_0.6.5_linux_amd64.zip" > /dev/null 2>&1
|
9
|
+
unzip vault_0.6.5_linux_amd64.zip -d /usr/bin;
|
10
|
+
fi
|
11
|
+
if [ ! -d "/etc/vault" ]; then sudo mkdir /etc/vault; fi
|
7
12
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
13
|
+
echo "Download and install Hashicorp Consul"
|
14
|
+
if [ ! -f /usr/bin/consul ]; then
|
15
|
+
curl --fail -sSO "https://releases.hashicorp.com/consul/0.8.5/consul_0.8.5_linux_amd64.zip" > /dev/null 2>&1
|
16
|
+
unzip consul_0.8.5_linux_amd64.zip -d /usr/bin;
|
17
|
+
fi
|
18
|
+
if [ ! -d "/etc/consul" ]; then sudo mkdir /etc/consul; fi
|
12
19
|
|
13
|
-
|
14
|
-
wget "https://releases.hashicorp.com/consul/0.8.5/consul_0.8.5_linux_amd64.zip"
|
15
|
-
unzip consul_0.8.5_linux_amd64.zip -d /usr/bin
|
16
|
-
sudo mkdir /etc/consul
|
20
|
+
########## Everything above this line is pre-installed on the 'adstudio-centos-provisioned-v*' box ############
|
17
21
|
|
18
|
-
|
19
|
-
consul -dev -server -bootstrap
|
22
|
+
echo "Launch the Consul Agent in Development mode"
|
23
|
+
consul agent -dev -server -bootstrap < /dev/null &> /dev/null &
|
20
24
|
|
21
|
-
|
25
|
+
echo "Launch the Vault Server in Development mode"
|
22
26
|
export VAULT_ADDR="http://127.0.0.1:8200"
|
23
27
|
export VAULT_TOKEN="root"
|
24
28
|
vault server -dev -dev-root-token-id=${VAULT_TOKEN} -dev-listen-address=0.0.0.0:8200 < /dev/null &> /dev/null &
|
29
|
+
sleep 5
|
25
30
|
vault mount -path=dev generic
|
26
31
|
|
27
|
-
|
32
|
+
echo "Create the addressing file so that Chef and other applications can access the Vault server"
|
28
33
|
cat << EOF > /etc/vault/tokens.json
|
29
34
|
{
|
30
35
|
"vault-addr": "${VAULT_ADDR}",
|
@@ -34,16 +39,7 @@ cat << EOF > /etc/vault/tokens.json
|
|
34
39
|
}
|
35
40
|
EOF
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
sudo yum install rh-ruby22
|
40
|
-
scl enable rh-ruby22 bash
|
41
|
-
sudo yum groupinstall Development tools -y
|
42
|
-
sudo yum install rh-ruby22-ruby-devel zlib-devel -y
|
43
|
-
|
44
|
-
## Install Sambot
|
45
|
-
gem install sambot
|
46
|
-
|
47
|
-
## Populate Vault
|
42
|
+
echo "Populate Vault with test secrets using the Chef embedded Ruby"
|
43
|
+
/opt/chef/embedded/bin/gem install sambot --no-ri --no-doc
|
48
44
|
cd /vagrant
|
49
|
-
sambot populate --vault
|
45
|
+
/opt/chef/embedded/bin/sambot populate --vault
|
@@ -17,7 +17,10 @@ platforms:
|
|
17
17
|
<!--% if @platforms.include?('centos') %-->
|
18
18
|
- name: centos-7.2
|
19
19
|
driver:
|
20
|
-
|
20
|
+
<!--% if @vault_setup == 'sidecar' %-->
|
21
|
+
box: adstudio/centos-provisioned-v5
|
22
|
+
<!--% end %-->
|
23
|
+
network:
|
21
24
|
- ["private_network", {ip: "192.168.255.10"}]
|
22
25
|
<!--% end %-->
|
23
26
|
<!--% if @platforms.include?('windows') %-->
|
data/lib/sambot/version.rb
CHANGED
data/lib/sambot.rb
CHANGED
@@ -18,15 +18,6 @@ require_relative 'sambot/chef/cookbook'
|
|
18
18
|
require_relative 'sambot/chef/server'
|
19
19
|
require_relative 'sambot/chef/generator'
|
20
20
|
|
21
|
-
require_relative 'sambot/rackspace/client'
|
22
|
-
require_relative 'sambot/rackspace/flavors'
|
23
|
-
require_relative 'sambot/rackspace/images'
|
24
|
-
require_relative 'sambot/rackspace/instances'
|
25
|
-
|
26
|
-
require_relative 'sambot/workflow/brew'
|
27
|
-
require_relative 'sambot/workflow/vault'
|
28
|
-
require_relative 'sambot/workflow/workstation'
|
29
|
-
|
30
21
|
require_relative 'sambot/cli'
|
31
22
|
|
32
23
|
module Sambot
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sambot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.176
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Olivier Kouame
|
@@ -444,17 +444,7 @@ files:
|
|
444
444
|
- lib/sambot/docs/create.txt
|
445
445
|
- lib/sambot/docs/version.txt
|
446
446
|
- lib/sambot/fs.rb
|
447
|
-
- lib/sambot/rackspace/client.rb
|
448
|
-
- lib/sambot/rackspace/flavors.rb
|
449
|
-
- lib/sambot/rackspace/images.rb
|
450
|
-
- lib/sambot/rackspace/instances.rb
|
451
447
|
- lib/sambot/runtime.rb
|
452
|
-
- lib/sambot/slack/api.rb
|
453
|
-
- lib/sambot/slack/dispatcher.rb
|
454
|
-
- lib/sambot/slack/formatter.rb
|
455
|
-
- lib/sambot/slack/gus_bot.rb
|
456
|
-
- lib/sambot/slack/product_tag.rb
|
457
|
-
- lib/sambot/slack/work_item.rb
|
458
448
|
- lib/sambot/template.rb
|
459
449
|
- lib/sambot/templates/.config.yml.erb
|
460
450
|
- lib/sambot/templates/.consul.yml
|
@@ -471,7 +461,6 @@ files:
|
|
471
461
|
- lib/sambot/templates/bootstrap_scripts/local/standalone_vault/bootstrap.ps1.erb
|
472
462
|
- lib/sambot/templates/bootstrap_scripts/local/standalone_vault/bootstrap.sh.erb
|
473
463
|
- lib/sambot/templates/chefignore
|
474
|
-
- lib/sambot/templates/consul_helper.rb
|
475
464
|
- lib/sambot/templates/git_hooks/pre-commit
|
476
465
|
- lib/sambot/templates/git_hooks/pre-push
|
477
466
|
- lib/sambot/templates/metadata.rb.erb
|
@@ -486,9 +475,6 @@ files:
|
|
486
475
|
- lib/sambot/testing/vault_helper.rb
|
487
476
|
- lib/sambot/ui.rb
|
488
477
|
- lib/sambot/version.rb
|
489
|
-
- lib/sambot/workflow/brew.rb
|
490
|
-
- lib/sambot/workflow/vault.rb
|
491
|
-
- lib/sambot/workflow/workstation.rb
|
492
478
|
- sambot.gemspec
|
493
479
|
homepage: http://github.com/okouam/sambot
|
494
480
|
licenses:
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'flavors'
|
4
|
-
require_relative 'instances'
|
5
|
-
require_relative 'images'
|
6
|
-
|
7
|
-
module Sambot
|
8
|
-
module Rackspace
|
9
|
-
class Client
|
10
|
-
|
11
|
-
RACKSPACE_ACCOUNTS = [
|
12
|
-
{ api_key: -> { ENV['ADVERTISING1_API_KEY'] }, id: 'advertising1' },
|
13
|
-
{ api_key: -> { ENV['SAMTAYLOR_API_KEY'] }, id: 'samtaylor' }
|
14
|
-
]
|
15
|
-
|
16
|
-
def initialize(api_key = RACKSPACE_ACCOUNTS[0][:api_key], account_id = RACKSPACE_ACCOUNTS[0][:id])
|
17
|
-
options = {
|
18
|
-
provider: 'Rackspace',
|
19
|
-
rackspace_api_key: api_key.call,
|
20
|
-
rackspace_username: account_id,
|
21
|
-
rackspace_region: 'LON'
|
22
|
-
}
|
23
|
-
options[:connection_options] = { proxy: ENV['FIXIE_URL'] } if ENV['FIXIE_URL']
|
24
|
-
Fog::Compute.new(options)
|
25
|
-
end
|
26
|
-
|
27
|
-
def instances
|
28
|
-
@instances ||= Instances.new(self)
|
29
|
-
end
|
30
|
-
|
31
|
-
def flavors
|
32
|
-
@flavors ||= Flavors.new(self)
|
33
|
-
end
|
34
|
-
|
35
|
-
def images
|
36
|
-
@images ||= Images.new(self)
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module Sambot
|
2
|
-
module Rackspace
|
3
|
-
class Flavors
|
4
|
-
|
5
|
-
def initialize(client)
|
6
|
-
@client = client
|
7
|
-
end
|
8
|
-
|
9
|
-
def all
|
10
|
-
@client.flavors.all.map { |flavor| { name: flavor.name, value: flavor.id } }.compact
|
11
|
-
end
|
12
|
-
|
13
|
-
def available
|
14
|
-
all.find_all { |x| x[:name] =~ /Standard/ }
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Sambot
|
4
|
-
module Rackspace
|
5
|
-
class Images
|
6
|
-
|
7
|
-
def initialize(client)
|
8
|
-
@client = client
|
9
|
-
end
|
10
|
-
|
11
|
-
def all
|
12
|
-
@client.images.all.map { |image| { name: image.name, value: image.id } }.compact
|
13
|
-
end
|
14
|
-
|
15
|
-
def available
|
16
|
-
all.find_all { |x| x[:name] =~ /AS/ }
|
17
|
-
end
|
18
|
-
|
19
|
-
def find_platform_by_image_id(id)
|
20
|
-
available_images = all
|
21
|
-
image = available_images.find { |x| x[:value] == id }
|
22
|
-
image[:name].match(/Linux/) ? 'L' : 'W'
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Sambot
|
4
|
-
module Rackspace
|
5
|
-
class Instances
|
6
|
-
|
7
|
-
def all(extended = false)
|
8
|
-
result = []
|
9
|
-
RACKSPACE_ACCOUNTS.each do |account|
|
10
|
-
api = Client.new(account[:api_key], account[:id])
|
11
|
-
api.servers.all.map do |server|
|
12
|
-
name = server.name
|
13
|
-
ip = server.addresses['private'].last['addr']
|
14
|
-
if extended
|
15
|
-
result << { name: name, value: ip, id: server.id }
|
16
|
-
else
|
17
|
-
result << { name: name, value: ip }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
result.flatten
|
22
|
-
end
|
23
|
-
|
24
|
-
def belonging_to(team)
|
25
|
-
results = self.all
|
26
|
-
team_initials = team.downcase
|
27
|
-
results.select do |instance|
|
28
|
-
instance_name = instance[:name].downcase
|
29
|
-
if team_initials == 'nw'
|
30
|
-
instance_name.start_with?(team_initials) || instance_name.start_with?('dev')
|
31
|
-
else
|
32
|
-
instance_name.start_with?(team_initials)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def find_next_index(team, role)
|
38
|
-
raise 'No team name was provided. It should be the short form of the team i.e. NW or AVG.' unless team
|
39
|
-
raise 'No cookbook name was provided. It needs to be a role cookbook.' unless role
|
40
|
-
team_instances = self.all.find_all { |x| x[:name] =~ /#{team}-#{role}/i }
|
41
|
-
return '01' if team_instances.size < 1
|
42
|
-
similar_instances = team_instances.map { |x| x[:name].upcase.gsub("#{team}-#{role}".upcase, '').gsub(/^\-/, '') }
|
43
|
-
current_index = similar_instances.map { |x| x.match(/(.+)-(.+)/)[1].to_i }.sort[-1] + 1
|
44
|
-
current_index.to_s.rjust(2, '0')
|
45
|
-
end
|
46
|
-
|
47
|
-
def as_rundeck_nodes
|
48
|
-
result = []
|
49
|
-
images = Images.all
|
50
|
-
flavors = Flavors.all
|
51
|
-
RACKSPACE_ACCOUNTS.each do |account|
|
52
|
-
api = Rackspace.connect(account[:api_key], account[:id])
|
53
|
-
api.servers.all.map do |server|
|
54
|
-
flavor = flavors.detect { |x| x[:value] == server.flavor_id }
|
55
|
-
image = images.detect { |x| x[:value] == server.image_id }
|
56
|
-
image_name = image ? image[:name] : 'unknown'
|
57
|
-
team = Teams.find_from_instance_name(server.name)
|
58
|
-
result << {
|
59
|
-
name: server.name,
|
60
|
-
team: team ? Teams.all.find { |x| x[:value] == team }[:name] : 'Night Watch',
|
61
|
-
os: find_os(server.name),
|
62
|
-
hostname: server.addresses['private'].last['addr'],
|
63
|
-
created: server.created,
|
64
|
-
state: server.state,
|
65
|
-
role: 'none',
|
66
|
-
flavor: flavor ? flavor[:name] : 'unknown',
|
67
|
-
image: image_name
|
68
|
-
}
|
69
|
-
end
|
70
|
-
end
|
71
|
-
result.flatten
|
72
|
-
end
|
73
|
-
|
74
|
-
def by_name(name)
|
75
|
-
instances = all(true)
|
76
|
-
x = instances.select { |y| y[:name].upcase == name.upcase }
|
77
|
-
x.size == 1 ? x[0][:id] : nil
|
78
|
-
end
|
79
|
-
|
80
|
-
def find_os(name)
|
81
|
-
name =~ /\-L\d+$/ ? 'Linux' : 'Windows'
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/lib/sambot/slack/api.rb
DELETED
@@ -1,13 +0,0 @@
|
|
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
|
@@ -1,16 +0,0 @@
|
|
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
|
@@ -1,30 +0,0 @@
|
|
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
|
data/lib/sambot/slack/gus_bot.rb
DELETED
@@ -1,14 +0,0 @@
|
|
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
|
@@ -1,19 +0,0 @@
|
|
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
|
@@ -1,105 +0,0 @@
|
|
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
|
File without changes
|
data/lib/sambot/workflow/brew.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Sambot
|
4
|
-
module Workflow
|
5
|
-
class Brew
|
6
|
-
|
7
|
-
def configure
|
8
|
-
UI.debug("Updating Homebrew formulas and casks")
|
9
|
-
update
|
10
|
-
tap('caskroom/cask')
|
11
|
-
update
|
12
|
-
end
|
13
|
-
|
14
|
-
def update
|
15
|
-
Bundler.with_clean_env do
|
16
|
-
`brew update`
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def tap(name)
|
21
|
-
Bundler.with_clean_env do
|
22
|
-
`brew tap #{name}`
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
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
|
33
|
-
end
|
34
|
-
|
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
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'vault'
|
4
|
-
require 'open4'
|
5
|
-
|
6
|
-
module Sambot
|
7
|
-
module Workflow
|
8
|
-
class Vault
|
9
|
-
|
10
|
-
def self.authenticate(username, password, forwards)
|
11
|
-
secret = get_user_token(username, password, forwards)
|
12
|
-
secret.auth.client_token
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.get_user_token(username, password, forwards)
|
16
|
-
::Vault.configure do |config|
|
17
|
-
sleep(3)
|
18
|
-
config.address = build_vault_address(forwards)
|
19
|
-
config.ssl_verify = false
|
20
|
-
return ::Vault.auth.ldap(username, password)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.setup_environment(forwards, target = File.expand_path('~/.zshrc'))
|
25
|
-
save_environment_variable('VAULT_SKIP_VERIFY', true, target)
|
26
|
-
save_environment_variable('VAULT_ADDR', build_vault_address(forwards), target)
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.build_vault_address(forwards)
|
30
|
-
"https://vault.brighter.io:#{forwards[:'vault.brighter.io'][:proxy_port]}"
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.save_environment_variable(key, value, target = File.expand_path('~/.zshrc'))
|
34
|
-
contents = File.read(target)
|
35
|
-
contents = contents.gsub(/export #{key}=#{value}/, '') if has_environment_variable?(key, value, target)
|
36
|
-
new_line = "export #{key}=#{value.to_s}\n"
|
37
|
-
UI.debug("Adding `#{new_line}` to your ~/.zshrc")
|
38
|
-
contents << new_line
|
39
|
-
File.write(target, contents)
|
40
|
-
ENV[key] = value.to_s
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.has_environment_variables?(forwards, target = File.expand_path('~/.zshrc'))
|
44
|
-
has_vault_skip_verify = has_environment_variable?('VAULT_SKIP_VERIFY', true, target)
|
45
|
-
has_vault_addr = has_environment_variable?('VAULT_ADDR', build_vault_address(forwards), target)
|
46
|
-
(has_vault_addr != nil) && (has_vault_skip_verify != nil)
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.has_environment_variable?(key, value, target = File.expand_path('~/.zshrc'))
|
50
|
-
contents = File.read(target)
|
51
|
-
contents.match(/export #{key}=#{value}/)
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.save_token(token, home_directory = File.expand_path('~'))
|
55
|
-
File.write(File.expand_path(File.join(home_directory, '.vault-token')), token)
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'bundler'
|
4
|
-
|
5
|
-
module Sambot
|
6
|
-
module Workflow
|
7
|
-
class Workstation
|
8
|
-
|
9
|
-
FORMULAS = {
|
10
|
-
'git': 'git',
|
11
|
-
'vault': 'vault',
|
12
|
-
'ruby-build': 'ruby-build',
|
13
|
-
'rbenv': 'rbenv'
|
14
|
-
}
|
15
|
-
|
16
|
-
CASKS = {
|
17
|
-
'virtualbox': 'virtualbox',
|
18
|
-
'vagrant': 'vagrant',
|
19
|
-
'chefdk': 'chef'
|
20
|
-
}
|
21
|
-
|
22
|
-
XCODE_INSTALLATION_SCRIPT = 'xcode-select --install'
|
23
|
-
|
24
|
-
def self.configure(username)
|
25
|
-
update_environment_variables
|
26
|
-
install_native_binaries
|
27
|
-
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')
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.install_native_binaries
|
31
|
-
if `xcode-select version`
|
32
|
-
UI.info("Not installing XCode Developer Tools as they are already present")
|
33
|
-
else
|
34
|
-
system(XCODE_INSTALLATION_SCRIPT)
|
35
|
-
end
|
36
|
-
brew = Brew.new
|
37
|
-
brew.configure
|
38
|
-
install_formulas(brew)
|
39
|
-
install_casks(brew)
|
40
|
-
update_ruby
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.install_casks(brew)
|
44
|
-
CASKS.each do |formula, binary|
|
45
|
-
brew.install_cask(formula, binary)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.install_formulas(brew)
|
50
|
-
FORMULAS.each do |formula, binary|
|
51
|
-
brew.install_formula(formula, binary)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.update_environment_variables
|
56
|
-
UI.debug('Updating your Vault environment variables')
|
57
|
-
Vault.setup_environment(Session::FORWARDS)
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.update_ruby
|
61
|
-
profile = File.read(File.expand_path("~/.bash_profile"))
|
62
|
-
`echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile` unless /rbenv init/.match(profile)
|
63
|
-
current_ruby = `ruby -v`
|
64
|
-
if /ruby 2\.4/.match(current_ruby)
|
65
|
-
UI.info("Ruby 2.4.0 is already installed")
|
66
|
-
else
|
67
|
-
UI.info("Installing Ruby 2.4.0")
|
68
|
-
`rbenv install 2.4.0`
|
69
|
-
`rbenv global 2.4.0`
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|