sambot 0.1.19
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +8 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/README.md +20 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/sambot +3 -0
- data/bin/setup +8 -0
- data/lib/sambot.rb +5 -0
- data/lib/sambot/cli.rb +33 -0
- data/lib/sambot/commands/cookbook.rb +68 -0
- data/lib/sambot/commands/inventory.rb +13 -0
- data/lib/sambot/commands/secret.rb +27 -0
- data/lib/sambot/commands/teamcity.rb +13 -0
- data/lib/sambot/domain/common/application_exception.rb +9 -0
- data/lib/sambot/domain/common/config.rb +25 -0
- data/lib/sambot/domain/common/file_checker.rb +30 -0
- data/lib/sambot/domain/common/runtime.rb +25 -0
- data/lib/sambot/domain/common/template_provider.rb +13 -0
- data/lib/sambot/domain/common/ui.rb +17 -0
- data/lib/sambot/domain/cookbooks/assistant_chef.rb +87 -0
- data/lib/sambot/domain/cookbooks/kitchen.rb +30 -0
- data/lib/sambot/domain/cookbooks/metadata.rb +30 -0
- data/lib/sambot/domain/secrets/vault.rb +28 -0
- data/lib/sambot/templates/.gitignore +31 -0
- data/lib/sambot/templates/.kitchen.gcp.linux.yml +39 -0
- data/lib/sambot/templates/.kitchen.gcp.windows.yml +39 -0
- data/lib/sambot/templates/.kitchen.linux.yml +16 -0
- data/lib/sambot/templates/.kitchen.rackspace.linux.yml +27 -0
- data/lib/sambot/templates/.kitchen.rackspace.windows.yml +29 -0
- data/lib/sambot/templates/.kitchen.windows.yml +16 -0
- data/lib/sambot/templates/metadata.rb.erb +9 -0
- data/lib/sambot/templates/pre_push +4 -0
- data/lib/sambot/version.rb +3 -0
- data/sambot.gemspec +30 -0
- metadata +209 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13646525edfdebe22db06eb03641637b8e13fb24
|
4
|
+
data.tar.gz: b5d51109ac21f78d913009a0681e184b4626e2cd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 99fcf7c187b4cec866c6bb54056c0aca9cfb247dce41efb6751d23fc7b987088c9032bc45af03049b0ce9dac414ebdceec8815bfbc4733a08d31381d33cfbd3d
|
7
|
+
data.tar.gz: 7a51961cb15d54e62eac4631dbd9fb8ad7fca6b330efe59338aba8e85dd98f6277e264a9759e3090829aec6fc80fa1c2296318c168197f7647ec0bdde9d9aad6
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.6
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Sambot
|
2
|
+
|
3
|
+
Sambot is our internal Platform Engineering gem to help standardize and simplify our DevOps workflow.
|
4
|
+
|
5
|
+
It can be used both as a library - to read secrets from Hashicorp Vault in a Chef cookbook for example - or as an
|
6
|
+
executable to guide tasks such as managing Chef cookbooks.
|
7
|
+
|
8
|
+
## Usage
|
9
|
+
|
10
|
+
To install the gem, simply run `gem install sambot`.
|
11
|
+
|
12
|
+
Run `sambot` to be shown the help menu.
|
13
|
+
|
14
|
+
## Available Commands
|
15
|
+
|
16
|
+
To view the list of available commands and their descriptions, refer to the files in lib/sambot/commands.
|
17
|
+
|
18
|
+
## Contributing
|
19
|
+
|
20
|
+
Bug reports and pull requests are welcome on GitHub at https://github.exacttarget.com/ads-devops/sambot.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'sambot'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require 'pry'
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/sambot
ADDED
data/bin/setup
ADDED
data/lib/sambot.rb
ADDED
data/lib/sambot/cli.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require_relative 'domain/common/application_exception'
|
3
|
+
require_relative 'domain/common/file_checker'
|
4
|
+
require_relative 'domain/secrets/vault'
|
5
|
+
require_relative 'domain/common/ui'
|
6
|
+
require_relative 'domain/common/config'
|
7
|
+
require_relative 'domain/common/runtime'
|
8
|
+
require_relative 'domain/common/template_provider'
|
9
|
+
require_relative 'domain/cookbooks/kitchen'
|
10
|
+
require_relative 'domain/cookbooks/assistant_chef'
|
11
|
+
require_relative 'domain/cookbooks/metadata'
|
12
|
+
require_relative 'commands/cookbook'
|
13
|
+
require_relative 'commands/secret'
|
14
|
+
require_relative 'commands/teamcity'
|
15
|
+
require_relative 'commands/inventory'
|
16
|
+
|
17
|
+
module Sambot
|
18
|
+
class CLI < Thor
|
19
|
+
|
20
|
+
desc 'teamcity', 'Manage TeamCity'
|
21
|
+
subcommand 'teamcity', Sambot::Commands::TeamCity
|
22
|
+
|
23
|
+
desc 'cookbook', 'Manage Chef cookbooks'
|
24
|
+
subcommand 'cookbook', Sambot::Commands::Cookbook
|
25
|
+
|
26
|
+
desc 'secret', 'Manage secrets inside Chef cookbooks'
|
27
|
+
subcommand 'secret', Sambot::Commands::Secret
|
28
|
+
|
29
|
+
desc 'inventory', 'Manage instance inventories'
|
30
|
+
subcommand 'inventory', Sambot::Commands::Inventory
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Sambot
|
2
|
+
module Commands
|
3
|
+
|
4
|
+
ESSENTIAL_FILES = ['.config.yml', 'spec', 'recipes', 'README.md'].freeze
|
5
|
+
GENERATED_FILES = ['teamcity.sh', 'chefignore', 'Berksfile', '.rubocop.yml', '.gitignore'].freeze
|
6
|
+
|
7
|
+
class Cookbook < Thor
|
8
|
+
|
9
|
+
include Domain::Common::UI
|
10
|
+
include Domain::Common::Runtime
|
11
|
+
|
12
|
+
namespace 'cookbook'
|
13
|
+
|
14
|
+
desc 'clean', 'Remove all generated build files from a cookbook'
|
15
|
+
long_desc <<-LONGDESC
|
16
|
+
`sambot cookbook clean` will remove all files generated by `sambot cookbook build`.
|
17
|
+
This is required to ensure the generated files are not stored in source control.
|
18
|
+
LONGDESC
|
19
|
+
def clean
|
20
|
+
ensure_latest
|
21
|
+
info('Removing all generated files from this cookbook.')
|
22
|
+
modified_files = Sambot::Domain::Cookbooks::AssistantChef.new.clean_cookbook(GENERATED_FILES)
|
23
|
+
modified_files.each {|file| debug("./#{file} has been removed.")}
|
24
|
+
info('The cookbook has been successfully cleaned.')
|
25
|
+
rescue Domain::Common::ApplicationException => e
|
26
|
+
say(e.message, :red)
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'build', 'Builds a cookbook from its configuration file'
|
30
|
+
long_desc <<-LONGDESC
|
31
|
+
`sambot cookbook build` will generate all the files required for the functioning
|
32
|
+
of a Chef cookbook from a configuration file. The motivation behind this setup is to
|
33
|
+
standardize and simplify the Chef cookbook creation workflow. The configuration file should be
|
34
|
+
called .config.yml and stored in the root of the Chef cookbook.
|
35
|
+
LONGDESC
|
36
|
+
def build
|
37
|
+
ensure_latest
|
38
|
+
modified_files = Sambot::Domain::Cookbooks::AssistantChef.new.build_cookbook(ESSENTIAL_FILES, GENERATED_FILES)
|
39
|
+
modified_files.each {|file| debug("./#{file} has been added to the cookbook.")}
|
40
|
+
info('The cookbook has been successfully built.')
|
41
|
+
rescue Domain::Common::ApplicationException => e
|
42
|
+
say(e.message, :red)
|
43
|
+
end
|
44
|
+
|
45
|
+
desc 'generate', 'Creates a new cookbook'
|
46
|
+
long_desc <<-LONGDESC
|
47
|
+
`sambot cookbook generate` will create a new cookbook. This can be either a
|
48
|
+
wrapper cookbook or an instance role cookbook.
|
49
|
+
LONGDESC
|
50
|
+
option :name
|
51
|
+
option :platform, :desc => 'Can be either "windows" or "linux"'
|
52
|
+
option :type, :desc => 'Can be either "wrapper" or "role"'
|
53
|
+
def generate()
|
54
|
+
ensure_latest
|
55
|
+
name = ask(' What is the name of this cookbook?')
|
56
|
+
platform = ask(' What operating system will this cookbook run on?', :limited_to => ['windows', 'linux'])
|
57
|
+
type = ask(' What type of cookbook will this be?', :limited_to => ['wrapper', 'role'])
|
58
|
+
Sambot::Domain::Cookbooks::AssistantChef.new.generate_cookbook(name, options[:platform], options[:type], ESSENTIAL_FILES, GENERATED_FILES)
|
59
|
+
info('The cookbook has been successfully generated.')
|
60
|
+
rescue Domain::Common::ApplicationException => e
|
61
|
+
say(e.message, :red)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
module Sambot
|
3
|
+
module Commands
|
4
|
+
|
5
|
+
class Secret < Thor
|
6
|
+
|
7
|
+
namespace 'secret'
|
8
|
+
|
9
|
+
desc 'read PATH', 'Reads a secret from the vault'
|
10
|
+
long_desc <<-LONGDESC
|
11
|
+
`sambot secret read /path/to/my/secret` will read the secret located in the
|
12
|
+
path provided out of Hashicorp Vault. It relies on a proprietary tool written
|
13
|
+
by the Advertising Studio Platform Engineering team called as-vault. Make sure
|
14
|
+
you have this tool installed before using this command.
|
15
|
+
LONGDESC
|
16
|
+
def read(path)
|
17
|
+
Sambot::Vault.new.read(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'write', 'Write a secret to the vault'
|
21
|
+
def write
|
22
|
+
Sambot::Vault.new.write(path)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Sambot
|
4
|
+
module Domain
|
5
|
+
module Common
|
6
|
+
class Config
|
7
|
+
|
8
|
+
CONFIGURATION_FILENAME = '.config.yml'.freeze
|
9
|
+
|
10
|
+
def read(path = nil)
|
11
|
+
path ||= File.join(Dir.getwd, CONFIGURATION_FILENAME)
|
12
|
+
raise ApplicationException, "The configuration file was not found at #{path}." unless File.exist?(path)
|
13
|
+
config = YAML.load_file(path)
|
14
|
+
raise ApplicationException, 'Missing platform in the .config.yml configuration file' unless config['platform']
|
15
|
+
raise ApplicationException, 'Missing version in the .config.yml configuration file' unless config['version']
|
16
|
+
raise ApplicationException, 'Missing list of suites in the .config.yml configuration file' unless config['suites']
|
17
|
+
raise ApplicationException, 'Missing description in the .config.yml configuration file' unless config['description']
|
18
|
+
config['name'] = File.basename(Dir.getwd)
|
19
|
+
config
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Sambot
|
2
|
+
module Domain
|
3
|
+
module Common
|
4
|
+
class FileChecker
|
5
|
+
|
6
|
+
def verify(path)
|
7
|
+
return if File.exist?(path) || Dir.exist?(path)
|
8
|
+
raise ApplicationException, "The file or directory #{path} was not found in the current directory."
|
9
|
+
end
|
10
|
+
|
11
|
+
def update(files)
|
12
|
+
return unless files
|
13
|
+
files.each do |filename|
|
14
|
+
update_template(filename)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def update_template(filename)
|
21
|
+
working_path = filename
|
22
|
+
template_path = TemplateProvider.new.get_path(filename)
|
23
|
+
File.delete(working_path) if File.exist?(working_path)
|
24
|
+
FileUtils.cp(template_path, working_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'gems'
|
2
|
+
|
3
|
+
module Sambot
|
4
|
+
module Domain
|
5
|
+
module Common
|
6
|
+
module Runtime
|
7
|
+
|
8
|
+
def 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
|
+
|
13
|
+
def ensure_latest
|
14
|
+
latest_version = Gems.new.versions('sambot')[0]["number"]
|
15
|
+
debug("Current Sambot version is #{Sambot::VERSION}.")
|
16
|
+
debug("Latest Sambot version is #{latest_version}.")
|
17
|
+
if is_obsolete
|
18
|
+
say('A newer version of the sambot gem exists. Please update the gem before continuing.', :red)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Sambot
|
4
|
+
module Domain
|
5
|
+
module Cookbooks
|
6
|
+
class AssistantChef
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@modified_files = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_cookbook(essential_files, generated_files)
|
13
|
+
validate_cookbook_structure(essential_files, generated_files)
|
14
|
+
config = Common::Config.new.read
|
15
|
+
setup_test_kitchen(config)
|
16
|
+
build_metadata(config)
|
17
|
+
copy_git_hooks()
|
18
|
+
@modified_files
|
19
|
+
end
|
20
|
+
|
21
|
+
def clean_cookbook(generated_files)
|
22
|
+
delete_file('metadata.rb')
|
23
|
+
generated_files.each { |file| delete_file(file) }
|
24
|
+
Dir.glob('\.kitchen*\.yml').each { |file| delete_file(file)}
|
25
|
+
@modified_files
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate_cookbook(name, platform, type, description, essential_files, generated_files)
|
29
|
+
FileUtils.mkdir(name)
|
30
|
+
FileUtils.mkdir(File.join(name, 'test'))
|
31
|
+
FileUtils.mkdir(File.join(name, 'spec'))
|
32
|
+
FileUtils.mkdir(File.join(name, 'recipes'))
|
33
|
+
Dir.chdir(name) do
|
34
|
+
write_config(description, platform, type)
|
35
|
+
build_cookbook(essential_files, generated_files)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def write_config(description, platform, type)
|
42
|
+
contents = {
|
43
|
+
:version => '0.0.1',
|
44
|
+
:platform => platform,
|
45
|
+
:suites => nil,
|
46
|
+
:description => nil
|
47
|
+
}.to_yaml
|
48
|
+
File.write('.config.yml', contents)
|
49
|
+
end
|
50
|
+
|
51
|
+
def copy_git_hooks
|
52
|
+
working_path = '.git/hooks/pre_push'
|
53
|
+
template_path = Common::TemplateProvider.new.get_path('pre_push')
|
54
|
+
File.delete(working_path) if File.exist?(working_path)
|
55
|
+
FileUtils.cp(template_path, working_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete_file(filename)
|
59
|
+
return unless File.exist?(filename)
|
60
|
+
File.delete(filename)
|
61
|
+
@modified_files << filename
|
62
|
+
end
|
63
|
+
|
64
|
+
def validate_cookbook_structure(essential_files, generated_files)
|
65
|
+
essential_files.each { |path| Common::FileChecker.new.verify(path) }
|
66
|
+
Common::FileChecker.new.update(generated_files)
|
67
|
+
@modified_files = @modified_files + generated_files
|
68
|
+
end
|
69
|
+
|
70
|
+
def setup_test_kitchen(config)
|
71
|
+
files = Kitchen.new.generate_yml(config['name'], config['platform'], config['suites'])
|
72
|
+
files.each do |filename, contents|
|
73
|
+
File.write(filename, contents)
|
74
|
+
@modified_files << filename
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_metadata(config)
|
79
|
+
result = Metadata.new.generate(config['name'], config['platform'], config['version'], config['description'])
|
80
|
+
File.write('metadata.rb', result)
|
81
|
+
@modified_files << 'metadata.rb'
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Sambot
|
2
|
+
module Domain
|
3
|
+
module Cookbooks
|
4
|
+
class Kitchen
|
5
|
+
|
6
|
+
def generate_yml(name, platform, suites = nil)
|
7
|
+
raise ApplicationException, 'Missing platform when trying to generate Test-Kitchen YAML.' unless platform
|
8
|
+
raise ApplicationException, 'Missing cookbook name when trying to generate Test-Kitchen YAML.' unless name
|
9
|
+
result = {}
|
10
|
+
['', '.gcp', '.rackspace'].map do |type|
|
11
|
+
yaml = load_yaml(type, platform, name)
|
12
|
+
yaml['suites'] = suites if suites
|
13
|
+
result[".kitchen#{type}.yml"] = yaml.to_yaml
|
14
|
+
end
|
15
|
+
result
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def load_yaml(type, platform, name)
|
21
|
+
filename = File.join(File.dirname(__FILE__), '../../templates', ".kitchen#{type}.#{platform}.yml")
|
22
|
+
contents = File.read(filename)
|
23
|
+
contents = contents.gsub(/@@cookbook_name@@/, name)
|
24
|
+
YAML.load(contents)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
|
3
|
+
module Sambot
|
4
|
+
module Domain
|
5
|
+
module Cookbooks
|
6
|
+
class Metadata
|
7
|
+
|
8
|
+
def generate(name, platform, version, description)
|
9
|
+
context = {
|
10
|
+
'cookbook_name' => name,
|
11
|
+
'cookbook_platfrom' => platform,
|
12
|
+
'cookbook_version' => version,
|
13
|
+
'cookbook_description' => description
|
14
|
+
}
|
15
|
+
generate_metadata(context)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_metadata(context)
|
21
|
+
filename = File.join(File.dirname(__FILE__), '../../templates', 'metadata.rb.erb')
|
22
|
+
input = File.read(filename)
|
23
|
+
eruby = Erubis::Eruby.new(input)
|
24
|
+
eruby.evaluate(context)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Sambot
|
2
|
+
module Domain
|
3
|
+
module Chef
|
4
|
+
class Vault
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
if Gem.win_platform?
|
8
|
+
@tool_dir = 'C:/Program Files/vault'
|
9
|
+
@tool_exe = 'as-vault-tool.exe'
|
10
|
+
else
|
11
|
+
@tool_dir = '/opt/vault-tool'
|
12
|
+
@tool_exe = 'as-vault-tool'
|
13
|
+
end
|
14
|
+
@tool_version = '1.0.2'
|
15
|
+
end
|
16
|
+
|
17
|
+
def read(path)
|
18
|
+
`#{@tool_dir}/#{@tool_version}/#{@tool_exe} read -p #{path}`
|
19
|
+
end
|
20
|
+
|
21
|
+
def write(path)
|
22
|
+
raise 'Not yet implemented'
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
.vagrant
|
2
|
+
nodes
|
3
|
+
env
|
4
|
+
syntaxcache
|
5
|
+
*.pem
|
6
|
+
.kitchen/
|
7
|
+
.kitchen.local.yml
|
8
|
+
.vagrant
|
9
|
+
Berksfile.lock
|
10
|
+
*~
|
11
|
+
*#
|
12
|
+
*.lock
|
13
|
+
.#*
|
14
|
+
\#*#
|
15
|
+
.*.sw[a-z]
|
16
|
+
*.un~
|
17
|
+
# Bundler
|
18
|
+
Gemfile.lock
|
19
|
+
bin/*
|
20
|
+
.bundle/*
|
21
|
+
.kitchen/
|
22
|
+
.kitchen.local.yml
|
23
|
+
berks-cookbooks
|
24
|
+
Berksfile
|
25
|
+
teamcity.sh
|
26
|
+
metadata.rb
|
27
|
+
.kitchen.rackspace.yml
|
28
|
+
.kitchen.gcp.yml
|
29
|
+
.rubocop.yml
|
30
|
+
chefignore
|
31
|
+
teamcity.sh
|
@@ -0,0 +1,39 @@
|
|
1
|
+
---
|
2
|
+
provisioner:
|
3
|
+
name: chef_zero
|
4
|
+
log_level: info
|
5
|
+
deprecations_as_errors: true
|
6
|
+
cookbooks_path:
|
7
|
+
- .
|
8
|
+
|
9
|
+
platforms:
|
10
|
+
- name: linux
|
11
|
+
driver:
|
12
|
+
name: "gce"
|
13
|
+
region: <%= ENV['GCP_REGION'] %>
|
14
|
+
project: <%= ENV['GCP_PROJECT'] %>
|
15
|
+
image_project: <%= ENV['GCP_IMAGE_PROJECT'] %>
|
16
|
+
image_family: <%= ENV['GCP_IMAGE_FAMILY'] %>
|
17
|
+
network: <%= ENV['GCP_NETWORK'] %>
|
18
|
+
subnet: <%= ENV['GCP_SUBNETWORK'] %>
|
19
|
+
use_private_ip: false
|
20
|
+
preemptible: true
|
21
|
+
service_account_name: <%= ENV['GCP_SERVICE_ACCOUNT_NAME'] %>
|
22
|
+
service_account_scopes:
|
23
|
+
- userinfo-email
|
24
|
+
- logging-write
|
25
|
+
- monitoring-write
|
26
|
+
tags:
|
27
|
+
- "test-kitchen"
|
28
|
+
- "consul-agent"
|
29
|
+
- "vault-client"
|
30
|
+
|
31
|
+
transport:
|
32
|
+
username: chefuser
|
33
|
+
ssh_key:
|
34
|
+
- <%= ENV['GCP_SSH_KEY'] || "" %>
|
35
|
+
|
36
|
+
verifier:
|
37
|
+
name: inspec
|
38
|
+
format: junit
|
39
|
+
output: inspec_results.xml
|
@@ -0,0 +1,39 @@
|
|
1
|
+
---
|
2
|
+
provisioner:
|
3
|
+
name: chef_zero
|
4
|
+
log_level: info
|
5
|
+
deprecations_as_errors: true
|
6
|
+
cookbooks_path:
|
7
|
+
- .
|
8
|
+
|
9
|
+
platforms:
|
10
|
+
- name: windows
|
11
|
+
driver:
|
12
|
+
name: "gce"
|
13
|
+
region: <%= ENV['GCP_REGION'] %>
|
14
|
+
project: <%= ENV['GCP_PROJECT'] %>
|
15
|
+
image_project: <%= ENV['GCP_IMAGE_PROJECT'] %>
|
16
|
+
image_family: <%= ENV['GCP_IMAGE_FAMILY'] %>
|
17
|
+
network: <%= ENV['GCP_NETWORK'] %>
|
18
|
+
subnet: <%= ENV['GCP_SUBNETWORK'] %>
|
19
|
+
use_private_ip: false
|
20
|
+
preemptible: true
|
21
|
+
service_account_name: <%= ENV['GCP_SERVICE_ACCOUNT_NAME'] %>
|
22
|
+
service_account_scopes:
|
23
|
+
- userinfo-email
|
24
|
+
- logging-write
|
25
|
+
- monitoring-write
|
26
|
+
tags:
|
27
|
+
- "test-kitchen"
|
28
|
+
- "consul-agent"
|
29
|
+
- "vault-client"
|
30
|
+
|
31
|
+
transport:
|
32
|
+
username: chefuser
|
33
|
+
ssh_key:
|
34
|
+
- <%= ENV['GCP_SSH_KEY'] || "" %>
|
35
|
+
|
36
|
+
verifier:
|
37
|
+
name: inspec
|
38
|
+
format: junit
|
39
|
+
output: inspec_results.xml
|
@@ -0,0 +1,27 @@
|
|
1
|
+
---
|
2
|
+
provisioner:
|
3
|
+
name: chef_zero
|
4
|
+
log_level: info
|
5
|
+
deprecations_as_errors: true
|
6
|
+
cookbooks_path:
|
7
|
+
- .
|
8
|
+
|
9
|
+
platforms:
|
10
|
+
- name: linux
|
11
|
+
transport:
|
12
|
+
ssh_key: ./id_rsa
|
13
|
+
driver:
|
14
|
+
name: rackspace
|
15
|
+
rackconnect_wait: true
|
16
|
+
servicenet: true
|
17
|
+
require_chef_omnibus: true
|
18
|
+
no_ssh_tcp_check: true
|
19
|
+
no_ssh_tcp_check_sleep: 240
|
20
|
+
image_id: 398c5f65-23e2-44da-97d8-d28ff5ec583b
|
21
|
+
flavor_id: 6
|
22
|
+
public_key_path: ./id_rsa.pub
|
23
|
+
rackspace_region: 'lon'
|
24
|
+
server_name: @@cookbook_name@@-<%= Time.now.to_i %>
|
25
|
+
|
26
|
+
verifier:
|
27
|
+
name: inspec
|
@@ -0,0 +1,29 @@
|
|
1
|
+
---
|
2
|
+
provisioner:
|
3
|
+
name: chef_zero
|
4
|
+
log_level: info
|
5
|
+
deprecations_as_errors: true
|
6
|
+
cookbooks_path:
|
7
|
+
- .
|
8
|
+
|
9
|
+
platforms:
|
10
|
+
- name: "windows"
|
11
|
+
transport:
|
12
|
+
ssh_key: ./id_rsa
|
13
|
+
driver:
|
14
|
+
name: rackspace
|
15
|
+
rackconnect_wait: true
|
16
|
+
servicenet: true
|
17
|
+
require_chef_omnibus: true
|
18
|
+
no_ssh_tcp_check: true
|
19
|
+
no_ssh_tcp_check_sleep: 240
|
20
|
+
image_id: 398c5f65-23e2-44da-97d8-d28ff5ec583b
|
21
|
+
flavor_id: 6
|
22
|
+
public_key_path: ./id_rsa.pub
|
23
|
+
rackspace_region: 'lon'
|
24
|
+
server_name: @@cookbook_name@@-<%= Time.now.to_i %>
|
25
|
+
|
26
|
+
verifier:
|
27
|
+
name: inspec
|
28
|
+
format: junit
|
29
|
+
output: inspec_results.xml
|
@@ -0,0 +1,9 @@
|
|
1
|
+
name '<%= @cookbook_name %>'
|
2
|
+
maintainer 'Salesforce Marketing Cloud - Advertising Studio'
|
3
|
+
maintainer_email 'as-nightswatch@salesforce.com'
|
4
|
+
license 'All rights reserved'
|
5
|
+
description '<%= @cookbook_description %>'
|
6
|
+
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
|
7
|
+
version '<%= @cookbook_version %>'
|
8
|
+
issues_url 'https://github.exacttarget.com/ads-cookbooks/<%= @cookbook_name %>/issues'
|
9
|
+
source_url 'https://github.exacttarget.com/ads-cookbooks/<%= @cookbook_name %>'
|
data/sambot.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sambot/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'sambot'
|
8
|
+
spec.version = Sambot::VERSION
|
9
|
+
spec.authors = ['Olivier Kouame']
|
10
|
+
spec.email = ['olivier.kouame@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Tooling for a DevOps workflow'
|
13
|
+
spec.homepage = 'http://github.com/okouam/sambot'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = 'bin'
|
19
|
+
spec.executables = 'sambot'
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'thor', '~> 0.19'
|
23
|
+
spec.add_dependency 'erubis', '~> 2.7', '>= 2.7.0'
|
24
|
+
spec.add_dependency 'gems', '~> 1.0', '>= 1.0.0'
|
25
|
+
spec.add_development_dependency 'rubocop', '~> 0.49'
|
26
|
+
spec.add_development_dependency 'gem-release', '~> 1.0.0'
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sambot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.19
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Olivier Kouame
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.19'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.19'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: erubis
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.7'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 2.7.0
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.7'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.7.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: gems
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.0'
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.0.0
|
57
|
+
type: :runtime
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '1.0'
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.0.0
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rubocop
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0.49'
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0.49'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: gem-release
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 1.0.0
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 1.0.0
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: bundler
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '1.14'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '1.14'
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: rake
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - "~>"
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '10.0'
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '10.0'
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: rspec
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '3.0'
|
130
|
+
type: :development
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - "~>"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '3.0'
|
137
|
+
description:
|
138
|
+
email:
|
139
|
+
- olivier.kouame@gmail.com
|
140
|
+
executables:
|
141
|
+
- sambot
|
142
|
+
extensions: []
|
143
|
+
extra_rdoc_files: []
|
144
|
+
files:
|
145
|
+
- ".gitignore"
|
146
|
+
- ".rspec"
|
147
|
+
- ".rubocop.yml"
|
148
|
+
- ".ruby-version"
|
149
|
+
- Gemfile
|
150
|
+
- README.md
|
151
|
+
- Rakefile
|
152
|
+
- bin/console
|
153
|
+
- bin/sambot
|
154
|
+
- bin/setup
|
155
|
+
- lib/sambot.rb
|
156
|
+
- lib/sambot/cli.rb
|
157
|
+
- lib/sambot/commands/cookbook.rb
|
158
|
+
- lib/sambot/commands/inventory.rb
|
159
|
+
- lib/sambot/commands/secret.rb
|
160
|
+
- lib/sambot/commands/teamcity.rb
|
161
|
+
- lib/sambot/domain/common/application_exception.rb
|
162
|
+
- lib/sambot/domain/common/config.rb
|
163
|
+
- lib/sambot/domain/common/file_checker.rb
|
164
|
+
- lib/sambot/domain/common/runtime.rb
|
165
|
+
- lib/sambot/domain/common/template_provider.rb
|
166
|
+
- lib/sambot/domain/common/ui.rb
|
167
|
+
- lib/sambot/domain/cookbooks/assistant_chef.rb
|
168
|
+
- lib/sambot/domain/cookbooks/kitchen.rb
|
169
|
+
- lib/sambot/domain/cookbooks/metadata.rb
|
170
|
+
- lib/sambot/domain/secrets/vault.rb
|
171
|
+
- lib/sambot/templates/.gitignore
|
172
|
+
- lib/sambot/templates/.kitchen.gcp.linux.yml
|
173
|
+
- lib/sambot/templates/.kitchen.gcp.windows.yml
|
174
|
+
- lib/sambot/templates/.kitchen.linux.yml
|
175
|
+
- lib/sambot/templates/.kitchen.rackspace.linux.yml
|
176
|
+
- lib/sambot/templates/.kitchen.rackspace.windows.yml
|
177
|
+
- lib/sambot/templates/.kitchen.windows.yml
|
178
|
+
- lib/sambot/templates/.rubocop.yml
|
179
|
+
- lib/sambot/templates/Berksfile
|
180
|
+
- lib/sambot/templates/chefignore
|
181
|
+
- lib/sambot/templates/metadata.rb.erb
|
182
|
+
- lib/sambot/templates/pre_push
|
183
|
+
- lib/sambot/templates/teamcity.sh
|
184
|
+
- lib/sambot/version.rb
|
185
|
+
- sambot.gemspec
|
186
|
+
homepage: http://github.com/okouam/sambot
|
187
|
+
licenses: []
|
188
|
+
metadata: {}
|
189
|
+
post_install_message:
|
190
|
+
rdoc_options: []
|
191
|
+
require_paths:
|
192
|
+
- lib
|
193
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
194
|
+
requirements:
|
195
|
+
- - ">="
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - ">="
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
203
|
+
requirements: []
|
204
|
+
rubyforge_project:
|
205
|
+
rubygems_version: 2.4.5.2
|
206
|
+
signing_key:
|
207
|
+
specification_version: 4
|
208
|
+
summary: Tooling for a DevOps workflow
|
209
|
+
test_files: []
|