vagrant-config_builder 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +14 -0
- data/README.markdown +65 -0
- data/examples/roles.yaml +29 -0
- data/examples/vms.yaml +12 -0
- data/lib/config_builder/action/load_extensions.rb +14 -0
- data/lib/config_builder/class_registry.rb +58 -0
- data/lib/config_builder/filter/roles.rb +71 -0
- data/lib/config_builder/filter.rb +5 -0
- data/lib/config_builder/filter_stack.rb +31 -0
- data/lib/config_builder/loader/yaml.rb +32 -0
- data/lib/config_builder/loader.rb +22 -0
- data/lib/config_builder/model/base.rb +86 -0
- data/lib/config_builder/model/network/forwarded_port.rb +32 -0
- data/lib/config_builder/model/network/private_network.rb +15 -0
- data/lib/config_builder/model/provider/virtualbox.rb +35 -0
- data/lib/config_builder/model/provisioner/puppet.rb +23 -0
- data/lib/config_builder/model/provisioner/puppet_server.rb +15 -0
- data/lib/config_builder/model/provisioner/shell.rb +27 -0
- data/lib/config_builder/model/root.rb +41 -0
- data/lib/config_builder/model/ssh.rb +10 -0
- data/lib/config_builder/model/synced_folder.rb +43 -0
- data/lib/config_builder/model/vm.rb +130 -0
- data/lib/config_builder/model.rb +62 -0
- data/lib/config_builder/model_delegator.rb +30 -0
- data/lib/config_builder/plugin.rb +15 -0
- data/lib/config_builder/runner.rb +25 -0
- data/lib/config_builder/version.rb +3 -0
- data/lib/config_builder.rb +14 -0
- data/lib/vagrant-config_builder.rb +1 -0
- data/vagrant-config_builder.gemspec +19 -0
- metadata +76 -0
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`
|
data/examples/roles.yaml
ADDED
@@ -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,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,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,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
|