vagrant-config_builder 0.1.0

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.
data/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ Copyright 2013 Adrien Thebo
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+
data/README.markdown ADDED
@@ -0,0 +1,65 @@
1
+ Vagrant Config Builder
2
+ ======================
3
+
4
+ Configure and manage your Vagrant environments with data.
5
+
6
+ Synopsis
7
+ --------
8
+
9
+ This plugin provides an interface to the Vagrant configuration constructs in a
10
+ logic free manner. You can format your input data to fit your needs and use
11
+ `vagrant-config_builder` to transform that into the needed Vagrant config.
12
+
13
+ Example
14
+ -------
15
+
16
+ This example loads all yaml files in the config directory and generates a
17
+ Vagrant config based on that information. File names are arbitrary and chosen
18
+ for clarity.
19
+
20
+ #### Directory structure
21
+
22
+ .
23
+ ├── config
24
+ │   ├── roles.yaml
25
+ │   └── vms.yaml
26
+ └── Vagrantfile
27
+
28
+ #### Vagrantfile
29
+
30
+ require 'config_builder'
31
+ Vagrant.configure('2', &ConfigBuilder.load(
32
+ :yaml,
33
+ :yamldir,
34
+ File.expand_path('config', __DIR__)
35
+ ))
36
+
37
+ #### config/roles.yaml
38
+
39
+ ---
40
+ roles:
41
+ bigvm:
42
+ provider:
43
+ type: virtualbox
44
+ customize: [[modifyvm, !ruby/sym id, '--memory', 1024]]
45
+
46
+ #### config/vms.yaml
47
+
48
+ ---
49
+ vms:
50
+ -
51
+ name: db
52
+ private_networks: [ {ip: '10.20.1.2'} ]
53
+ box: centos-5-i386
54
+ roles: bigvm
55
+ -
56
+ name: web
57
+ private_networks: [ {ip: '10.20.1.3'} ]
58
+ box: centos-5-i386
59
+
60
+ Installation
61
+ ------------
62
+
63
+ Installation into the Vagrant internal gems:
64
+
65
+ * `vagrant plugin install vagrant-config_builder`
@@ -0,0 +1,29 @@
1
+ ---
2
+ roles:
3
+ puppetmaster:
4
+ provider:
5
+ type: virtualbox
6
+ customize: [[modifyvm, !ruby/sym id, '--memory', 1024]]
7
+ provisioners:
8
+ -
9
+ type: shell
10
+ inline: 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
11
+ -
12
+ type: hosts
13
+ -
14
+ type: pe_bootstrap
15
+ role: !ruby/sym master
16
+ relocate_manifests: false
17
+ version: '2.6.0'
18
+ puppetagent:
19
+ provisioners:
20
+ -
21
+ type: shell
22
+ inline: 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
23
+ -
24
+ type: hosts
25
+ -
26
+ type: pe_bootstrap
27
+ role: !ruby/sym agent
28
+ version: '2.6.0'
29
+
data/examples/vms.yaml ADDED
@@ -0,0 +1,12 @@
1
+ ---
2
+ vms:
3
+ -
4
+ name: master
5
+ private_networks: [ {auto_network: true} ]
6
+ box: centos-5-i386
7
+ roles: puppetmaster
8
+ -
9
+ name: agent
10
+ private_networks: [ {auto_network: true} ]
11
+ box: centos-5-i386
12
+ roles: puppetagent
@@ -0,0 +1,14 @@
1
+ module ConfigBuilder
2
+ module Action
3
+ class LoadExtensions
4
+ def initialize(app, env)
5
+ @app, @env = app, env
6
+ end
7
+
8
+ def call(hash)
9
+ hash[:env].hook(:config_builder_extension)
10
+ @app.call(hash)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,58 @@
1
+ require 'vagrant/errors'
2
+
3
+ module ConfigBuilder
4
+
5
+ # This defines a registry for classes, and behaves as a factory for registered classes.
6
+ #
7
+ # @api private
8
+ class ClassRegistry
9
+
10
+ class UnknownEntryError < Vagrant::Errors::VagrantError; end
11
+
12
+ def initialize(name)
13
+ @name = name
14
+ @klasses = {}
15
+ end
16
+
17
+ # Register a class with a given identifier
18
+ #
19
+ # @param identifier [Symbol]
20
+ # @param klass [Class]
21
+ #
22
+ # @return [void]
23
+ def register(identifier, klass)
24
+ @klasses[identifier] = klass
25
+ end
26
+
27
+ # Retrieve a class associated with the specified identifier
28
+ #
29
+ # @param identifier [Symbol]
30
+ #
31
+ # @return [Class]
32
+ def retrieve(identifier)
33
+ if (klass = @klasses[identifier])
34
+ klass
35
+ else
36
+ raise UnknownEntryError, "#{self.inspect} doesn't have an entry registered with key #{identifier.inspect}"
37
+ end
38
+ end
39
+
40
+ # Generate a class instance with the given hash
41
+ #
42
+ # @param hash [Hash] The identifier and options for the new object
43
+ # @option hash type [String] The identifier of the class to instantiate
44
+ #
45
+ # @return [Object] The generated object
46
+ def generate(hash)
47
+ identifier = hash.delete('type')
48
+
49
+ klass = retrieve(identifier)
50
+
51
+ klass.new_from_hash(hash)
52
+ end
53
+
54
+ def inspect
55
+ "<#{self.class}: (#{@name})>"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,71 @@
1
+ class ConfigBuilder::Filter::Roles
2
+
3
+ def run(input)
4
+ strip_filter_data(input)
5
+
6
+ vms = @vms.map { |vm_hash| filter_vm(vm_hash) }
7
+
8
+ add_filtered_data(input, vms)
9
+
10
+ input
11
+ end
12
+
13
+ private
14
+
15
+ def strip_filter_data(input)
16
+ @roles = input.delete('roles')
17
+ @vms = input.delete('vms')
18
+ end
19
+
20
+ def add_filtered_data(input, vms)
21
+ input['vms'] = vms
22
+ end
23
+
24
+ def filter_vm(vm_hash)
25
+ role_names = roles_for_vm(vm_hash.delete('roles'))
26
+
27
+ new_vm_hash = merge_role_definitions(role_names)
28
+ new_vm_hash.merge!(vm_hash)
29
+
30
+ new_vm_hash
31
+ end
32
+
33
+ # Generate a hash of all the merged roles. Roles specified later in the hash
34
+ # overwrite earlier roles.
35
+ #
36
+ # @param names [Hash]
37
+ #
38
+ # @return [Hash]
39
+ def merge_role_definitions(role_names)
40
+ vm_template = {}
41
+
42
+ role_names.each do |name|
43
+ role_definition = @roles[name]
44
+ vm_template.merge!(role_definition)
45
+ end
46
+
47
+ vm_template
48
+ end
49
+
50
+ # @return [Array]
51
+ def roles_for_vm(role_field)
52
+ case role_field
53
+ when Array
54
+ rval = role_field
55
+ when String
56
+ rval = [role_field]
57
+ when NilClass
58
+ rval = []
59
+ end
60
+
61
+ rval
62
+ end
63
+
64
+ def role_definition(name)
65
+ if (defn = @roles[name])
66
+ defn
67
+ else
68
+ raise "Couldn't find role named #{name.inspect} in roles #{@roles.keys.inspect}"
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,5 @@
1
+ module ConfigBuilder
2
+ module Filter
3
+ require 'config_builder/filter/roles'
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ require 'config_builder/filter'
2
+
3
+ module ConfigBuilder
4
+ class FilterStack
5
+
6
+ def initialize
7
+ @filter_stack = []
8
+ end
9
+
10
+ # @param input [Hash]
11
+ #
12
+ # @return [Hash]
13
+ def filter(input)
14
+ set_filters(input.delete(:filters))
15
+
16
+ @filter_stack.inject(input) do |current_input, filter|
17
+ filter.run(current_input)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def set_filters(list)
24
+ if list.nil?
25
+ @filter_stack << ConfigBuilder::Filter::Roles.new
26
+ else
27
+ raise NotImplementedError, "Custom lists of filters not implemented."
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ require 'yaml'
2
+
3
+ class ConfigBuilder::Loader::YAML
4
+
5
+ # Load configuration from all files in a given directory
6
+ #
7
+ # @param dir_path [String]
8
+ #
9
+ # @return [Hash]
10
+ def yamldir(dir_path)
11
+ glob_path = File.join(dir_path, '*.{yml,yaml}')
12
+
13
+ rv = {}
14
+ Dir.glob(glob_path).each do |file|
15
+ contents = ::YAML.load_file(file)
16
+ rv.merge!(contents)
17
+ end
18
+
19
+ rv
20
+ end
21
+
22
+ # Load configuration from a file
23
+ #
24
+ # @param file_path [String]
25
+ #
26
+ # @return [Hash]
27
+ def yamlfile(file_path)
28
+ ::YAML.load_file(file_path)
29
+ end
30
+
31
+ ConfigBuilder::Loader.register(:yaml, self)
32
+ end
@@ -0,0 +1,22 @@
1
+ require 'config_builder/class_registry'
2
+
3
+ module ConfigBuilder
4
+ module Loader
5
+ @registry = ConfigBuilder::ClassRegistry.new(:loader)
6
+
7
+ def self.register(identifier, klass)
8
+ @registry.register(identifier, klass)
9
+ end
10
+
11
+ def self.retrieve(identifier)
12
+ @registry.retrieve(identifier)
13
+ end
14
+
15
+ def self.generate(identifier, method_name, method_value)
16
+ obj = retrieve(identifier).new
17
+ obj.send(method_name, method_value)
18
+ end
19
+
20
+ require 'config_builder/loader/yaml'
21
+ end
22
+ end
@@ -0,0 +1,86 @@
1
+ # A ConfigBuilder model implements a logic-less interface to a component of
2
+ # Vagrant.
3
+ #
4
+ # A model should implement the following methods:
5
+ #
6
+ # ## `self.new_from_hash`
7
+ #
8
+ # This method takes an arbitrarily nested data structure of basic data types
9
+ # (Arrays, Hashes, Numerics, Strings, etc) and instantiates a new object
10
+ # with attributes set based on that data structure.
11
+ #
12
+ # ## `#to_proc`
13
+ #
14
+ # This method takes the object attributes and generates a lambda that will
15
+ # create a Vagrant config with the state specified by the attributes. The
16
+ # lambda should have an arity of one and should be passed a `config` object.
17
+ # The generated block will generate the Vagrant config that implements the
18
+ # behavior specified by the object attributes.
19
+ #
20
+ # If the Model delegates certain configuration to other models, the generated
21
+ # lambda should be able to evaluate lambdas from the delegated models.
22
+ #
23
+ # Implementing classes do not need to inherit from ConfigBuilder::Model::Base,
24
+ # but it makes life easier.
25
+ class ConfigBuilder::Model::Base
26
+
27
+ # Deserialize a hash into a configbuilder model
28
+ #
29
+ # @param attributes [Hash] The model attributes as represented in a hash.
30
+ # @return [Object < ConfigBuilder::Model]
31
+ def self.new_from_hash(attributes)
32
+ obj = new()
33
+ obj.attrs = attributes
34
+ obj
35
+ end
36
+
37
+ # @api private
38
+ def attrs=(config)
39
+ hash = config.inject({}) { |hash, (key, value)| hash[key.to_sym] = value; hash }
40
+
41
+ if @defaults
42
+ @attrs = @defaults.merge(hash)
43
+ else
44
+ @attrs = hash
45
+ end
46
+ end
47
+
48
+ # Generate a block based on configuration specified by the attributes
49
+ #
50
+ # @abstract
51
+ # @return [Proc]
52
+ def to_proc
53
+ raise NotImplementedError
54
+ end
55
+
56
+ # Generate a block based on the attribute configuration and call it with
57
+ # the given config.
58
+ #
59
+ # @param [Vagrant.plugin('2', :config)]
60
+ # @return [void]
61
+ def call(config)
62
+ to_proc.call(config)
63
+ end
64
+
65
+ # @param identifier [Symbol]
66
+ #
67
+ # @return [Object] The value of the model attribute specified by `identifier`
68
+ #
69
+ # @todo validate identifier
70
+ def attr(identifier)
71
+ @attrs[identifier]
72
+ end
73
+ private :attr
74
+
75
+ class << self
76
+
77
+ # @param identifier [Symbol]
78
+ def def_model_attribute(identifier)
79
+ model_attributes << identifier
80
+ end
81
+
82
+ def model_attributes
83
+ (@identifiers ||= [])
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,32 @@
1
+ # Vagrant forwarded port model
2
+ #
3
+ # @see http://docs.vagrantup.com/v2/networking/forwarded_ports.html
4
+ class ConfigBuilder::Model::Network::ForwardedPort < ConfigBuilder::Model::Base
5
+
6
+ # @!attribute [rw] guest
7
+ # @return [Fixnum] The guest port
8
+ def_model_attribute :guest
9
+
10
+ # @!attribute [rw] host
11
+ # @return [Fixnum] The host port
12
+ def_model_attribute :host
13
+
14
+ # @!attribute [rw] auto_correct
15
+ # @return [Boolean] Whether to automatically correct port collisions
16
+ def_model_attribute :auto_correct
17
+
18
+ def initialize
19
+ @defaults = {:auto_correct => false}
20
+ end
21
+
22
+ def to_proc
23
+ Proc.new do |vm_config|
24
+ vm_config.network(
25
+ :forwarded_port,
26
+ :guest => attr(:guest),
27
+ :host => attr(:host),
28
+ :auto_correct => attr(:auto_correct)
29
+ )
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ # Vagrant private network
2
+ #
3
+ # @see http://docs.vagrantup.com/v2/networking/private_network.html
4
+ class ConfigBuilder::Model::Network::PrivateNetwork < ConfigBuilder::Model::Base
5
+
6
+ # @!attribute [rw] :ip
7
+ # @return [String] The IP address to use for the private network interface
8
+ def_model_attribute :ip
9
+
10
+ def to_proc
11
+ Proc.new do |vm_config|
12
+ vm_config.network(:private_network, :ip => attr(:ip))
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ # @see http://docs.vagrantup.com/v2/virtualbox/configuration.html
2
+ class ConfigBuilder::Model::Provider::Virtualbox < ConfigBuilder::Model::Base
3
+
4
+ # @!attribute [rw] name
5
+ # @return [String] The name of the created VM in the Virtualbox GUI
6
+ def_model_attribute :name
7
+
8
+ # @!attribute [rw] customize
9
+ # @return [Array<String>] A list of customize arguments to use upon VM instantiation.
10
+ def_model_attribute :customize
11
+
12
+ # @!attribute [rw] gui
13
+ # @return [Boolean] Whether the GUI should be launched when the VM is created
14
+ def_model_attribute :gui
15
+
16
+ def initialize
17
+ @defaults = {:customize => []}
18
+ end
19
+
20
+ def to_proc
21
+ Proc.new do |vm_config|
22
+ vm_config.provider 'virtualbox' do |vb_config|
23
+ vb_config.name = attr(:name) if attr(:name)
24
+
25
+ attr(:customize).each do |cmd|
26
+ vb_config.customize cmd
27
+ end
28
+
29
+ vb_config.gui = attr(:gui) if attr(:gui)
30
+ end
31
+ end
32
+ end
33
+
34
+ ConfigBuilder::Model::Provider.register('virtualbox', self)
35
+ end
@@ -0,0 +1,23 @@
1
+ # @see http://docs.vagrantup.com/v2/provisioning/puppet_apply.html
2
+ class ConfigBuilder::Model::Provisioner::Puppet
3
+
4
+ # @!attribute [rw] manifests_path
5
+ # @return [String] The path to the puppet manifests.
6
+ attr_accessor :manifests_path
7
+
8
+ # @!attribute [rw] manifest_file
9
+ # @return [String] The name of the manifest to apply
10
+ attr_accessor :manifest_file
11
+
12
+ # @!attribute [rw] module_path
13
+ # @return [String] A colon separated set of filesystem paths for Puppet
14
+ attr_accessor :module_path
15
+
16
+ # @!attribute [rw] facter
17
+ # @return [Hash] A hash of values to use as facts
18
+ attr_accessor :facter
19
+
20
+ # @!attribute [rw] options
21
+ # @return [String] An arbitrary set of arguments for the `puppet` command
22
+ attr_accessor :options
23
+ end
@@ -0,0 +1,15 @@
1
+ # @see http://docs.vagrantup.com/v2/provisioning/puppet_agent.html
2
+ class ConfigBuilder::Model::Provisioner::PuppetServer
3
+
4
+ # @!attribute [rw] puppet_server
5
+ # @return [String]
6
+ attr_accessor :puppet_server
7
+
8
+ # @!attribute [rw] node_name
9
+ # @return [String]
10
+ attr_accessor :node_name
11
+
12
+ # @!attribute [rw] options
13
+ # @return [String]
14
+ attr_accessor :options
15
+ end
@@ -0,0 +1,27 @@
1
+ # @see http://docs.vagrantup.com/v2/provisioning/shell.html
2
+ class ConfigBuilder::Model::Provisioner::Shell < ConfigBuilder::Model::Base
3
+
4
+ # @!attribute [rw] inline
5
+ # @return [String] The inline shell command to run
6
+ def_model_attribute :inline
7
+
8
+ # @!attribute [rw] path
9
+ # @return [String] The path to the shell script to run
10
+ def_model_attribute :path
11
+
12
+ # @!attribute [rw] args
13
+ # @return [String] A string acting as an argument vector to the command.
14
+ def_model_attribute :args
15
+
16
+ def to_proc
17
+ Proc.new do |vm_config|
18
+ vm_config.provision :shell do |shell_config|
19
+ shell_config.inline = attr(:inline) if attr(:inline)
20
+ shell_config.path = attr(:path) if attr(:path)
21
+ shell_config.args = attr(:args) if attr(:args)
22
+ end
23
+ end
24
+ end
25
+
26
+ ConfigBuilder::Model::Provisioner.register('shell', self)
27
+ end
@@ -0,0 +1,41 @@
1
+ # Model the root level Vagrant config object
2
+ #
3
+ # @see http://docs.vagrantup.com/v2/vagrantfile/index.html
4
+ class ConfigBuilder::Model::Root < ConfigBuilder::Model::Base
5
+
6
+ include ConfigBuilder::ModelDelegator
7
+
8
+ def_model_delegator :vagrant
9
+ def_model_delegator :ssh
10
+ def_model_delegator :vms
11
+
12
+
13
+ def initialize
14
+ @defaults = {:vms => [], :vagrant => {}}
15
+ end
16
+
17
+ def to_proc
18
+ Proc.new do |root_config|
19
+ eval_models(root_config)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def eval_vms(root_config)
26
+ attr(:vms).each do |hash|
27
+ v = ConfigBuilder::Model::VM.new_from_hash(hash)
28
+ v.call(root_config)
29
+ end
30
+ end
31
+
32
+ def eval_vagrant(root_config)
33
+ if attr(:vagrant).has_key? :host
34
+ root_config.vagrant.host = attr(:vagrant)[:host]
35
+ end
36
+ end
37
+
38
+ def eval_ssh(root_config)
39
+
40
+ end
41
+ end
@@ -0,0 +1,10 @@
1
+ # @see http://docs.vagrantup.com/v2/vagrantfile/ssh_settings.html
2
+ class ConfigBuilder::Model::SSH < ConfigBuilder::Model::Base
3
+ # @!attribute [rw] guest_port
4
+ # @!attribute [rw] keepalive
5
+ # @!attribute [rw] max_tries
6
+ # @!attribute [rw] timeout
7
+ # @!attribute [rw] forward_x11
8
+ # @!attribute [rw] forward_agent
9
+ # @!attribute [rw] shell
10
+ end
@@ -0,0 +1,43 @@
1
+ # Vagrant shared folder model.
2
+ #
3
+ # @see http://docs.vagrantup.com/v2/synced-folders/index.html
4
+ class ConfigBuilder::Model::SyncedFolder < ConfigBuilder::Model::Base
5
+
6
+ # @!attribute [rw] host_path
7
+ # @return [String] The host file path to mount on the guest
8
+ def_model_attribute :host_path
9
+
10
+ # @!attribute [rw] guest_path
11
+ # @return [String] The guest file path to be used as the mount point
12
+ def_model_attribute :guest_path
13
+
14
+ # @!attribute [rw] extra
15
+ # A set of arbitrary options to pass to the virtualbox mount command.
16
+ # @return [String]
17
+ def_model_attribute :extra
18
+
19
+ # @!attribute [rw] disabled
20
+ # @return [Boolean] If the mount point should be disabled.
21
+ def_model_attribute :disabled
22
+
23
+ # @!attribute [rw] nfs
24
+ # @return [Boolean] If the mount point should use NFS
25
+ def_model_attribute :nfs
26
+
27
+ def to_proc
28
+ Proc.new do |vm_config|
29
+ vm_config.synced_folder(attr(:host_path), attr(:guest_path), folder_opts)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def folder_opts
36
+ h = {}
37
+ h[:extra] = attr(:extra) if attr(:extra)
38
+ h[:disabled] = attr(:disabled) if attr(:disabled)
39
+ h[:nfs] = attr(:nfs) if attr(:nfs)
40
+
41
+ h
42
+ end
43
+ end
@@ -0,0 +1,130 @@
1
+ # @see http://docs.vagrantup.com/v2/vagrantfile/machine_settings.html
2
+ class ConfigBuilder::Model::VM < ConfigBuilder::Model::Base
3
+
4
+ include ConfigBuilder::ModelDelegator
5
+
6
+ # @!attribute [rw] provider
7
+ # @return [Hash<Symbol, Object>] The provider configuration for
8
+ # this VM
9
+ # @example
10
+ # >> vm.provider
11
+ # => {
12
+ # :type => 'virtualbox',
13
+ # :name => 'tiny-tina',
14
+ # :gui => false,
15
+ # }
16
+ def_model_delegator :provider
17
+
18
+ # @!attribute [rw] provisioners
19
+ # @return [Array<Hash<Symbol, Object>>] A collection of provisioner
20
+ # parameters in the order that they should be applied
21
+ # of provisioner types, and a list of provisioner instances for each type
22
+ # @example
23
+ # >> vm.provisioners
24
+ # => [
25
+ # {:type => :shell, :path => '/vagrant/bin/magic.sh'},
26
+ # {:type => :shell, :inline => '/bin/echo hello world'},
27
+ #
28
+ # {:type => :puppet, :manifest => 'foo.pp'},
29
+ # {:type => :puppet, :manifest => 'bar.pp', :modulepath => '/vagrant/modules'},
30
+ # ]
31
+ def_model_delegator :provisioners
32
+
33
+ # @!attribute [rw] forwarded_ports
34
+ # @return [Array<Hash<Symbol, Object>>] A collection of port mappings
35
+ # @example
36
+ # >> vm.forwarded_ports
37
+ # => [
38
+ # {:guest => 80, :host => 20080},
39
+ # {:guest => 443, :host => 20443},
40
+ # ]
41
+ def_model_delegator :forwarded_ports
42
+
43
+ # @!attribute [rw] private_networks
44
+ # @return [Array<Hash<Symbol, Object>>] A collection of IP address network
45
+ # settings.
46
+ # @example
47
+ # >> vm.private_networks
48
+ # => [
49
+ # {:ip => '10.20.4.1'},
50
+ # {:ip => '192.168.100.5', :netmask => '255.255.255.128'},
51
+ # ]
52
+ def_model_delegator :private_networks
53
+
54
+ # @!attribute [rw] synced_folders
55
+ # @return [Array<Hash<Symbol, Object>>]
56
+ # @example
57
+ # >> vm.synced_folders
58
+ # => [
59
+ # {:host_path => 'manifests/', :guest_path => '/root/manifests', :disabled => false},
60
+ # {:host_path => 'modules/', :guest_path => '/root/modules'},
61
+ # ]
62
+ #
63
+ def_model_delegator :synced_folders
64
+
65
+ # @!attribute [rw] box
66
+ # @return [String] The name of the Vagrant box to instantiate for this VM
67
+ def_model_attribute :box
68
+
69
+ # @!attribute [rw] name
70
+ # @return [String] The name of the instantiated box in this environment
71
+ def_model_attribute :name
72
+
73
+ def initialize
74
+ @defaults = {
75
+ :provisioners => [],
76
+ :forwarded_ports => [],
77
+ :private_networks => [],
78
+ :synced_folders => [],
79
+ }
80
+ end
81
+
82
+ def to_proc
83
+ Proc.new do |global_config|
84
+ global_config.vm.define(attr(:name)) do |config|
85
+ vm_config = config.vm
86
+
87
+ vm_config.box = attr(:box) if defined? attr(:box)
88
+
89
+ eval_models(vm_config)
90
+ end
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def eval_provisioners(vm_config)
97
+ attr(:provisioners).each do |hash|
98
+ p = ConfigBuilder::Model::Provisioner.new_from_hash(hash)
99
+ p.call(vm_config)
100
+ end
101
+ end
102
+
103
+ def eval_provider(vm_config)
104
+ if attr(:provider)
105
+ p = ConfigBuilder::Model::Provider.new_from_hash(attr(:provider))
106
+ p.call(vm_config)
107
+ end
108
+ end
109
+
110
+ def eval_private_networks(vm_config)
111
+ attr(:private_networks).each do |hash|
112
+ n = ConfigBuilder::Model::Network::PrivateNetwork.new_from_hash(hash)
113
+ n.call(vm_config)
114
+ end
115
+ end
116
+
117
+ def eval_forwarded_ports(vm_config)
118
+ attr(:forwarded_ports).each do |hash|
119
+ f = ConfigBuilder::Model::Network::ForwardedPort.new_from_hash(hash)
120
+ f.call(vm_config)
121
+ end
122
+ end
123
+
124
+ def eval_synced_folders(vm_config)
125
+ attr(:synced_folders).each do |hash|
126
+ f = ConfigBuilder::Model::SyncedFolder.new_from_hash(hash)
127
+ f.call(vm_config)
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,62 @@
1
+ require 'vagrant/errors'
2
+ require 'config_builder/class_registry'
3
+ require 'config_builder/model_delegator'
4
+
5
+ module ConfigBuilder
6
+
7
+ module Model
8
+
9
+ class UnknownAttributeError < Vagrant::Errors::VagrantError; end
10
+
11
+ require 'config_builder/model/base'
12
+
13
+ require 'config_builder/model/root'
14
+
15
+ require 'config_builder/model/ssh'
16
+ #require 'config_builder/model/host'
17
+
18
+ require 'config_builder/model/vm'
19
+ require 'config_builder/model/synced_folder'
20
+
21
+ def self.generate(hash)
22
+ ConfigBuilder::Model::Root.new_from_hash(hash)
23
+ end
24
+
25
+ module Network
26
+ require 'config_builder/model/network/forwarded_port'
27
+ require 'config_builder/model/network/private_network'
28
+ end
29
+
30
+ module Provider
31
+
32
+ @registry = ConfigBuilder::ClassRegistry.new(:provider)
33
+
34
+ def self.new_from_hash(hash)
35
+ @registry.generate(hash)
36
+ end
37
+
38
+ def self.register(name, klass)
39
+ @registry.register(name, klass)
40
+ end
41
+
42
+ require 'config_builder/model/provider/virtualbox'
43
+ end
44
+
45
+ module Provisioner
46
+
47
+ @registry = ConfigBuilder::ClassRegistry.new(:provisioner)
48
+
49
+ def self.new_from_hash(hash)
50
+ @registry.generate(hash)
51
+ end
52
+
53
+ def self.register(name, klass)
54
+ @registry.register(name, klass)
55
+ end
56
+
57
+ require 'config_builder/model/provisioner/shell'
58
+ require 'config_builder/model/provisioner/puppet'
59
+ require 'config_builder/model/provisioner/puppet_server'
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,30 @@
1
+ module ConfigBuilder
2
+ module ModelDelegator
3
+
4
+ def model_delegators
5
+ self.class.model_delegators
6
+ end
7
+
8
+ def eval_models(config)
9
+ model_delegators.each do |model|
10
+ meth = "eval_#{model}"
11
+ send(meth, config)
12
+ end
13
+ end
14
+
15
+ def self.included(klass)
16
+ klass.extend ClassMethods
17
+ end
18
+
19
+ module ClassMethods
20
+ def def_model_delegator(identifier)
21
+ def_model_attribute(identifier)
22
+ model_delegators << identifier
23
+ end
24
+
25
+ def model_delegators
26
+ (@models ||= [])
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,15 @@
1
+ require 'vagrant'
2
+
3
+ require 'config_builder/action/load_extensions'
4
+
5
+ module VagrantPlugins
6
+ module ConfigBuilder
7
+ class Plugin < Vagrant.plugin('2')
8
+ name "Generate Vagrant configuration from logic-less data sources"
9
+
10
+ action_hook('ConfigBuilder: load extensions', :environment_load) do |hook|
11
+ hook.prepend(::ConfigBuilder::Action::LoadExtensions)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ require 'config_builder/loader'
2
+ require 'config_builder/filter_stack'
3
+ require 'config_builder/model'
4
+
5
+ module ConfigBuilder
6
+ class Runner
7
+
8
+ def run(identifier, method, value)
9
+ data = ConfigBuilder::Loader.generate(identifier, method, value)
10
+ filtered_data = run_filters(data)
11
+ model = generate_model(filtered_data)
12
+ end
13
+
14
+ private
15
+
16
+ def run_filters(data)
17
+ stack = ConfigBuilder::FilterStack.new
18
+ stack.filter(data)
19
+ end
20
+
21
+ def generate_model(filtered_hash)
22
+ ConfigBuilder::Model.generate(filtered_hash)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module ConfigBuilder
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,14 @@
1
+ require 'vagrant'
2
+
3
+ module ConfigBuilder
4
+ require 'config_builder/loader'
5
+ require 'config_builder/model'
6
+ require 'config_builder/runner'
7
+ require 'config_builder/plugin'
8
+ require 'config_builder/version'
9
+
10
+ def self.load(identifier, method, value)
11
+ runner = ConfigBuilder::Runner.new
12
+ runner.run(identifier, method, value)
13
+ end
14
+ end
@@ -0,0 +1 @@
1
+ require 'config_builder'
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH << File.expand_path(File.join('..', 'lib'), __FILE__)
2
+ require 'config_builder/version'
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'vagrant-config_builder'
6
+ gem.version = ConfigBuilder::VERSION
7
+
8
+ gem.summary = 'Generate Vagrant configurations from arbitrary data'
9
+
10
+ gem.authors = 'Adrien Thebo'
11
+ gem.email = 'adrien@somethingsinistral.net'
12
+ gem.homepage = 'https://github.com/adrienthebo/vagrant-config_builder'
13
+
14
+ gem.has_rdoc = true
15
+ gem.license = 'Apache 2.0'
16
+
17
+ gem.files = %x{git ls-files -z}.split("\0")
18
+ gem.require_path = 'lib'
19
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-config_builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adrien Thebo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-08 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description:
15
+ email: adrien@somethingsinistral.net
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE
21
+ - README.markdown
22
+ - examples/roles.yaml
23
+ - examples/vms.yaml
24
+ - lib/config_builder.rb
25
+ - lib/config_builder/action/load_extensions.rb
26
+ - lib/config_builder/class_registry.rb
27
+ - lib/config_builder/filter.rb
28
+ - lib/config_builder/filter/roles.rb
29
+ - lib/config_builder/filter_stack.rb
30
+ - lib/config_builder/loader.rb
31
+ - lib/config_builder/loader/yaml.rb
32
+ - lib/config_builder/model.rb
33
+ - lib/config_builder/model/base.rb
34
+ - lib/config_builder/model/network/forwarded_port.rb
35
+ - lib/config_builder/model/network/private_network.rb
36
+ - lib/config_builder/model/provider/virtualbox.rb
37
+ - lib/config_builder/model/provisioner/puppet.rb
38
+ - lib/config_builder/model/provisioner/puppet_server.rb
39
+ - lib/config_builder/model/provisioner/shell.rb
40
+ - lib/config_builder/model/root.rb
41
+ - lib/config_builder/model/ssh.rb
42
+ - lib/config_builder/model/synced_folder.rb
43
+ - lib/config_builder/model/vm.rb
44
+ - lib/config_builder/model_delegator.rb
45
+ - lib/config_builder/plugin.rb
46
+ - lib/config_builder/runner.rb
47
+ - lib/config_builder/version.rb
48
+ - lib/vagrant-config_builder.rb
49
+ - vagrant-config_builder.gemspec
50
+ homepage: https://github.com/adrienthebo/vagrant-config_builder
51
+ licenses:
52
+ - Apache 2.0
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 1.8.23
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Generate Vagrant configurations from arbitrary data
75
+ test_files: []
76
+ has_rdoc: true