builderator 0.3.15 → 1.0.0.pre.rc.1

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +440 -0
  4. data/README.md +72 -18
  5. data/Rakefile +1 -2
  6. data/VERSION +1 -1
  7. data/bin/build-clean +102 -0
  8. data/bin/build-data +45 -0
  9. data/builderator.gemspec +7 -4
  10. data/docs/configuration.md +154 -0
  11. data/docs/configuration/cookbook.md +19 -0
  12. data/docs/configuration/profile.md +71 -0
  13. data/docs/versioning.md +65 -0
  14. data/lib/builderator.rb +3 -0
  15. data/lib/builderator/config.rb +93 -0
  16. data/lib/builderator/config/attributes.rb +287 -0
  17. data/lib/builderator/config/defaults.rb +163 -0
  18. data/lib/builderator/config/file.rb +336 -0
  19. data/lib/builderator/config/rash.rb +80 -0
  20. data/lib/builderator/control/cleaner.rb +138 -0
  21. data/lib/builderator/control/cookbook.rb +16 -0
  22. data/lib/builderator/control/data.rb +16 -0
  23. data/lib/builderator/control/data/image.rb +98 -0
  24. data/lib/builderator/control/version.rb +128 -0
  25. data/lib/builderator/control/version/auto.rb +48 -0
  26. data/lib/builderator/control/version/bump.rb +82 -0
  27. data/lib/builderator/control/version/comparable.rb +77 -0
  28. data/lib/builderator/control/version/git.rb +45 -0
  29. data/lib/builderator/control/version/scm.rb +92 -0
  30. data/lib/builderator/interface.rb +67 -0
  31. data/lib/builderator/interface/berkshelf.rb +38 -0
  32. data/lib/builderator/interface/packer.rb +75 -0
  33. data/lib/builderator/interface/vagrant.rb +31 -0
  34. data/lib/builderator/metadata.rb +5 -3
  35. data/lib/builderator/model/cleaner.rb +49 -0
  36. data/lib/builderator/model/cleaner/images.rb +93 -0
  37. data/lib/builderator/model/cleaner/instances.rb +58 -0
  38. data/lib/builderator/model/cleaner/launch_configs.rb +47 -0
  39. data/lib/builderator/model/cleaner/scaling_groups.rb +45 -0
  40. data/lib/builderator/model/cleaner/snapshots.rb +50 -0
  41. data/lib/builderator/model/cleaner/volumes.rb +48 -0
  42. data/lib/builderator/patch/berkshelf.rb +18 -0
  43. data/lib/builderator/patch/thor-actions.rb +47 -0
  44. data/lib/builderator/tasks.rb +127 -17
  45. data/lib/builderator/tasks/berkshelf.rb +63 -0
  46. data/lib/builderator/tasks/packer.rb +17 -56
  47. data/lib/builderator/tasks/vagrant.rb +111 -42
  48. data/lib/builderator/tasks/vendor.rb +94 -0
  49. data/lib/builderator/tasks/version.rb +58 -0
  50. data/lib/builderator/util.rb +37 -11
  51. data/lib/builderator/util/aws_exception.rb +1 -1
  52. data/lib/builderator/util/limit_exception.rb +12 -11
  53. data/lib/builderator/util/task_exception.rb +0 -2
  54. data/mkmf.log +4 -0
  55. data/spec/config_spec.rb +30 -0
  56. data/spec/data/Berksfile +6 -0
  57. data/spec/data/Buildfile +0 -0
  58. data/spec/data/Vagrantfile +0 -0
  59. data/spec/data/history.json +483 -0
  60. data/spec/data/packer.json +0 -0
  61. data/spec/interface_spec.rb +36 -0
  62. data/spec/resource/Buildfile +27 -0
  63. data/spec/spec_helper.rb +90 -0
  64. data/spec/version_spec.rb +282 -0
  65. data/template/Berksfile.erb +10 -0
  66. data/template/Buildfile.erb +28 -0
  67. data/template/Gemfile.erb +16 -0
  68. data/template/README.md.erb +61 -0
  69. data/template/Vagrantfile.erb +75 -0
  70. data/template/gitignore.erb +104 -0
  71. data/{.rubocop.yml → template/rubocop.erb} +0 -0
  72. metadata +203 -56
  73. data/.gitignore +0 -14
  74. data/lib/builderator/control/ami.rb +0 -65
  75. data/lib/builderator/control/clean.rb +0 -130
  76. data/lib/builderator/model.rb +0 -46
  77. data/lib/builderator/model/images.rb +0 -89
  78. data/lib/builderator/model/instances.rb +0 -55
  79. data/lib/builderator/model/launch_configs.rb +0 -46
  80. data/lib/builderator/model/scaling_groups.rb +0 -43
  81. data/lib/builderator/model/snapshots.rb +0 -49
  82. data/lib/builderator/model/volumes.rb +0 -48
  83. data/lib/builderator/tasks/ami.rb +0 -47
  84. data/lib/builderator/tasks/berks.rb +0 -68
  85. data/lib/builderator/tasks/clean.rb +0 -97
  86. data/lib/builderator/util/berkshim.rb +0 -34
  87. data/lib/builderator/util/cookbook.rb +0 -87
  88. data/lib/builderator/util/packer.rb +0 -39
  89. data/lib/builderator/util/shell.rb +0 -44
