sambot 0.1.158 → 0.1.159
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.rb +1 -0
- data/lib/sambot/base_command.rb +1 -24
- data/lib/sambot/chef/cookbook.rb +32 -54
- data/lib/sambot/chef/generator.rb +28 -38
- data/lib/sambot/chef/hooks.rb +4 -2
- data/lib/sambot/chef/kitchen.rb +33 -42
- data/lib/sambot/chef/metadata.rb +14 -14
- data/lib/sambot/cli.rb +22 -19
- data/lib/sambot/config.rb +59 -4
- data/lib/sambot/docs/bump.txt +1 -0
- data/lib/sambot/docs/{generate.txt → create.txt} +0 -0
- data/lib/sambot/fs.rb +33 -0
- data/lib/sambot/runtime.rb +13 -29
- data/lib/sambot/template.rb +22 -1
- data/lib/sambot/templates/.config.yml.erb +7 -7
- data/lib/sambot/{docs/configure.txt → templates/.consul.yml} +0 -0
- data/lib/sambot/templates/.vault.yml +0 -0
- data/lib/sambot/templates/README.md +0 -0
- data/lib/sambot/templates/Vagrantfile.erb +7 -5
- data/lib/sambot/templates/attributes/default.rb +0 -0
- data/lib/sambot/templates/{gcp_bootstrap.ps1.erb → bootstrap_scripts/google/bootstrap.ps1.erb} +0 -0
- data/lib/sambot/templates/{gcp_bootstrap.sh.erb → bootstrap_scripts/google/bootstrap.sh.erb} +0 -1
- data/lib/sambot/templates/bootstrap_scripts/local/sidecar_vault/bootstrap.ps1.erb +33 -0
- data/lib/sambot/templates/bootstrap_scripts/local/sidecar_vault/bootstrap.sh.erb +34 -0
- data/lib/sambot/templates/{local_bootstrap.ps1 → bootstrap_scripts/local/standalone_vault/bootstrap.ps1.erb} +0 -0
- data/lib/sambot/templates/{local_bootstrap.sh → bootstrap_scripts/local/standalone_vault/bootstrap.sh.erb} +0 -0
- data/lib/sambot/templates/{pre-commit → git_hooks/pre-commit} +0 -0
- data/lib/sambot/templates/{pre-push → git_hooks/pre-push} +0 -0
- data/lib/sambot/templates/local/vault/helper.rb +11 -0
- data/lib/sambot/templates/recipes/configure.rb.erb +0 -0
- data/lib/sambot/templates/recipes/default.rb.erb +0 -0
- data/lib/sambot/templates/recipes/install.rb.erb +0 -0
- data/lib/sambot/templates/spec/spec_helper.rb +2 -0
- data/lib/sambot/templates/test/default_test.rb +0 -0
- data/lib/sambot/templates/{.kitchen.gcp.yml.erb → test_kitchen/google.yml.erb} +0 -0
- data/lib/sambot/templates/{.kitchen.yml.erb → test_kitchen/local.yml.erb} +2 -2
- data/lib/sambot/templates/{.kitchen.rackspace.yml.erb → test_kitchen/rackspace.yml.erb} +5 -5
- data/lib/sambot/ui.rb +12 -6
- data/lib/sambot/version.rb +1 -1
- metadata +26 -17
- data/lib/sambot/commands/cookbook_cmd.rb +0 -44
- data/lib/sambot/docs/start.txt +0 -21
- data/lib/sambot/docs/stop.txt +0 -7
- data/lib/sambot/workflow/dns.rb +0 -43
data/lib/sambot/config.rb
CHANGED
@@ -8,7 +8,7 @@ module Sambot
|
|
8
8
|
|
9
9
|
CONFIGURATION_FILENAME = '.config.yml'.freeze
|
10
10
|
|
11
|
-
def bump_version(path = nil)
|
11
|
+
def self.bump_version(path = nil)
|
12
12
|
path ||= File.join(Dir.getwd, CONFIGURATION_FILENAME)
|
13
13
|
config = YAML.load_file(path)
|
14
14
|
version = config['version']
|
@@ -17,7 +17,11 @@ module Sambot
|
|
17
17
|
config['version']
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
20
|
+
def initialize(opts)
|
21
|
+
@opts = opts
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.read(path = nil)
|
21
25
|
path ||= File.join(Dir.getwd, CONFIGURATION_FILENAME)
|
22
26
|
raise ApplicationError, "The configuration file was not found at #{path}." unless File.exist?(path)
|
23
27
|
config = YAML.load_file(path)
|
@@ -33,12 +37,63 @@ module Sambot
|
|
33
37
|
end
|
34
38
|
config['platforms'] = config['platform']
|
35
39
|
end
|
36
|
-
config
|
40
|
+
Config.new(config)
|
41
|
+
end
|
42
|
+
|
43
|
+
def available_platforms
|
44
|
+
platforms = @opts[:platforms] if @opts.has_key?(:platforms)
|
45
|
+
platforms = @opts['platforms'] if @opts.has_key?('platforms')
|
46
|
+
platforms
|
47
|
+
end
|
48
|
+
|
49
|
+
def gems
|
50
|
+
@opts['gems'] || @opts[:gems] || []
|
51
|
+
end
|
52
|
+
|
53
|
+
def dependencies
|
54
|
+
items = @opts['dependencies'] || @opts[:dependencies]
|
55
|
+
items ? items.map { |x| transform_hashes(x) } : []
|
56
|
+
end
|
57
|
+
|
58
|
+
def dependencies=(value)
|
59
|
+
@opts['dependencies'] = @opts[:dependencies] = value
|
60
|
+
end
|
61
|
+
|
62
|
+
def transform_hashes(obj)
|
63
|
+
obj.is_a?(Hash) ? "#{obj.keys.first}', '#{obj.values.first}" : obj
|
64
|
+
end
|
65
|
+
|
66
|
+
def description
|
67
|
+
@opts['description'] || @opts[:description]
|
68
|
+
end
|
69
|
+
|
70
|
+
def identifier
|
71
|
+
@opts['identifier'] || @opts[:identifier]
|
72
|
+
end
|
73
|
+
|
74
|
+
def suites
|
75
|
+
@opts['suites'] || @opts[:suites]
|
76
|
+
end
|
77
|
+
|
78
|
+
def version
|
79
|
+
@opts['version'] || @opts[:version]
|
80
|
+
end
|
81
|
+
|
82
|
+
def name
|
83
|
+
@opts['name'] || @opts[:name]
|
84
|
+
end
|
85
|
+
|
86
|
+
def runs_on_centos?
|
87
|
+
available_platforms.include?('centos')
|
88
|
+
end
|
89
|
+
|
90
|
+
def runs_on_windows?
|
91
|
+
available_platforms.include?('windows')
|
37
92
|
end
|
38
93
|
|
39
94
|
private
|
40
95
|
|
41
|
-
def bump(version)
|
96
|
+
def self.bump(version)
|
42
97
|
UI.debug("Old cookbook version: #{version}")
|
43
98
|
version_info = Semantic::Version.new version
|
44
99
|
new_version = "#{version_info.major}.#{version_info.minor}.#{version_info.patch + 1}"
|
@@ -0,0 +1 @@
|
|
1
|
+
Nothing yet - please add to this!
|
File without changes
|
data/lib/sambot/fs.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_command'
|
4
|
+
|
5
|
+
module Sambot
|
6
|
+
class FS
|
7
|
+
|
8
|
+
def self.delete(filename)
|
9
|
+
return unless File.exist?(filename)
|
10
|
+
File.delete(filename)
|
11
|
+
UI.debug("./#{filename} has been removed.")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.exist?(resource)
|
15
|
+
File.exist?(resource) || Dir.exist?(resource)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.mkdir(resource)
|
19
|
+
unless FS.exist?(resource)
|
20
|
+
FileUtils.mkdir(resource)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.copy(resource)
|
25
|
+
unless FS.exist?(resource)
|
26
|
+
filename = File.expand_path(File.join(File.dirname(__FILE__), 'templates', resource))
|
27
|
+
UI.debug("Copying #{filename} to #{resource}")
|
28
|
+
FileUtils.cp_r(filename, resource)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
data/lib/sambot/runtime.rb
CHANGED
@@ -3,37 +3,21 @@
|
|
3
3
|
require 'gems'
|
4
4
|
|
5
5
|
module Sambot
|
6
|
-
|
6
|
+
module Runtime
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def self.is_obsolete
|
9
|
+
latest_version = Gems.new.versions('sambot')[0]["number"]
|
10
|
+
Gem::Version.new(Sambot::VERSION) < Gem::Version.new(latest_version)
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def self.sudo(command, flag_errors: true)
|
23
|
-
UI.warn("Running the command `sudo -S #{command}`")
|
24
|
-
output = ''
|
25
|
-
Open4::popen4("sudo -S #{command}") do |pid, stdin, stdout, stderr|
|
26
|
-
stdin.puts ENV['SAMBOT_SUDO_PASSWORD']
|
27
|
-
stdin.close
|
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
|
34
|
-
end
|
35
|
-
output
|
36
|
-
end
|
13
|
+
def self.ensure_latest
|
14
|
+
latest_version = Gems.new.versions('sambot')[0]["number"]
|
15
|
+
UI.debug("Current version is #{Sambot::VERSION}")
|
16
|
+
UI.debug("Latest version is #{latest_version}")
|
17
|
+
if is_obsolete
|
18
|
+
UI.info('A newer version of this gem exists - please update the gem before continuing')
|
19
|
+
end
|
20
|
+
end
|
37
21
|
|
38
22
|
end
|
39
23
|
end
|
data/lib/sambot/template.rb
CHANGED
@@ -14,15 +14,36 @@ module Sambot
|
|
14
14
|
def evaluate(context = {}, opts = {})
|
15
15
|
input = File.read(path)
|
16
16
|
input = yield(input) if block_given?
|
17
|
-
puts opts
|
18
17
|
eruby = Erubis::Eruby.new(input, opts)
|
19
18
|
eruby.evaluate(context)
|
20
19
|
end
|
21
20
|
|
21
|
+
def process(opts)
|
22
|
+
File.delete(opts[:dest]) if File.exist?(opts[:dest])
|
23
|
+
if opts[:eruby]
|
24
|
+
UI.debug("Parsing #{self.path} using Erubis")
|
25
|
+
self.write({}, opts[:dest])
|
26
|
+
else
|
27
|
+
FileUtils.cp(self.path, opts[:dest].to_s)
|
28
|
+
end
|
29
|
+
if File.executable?(self.path)
|
30
|
+
UI.debug("Making #{opts[:dest]} executable")
|
31
|
+
make_executable(opts[:dest])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
22
35
|
def write(ctx, dest)
|
23
36
|
contents = evaluate(ctx)
|
24
37
|
File.write(dest, contents)
|
25
38
|
end
|
26
39
|
|
40
|
+
private
|
41
|
+
|
42
|
+
def make_executable(working_path)
|
43
|
+
current_mask = File.stat(self.path).mode
|
44
|
+
new_mask = current_mask | '0000000000000001'.to_i(2)
|
45
|
+
File.chmod(new_mask, working_path)
|
46
|
+
end
|
47
|
+
|
27
48
|
end
|
28
49
|
end
|
@@ -1,22 +1,22 @@
|
|
1
1
|
# The name of the role or wrapper cookbook. Should be of the form as-role-xxx if a role cookbook
|
2
2
|
# and as-xxx if a wrapper cookbook.
|
3
|
-
name: <%= @name %>
|
3
|
+
name: <%= @config.name %>
|
4
4
|
# The cookbook version. It will be added to the metadata.rb and needs to be incremented whenenver
|
5
5
|
# a new cookbook version needs to be pushed to the Chef Server.
|
6
6
|
version: 0.0.1
|
7
7
|
# The different platforms on which this cookbook can run. This dictates the contents of the .kitchen files
|
8
8
|
# and which files are generated for the cookbook. The values can be 'centos', 'windows' or both.
|
9
9
|
platforms:
|
10
|
-
<% @
|
10
|
+
<% @config.available_platforms.each do |platform| %>
|
11
11
|
- <%= platform %>
|
12
12
|
<% end %>
|
13
|
-
# An array of gems to be added to the metadata.rb file.
|
13
|
+
# An array of gems to be added to the metadata.rb file.
|
14
14
|
gems:
|
15
15
|
# The identifier used when generating instance names. Not yet implemented but in future, if the
|
16
16
|
# identifier is OCTPS for example, a typical instance name would be OCTPS03-W8.
|
17
|
-
identifier: <%= @identifier %>
|
17
|
+
identifier: <%= @config.identifier %>
|
18
18
|
# The description o fthe cookbook that will go into the metadata.rb.
|
19
|
-
description: <%= @description %>
|
19
|
+
description: <%= @config.description %>
|
20
20
|
# The test suites that will be added to the .kitchen files.
|
21
21
|
suites:
|
22
22
|
- name: default
|
@@ -32,7 +32,7 @@ suites:
|
|
32
32
|
# The structure above will run recipes aaa and bbb when running Test-Kitchen locally, and recipe aaa when
|
33
33
|
# running Test-Kitchen in DEV environments i.e. GCP or Rackspace.
|
34
34
|
run_list:
|
35
|
-
- recipe[<%= @name %>::default]
|
35
|
+
- recipe[<%= @config.name %>::default]
|
36
36
|
# Custom attributes for the test. The following structure will be automatically added in the generated
|
37
37
|
# Test-Kitchen files:
|
38
38
|
# attributes:
|
@@ -40,5 +40,5 @@ suites:
|
|
40
40
|
attributes:
|
41
41
|
verifier:
|
42
42
|
inspec_tests:
|
43
|
-
- name: <%= @name %>-profile
|
43
|
+
- name: <%= @config.name %>-profile
|
44
44
|
git: git@github.exacttarget.com:ads-chef-profiles/<%= @name %>-profile.git
|
File without changes
|
File without changes
|
File without changes
|
@@ -81,21 +81,23 @@ Vagrant.configure("2") do |c|
|
|
81
81
|
<% end %>
|
82
82
|
|
83
83
|
c.vm.synced_folder ".", "/vagrant", disabled: true
|
84
|
+
|
84
85
|
<% config[:synced_folders].each do |source, destination, options| %>
|
85
86
|
c.vm.synced_folder <%= source.inspect %>, <%= destination.inspect %>, <%= options %>
|
86
87
|
<% end %>
|
87
88
|
|
88
89
|
<% if config[:box] =~ /centos/ %>
|
89
|
-
c.vm.provision "shell", inline: "bash /vagrant/
|
90
|
+
c.vm.provision "shell", inline: "bash /vagrant/bootstrap.sh"
|
90
91
|
<% else %>
|
91
|
-
c.vm.provision "shell", inline: "powershell -ExecutionPolicy Bypass -File C:/Vagrant/
|
92
|
+
c.vm.provision "shell", inline: "powershell -ExecutionPolicy Bypass -File C:/Vagrant/bootstrap.ps1"
|
92
93
|
<% end %>
|
93
94
|
|
94
95
|
c.vm.provider "virtualbox" do |p|
|
95
96
|
p.linked_clone = true
|
96
|
-
|
97
|
-
|
98
|
-
|
97
|
+
end
|
98
|
+
|
99
|
+
c.trigger.after :up do
|
100
|
+
run "service apache2 start"
|
99
101
|
end
|
100
102
|
|
101
103
|
end
|
File without changes
|
data/lib/sambot/templates/{gcp_bootstrap.ps1.erb → bootstrap_scripts/google/bootstrap.ps1.erb}
RENAMED
File without changes
|
data/lib/sambot/templates/{gcp_bootstrap.sh.erb → bootstrap_scripts/google/bootstrap.sh.erb}
RENAMED
@@ -3,7 +3,6 @@
|
|
3
3
|
yum install -y unzip wget
|
4
4
|
if [ ! -d /etc/vault ]; then mkdir /etc/vault; fi
|
5
5
|
|
6
|
-
token=$(vault token-create -policy=nightswatch-ro -role=nightswatch-ro -wrap-ttl=72h | awk '/^wrapping_token:/ {print $2}')
|
7
6
|
cat << EOF > /etc/vault/tokens.json
|
8
7
|
{
|
9
8
|
"vault-addr": "<%= ENV['GCP_VAULT_ADDR'] %>",
|
@@ -0,0 +1,33 @@
|
|
1
|
+
$env:VAULT_ADDR="http://127.0.0.1:8200"
|
2
|
+
$env:VAULT_TOKEN="root"
|
3
|
+
|
4
|
+
Add-Type -AssemblyName "System.IO.Compression.FileSystem"
|
5
|
+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
6
|
+
|
7
|
+
New-Item 'C:\Program Files\vault' -ItemType Directory -Force
|
8
|
+
$wc = New-Object System.Net.WebClient
|
9
|
+
$url = "https://releases.hashicorp.com/vault/0.6.5/vault_0.6.5_windows_amd64.zip"
|
10
|
+
$output = "C:\Program Files\vault"
|
11
|
+
$zipfile = "$output\$($url.Split('/')[-1])"
|
12
|
+
$wc.DownloadFile($url, "$zipfile")
|
13
|
+
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $output)
|
14
|
+
|
15
|
+
$url = "https://storage.googleapis.com/ads-devops-chef/as-vault-tool/1.0.2/windows_amd64.zip"
|
16
|
+
$zipfile = "$output\$($url.Split('/')[-1])"
|
17
|
+
$wc.DownloadFile($url, $zipfile)
|
18
|
+
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $output)
|
19
|
+
|
20
|
+
$token = ($(& "$output\vault" token-create -policy=nightswatch-ro -role=nightswatch-ro -wrap-ttl=72h) -match '^wrapping_token:').Split(' ')[-1].Trim()
|
21
|
+
$json = @"
|
22
|
+
{
|
23
|
+
"vault-addr": "$env:VAULT_ADDR",
|
24
|
+
"skip-verify": true,
|
25
|
+
"wrapped": "$token",
|
26
|
+
"access": ""
|
27
|
+
}
|
28
|
+
"@
|
29
|
+
|
30
|
+
New-Item 'C:\ProgramData\vault' -ItemType Directory -Force
|
31
|
+
Set-Content -Path 'C:\ProgramData\vault\tokens.json' -Value $json
|
32
|
+
|
33
|
+
& "$output\as-vault-tool" tokenrenew
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/bin/bash -e
|
2
|
+
|
3
|
+
## Download and install Hashicorp Vault
|
4
|
+
sudo yum install -y unzip wget
|
5
|
+
wget "https://releases.hashicorp.com/vault/0.6.5/vault_0.6.5_linux_amd64.zip"
|
6
|
+
unzip vault_0.6.5_linux_amd64.zip -d /usr/bin
|
7
|
+
sudo mkdir /etc/vault
|
8
|
+
|
9
|
+
## Launch the Vault Server in Development mode
|
10
|
+
export VAULT_ADDR="http://127.0.0.1:8200"
|
11
|
+
export VAULT_TOKEN="root"
|
12
|
+
vault server -dev -dev-root-token-id=${VAULT_TOKEN} -dev-listen-address=0.0.0.0:8200 < /dev/null &> /dev/null &
|
13
|
+
|
14
|
+
## Create the addressing file so that Chef and other applicatons can access the Vault server
|
15
|
+
cat << EOF > /etc/vault/tokens.json
|
16
|
+
{
|
17
|
+
"vault-addr": "${VAULT_ADDR}",
|
18
|
+
"skip-verify": true,
|
19
|
+
"wrapped": "",
|
20
|
+
"access": "root"
|
21
|
+
}
|
22
|
+
EOF
|
23
|
+
|
24
|
+
## Install Ruby
|
25
|
+
sudo yum install -y ruby
|
26
|
+
|
27
|
+
## Create the script to populate Vault from the secrets file
|
28
|
+
gem install vault
|
29
|
+
cat << EOF > /tmp/populate_secrets.rb
|
30
|
+
require
|
31
|
+
EOF
|
32
|
+
|
33
|
+
## Populate Vault
|
34
|
+
ruby /tmp/populate_secrets.rb
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'vault'
|
3
|
+
|
4
|
+
config = File.expand_path(File.join(File.dirname(__FILE__),'../.secrets.yml'))
|
5
|
+
secrets = YAML.load(File.read(config))
|
6
|
+
secrets.each do |secret|
|
7
|
+
data = secret["contents"]
|
8
|
+
data = File.read() if data.start_with?('file::')
|
9
|
+
Vault.logical.write(secret["path"], value: secret["contents"])
|
10
|
+
puts "Updated the secret located at #{secret['path']}"
|
11
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -15,7 +15,7 @@ provisioner:
|
|
15
15
|
|
16
16
|
platforms:
|
17
17
|
<!--% if @platforms.include?('centos') %-->
|
18
|
-
- name:
|
18
|
+
- name: centos
|
19
19
|
driver:
|
20
20
|
network:
|
21
21
|
- ["private_network", {ip: "192.168.255.10"}]
|
@@ -23,7 +23,7 @@ platforms:
|
|
23
23
|
<!--% if @platforms.include?('windows') %-->
|
24
24
|
- name: windows-2012R2
|
25
25
|
driver:
|
26
|
-
box:
|
26
|
+
box: sfadstudio/Server2012R2
|
27
27
|
network:
|
28
28
|
- ["private_network", {ip: "192.168.255.11"}]
|
29
29
|
transport:
|
@@ -22,7 +22,7 @@ platforms:
|
|
22
22
|
flavor_id: 6
|
23
23
|
public_key_path: ./id_rsa.pub
|
24
24
|
rackspace_region: 'lon'
|
25
|
-
server_name:
|
25
|
+
server_name: <!--%= @name %-->-<%= Time.now.to_i %>
|
26
26
|
<!--% end %-->
|
27
27
|
<!--% if @platforms.include?('windows') %-->
|
28
28
|
- name: windows
|
@@ -30,10 +30,10 @@ platforms:
|
|
30
30
|
name: rax
|
31
31
|
log_level: info
|
32
32
|
wait_for: 3600
|
33
|
-
use_private_ip:
|
34
|
-
rackspace_username:
|
35
|
-
rackspace_api_key:
|
36
|
-
network:
|
33
|
+
use_private_ip: <%= ENV['IN_CI_PIPELINE'] %>
|
34
|
+
rackspace_username: <%= ENV['RACKSPACE_USERNAME'] %>
|
35
|
+
rackspace_api_key: <%= ENV['RACKSPACE_API_KEY'] %>
|
36
|
+
network: <%= ENV['NETWORK'] || 'public' %>
|
37
37
|
image_id: 8bfada8f-9917-46dd-aa82-be533d5279fa
|
38
38
|
flavor_id: general1-4
|
39
39
|
rackspace_region: LON
|