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.
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: []