data/README.md CHANGED
@@ -1,30 +1,84 @@
1
1
  # Builderator
2
- __Tools to make CI Packer builds awesome__
3
2
 
4
- ## Installation
3
+ Orchestration and configuration of the code development life-cycle.
5
4
 
6
- Add this line to your application's Gemfile:
5
+ ## Commands
7
6
 
8
- ```ruby
9
- gem 'builderator'
10
- ```
7
+ ### `local [PROFILE = default]`
8
+
9
+ Provision a local VM using Vagrant and, by default, VirtualBox. Uses Berkshelf to fetch cookbooks, and Chef to provision the VM.
10
+
11
+ ### `ec2 [PROFILE = default]`
12
+
13
+ Provision an EC2 VM using Vagrant. Same workflow as `local` using the `vagrant-aws` plugin.
14
+
15
+ ### `release [PROFILE = default]`
16
+
17
+ Perform release tasks and execute Packer builds with released artifacts.
18
+
19
+ ## Configuration
20
+
21
+ Configuration can be loaded from DSL files as well as JSON and command line arguments. By default, Builderator searches in your home directory (`$HOME/.builderator/Buildfile`) and the working directory (`./Builderator`) for DSL files. Configuration sources are layered and flattened into a single DSL in the following order:
22
+
23
+ * Global defaults defined in the Builderator sources
24
+ * `Config.defaults` set by plugins, tasks, etc. in code
25
+ * `$HOME/.builderator/Buildfile`
26
+ * `./Buildfile`
27
+ * `Config.overrides` set by plugins, tasks, etc. in code
28
+ * CLI arguments loaded from Thor
29
+
30
+ [Additional documentation](docs/configuration.md) describes the configuration DSL interface.
31
+
32
+ ## Integrations
11
33
 
