dewiring 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +15 -0
  2. data/bin/wire +7 -0
  3. data/bin/wire-network-container.sh +547 -0
  4. data/lib/test_fig.rb +46 -0
  5. data/lib/wire/cli/cli_commands.rb +88 -0
  6. data/lib/wire/cli/main_cli.rb +129 -0
  7. data/lib/wire/cli.rb +8 -0
  8. data/lib/wire/commands/base_command.rb +139 -0
  9. data/lib/wire/commands/down_command.rb +69 -0
  10. data/lib/wire/commands/down_command_handler.rb +199 -0
  11. data/lib/wire/commands/init_command.rb +89 -0
  12. data/lib/wire/commands/init_interactive.rb +75 -0
  13. data/lib/wire/commands/spec_command.rb +240 -0
  14. data/lib/wire/commands/spec_templates.rb +134 -0
  15. data/lib/wire/commands/up_command.rb +69 -0
  16. data/lib/wire/commands/up_command_handler.rb +193 -0
  17. data/lib/wire/commands/updown_command_base.rb +80 -0
  18. data/lib/wire/commands/validate_command.rb +64 -0
  19. data/lib/wire/commands/verify_command.rb +196 -0
  20. data/lib/wire/commands/verify_command_handler.rb +134 -0
  21. data/lib/wire/commands.rb +19 -0
  22. data/lib/wire/common.rb +42 -0
  23. data/lib/wire/execution/local_exec.rb +110 -0
  24. data/lib/wire/execution.rb +7 -0
  25. data/lib/wire/model/appgroup_validation.rb +45 -0
  26. data/lib/wire/model/loader.rb +49 -0
  27. data/lib/wire/model/network_validation.rb +111 -0
  28. data/lib/wire/model/project.rb +64 -0
  29. data/lib/wire/model/state.rb +154 -0
  30. data/lib/wire/model/validation.rb +66 -0
  31. data/lib/wire/model/verification.rb +37 -0
  32. data/lib/wire/model.rb +13 -0
  33. data/lib/wire/resource/bridge.rb +76 -0
  34. data/lib/wire/resource/dhcp_range_config.rb +135 -0
  35. data/lib/wire/resource/fig_adapter.rb +127 -0
  36. data/lib/wire/resource/ip_binary.rb +141 -0
  37. data/lib/wire/resource/ipaddr_ext.rb +38 -0
  38. data/lib/wire/resource/ipaddr_on_intf.rb +108 -0
  39. data/lib/wire/resource/network_injection.rb +138 -0
  40. data/lib/wire/resource/resource.rb +52 -0
  41. data/lib/wire/resource.rb +14 -0
  42. data/lib/wire/version.rb +14 -0
  43. data/lib/wire.rb +24 -0
  44. metadata +117 -0
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+
3
+ # The MIT License (MIT)
4
+ # Copyright (c) 2014 Andreas Schmidt, andreas@de-wiring.net
5
+ #
6
+
7
+ # Wire module
8
+ module Wire
9
+ # interactive ask_ commands
10
+ class InitInteractive
11
+ # ask for a comma separated list of zone names
12
+ # returns
13
+ # - [Array] of zone names
14
+ def self.ask_for_zone_names
15
+ question = <<-EOF
16
+ Please enter the names of desired system zones,
17
+ as a comma-separated list:
18
+ EOF
19
+ puts question
20
+ print '> '
21
+
22
+ line = STDIN.gets.chomp
23
+
24
+ line.split(',').map { |zone_name| zone_name.strip }
25
+ end
26
+
27
+ # Ask for network names in a zone given by +zone_name+
28
+ # Returns
29
+ # - [Array] of network names
30
+ def self.ask_for_network_in_zone(zone_name)
31
+ question = <<-EOF
32
+ - Configuring networks in zone #{zone_name}:
33
+ Please enter the names of logical networks
34
+ (or leave empty if no networks desired):
35
+ EOF
36
+ puts question
37
+ print '> '
38
+
39
+ line = STDIN.gets.chomp
40
+
41
+ line.split(',').map { |network_name| network_name.strip }
42
+ end
43
+
44
+ # For a network given by +network_name+, ask for details
45
+ # i.e. ipaddress etc.
46
+ # Returns
47
+ # - [Hash] of details
48
+ def self.ask_detail_data_for_network(network_name)
49
+ question = <<-EOF
50
+ = Configuring network #{network_name}
51
+ Please enter network address in cidr (i.e.192.168.1.0/24)
52
+ EOF
53
+ puts question
54
+ print '> '
55
+
56
+ line = STDIN.gets.chomp
57
+ result = {}
58
+
59
+ result.store :network, line.chomp.strip
60
+
61
+ question = <<-EOF
62
+ Please enter ip address of this network on host (i.e.192.168.1.1)
63
+ OR leave empty if not desired.
64
+ EOF
65
+ puts question
66
+ print '> '
67
+
68
+ line = STDIN.gets.chomp.strip
69
+
70
+ result.store(:hostip, line) if line.size > 0
71
+
72
+ result
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,240 @@
1
+ # encoding: utf-8
2
+
3
+ # The MIT License (MIT)
4
+ # Copyright (c) 2014 Andreas Schmidt, andreas@de-wiring.net
5
+ #
6
+
7
+ # Wire module
8
+ module Wire
9
+ # SpecCommand generates a serverspec output for
10
+ # given model which tests all model elements.
11
+ # optionally runs serverspec
12
+ class SpecCommand < BaseCommand
13
+ # +project+ to operate on
14
+ attr_accessor :project
15
+ # +target_dir+ to read model from (and put specs into)
16
+ attr_accessor :target_dir
17
+
18
+ # spec_code will contain all serverspec
19
+ # code blocks, ready to be written to file
20
+ attr_accessor :spec_code
21
+
22
+ # initializes empty spec
23
+ def initialize
24
+ @spec_code = []
25
+ end
26
+
27
+ # process specification for whole project model
28
+ def run_on_project
29
+ @target_dir = @params[:target_dir]
30
+ zones = @project.get_element('zones')
31
+
32
+ # iterates all zones, descend into zone
33
+ run_on_project_zones(zones)
34
+
35
+ # use the specwrite class to write a complete
36
+ # serverspec example in a subdirectory(serverspec)
37
+ target_specdir = File.join(@target_dir, 'serverspec')
38
+
39
+ begin
40
+ spec_writer = SpecWriter.new(target_specdir, @spec_code)
41
+ spec_writer.write
42
+
43
+ outputs 'SPEC', "Serverspecs written to #{target_specdir}. Run:"
44
+ outputs 'SPEC', "( cd #{target_specdir}; sudo rake spec )"
45
+ outputs 'SPEC', 'To run automatically, use --run'
46
+ rescue => exception
47
+ $log.error "Error writing serverspec files, #{exception}"
48
+ STDERR.puts e.inspect
49
+ end
50
+
51
+ run_serverspec(target_specdir) if @params[:auto_run]
52
+ end
53
+
54
+ # executes serverspec in its target directory
55
+ # TODO: stream into stdout instead of Kernel.``
56
+ # params:
57
+ # +target_dir+ model and output dir
58
+ def run_serverspec(target_specdir)
59
+ $log.debug 'Running serverspec'
60
+ cmd = "cd #{target_specdir} && sudo rake spec"
61
+ $log.debug "cmd=#{cmd}"
62
+ result = `#{cmd}`
63
+ puts result
64
+ end
65
+
66
+ # run verification on +zones+
67
+ def run_on_project_zones(zones)
68
+ zones.select do |zone_name, _|
69
+ $log.debug("Creating specs for zone #{zone_name} ...")
70
+ run_on_zone(zone_name)
71
+ $log.debug("Done for zone #{zone_name} ...")
72
+ end
73
+ end
74
+
75
+ # run spec steps in given +zone_name+
76
+ def run_on_zone(zone_name)
77
+ networks = @project.get_element('networks')
78
+
79
+ # select networks in current zone only
80
+ networks_in_zone = networks.select do|_, network_data|
81
+ network_data[:zone] == zone_name
82
+ end
83
+ networks_in_zone.each do |network_name, network_data|
84
+ run_on_network_in_zone zone_name, network_name, network_data
85
+ end
86
+
87
+ # select application groups in current zone
88
+ objects_in_zone('appgroups', zone_name).each do |appgroup_name, appgroup_data|
89
+ run_on_appgroup_in_zone zone_name, appgroup_name, appgroup_data
90
+ end
91
+ end
92
+
93
+ # given a network object, this generates spec
94
+ # for it.
95
+ # params:
96
+ # +zone_name+ name of zone (needed for erb context)
97
+ # +bridge_name+ name of network/bridge (needed for erb context)
98
+ # +network_data+ network details
99
+ # rubocop:disable Lint/UnusedMethodArgument
100
+ # rubocop:disable Lint/UselessAssignment
101
+ # :reek:UnusedParameters
102
+ def run_on_network_in_zone(zone_name, bridge_name, network_data)
103
+ $log.debug("Creating specs for network #{bridge_name}")
104
+
105
+ template = SpecTemplates.build_template__bridge_exists
106
+ erb = ERB.new(template, nil, '%')
107
+ @spec_code << erb.result(binding)
108
+
109
+ # render template for hostip (if any)
110
+ ip = network_data[:hostip]
111
+ if ip
112
+ template = SpecTemplates.build_template__ip_is_up
113
+ erb = ERB.new(template, nil, '%')
114
+ @spec_code << erb.result(binding)
115
+ end
116
+
117
+ # render dhcp spec (if any)
118
+ dhcp_data = network_data[:dhcp]
119
+ if dhcp_data
120
+ ip_start = dhcp_data[:start]
121
+ ip_end = dhcp_data[:end]
122
+ hostip = ip
123
+ template = SpecTemplates.build_template__dhcp_is_valid
124
+ erb = ERB.new(template, nil, '%')
125
+ @spec_code << erb.result(binding)
126
+
127
+ end
128
+
129
+ $log.debug("Done for network #{bridge_name}")
130
+ end
131
+
132
+ # given an appgroup object, this generates spec
133
+ # for it.
134
+ # params:
135
+ # +zone_name+ name of zone (needed for erb context)
136
+ # +appgroup_name+ name of appgroup (needed for erb context)
137
+ # +appgroup_data+ appgroup details
138
+ # rubocop:disable Lint/UnusedMethodArgument Lint/UselessAssignment
139
+ # :reek:UnusedParameters
140
+ def run_on_appgroup_in_zone(zone_name, appgroup_name, appgroup_data)
141
+ $log.debug("Creating specs for appgroup #{appgroup_name}")
142
+
143
+ # check controller
144
+ controller_data = appgroup_data[:controller]
145
+ if controller_data[:type] == 'fig'
146
+ # get fig file name
147
+ figfile_part = controller_data[:file] || "#{zone_name}/fig.yaml"
148
+ figfile = File.join(File.expand_path(@target_dir), figfile_part)
149
+
150
+ template = SpecTemplates.build_template__fig_file_is_valid
151
+ erb = ERB.new(template, nil, '%')
152
+ @spec_code << erb.result(binding)
153
+
154
+ template = SpecTemplates.build_template__fig_containers_are_up
155
+ erb = ERB.new(template, nil, '%')
156
+ @spec_code << erb.result(binding)
157
+ end
158
+
159
+ $log.debug("Done for appgroup #{appgroup_name}")
160
+ end
161
+ end
162
+
163
+ # SpecWriter is able to create a directory
164
+ # structure according to basic serverspec
165
+ # needs and fill in the templates
166
+ class SpecWriter
167
+ # create SpecWriter in +target_dir+ directory
168
+ # with given +spec_contents+
169
+ def initialize(target_dir, spec_contents)
170
+ @target_dir = target_dir
171
+ @spec_contents = spec_contents
172
+ end
173
+
174
+ # writes spec to disk
175
+ def write
176
+ ensure_directory_structure
177
+ ensure_files
178
+ end
179
+
180
+ # make sure that we have a rspec-conformant dir structure
181
+ def ensure_directory_structure
182
+ ensure_directory @target_dir
183
+ ensure_directory File.join(@target_dir, 'spec')
184
+ ensure_directory File.join(@target_dir, 'spec', 'localhost')
185
+ end
186
+
187
+ # writes erb +template+ to open +file+ object
188
+ def write_template(template, file)
189
+ erb = ERB.new(template, nil, '%')
190
+ file.puts(erb.result(binding))
191
+ end
192
+
193
+ # ensures that all serverspec skeleton files such as
194
+ # Rakefile, spec_helper etc. exist
195
+ # Then writes the models specification files into the
196
+ # skeleton
197
+ def ensure_files
198
+ rakefile_name = File.join(@target_dir, 'Rakefile')
199
+ file?(rakefile_name) || File.open(rakefile_name, 'w') do |file|
200
+ write_template(SpecTemplates.template_rakefile, file)
201
+ end
202
+
203
+ spechelper_name = File.join(@target_dir, 'spec', 'spec_helper.rb')
204
+ file?(spechelper_name) || File.open(spechelper_name, 'w') do |file|
205
+ write_template(SpecTemplates.template_spec_helper, file)
206
+ end
207
+
208
+ specfile_name = File.join(@target_dir, 'spec', 'localhost', 'wire_spec.rb')
209
+ File.open(specfile_name, 'w') do |file|
210
+ template = <<ERB
211
+ require 'spec_helper.rb'
212
+
213
+ # begin of generated specs
214
+
215
+ <%= @spec_contents.join('\n') %>
216
+
217
+ # end of spec file
218
+ ERB
219
+ write_template(template, file)
220
+ end
221
+ end
222
+
223
+ private
224
+
225
+ # make sure that +target_dir+ exists
226
+ def ensure_directory(target_dir)
227
+ return if File.exist?(target_dir)
228
+ begin
229
+ FileUtils.mkdir_p(target_dir)
230
+ rescue => excpt
231
+ $log.error "ERROR: Unable to create #{target_dir}: #{excpt}"
232
+ end
233
+ end
234
+
235
+ # checks if +target_file+ exists
236
+ def file?(target_file)
237
+ File.exist?(target_file) && File.file?(target_file)
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,134 @@
1
+ # encoding: utf-8
2
+
3
+ # The MIT License (MIT)
4
+ # Copyright (c) 2014 Andreas Schmidt, andreas@de-wiring.net
5
+ #
6
+
7
+ # Wire module
8
+ module Wire
9
+ # stateless erb template methods used by spec_command.rb
10
+ class SpecTemplates
11
+ # rubocop:disable Lint/UnusedMethodArgument
12
+ # :reek:UnusedParameters
13
+ def self.build_template__bridge_exists
14
+ <<ERB
15
+ describe 'In zone <%= zone_name %> we should have an ovs bridge named <%= bridge_name %>' do
16
+ describe command "sudo ovs-vsctl list-br" do
17
+ its(:stdout) { should match /<%= bridge_name %>/ }
18
+ end
19
+ end
20
+ ERB
21
+ end
22
+
23
+ # rubocop:disable Lint/UnusedMethodArgument
24
+ # :reek:UnusedParameters
25
+ def self.build_template__ip_is_up
26
+ <<ERB
27
+ describe 'In zone <%= zone_name %> we should have the ip <%= ip %> ' \
28
+ 'on ovs bridge named <%= bridge_name %>' do
29
+ describe interface "<%= bridge_name %>" do
30
+ it { should have_ipv4_address '<%= ip %>' }
31
+ end
32
+ end
33
+ ERB
34
+ end
35
+
36
+ # rubocop:disable Lint/UnusedMethodArgument
37
+ # :reek:UnusedParameters
38
+ # requires zone_name, hostip, bridge_name, ip_start, ip_end
39
+ def self.build_template__dhcp_is_valid
40
+ <<ERB
41
+ describe 'In zone <%= zone_name %> we should have dhcp service on ip <%= hostip %> ' \
42
+ 'on ovs bridge named <%= bridge_name %>, serving addresses from ' \
43
+ '<%= ip_start %> to <%= ip_end %>' do
44
+
45
+ describe file '/etc/dnsmasq.d/wire__<%= zone_name %>.conf' do
46
+ it { should be_file }
47
+ its(:content) { should match /<%= ip_start %>/ }
48
+ its(:content) { should match /<%= ip_end %>/ }
49
+ its(:content) { should match /<%= bridge_name %>/ }
50
+ end
51
+
52
+ describe process 'dnsmasq' do
53
+ it { should be_running }
54
+ end
55
+
56
+ describe port(67) do
57
+ it { should be_listening.with('udp') }
58
+ end
59
+
60
+ describe command '/bin/netstat -nlup' do
61
+ its(:stdout) { should match /67.*dnsmasq/ }
62
+ end
63
+ end
64
+ ERB
65
+ end
66
+
67
+ # rubocop:disable Lint/UnusedMethodArgument
68
+ # :reek:UnusedParameters
69
+ # requires figfile, appgroup_name
70
+ def self.build_template__fig_file_is_valid
71
+ <<ERB
72
+ describe 'In zone <%= zone_name %> we should have fig model file for '\
73
+ 'appgroup <%= appgroup_name %>' do
74
+ describe file '<%= figfile %>' do
75
+ it { should be_file }
76
+ end
77
+ end
78
+ ERB
79
+ end
80
+
81
+ # rubocop:disable Lint/UnusedMethodArgument
82
+ # :reek:UnusedParameters
83
+ # requires zone_name, figfile, appgroup_name
84
+ def self.build_template__fig_containers_are_up
85
+ <<ERB
86
+ describe 'In zone <%= zone_name %> we should have containers managed '\
87
+ 'by fig for appgroup <%= appgroup_name %>' do
88
+ describe command 'sudo fig -p <%= appgroup_name %> -f <%= figfile %> ps' do
89
+ its(:stdout) { should match /Up/ }
90
+ end
91
+ end
92
+ ERB
93
+ end
94
+
95
+ # generate template part
96
+ # returns
97
+ # - erb template for spec_helper.rb file
98
+ def self.template_spec_helper
99
+ <<ERB
100
+ require 'serverspec'
101
+ require 'rspec/its'
102
+
103
+ include SpecInfra::Helper::Exec
104
+ include SpecInfra::Helper::DetectOS
105
+
106
+ RSpec.configure do |c|
107
+ if ENV['ASK_SUDO_PASSWORD']
108
+ require 'highline/import'
109
+ c.sudo_password = ask("Enter sudo password: ") { |q| q.echo = false }
110
+ else
111
+ c.sudo_password = ENV['SUDO_PASSWORD']
112
+ end
113
+ end
114
+ ERB
115
+ end
116
+
117
+ # generate template part
118
+ # returns
119
+ # - erb template for Rakefile
120
+ def self.template_rakefile
121
+ <<ERB
122
+ require 'rake'
123
+ require 'rspec/core/rake_task'
124
+
125
+ RSpec::Core::RakeTask.new(:spec) do |t|
126
+ t.pattern = 'spec/*/*_spec.rb'
127
+ t.rspec_opts = '--format documentation --color'
128
+ end
129
+
130
+ task :default => :spec
131
+ ERB
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ # The MIT License (MIT)
4
+ # Copyright (c) 2014 Andreas Schmidt, andreas@de-wiring.net
5
+ #
6
+
7
+ # Wire module
8
+ module Wire
9
+ # UpCommand reads yaml, parses model elements
10
+ # and brings all defined model elements "up", that is
11
+ # starting bridges, containers etc.
12
+ class UpCommand < UpDownCommand
13
+ # allow to get access to handler object
14
+ attr_reader :handler
15
+
16
+ # initialize
17
+ def initialize
18
+ @handler = UpCommandHandler.new
19
+ end
20
+
21
+ # run in given +zone_name+:
22
+ # returns:
23
+ # - bool: true if successful, false otherwise
24
+ # rubocop:disable CyclomaticComplexity
25
+ def run_on_zone(zone_name)
26
+ b_result = true
27
+
28
+ networks = @project.get_element('networks')
29
+
30
+ # select networks in current zone only
31
+ networks_in_zone = UpDownCommand.get_networks_for_zone(networks, zone_name)
32
+ networks_in_zone.each do |network_name, network_data|
33
+ $log.debug("Bringing up network #{network_name}")
34
+
35
+ success = @handler.handle_bridge(network_name)
36
+ b_result &= success
37
+ if success
38
+ # if we have a host ip on that bridge, take it down first
39
+ b_result &= default_handle_hostip(network_name, network_data, @handler)
40
+
41
+ # if we have dhcp, configure dnsmasq
42
+ b_result &= default_handle_dhcp(zone_name, network_name, network_data, @handler)
43
+ else
44
+ $log.debug("Will not touch dependant objects of #{network_name} due to previous error(s)")
45
+ end
46
+ end
47
+
48
+ # select appgroups in this zone and bring them up
49
+ appgroups_in_zone = objects_in_zone('appgroups', zone_name)
50
+ appgroups_in_zone.each do |appgroup_name, appgroup_data|
51
+ $log.debug("Processing appgroup \'#{appgroup_name}\'")
52
+
53
+ success = handler.handle_appgroup(zone_name,
54
+ appgroup_name, appgroup_data,
55
+ @project.target_dir)
56
+ b_result &= success
57
+
58
+ # process network attachments
59
+ zone_networks = objects_in_zone('networks', zone_name)
60
+ success = handler.handle_network_attachments(zone_name, zone_networks,
61
+ appgroup_name, appgroup_data,
62
+ @project.target_dir)
63
+ b_result &= success
64
+ end
65
+
66
+ b_result
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,193 @@
1
+ # encoding: utf-8
2
+
3
+ # The MIT License (MIT)
4
+ # Copyright (c) 2014 Andreas Schmidt, andreas@de-wiring.net
5
+ #
6
+
7
+ # Wire module
8
+ module Wire
9
+ # handle_xxx methods for UpCommand
10
+ # rubocop:disable ClassLength
11
+ class UpCommandHandler < BaseCommand
12
+ # bring bridge resource up, identified by
13
+ # +bridge_name+
14
+ # Returns
15
+ # - [Bool] true if hostip if up on bridge
16
+ def handle_bridge(bridge_name)
17
+ b_result = true
18
+
19
+ # we should have a bridge with that name.
20
+ bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
21
+ if bridge_resource.up?
22
+ outputs 'UP', "Bridge #{bridge_name} already up.", :ok2
23
+ else
24
+ bridge_resource.up
25
+ if bridge_resource.up?
26
+ outputs 'UP', "Bridge #{bridge_name} up.", :ok
27
+ state.update(:bridge, bridge_name, :up)
28
+ else
29
+ outputs 'UP', "Error bringing up bridge #{bridge_name}.", :err
30
+ b_result = false
31
+ end
32
+
33
+ end
34
+ b_result
35
+ end
36
+
37
+ # bring ip resource up on device identified by
38
+ # +bridge_name+ and +host_ip+
39
+ # Returns
40
+ # - [Bool] true if hostip if up on bridge
41
+ def handle_hostip(bridge_name, hostip)
42
+ b_result = true
43
+
44
+ # we should have a bridge with that name.
45
+ hostip_resource = Wire::Resource::ResourceFactory
46
+ .instance.create(:bridgeip, hostip, bridge_name)
47
+ if hostip_resource.up?
48
+ outputs 'UP', "IP #{hostip} on bridge #{bridge_name} already up.", :ok2
49
+ else
50
+ hostip_resource.up
51
+ if hostip_resource.up?
52
+ outputs 'UP', "IP #{hostip} on bridge #{bridge_name} up.", :ok
53
+ state.update(:hostip, hostip, :up)
54
+ else
55
+ outputs 'UP', "Error bringing up ip #{hostip} on bridge #{bridge_name}.", :err
56
+ b_result = false
57
+ end
58
+
59
+ end
60
+ b_result
61
+ end
62
+
63
+ # configures dnsmasq for dhcp
64
+ # +zone_name+ name of zone
65
+ # +network_name+ name of network (and bridge)
66
+ # +network+ network entry
67
+ # +address_start+ start of address range (i.e.192.168.10.10)
68
+ # +address_end+ end of dhcp address range (i.e.192.168.10.100)
69
+ # Returns
70
+ # - [Bool] true if dhcp setup is valid
71
+ def handle_dhcp(zone_name, network_name, network_entry, address_start, address_end)
72
+ resource_dhcp = Wire::Resource::ResourceFactory
73
+ .instance.create(:dhcpconfig, "wire__#{zone_name}", network_name,
74
+ network_entry, address_start, address_end)
75
+ if resource_dhcp.up?
76
+ outputs 'UP', "dnsmasq/dhcp config on network \'#{network_name}\' is already up.", :ok2
77
+ return true
78
+ else
79
+ resource_dhcp.up
80
+ if resource_dhcp.up?
81
+ outputs 'UP', "dnsmasq/dhcp config on network \'#{network_name}\' is up.", :ok
82
+ state.update(:dnsmasq, network_name, :up)
83
+ return true
84
+ else
85
+ outputs 'UP', "Error configuring dnsmasq/dhcp config on network \'#{network_name}\'.",
86
+ :err
87
+ return false
88
+ end
89
+ end
90
+ end
91
+
92
+ # take the appgroups' controller and directs methods to
93
+ # it. First checks if appgroup is up. If so, ok. If not, bring it up
94
+ # and ensure that it's up
95
+ # Params:
96
+ # +zone_name+:: Name of zone
97
+ # +appgroup_name+:: Name of Appgroup
98
+ # +appgroup_entry+:: Appgroup data from model
99
+ def handle_appgroup(zone_name, appgroup_name, appgroup_entry, target_dir)
100
+ # get path
101
+ controller_entry = appgroup_entry[:controller]
102
+
103
+ if controller_entry[:type] == 'fig'
104
+ return handle_appgroup__fig(zone_name, appgroup_name, appgroup_entry, target_dir)
105
+ end
106
+
107
+ $log.error "Appgroup not handled, unknown controller type #{controller_entry[:type]}"
108
+ false
109
+ end
110
+
111
+ # implement appgroup handling for fig controller
112
+ # Params:
113
+ # +zone_name+:: Name of zone
114
+ # +appgroup_name+:: Name of Appgroup
115
+ # +appgroup_entry+:: Appgroup data from model
116
+ # +target_dir+:: Target directory (where fig file is located)
117
+ def handle_appgroup__fig(zone_name, appgroup_name, appgroup_entry, target_dir)
118
+ # get path
119
+ controller_entry = appgroup_entry[:controller]
120
+
121
+ fig_path = File.join(File.expand_path(target_dir), controller_entry[:file])
122
+
123
+ resource_fig = Wire::Resource::ResourceFactory
124
+ .instance.create(:figadapter, "#{appgroup_name}", fig_path)
125
+
126
+ if resource_fig.up?
127
+ outputs 'UP', "appgroup \'#{appgroup_name}\' in zone #{zone_name} is already up.", :ok2
128
+ return true
129
+ else
130
+ resource_fig.up
131
+ if resource_fig.up?
132
+ outputs 'UP', "appgroup \'#{appgroup_name}\' in zone #{zone_name} is up.", :ok
133
+ state.update(:appgroup, appgroup_name, :up)
134
+ return true
135
+ else
136
+ outputs 'UP', "Error bringing up appgroup \'#{appgroup_name}\' in zone #{zone_name} .",
137
+ :err
138
+ return false
139
+ end
140
+ end
141
+ end
142
+
143
+ # attaches networks to containers of appgroup
144
+ # Params:
145
+ # ++_zone_name++: Name of zone
146
+ # ++networks++: Array of networks names, what to attach
147
+ # ++appgroup_name++: Name of appgroup
148
+ # ++appgroup_entry++: appgroup hash
149
+ # ++target_dir++: project target dir
150
+ # Returns
151
+ # - [Bool] true if appgroup setup is ok
152
+ def handle_network_attachments(_zone_name, networks, appgroup_name,
153
+ appgroup_entry, target_dir)
154
+ # query container ids of containers running here
155
+ # get path
156
+ controller_entry = appgroup_entry[:controller]
157
+
158
+ container_ids = []
159
+
160
+ if controller_entry[:type] == 'fig'
161
+ fig_path = File.join(File.expand_path(target_dir), controller_entry[:file])
162
+
163
+ resource_fig = Wire::Resource::ResourceFactory
164
+ .instance.create(:figadapter, "#{appgroup_name}", fig_path)
165
+
166
+ container_ids = resource_fig.up_ids || []
167
+ $log.debug "Got #{container_ids.size} container id(s) from adapter"
168
+ end
169
+
170
+ #
171
+ resource_nw = Wire::Resource::ResourceFactory
172
+ .instance.create(:networkinjection, appgroup_name, networks.keys, container_ids)
173
+ if resource_nw.up?
174
+ outputs 'UP', "appgroup \'#{appgroup_name}\' already has valid network " \
175
+ 'attachments.', :ok2
176
+ state.update(:appgroup, appgroup_name, :up)
177
+ return true
178
+ else
179
+ resource_nw.up
180
+ if resource_nw.up?
181
+ outputs 'UP', "appgroup \'#{appgroup_name}\' attached " \
182
+ "networks #{networks.keys.join(',')}.", :ok
183
+ state.update(:appgroup, appgroup_name, :up)
184
+ return true
185
+ else
186
+ outputs 'UP', "Error attaching networks to appgroup \'#{appgroup_name}\'.",
187
+ :err
188
+ return false
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end