dewiring 0.1.2

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