12
- And then execute:
34
+ Builderator integrates with other tools, including [Berkshelf](http://berkshelf.com), [Vagrant](https://www.vagrantup.com/), and [Packer](https://www.packer.io/), to orchestrate workflows by generating `Berksfile`s, `Vagrantfile`s, and JSON strings for Packer. This means that you can replace all of these files in your project with a single `Buildfile`.
13
35
 
14
- $ bundle
36
+ ### Packer
15
37
 
16
- Or install it yourself as:
38
+ The Packer integration generates Packer JSON and passes it to STDIN of `packer build -`.
17
39
 
18
- $ gem install builderator
40
+ *NOTE* Currently, we assume that you're building Ubuntu images, as one of the provisioners is hard-coded to chown the Chef data directories to `ubuntu:ubuntu`
19
41
 
20
- ## Usage
42
+ ## Versioning
21
43
 
22
- Run `bundle exec thor build help`
44
+ Builderator can automatically detect versions from SCM tags, increment the latest version of an SCM branch by a variety of steps, and create new SCM tags for new versions.
45
+
46
+ [Additional documentation](docs/versioning.md) describes CLI commands, configuration, and detailed behavior.
47
+
48
+ ## Generators
49
+
50
+ Builderator includes a task to generate common project trees from configuration definitions and templates.
51
+
52
+ Each type of project is configurable via the project collection in the `generator` namespace:
53
+
54
+ ```ruby
55
+ generator.project :default do |default|
56
+ default.ruby.version '2.1.5'
57
+ default.builderator.version '~> 1.0'
58
+
59
+ default.vagrant do |vagrant|
60
+ vagrant.install false
61
+ vagrant.version 'v1.8.0'
62
+
63
+ vagrant.plugin 'vagrant-aws'
64
+ vagrant.plugin 'vagrant-omnibus'
65
+ end
66
+
67
+ default.resource :berksfile do |berksfile|
68
+ berksfile.path 'Berksfile', 'Berksfile.lock'
69
+ berksfile.action :rm
70
+ end
71
+
72
+ default.resource :buildfile do |buildfile|
73
+ buildfile.path 'Buildfile'
74
+ buildfile.action :create
75
+ buildfile.template 'template/Buildfile.erb'
76
+ end
77
+
78
+ # ...
79
+ end
80
+ ```
23
81
 
24
- ## Contributing
82
+ Valid actions for resources include `:ignore`, `:create` (update only if missing), `:sync` (create or update with prompt), and `:rm`. `:create` and `:sync` actions require a valid template source.
25
83
 
26
- 1. Fork it ( https://github.com/[my-github-username]/builderator/fork )
27
- 2. Create your feature branch (`git checkout -b my-new-feature`)
28
- 3. Commit your changes (`git commit -am 'Add some feature'`)
29
- 4. Push to the branch (`git push origin my-new-feature`)
30
- 5. Create a new Pull Request
84
+ By default, the `generator` subcommand includes a `default` project which removes Vagrant, Berkshelf, and Packer configurations.
data/Rakefile CHANGED
@@ -1,2 +1 @@
1
- require "bundler/gem_tasks"
2
-
1
+ require 'bundler/gem_tasks'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.15
1
+ 1.0.0-rc.1
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'thor'
4
+
5
+ require_relative '../lib/builderator/config'
6
+ require_relative '../lib/builderator/control/cleaner'
7
+
8
+ module Builderator
9
+ module Tasks
10
+ ##
11
+ # Tasks to identify and remove unused EC2 resources
12
+ ##
13
+ class Cleaner < Thor
14
+ class_option :region,
15
+ :type => :string,
16
+ :aliases => :r,
17
+ :desc => 'AWS Region in which to perform tasks'
18
+ class_option :commit,
19
+ :type => :boolean,
20
+ :default => false,
21
+ :desc => 'Perform mutating API calls to cleanup resources'
22
+ class_option :filter,
23
+ :type => :array,
24
+ :aliases => :f,
25
+ :desc => 'Key/value pairs to filter resources (--filter name foo owner_id 123456789)'
26
+ class_option :force,
27
+ :type => :boolean,
28
+ :default => false,
29
+ :desc => 'Disable safety restrictions, including resource limits'
30
+
31
+ class_option 'group-by',
32
+ :type => :array,
33
+ :desc => 'Tags/properties by which to group resources for pruning'
34
+ class_option 'sort-by',
35
+ :type => :string,
36
+ :default => 'creation_date',
37
+ :desc => 'Tag/property by which to sort grouped resources'
38
+ class_option :keep,
39
+ :type => :numeric,
40
+ :default => 5,
41
+ :desc => 'Number of resources in each group to keep'
42
+
43
+ def initialize(*_)
44
+ super
45
+
46
+ ## Convert array of filter key-values to a hash
47
+ options['filters'] = Hash[*options['filter']] if options['filter'].is_a?(Array)
48
+
49
+ ## Load command flags
50
+ Config.argv(:cleaner => options, :aws => { :region => options['region'] })
51
+ Config.load(File.join(ENV['HOME'], '.builderator/Buildfile'))
52
+ Config.load(Util.relative_path('Buildfile').to_s)
53
+
54
+ Config.recompile
55
+
56
+ say_status 'dry-run', 'This is a dry-run.' unless Config.cleaner.commit
57
+ end
58
+
59
+ desc 'configs', 'Delete unused launch configurations'
60
+ def configs
61
+ Control::Cleaner.configs!(&method(:say_status))
62
+ end
63
+
64
+ desc 'images', 'Deregister unused images'
65
+ def images
66
+ Control::Cleaner.images!(&method(:say_status))
67
+ end
68
+
69
+ desc 'snapshots', 'Delete unused snapshots'
70
+ def snapshots
71
+ Control::Cleaner.snapshots!(&method(:say_status))
72
+ end
73
+
74
+ desc 'volumes', 'Delete unused volumes'
75
+ def volumes
76
+ Control::Cleaner.volumes!(&method(:say_status))
77
+ end
78
+
79
+ desc 'all', 'Cleaner volumes, launch configs, images, and snapshots in order'
80
+ def all
81
+ volumes
82
+ configs
83
+ images
84
+ snapshots
85
+
86
+ ## TODO Print resource counts here.
87
+ return if Control::Cleaner.exceptions.empty?
88
+
89
+ say_status :fail, 'Not all tasks completed successfully. The following '\
90
+ 'exceptions occured:', :red
91
+ Control::Cleaner.exceptions.each do |e|
92
+ say_status(*e.status)
93
+ end
94
+
95
+ ## Mark the Jenkins job as fail if there were errors.
96
+ exit(1)
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ Builderator::Tasks::Cleaner.start(ARGV)
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'thor'
4
+
5
+ require_relative '../lib/builderator/config'
6
+ require_relative '../lib/builderator/control/data'
7
+
8
+ module Builderator
9
+ module Tasks
10
+ ##
11
+ # Tasks to search AWS APIs
12
+ ##
13
+ class Data < Thor
14
+ def initialize(*_)
15
+ super
16
+
17
+ Config.load(File.join(ENV['HOME'], '.builderator/Buildfile'))
18
+ Config.load(Util.relative_path('Buildfile').to_s)
19
+
20
+ Config.recompile
21
+ end
22
+
23
+ desc 'image ', 'Search for AMIs'
24
+ method_option 'filter', :type => :string, :aliases => :f
25
+ method_option 'latest', :type => :boolean, :aliases => :l, :default => false
26
+ def image(*query)
27
+ query = Hash[*query]
28
+
29
+ ## Load a pre-defined filter
30
+ query['filter'] = options['filter']
31
+
32
+ result = Control::Data.image(query)
33
+
34
+ if options['latest']
35
+ puts result.first.image_id
36
+ return
37
+ end
38
+
39
+ puts result.map(&:image_id).join(', ')
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ Builderator::Tasks::Data.start(ARGV)
@@ -13,18 +13,21 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'https://github.com/rapid7/builderator'
14
14
  spec.license = 'MIT'
15
15
 
16
- spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = Dir[File.join(Builderator::PATH, 'bin/*')].map { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(/^(test|spec|features)\//)
16
+ spec.files = Dir['**/*']
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.add_development_dependency 'rake', '~> 10.0'
22
+ spec.add_development_dependency 'rspec', '~> 3.0'
23
+ spec.add_development_dependency 'rubocop', '~> 0.35'
24
+ spec.add_development_dependency 'thor-scmversion', '1.7.0'
22
25
 
23
26
  spec.add_dependency 'aws-sdk', '~> 2.0'
24
27
  spec.add_dependency 'bundler', '~> 1.7.0'
25
28
  spec.add_dependency 'berkshelf', '~> 3.2'
26
29
  spec.add_dependency 'chef', '~> 12.0'
30
+ spec.add_dependency 'faraday_middleware', '~> 0.10.0'
27
31
  spec.add_dependency 'ignorefile'
28
32
  spec.add_dependency 'thor', '~> 0.19.0'
29
- spec.add_dependency 'thor-scmversion', '1.7.0'
30
33
  end
@@ -0,0 +1,154 @@
1
+ Configuration DSL
2
+ =================
3
+
4
+ The configuration DSL is made up of key-value pairs, called `attributes`, which are grouped into `namespaces` and `collections`.
5
+
6
+ Namespaces can accessed with blocks, or with a fluent interface:
7
+
8
+ ```ruby
9
+ aws do |a|
10
+ a.region = 'us-west-1'
11
+ end
12
+
13
+ ## Is the same as
14
+ aws.region = 'us-west-1'
15
+ ```
16
+
17
+ Collections are named sets. Like namespaces, they can be accessed with blocks, or a fluent interface:
18
+
19
+ ```ruby
20
+ profile :default do |default_profile|
21
+ default_profile.chef.run_list 'apt:default', 'redis:server'
22
+ end
23
+
24
+ profile(:default).chef.environment 'development'
25
+ ```
26
+
27
+ In the example above, the same collection is accessed twice. The final result looks like:
28
+
29
+ ```json
30
+ {
31
+ "profile": {
32
+ "default": {
33
+ "chef": {
34
+ "run_list": ["apt:default", "redis:server"],
35
+ "environment": "development"
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## Helper Methods
43
+
44
+ * `lookup(source, query)` - Query an external data-source for a value inline.
45
+ * Source `:image`: Return an array of EC2 instances, sorted by `creation_date` (See http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Client.html#describe_images-instance_method)
46
+
47
+ * `vendored(name, path)` - Return the absolute path to `path` in the named vendor resource. _ Hint: Use this helper to reference Builderator policy files and Chef data_bag and environment sources in an external repository._
48
+
49
+ ## Configuration File DSL
50
+
51
+ Collections and namespaces may be nested indefinitely.
52
+
53
+ * [Namespace `cookbook`](configuration/cookbook.md)
54
+ * [Collection `profile`](configuration/profile.md)
55
+
56
+ * `build_name, required: true` The name of the build
57
+ * `build_number` Optional reference to the CI build number for this release
58
+ * `build_url` Optional link the CI page for this release
59
+ * `description` A short human-readable description of the build
60
+ * `version` The version of this release of the build. Auto-populated by `autoversion` by default
61
+ * `cleanup` Enable post-build cleanup tasks. Default `true`
62
+
63
+ * `relative(path)` - Return the absolute path to `path` relative to the calling Buildfile _Hint: Use this helper to reference templates included with a vendored policy._
64
+
65
+ ## Namespace `autoversion`
66
+
67
+ * `create_tags` During a release, automatically create and push new SCM tags
68
+ * `search_tags` Use SCM tags to determine the current version of the build
69
+
70
+ ## Namespace `chef`
71
+
72
+ Global configurations for chef provisioners in Vagrant and Packer
73
+
74
+ * `log_level` Chef client/solo log level
75
+ * `staging_directory` the path in VMs and images that Chef artifacts should be mounted/copied to. Defaults to `/var/chef`
76
+ * `version` The version of chef to install with Omnibus
77
+
78
+ ## Namespace `local`
79
+
80
+ Local paths used for build tasks
81
+
82
+ * `cookbook_path` Path at which to vendor cookbooks. Default `.builderator/cookbooks`
83
+ * `data_bag_path` and `environment_path` Paths that Chef providers should load data-bag and environment documents from.
84
+
85
+ ## Collection `policy`
86
+
87
+ Load additional attributes into the parent file from a relative path
88
+
89
+ * `path` Load a DSL file, relative => true
90
+ * `json` Load a JSON file relative => true
91
+
92
+ ## Namespace `aws`
93
+
94
+ AWS API configurations. _Hint: Configure these in `$HOME/.builderator/Buildfile`, or use a built-in credential source, e.g. ~/.aws/config!_
95
+
96
+ * `region` The default AWS region to use
97
+ * `access_key` and `secret_key` A valid IAM key-pair
98
+
99
+ ## Collection `vendor`
100
+
101
+ Fetch remote artifacts for builds
102
+
103
+ * Sources:
104
+ * `path` Link to a local file/directory
105
+ * `git` Fetch a git repository
106
+ * `github` Fetch a git repository from a GitHub URI (e.g. `OWNER/REPO`) using the SSH protocol. You must have a valid SSH key configuration for public GitHub.
107
+ * Git-specific parameters:
108
+ * `branch`
109
+ * `tag`
110
+ * `ref`
111
+ * `rel` Checkout a sub-directory of a git repository
112
+
113
+ ## Namespace `cleaner`
114
+
115
+ Configuration parameters for `build-clean` tasks
116
+
117
+ ### Namespace `limits`
118
+
119
+ Maximum number of resources to remove without manual override
120
+
121
+ * `images`
122
+ * `launch_configs`
123
+ * `snapshots`
124
+ * `volumes`
125
+
126
+ ## Namespace `generator`
127
+
128
+ Configurations for the `generator` task
129
+
130
+ ### Collection `project`
131
+
132
+ * `builderator.version` The version of Builderator to install with Bundler
133
+ * `ruby.version` The version of ruby to require for Bundler and `rbenv`/`rvm`
134
+
135
+ #### Namespace `vagrant`
136
+
137
+ * `install` Boolean, include the vagrant gem from GitHub `mitchellh/vagrant`
138
+ * `version` The version of Vagrant to use from GitHub, if `install` is true
139
+
140
+ ##### Collection `plugin`
141
+
142
+ Vagrant plugins to install, either with the `build vagrant plugin` command, for a system-wide installation of Vagrant, or in the generated Gemfile if `install` is true
143
+
144
+ #### Collection `resource`
145
+
146
+ Add a managed file to the project definition
147
+
148
+ * `action` One of
149
+ * `:create` Add a file from a template if it's missing
150
+ * `:sync` Create or update a file from a template, stopping to ask for instructions if the file exists and the templated output does not match
151
+ * `:ignore` Do nothing
152
+ * `:rm` Delete a file if it exists
153
+ * `path` One or more path in the working directory the this resource manages. Action `:rm` will delete multiple files, while `:create` and `:sync` will only use the first element of the list as their destination.
154
+ * `template` The path to an ERB template. Must be an absolute path: use the [helpers](#helpers) in the Buildfile namespace to extend paths inline.
@@ -0,0 +1,19 @@
1
+ cookbook
2
+ ========
3
+
4
+ * `path` The path to a local cookbook source, including a valid `metadata.rb` file.
5
+ * `sources, type: list, singular: add_source, unique: true` Supermarket APIs to resolve cookbook dependencies from
6
+ * `metadata` Boolean. Read dependencies from local cookbook metadata.
7
+
8
+ ## `depends name`
9
+
10
+ Collection of declared cookbook dependencies. Options are passed to [Berkshelf](http://berkshelf.com/). Check out their docs for additional details.
11
+
12
+ * `version` A version constraint spec for the cookbook
13
+ * `git` A git URI from which to fetch the cookbook
14
+ * `GitHub` A GitHub URL from which to fetch the cookbook
15
+ * `branch` A branch reference from which to fetch the cookbook
16
+ * `tag` A tag reference from which to fetch the cookbook
17
+ * `ref` A comittish reference from which to fetch the cookbook
18
+ * `rel` The sub-directory of a git repository to check out as a cookbook
19
+ * `path` The path to a local cookbook, relative to the build workspace.