builderator 0.3.15 → 1.0.0.pre.rc.1

Sign up to get free protection for your applications and to get access to all the features.
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.