sambot 0.1.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +8 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +4 -0
  7. data/README.md +20 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/sambot +3 -0
  11. data/bin/setup +8 -0
  12. data/lib/sambot.rb +5 -0
  13. data/lib/sambot/cli.rb +33 -0
  14. data/lib/sambot/commands/cookbook.rb +68 -0
  15. data/lib/sambot/commands/inventory.rb +13 -0
  16. data/lib/sambot/commands/secret.rb +27 -0
  17. data/lib/sambot/commands/teamcity.rb +13 -0
  18. data/lib/sambot/domain/common/application_exception.rb +9 -0
  19. data/lib/sambot/domain/common/config.rb +25 -0
  20. data/lib/sambot/domain/common/file_checker.rb +30 -0
  21. data/lib/sambot/domain/common/runtime.rb +25 -0
  22. data/lib/sambot/domain/common/template_provider.rb +13 -0
  23. data/lib/sambot/domain/common/ui.rb +17 -0
  24. data/lib/sambot/domain/cookbooks/assistant_chef.rb +87 -0
  25. data/lib/sambot/domain/cookbooks/kitchen.rb +30 -0
  26. data/lib/sambot/domain/cookbooks/metadata.rb +30 -0
  27. data/lib/sambot/domain/secrets/vault.rb +28 -0
  28. data/lib/sambot/templates/.gitignore +31 -0
  29. data/lib/sambot/templates/.kitchen.gcp.linux.yml +39 -0
  30. data/lib/sambot/templates/.kitchen.gcp.windows.yml +39 -0
  31. data/lib/sambot/templates/.kitchen.linux.yml +16 -0
  32. data/lib/sambot/templates/.kitchen.rackspace.linux.yml +27 -0
  33. data/lib/sambot/templates/.kitchen.rackspace.windows.yml +29 -0
  34. data/lib/sambot/templates/.kitchen.windows.yml +16 -0
  35. data/lib/sambot/templates/metadata.rb.erb +9 -0
  36. data/lib/sambot/templates/pre_push +4 -0
  37. data/lib/sambot/version.rb +3 -0
  38. data/sambot.gemspec +30 -0
  39. 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
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ Metrics/LineLength:
2
+ Max: 200
3
+
4
+ Documentation:
5
+ Enabled: false
6
+
7
+ Metrics/AbcSize:
8
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sammy.gemspec
4
+ gemspec
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
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
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
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/sambot'
3
+ Sambot::CLI.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/sambot.rb ADDED
@@ -0,0 +1,5 @@
1
+ require_relative 'sambot/version'
2
+ require_relative 'sambot/cli'
3
+
4
+ module Sambot
5
+ end
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,13 @@
1
+ module Sambot
2
+ module Commands
3
+
4
+ class Inventory < Thor
5
+
6
+ namespace 'inventory'
7
+
8
+ def generate
9
+ end
10
+
11
+ end
12
+ end
13
+ 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,13 @@
1
+ module Sambot
2
+ module Commands
3
+
4
+ class TeamCity < Thor
5
+
6
+ namespace 'teamcity'
7
+
8
+ def keys
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module Sambot
2
+ module Domain
3
+ module Common
4
+ class ApplicationException < RuntimeError
5
+
6
+ end
7
+ end
8
+ end
9
+ 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,13 @@
1
+ module Sambot
2
+ module Domain
3
+ module Common
4
+ class TemplateProvider
5
+
6
+ def get_path(filename)
7
+ File.join(File.dirname(__FILE__), '..', '..', 'templates', 'metadata.rb.erb')
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module Sambot
2
+ module Domain
3
+ module Common
4
+ module UI
5
+
6
+ def debug(msg)
7
+ say("debug: #{msg}", :yellow)
8
+ end
9
+
10
+ def info(msg)
11
+ say(" info: #{msg}", :green)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ 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,16 @@
1
+ ---
2
+ driver:
3
+ name: "vagrant"
4
+
5
+ provisioner:
6
+ name: chef_zero
7
+ log_level: info
8
+ deprecations_as_errors: true
9
+ cookbooks_path:
10
+ - .
11
+
12
+ platforms:
13
+ - name: "centos-7.2"
14
+
15
+ verifier:
16
+ name: inspec
@@ -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,16 @@
1
+ ---
2
+ driver:
3
+ name: "vagrant"
4
+
5
+ provisioner:
6
+ name: chef_zero
7
+ log_level: info
8
+ deprecations_as_errors: true
9
+ cookbooks_path:
10
+ - .
11
+
12
+ platforms:
13
+ - name: "centos-7.2"
14
+
15
+ verifier:
16
+ name: inspec
@@ -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 %>'
@@ -0,0 +1,4 @@
1
+ sambot cookbook build
2
+ chef exec foodcritic .
3
+ chef exec cookstyle .
4
+ sambot cookbook clean
@@ -0,0 +1,3 @@
1
+ module Sambot
2
+ VERSION = '0.1.19'.freeze
3
+ end
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: []