vagrant-compose 0.2.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,265 +0,0 @@
1
- require_relative "node_group"
2
-
3
-
4
- module VagrantPlugins
5
- module Compose
6
-
7
- # This class defines a cluster, thas is a set of group of nodes, where nodes in each group has similar characteristics.
8
- # Basically, a cluster is a data structure that can be used as a recipe for setting up and provisioning a
9
- # vagrant cluster composed by several machines with different roles.
10
- class Cluster
11
-
12
- # The name of the cluster
13
- attr_reader :name
14
-
15
- # The default vagrant base box to be used for creating vagrant machines in this cluster.
16
- # This setting can be changed at group/node level
17
- attr_accessor :box
18
-
19
- # The network domain to wich the cluster belongs (used for computing nodes fqdn)
20
- attr_accessor :domain
21
-
22
-
23
- # The root path for ansible playbook; it is used as a base path for computing ansible_group_vars and ansible_host_vars
24
- # It defaults to current directory/provisioning
25
- attr_accessor :ansible_playbook_path
26
-
27
- # A dictionary, allowing to setup ansible_group_vars generators foreach node_group
28
- attr_reader :ansible_group_vars
29
-
30
- # A dictionary, allowing to setup ansible_host_vars generators foreach node_group
31
- attr_reader :ansible_host_vars
32
-
33
- # A dictionary, allowing to setup context vars to be uses is value_generators when composing nodes
34
- attr_reader :ansible_context_vars
35
-
36
- # A variable that reflects if vagrant is tageting a single machine, like f.i. when executing vagrant up machine-name
37
- attr_reader :multimachine_filter
38
-
39
- # Costruttore di una istanza di cluster.
40
- def initialize(name)
41
- @group_index = 0
42
- @node_groups = {}
43
- @ansible_context_vars = {}
44
- @ansible_group_vars = {}
45
- @ansible_host_vars = {}
46
- @multimachine_filter = ""
47
- @ansible_playbook_path = File.join(Dir.pwd, 'provisioning')
48
-
49
- @name = name
50
- @box = 'ubuntu/trusty64'
51
- @domain = 'vagrant'
52
- end
53
-
54
- # Metodo per la creazione di un gruppo di nodi; in fase di creazione, il blocco inizializza
55
- # i valori/le expressioni da utilizzarsi nella valorizzazione degli attributi dei nodi in fase di compose.
56
- #
57
- # Oltre alla creazione dei nodi, il metodo prevede anche l'esecuzione di un blocco di codice per
58
- # la configurazione del gruppo di nodi stesso.
59
- def nodes(instances, name, &block)
60
- raise RuntimeError, "Nodes #{name} already exists in this cluster." unless not @node_groups.has_key?(name)
61
-
62
- @node_groups[name] = NodeGroup.new(@group_index, instances, name)
63
- @node_groups[name].box = @box
64
- @node_groups[name].boxname = lambda { |group_index, group_name, node_index| return "#{group_name}#{node_index + 1}" }
65
- @node_groups[name].hostname = lambda { |group_index, group_name, node_index| return "#{group_name}#{node_index + 1}" }
66
- @node_groups[name].aliases = []
67
- @node_groups[name].ip = lambda { |group_index, group_name, node_index| return "172.31.#{group_index}.#{100 + node_index + 1}" }
68
- @node_groups[name].cpus = 1
69
- @node_groups[name].memory = 256
70
- @node_groups[name].ansible_groups = []
71
- @node_groups[name].attributes = {}
72
-
73
- @group_index += 1
74
-
75
- block.call(@node_groups[name]) if block_given?
76
- end
77
-
78
- # Prepara il provisioning del cluster
79
- def compose
80
-
81
- @multimachine_filter = ((['up', 'provision'].include? ARGV[0]) && ARGV.length > 1) ? ARGV.drop(1) : [] # detect if running vagrant up/provision MACHINE
82
-
83
- ## Fase1: Creazione dei nodi
84
-
85
- # sviluppa i vari gruppi di nodi, creando i singoli nodi
86
- nodes = []
87
-
88
- @node_groups.each do |key, group|
89
- group.compose(@name, @domain, nodes.size) do |node|
90
- nodes << node
91
- end
92
- end
93
-
94
- # sviluppa i gruppi abbinando a ciascono i nodi creati
95
- # NB. tiene in considerazione anche l'eventualità che un gruppo possa essere composto da nodi appartenenti a diversi node_groups
96
- ansible_groups= {}
97
- nodes.each do |node|
98
- node.ansible_groups.each do |ansible_group|
99
- ansible_groups[ansible_group] = [] unless ansible_groups.has_key? (ansible_group)
100
- ansible_groups[ansible_group] << node
101
- end
102
- end
103
-
104
- ## Fase2: Configurazione provisioning del cluster via Ansible
105
- # Ogni nodo diventerà una vm su cui sarà fatto il provisioning, ovvero un host nell'inventory di ansible
106
- # Ad ogni gruppo corrispondono nodi con caratteristiche simili
107
-
108
- # genearazione inventory file per ansible, aka ansible_groups in Vagrant (NB. 1 group = 1 gruppo ansible)
109
- ansible_groups_provision = {}
110
- ansible_groups.each do |ansible_group, ansible_group_nodes|
111
- ansible_groups_provision[ansible_group] = []
112
- ansible_group_nodes.each do |node|
113
- ansible_groups_provision[ansible_group] << node.hostname if checkMultimachineFilter(node.boxname) #filter ansible groups if vagrant command on one node
114
- end
115
- end
116
- ansible_groups_provision['all_groups:children'] = ansible_groups.keys
117
-
118
- # Oltre alla creazione del file di inventory per ansible, contenente gruppi e host, è supportata:
119
- # - la creazione di file ansible_group_vars, ovvero di file preposti a contenere una serie di variabili - specifico di ogni gruppo di host -
120
- # per condizionare il provisioning ansible sulla base delle caratteristiche del cluster specifico
121
- # - la creazione di file ansible_host_vars, ovvero di file preposti a contenere una serie di variabili - specifico di ogni host -
122
- # per condizionare il provisioning ansible sulla base delle caratteristiche del cluster specifico
123
-
124
- # La generazione delle variabili utilizza una serie di VariableProvisioner, uno o più d'uno per ogni gruppo di hosts, configurati durante la
125
- # definizione del cluster.
126
-
127
- context = {}
128
-
129
- #genearazione context (NB. 1 group = 1 gruppo host ansible)
130
- ansible_groups.each do |ansible_group, ansible_group_nodes|
131
- # genero le variabili per il group
132
- provisioners = @ansible_context_vars[ansible_group]
133
- unless provisioners.nil?
134
-
135
- # se necessario, normalizzo provisioner in array provisioners
136
- provisioners = [ provisioners ] if not provisioners.respond_to?('each')
137
- # per tutti i provisioners abbinati al ruolo
138
- provisioners.each do |provisioner|
139
- begin
140
- vars = provisioner.call(context, ansible_group_nodes)
141
-
142
- #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi)
143
- context = context.merge(vars)
144
- rescue Exception => e
145
- raise VagrantPlugins::Compose::Errors::ContextVarExpressionError, :message => e.message, :ansible_group => ansible_group
146
- end
147
- end
148
- end
149
- end
150
-
151
- # cleanup ansible_group_vars files
152
- # TODO: make safe
153
- ansible_group_vars_path = File.join(@ansible_playbook_path, 'group_vars')
154
-
155
- FileUtils.mkdir_p(ansible_group_vars_path) unless File.exists?(ansible_group_vars_path)
156
- Dir.foreach(ansible_group_vars_path) {|f| fn = File.join(ansible_group_vars_path, f); File.delete(fn) if f.end_with?(".yml")}
157
-
158
- #generazione ansible_group_vars file (NB. 1 group = 1 gruppo host ansible)
159
- ansible_groups.each do |ansible_group, ansible_group_nodes|
160
- ansible_group_vars = {}
161
- # genero le variabili per il group
162
- provisioners = @ansible_group_vars[ansible_group]
163
- unless provisioners.nil?
164
- # se necessario, normalizzo provisioner in array provisioners
165
- provisioners = [ provisioners ] if not provisioners.respond_to?('each')
166
- # per tutti i provisioners abbinati al ruolo
167
- provisioners.each do |provisioner|
168
- begin
169
- vars = provisioner.call(context, ansible_group_nodes)
170
-
171
- #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi)
172
- ansible_group_vars = ansible_group_vars.merge(vars)
173
- rescue Exception => e
174
- raise VagrantPlugins::Compose::Errors::GroupVarExpressionError, :message => e.message, :ansible_group => ansible_group
175
- end
176
- end
177
- end
178
-
179
- # crea il file (se sono state generate delle variabili)
180
- unless ansible_group_vars.empty?
181
- # TODO: make safe
182
- File.open(File.join(ansible_group_vars_path,"#{ansible_group}.yml") , 'w+') do |file|
183
- file.puts YAML::dump(ansible_group_vars)
184
- end
185
- end
186
- end
187
-
188
- # cleanup ansible_host_vars files (NB. 1 nodo = 1 host)
189
- # TODO: make safe
190
- ansible_host_vars_path = File.join(@ansible_playbook_path, 'host_vars')
191
-
192
- FileUtils.mkdir_p(ansible_host_vars_path) unless File.exists?(ansible_host_vars_path)
193
- Dir.foreach(ansible_host_vars_path) {|f| fn = File.join(ansible_host_vars_path, f); File.delete(fn) if f.end_with?(".yml")}
194
-
195
- #generazione ansible_host_vars file
196
- nodes.each do |node|
197
- # genero le variabili per il nodo; il nodo, può essere abbinato a diversi gruppi
198
- ansible_host_vars = {}
199
- node.ansible_groups.each do |ansible_group|
200
- # genero le variabili per il gruppo
201
- provisioners = @ansible_host_vars[ansible_group]
202
- unless provisioners.nil?
203
- # se necessario, normalizzo provisioner in array provisioners
204
- provisioners = [ provisioners ] if not provisioners.respond_to?('each')
205
- # per tutti i provisioners abbinati al gruppo
206
- provisioners.each do |provisioner|
207
- begin
208
- vars = provisioner.call(context, node)
209
-
210
- #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi)
211
- ansible_host_vars = ansible_host_vars.merge(vars)
212
- rescue Exception => e
213
- raise VagrantPlugins::Compose::Errors::HostVarExpressionError, :message => e.message, :host => node.hostname, :ansible_group => ansible_group
214
- end
215
- end
216
- end
217
- end
218
-
219
- # crea il file (se sono state generate delle variabili)
220
- unless ansible_host_vars.empty?
221
- # TODO: make safe
222
- File.open(File.join(ansible_host_vars_path,"#{node.hostname}.yml") , 'w+') do |file|
223
- file.puts YAML::dump(ansible_host_vars)
224
- end
225
- end
226
- end
227
-
228
- return nodes, ansible_groups_provision
229
- end
230
-
231
- # Prepara il provisioning del cluster
232
- def from(file)
233
- puts "from #{file}"
234
- begin
235
- a = `ls`
236
- puts "get #{a}"
237
- rescue Exception => e
238
- raise VagrantPlugins::Compose::Errors::PyComposeError, :message => e.message
239
- end
240
- end
241
-
242
- def checkMultimachineFilter(boxname)
243
- if @multimachine_filter.length > 0
244
- @multimachine_filter.each do |name|
245
- if pattern = name[/^\/(.+?)\/$/, 1]
246
- # This is a regular expression name, so we convert to a regular
247
- # expression and allow that sort of matching.
248
- regex = Regexp.new(pattern)
249
- return boxname =~ regex
250
- else
251
- # String name, just look for a specific VM
252
- return boxname == name
253
- end
254
- end
255
- else
256
- # No name was given, so we return every VM in the order
257
- # configured.
258
- return true
259
- end
260
- end
261
-
262
- end
263
-
264
- end
265
- end
@@ -1,102 +0,0 @@
1
- require_relative "node"
2
-
3
- module VagrantPlugins
4
- module Compose
5
-
6
- # This class defines a group of nodes, representig a set of vagrant machines with similar characteristics.
7
- # Nodes will be composed by NodeGroup.compose method, according with the configuration of values/value_generator
8
- # of the group of node itself.
9
- class NodeGroup
10
-
11
- # A number identifying the group of nodes withing the cluster.
12
- attr_reader :index
13
-
14
- # The name of the group of nodes
15
- attr_reader :name
16
-
17
- # The number of nodes/instances to be created in the group of nodes.
18
- attr_reader :instances
19
-
20
- # The value/value generator to be used for assigning to each node in this group a vagrant base box to be used for creating vagrant machines implementing nodes in this group.
21
- attr_accessor :box
22
-
23
- # The value/value generator to be used for assigning to each node in this group a box name a.k.a. the name for the machine in VirtualBox/VMware console.
24
- attr_accessor :boxname
25
-
26
- # The value/value generator to be used for assigning to each node in this group a unique hostname
27
- attr_accessor :hostname
28
-
29
- # The value/value generator to be used for assigning to each node in this group a unique list of aliases a.k.a. alternative host names
30
- attr_accessor :aliases
31
-
32
- # The value/value generator to be used for assigning to each node in this groupa unique ip
33
- attr_accessor :ip
34
-
35
- # The value/value generator to be used for assigning to each node in this group cpus
36
- attr_accessor :cpus
37
-
38
- # The value/value generator to be used for assigning to each node in this group memory
39
- attr_accessor :memory
40
-
41
- # The value/value generator to be used for assigning each node in this group to a list of ansible groups
42
- attr_accessor :ansible_groups
43
-
44
- # The value/value generator to be used for assigning a dictionary with custom attributes - Hash(String, obj) - to each node in this group.
45
- attr_accessor :attributes
46
-
47
- def initialize(index, instances, name)
48
- @index = index
49
- @name = name
50
- @instances = instances
51
- end
52
-
53
- # Composes the group of nodes, by creating the required number of nodes
54
- # in accordance with values/value_generators.
55
- # Additionally, some "embedded" trasformation will be applied to attributes (boxname, hostname) and
56
- # some "autogenerated" node properties will be computed (fqdn).
57
- def compose(cluster_name, cluster_domain, cluster_offset)
58
- node_index = 0
59
- while node_index < @instances
60
- box = generate(:box, @box, node_index)
61
- boxname = maybe_prefix(cluster_name,
62
- "#{generate(:boxname, @boxname, node_index)}")
63
- hostname = maybe_prefix(cluster_name,
64
- "#{generate(:hostname, @hostname, node_index)}")
65
- aliases = generate(:aliases, @aliases, node_index).join(',')
66
- fqdn = cluster_domain.empty? ? "#{hostname}" : "#{hostname}.#{cluster_domain}"
67
- ip = generate(:ip, @ip, node_index)
68
- cpus = generate(:cpus, @cpus, node_index)
69
- memory = generate(:memory, @memory, node_index)
70
- ansible_groups = generate(:ansible_groups, @ansible_groups, node_index)
71
- attributes = generate(:attributes, @attributes, node_index)
72
- yield Node.new(box, boxname, hostname, fqdn, aliases, ip, cpus, memory, ansible_groups, attributes, cluster_offset + node_index, node_index)
73
-
74
- node_index += 1
75
- end
76
- end
77
-
78
- # utility function for concatenating cluster name (if present) to boxname/hostname
79
- def maybe_prefix(cluster_name, name)
80
- if cluster_name && cluster_name.length > 0
81
- "#{cluster_name}-" + name
82
- else
83
- name
84
- end
85
- end
86
-
87
- # utility function for resolving value/value generators
88
- def generate(var, generator, node_index)
89
- unless generator.respond_to? :call
90
- return generator
91
- else
92
- begin
93
- return generator.call(@index, @name, node_index)
94
- rescue Exception => e
95
- raise VagrantPlugins::Compose::Errors::AttributeExpressionError, :message => e.message, :attribute => var, :node_index => node_index, :node_group_name => name
96
- end
97
- end
98
- end
99
- end
100
-
101
- end
102
- end