Merge "Bump Puppet version 4.x to 5.x"
[integration/packaging/puppet-opendaylight.git] / spec / spec_helper.rb
1 require 'puppetlabs_spec_helper/module_spec_helper'
2 require 'rspec-puppet-facts'
3 include RspecPuppetFacts
4
5 # Customize filters to ignore 3rd-party code
6 # If the rspec coverage report shows not-our-code results, add it here
7 custom_filters = [
8 ]
9 RSpec::Puppet::Coverage.filters.push(*custom_filters)
10
11 #
12 # NB: This is a library of helper fns used by the rspec-puppet tests
13 #
14
15 # Tests that are common to all possible configurations
16 def generic_tests(options = {})
17   java_opts = options.fetch(:java_opts, '')
18   odl_bind_ip = options.fetch(:odl_bind_ip, '0.0.0.0')
19   inactivity_probe = options.fetch(:inactivity_probe, :undef)
20
21   # Confirm that module compiles
22   it { should compile }
23   it { should compile.with_all_deps }
24
25   # Confirm presence of classes
26   it { should contain_class('opendaylight') }
27   it { should contain_class('opendaylight::params') }
28   it { should contain_class('opendaylight::install') }
29   it { should contain_class('opendaylight::config') }
30   it { should contain_class('opendaylight::post_config') }
31   it { should contain_class('opendaylight::service') }
32
33   # Confirm relationships between classes
34   it { should contain_class('opendaylight::install').that_comes_before('Class[opendaylight::config]') }
35   it { should contain_class('opendaylight::config').that_requires('Class[opendaylight::install]') }
36   it { should contain_class('opendaylight::config').that_notifies('Class[opendaylight::service]') }
37   it { should contain_class('opendaylight::service').that_subscribes_to('Class[opendaylight::config]') }
38   it { should contain_class('opendaylight::service').that_comes_before('Class[opendaylight]') }
39   it { should contain_class('opendaylight::post_config').that_requires('Class[opendaylight::service]') }
40   it { should contain_class('opendaylight::post_config').that_comes_before('Class[opendaylight]') }
41   it { should contain_class('opendaylight').that_requires('Class[opendaylight::service]') }
42
43   # Confirm presence of generic resources
44   it { should contain_service('opendaylight') }
45   it { should contain_file('org.apache.karaf.features.cfg') }
46
47   # Confirm properties of generic resources
48   # NB: These hashes don't work with Ruby 1.8.7, but we
49   #   don't support 1.8.7 so that's okay. See issue #36.
50   it {
51     should contain_service('opendaylight').with(
52       'ensure'      => 'running',
53       'enable'      => 'true',
54       'hasstatus'   => 'true',
55       'hasrestart'  => 'true',
56     )
57   }
58   it {
59     should contain_file('org.apache.karaf.features.cfg').with(
60       'ensure'      => 'file',
61       'path'        => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
62       'owner'   => 'odl',
63       'group'   => 'odl',
64     )
65   }
66
67   it {
68     if odl_bind_ip =~ /.*:.*/
69         java_options = '-Djava.net.preferIPv6Addresses=true'
70     else
71         java_options = '-Djava.net.preferIPv4Stack=true'
72     end
73
74     should contain_file_line('Karaf Java Options').with(
75       'ensure' => 'present',
76       'path'   => '/opt/opendaylight/bin/karaf',
77       'line'   => "EXTRA_JAVA_OPTS=\"#{java_options}\"",
78       'match'  => '^EXTRA_JAVA_OPTS=.*$',
79       'after'  => '^PROGNAME=.*$'
80     )
81   }
82
83   it {
84     should contain_file('org.opendaylight.ovsdb.library.cfg').with(
85       'ensure'  => 'file',
86       'path'    => '/opt/opendaylight/etc/org.opendaylight.ovsdb.library.cfg',
87       'owner'   => 'odl',
88       'group'   => 'odl',
89       'content' =>  /ovsdb-listener-ip = #{odl_bind_ip}/
90     )
91   }
92
93   it {
94     should contain_file('default-openflow-connection-config.xml').with(
95       'ensure'  => 'file',
96       'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/default-openflow-connection-config.xml',
97       'owner'   => 'odl',
98       'group'   => 'odl',
99       'content' =>  /<address>#{odl_bind_ip}<\/address>/
100     )
101   }
102
103   unless inactivity_probe == :undef
104     it {
105       should contain_file('Configure inactivity probe timer').with(
106         'ensure'  => 'file',
107         'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-elanmanager-config.xml',
108         'owner'   => 'odl',
109         'group'   => 'odl',
110         'content' =>  /<controller-inactivity-probe>#{inactivity_probe}<\/controller-inactivity-probe>/
111       )
112     }
113   end
114
115 end
116
117 # Shared tests that specialize in testing log file size and rollover
118 def log_settings(options = {})
119   # Extraxt params. The dafault value should be same as in opendaylight::params
120   log_max_size = options.fetch(:log_max_size, '500MB')
121   log_max_rollover = options.fetch(:log_max_rollover, 4)
122   log_rollover_fileindex = options.fetch(:log_rollover_fileindex, 'min')
123   log_pattern = options.fetch(:log_pattern, '%d{ISO8601} | %-5p | %-16t | %-60c{6} | %m%n')
124   log_mechanism = options.fetch(:log_mechanism, 'file')
125   enable_paxosgi_logger = options.fetch(:enable_paxosgi_logger, false)
126
127   if log_mechanism == 'console'
128     it {
129       should contain_file_line('consoleappender').with(
130         'path'  => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
131         'line'  => 'karaf.log.console=INFO',
132         'after' => 'log4j2.rootLogger.appenderRef.Console.filter.threshold.type = ThresholdFilter',
133         'match' => '^karaf.log.console.*$'
134       )
135     }
136     it {
137       should contain_file_line('direct').with(
138         'path'  => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
139         'line'  => 'log4j2.appender.console.direct = true',
140         'after' => 'karaf.log.console=INFO',
141         'match' => '^log4j2.appender.console.direct.*$'
142       )
143     }
144   else
145
146     it {
147       should contain_file_line('logmaxsize').with(
148         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
149         'line'   => "log4j2.appender.rolling.policies.size.size = #{log_max_size}",
150         'match'  => '^log4j2.appender.rolling.policies.size.size.*$',
151       )
152     }
153     it {
154       should contain_file_line('rolloverstrategy').with(
155         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
156         'line'   => 'log4j2.appender.rolling.strategy.type = DefaultRolloverStrategy'
157       )
158     }
159     it {
160       should contain_file_line('logmaxrollover').with(
161         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
162         'line'   => "log4j2.appender.rolling.strategy.max = #{log_max_rollover}",
163         'match'  => '^log4j2.appender.rolling.strategy.max.*$',
164       )
165     }
166     it {
167       should contain_file_line('logrolloverfileindex').with(
168         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
169         'line'   => "log4j2.appender.rolling.strategy.fileIndex = #{log_rollover_fileindex}",
170         'match'  => '^log4j2.appender.rolling.strategy.fileIndex.*$',
171       )
172     }
173   end
174   it {
175     should contain_file_line('logpattern').with(
176       'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
177       'line'   => "log4j2.pattern = #{log_pattern}",
178       'match'  => '^log4j2.pattern.*$',
179     )
180   }
181   if enable_paxosgi_logger == true
182       presence = 'present'
183   else
184       presence = 'absent'
185   end
186
187   it {
188     should contain_file_line('paxosgiappenderref').with(
189       'ensure' => presence,
190       'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
191       'line'   => "log4j2.rootLogger.appenderRef.PaxOsgi.ref = PaxOsgi",
192     )
193   }
194   it {
195     should contain_file_line('paxosgisection').with(
196       'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
197       'line'   => "# OSGi appender",
198     )
199   }
200   it {
201     should contain_file_line('paxosgitype').with(
202       'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
203       'line'   => "log4j2.appender.osgi.type = PaxOsgi",
204     )
205   }
206   it {
207     should contain_file_line('paxosginame').with(
208       'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
209       'line'   => "log4j2.appender.osgi.name = PaxOsgi",
210     )
211   }
212   it {
213     should contain_file_line('paxosgifilter').with(
214       'path'   => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
215       'line'   => "log4j2.appender.osgi.filter = *",
216     )
217   }
218 end
219
220 # Shared tests that specialize in testing Karaf feature installs
221 def karaf_feature_tests(options = {})
222   # Extract params
223   # NB: This default list should be the same as the one in opendaylight::params
224   default_features = options.fetch(:default_features, ['standard', 'wrap', 'ssh'])
225   extra_features = options.fetch(:extra_features, [])
226
227   # The order of this list concat matters
228   features = default_features + extra_features
229   features_csv = features.join(',')
230
231   # Confirm properties of Karaf features config file
232   # NB: These hashes don't work with Ruby 1.8.7, but we
233   #   don't support 1.8.7 so that's okay. See issue #36.
234   it {
235     should contain_file('org.apache.karaf.features.cfg').with(
236       'ensure'      => 'file',
237       'path'        => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
238       'owner'   => 'odl',
239       'group'   => 'odl',
240     )
241   }
242   it {
243     should contain_file_line('featuresBoot').with(
244       'path'  => '/opt/opendaylight/etc/org.apache.karaf.features.cfg',
245       'line'  => "featuresBoot=#{features_csv}",
246       'match' => '^featuresBoot=.*$',
247     )
248   }
249 end
250
251 # Shared tests that specialize in testing ODL's REST port config
252 def odl_rest_port_tests(options = {})
253   # Extract params
254   # NB: This default value should be the same as one in opendaylight::params
255   odl_rest_port = options.fetch(:odl_rest_port, 8181)
256   odl_bind_ip = options.fetch(:odl_bind_ip, '0.0.0.0')
257   # Confirm properties of ODL REST port config file
258   # NB: These hashes don't work with Ruby 1.8.7, but we
259   #   don't support 1.8.7 so that's okay. See issue #36.
260   it {
261     should contain_augeas('ODL REST Port')
262   }
263
264   if not odl_bind_ip.eql? '0.0.0.0'
265     it {
266       should contain_augeas('ODL REST IP')
267       should contain_file_line('set pax bind IP').with(
268         'ensure'  => 'present',
269         'path'    => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
270         'line'    => "org.ops4j.pax.web.listening.addresses = #{odl_bind_ip}",
271         'require' => 'File[org.ops4j.pax.web.cfg]'
272       )
273       should contain_file_line('set karaf IP').with(
274         'ensure' => 'present',
275         'path'   => '/opt/opendaylight/etc/org.apache.karaf.shell.cfg',
276         'line'   => "sshHost = #{odl_bind_ip}",
277         'match'  => '^sshHost\s*=.*$',
278       )
279     }
280   else
281     it {
282       should_not contain_augeas('ODL REST IP')
283     }
284   end
285
286   it {
287     should contain_file_line('set pax bind port').with(
288         'ensure'  => 'present',
289         'path'    => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
290         'line'    => "org.osgi.service.http.port = #{odl_rest_port}",
291         'match'   => '^#?org.osgi.service.http.port\s.*$',
292         'require' => 'File[org.ops4j.pax.web.cfg]'
293     )
294   }
295 end
296
297 def log_level_tests(options = {})
298   # Extract params
299   # NB: This default value should be the same as one in opendaylight::params
300   log_levels = options.fetch(:log_levels, {})
301
302   if log_levels.empty?
303     # Should contain log level config file
304     it {
305       should_not contain_file_line('logger-org.opendaylight.ovsdb-level')
306     }
307     it {
308       should_not contain_file_line('logger-org.opendaylight.ovsdb-name')
309     }
310   else
311     # Verify each custom log level config entry
312     log_levels.each_pair do |logger, level|
313       underscored_version = "#{logger}".gsub('.', '_')
314       it {
315         should contain_file_line("logger-#{logger}-level").with(
316           'ensure' => 'present',
317           'path' => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
318           'line' => "log4j2.logger.#{underscored_version}.level = #{level}",
319           'match'  => "log4j2.logger.#{underscored_version}.level = .*$"
320         )
321         should contain_file_line("logger-#{logger}-name").with(
322           'ensure' => 'present',
323           'path' => '/opt/opendaylight/etc/org.ops4j.pax.logging.cfg',
324           'line' => "log4j2.logger.#{underscored_version}.name = #{logger}",
325           'match'  => "log4j2.logger.#{underscored_version}.name = .*$"
326         )
327       }
328     end
329   end
330 end
331
332 def enable_ha_tests(options = {})
333   # Extract params
334   enable_ha = options.fetch(:enable_ha, false)
335   odl_bind_ip = options.fetch(:odl_bind_ip, '0.0.0.0')
336   ha_node_ips = options.fetch(:ha_node_ips, [])
337   ha_db_modules = options.fetch(:ha_db_modules, { 'default' => false })
338   # HA_NODE_IPS size
339   ha_node_count = ha_node_ips.size
340
341   if (enable_ha) && (ha_node_count < 2)
342     # Check for HA_NODE_COUNT < 2
343     fail("Number of HA nodes less than 2: #{ha_node_count} and HA Enabled")
344   end
345
346   if enable_ha
347     ha_node_index = ha_node_ips.index(odl_bind_ip)
348     it {
349       should contain_file('akka.conf').with(
350         'path'    => '/opt/opendaylight/configuration/initial/akka.conf',
351         'ensure'  => 'file',
352         'owner'   => 'odl',
353         'group'   => 'odl',
354         'content' => /roles\s*=\s*\["member-#{ha_node_index}"\]/
355       )
356     }
357
358     ha_db_modules.each do |mod, urn|
359       it { should contain_file('module-shards.conf').with(
360         'path'    => '/opt/opendaylight/configuration/initial/module-shards.conf',
361         'ensure'  => 'file',
362         'owner'   => 'odl',
363         'group'   => 'odl',
364         'content' => /name = "#{mod}"/
365       )}
366       if mod == 'default'
367         it { should contain_file('modules.conf').with(
368           'path'    => '/opt/opendaylight/configuration/initial/modules.conf',
369           'ensure'  => 'file',
370           'owner'   => 'odl',
371           'group'   => 'odl'
372         )}
373       else
374         it { should contain_file('modules.conf').with(
375           'path'    => '/opt/opendaylight/configuration/initial/modules.conf',
376           'ensure'  => 'file',
377           'owner'   => 'odl',
378           'group'   => 'odl',
379           'content' => /name = "#{mod}"/,
380         )}
381       end
382     end
383   else
384     it {
385       should_not contain_file('akka.conf')
386       should_not contain_file('module-shards.conf')
387       should_not contain_file('modules.conf')
388       }
389   end
390 end
391
392 def rpm_install_tests(options = {})
393   # Extract params
394   rpm_repo = options.fetch(:rpm_repo, 'https://nexus.opendaylight.org/content/repositories/opendaylight-neon-epel-7-$basearch-devel')
395
396
397   # Default to CentOS 7 Yum repo URL
398
399   # Confirm presence of RPM-related resources
400   it { should contain_yumrepo('opendaylight') }
401   it { should contain_package('opendaylight') }
402
403   # Confirm relationships between RPM-related resources
404   it { should contain_package('opendaylight').that_requires('Yumrepo[opendaylight]') }
405   it { should contain_yumrepo('opendaylight').that_comes_before('Package[opendaylight]') }
406
407   # Confirm properties of RPM-related resources
408   # NB: These hashes don't work with Ruby 1.8.7, but we
409   #   don't support 1.8.7 so that's okay. See issue #36.
410   it {
411     should contain_yumrepo('opendaylight').with(
412       'enabled'     => '1',
413       'gpgcheck'    => '0',
414       'descr'       => 'OpenDaylight SDN Controller',
415       'baseurl'     => "#{rpm_repo}",
416     )
417   }
418   it {
419     should contain_package('opendaylight').with(
420       'ensure'   => 'present',
421     )
422   }
423 end
424
425 def deb_install_tests(options = {})
426   # Extract params
427   deb_repo = options.fetch(:deb_repo, 'ppa:odl-team/nitrogen')
428
429   # Confirm the presence of Deb-related resources
430   it { should contain_apt__ppa(deb_repo) }
431   it { should contain_package('opendaylight') }
432
433   # Confirm relationships between Deb-related resources
434   it { should contain_package('opendaylight').that_requires("Apt::Ppa[#{deb_repo}]") }
435   it { should contain_apt__ppa(deb_repo).that_comes_before('Package[opendaylight]') }
436
437   # Confirm presence of Deb-related resources
438   it {
439     should contain_package('opendaylight').with(
440       'ensure'   => 'present',
441     )
442   }
443 end
444
445 # Shared tests for unsupported OSs
446 def unsupported_os_tests(options = {})
447   # Extract params
448   expected_msg = options.fetch(:expected_msg)
449   rpm_repo = options.fetch(:rpm_repo, 'https://nexus.opendaylight.org/content/repositories/opendaylight-neon-epel-7-$basearch-devel')
450
451   # Confirm that classes fail on unsupported OSs
452   it { expect { should contain_class('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
453   it { expect { should contain_class('opendaylight::install') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
454   it { expect { should contain_class('opendaylight::config') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
455   it { expect { should contain_class('opendaylight::service') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
456
457   # Confirm that other resources fail on unsupported OSs
458   it { expect { should contain_yumrepo('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
459   it { expect { should contain_package('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
460   it { expect { should contain_service('opendaylight') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
461   it { expect { should contain_file('org.apache.karaf.features.cfg') }.to raise_error(Puppet::Error, /#{expected_msg}/) }
462 end
463
464 # Shared tests that specialize in testing SNAT mechanism
465 def snat_mechanism_tests(snat_mechanism='controller')
466   it { should contain_file('/opt/opendaylight/etc/opendaylight') }
467   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore')}
468   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial')}
469   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial/config')}
470
471   # Confirm snat_mechanism
472   it {
473     should contain_file('netvirt-natservice-config.xml').with(
474       'ensure'      => 'file',
475       'path'        => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/netvirt-natservice-config.xml',
476       'owner'   => 'odl',
477       'group'   => 'odl',
478       'content'     =>  /<nat-mode>#{snat_mechanism}<\/nat-mode>/
479       )
480     }
481 end
482
483 # Shared tests that specialize in testing SFC Config
484 def sfc_tests(options = {})
485   extra_features = options.fetch(:extra_features, [])
486
487   if extra_features.include? 'odl-netvirt-sfc'
488     sfc_enabled = true
489   else
490     sfc_enabled = false
491   end
492
493   it { should contain_file('/opt/opendaylight/etc/opendaylight') }
494   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore')}
495   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial')}
496   it { should contain_file('/opt/opendaylight/etc/opendaylight/datastore/initial/config')}
497
498   it {
499     should contain_file('genius-itm-config.xml').with(
500       'ensure'  => 'file',
501       'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/genius-itm-config.xml',
502       'owner'   => 'odl',
503       'group'   => 'odl',
504       'content' => /<gpe-extension-enabled>#{sfc_enabled}<\/gpe-extension-enabled>/
505       )
506     }
507 end
508
509 # Shared tests that specialize in testing DSCP marking config
510 def dscp_tests(options = {})
511   inherit_dscp_marking = options.fetch(:inherit_dscp_marking, false)
512
513   if inherit_dscp_marking
514     it {
515       should contain_file('genius-itm-config.xml').with(
516         'ensure'  => 'file',
517         'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/genius-itm-config.xml',
518         'owner'   => 'odl',
519         'group'   => 'odl',
520         'content' => /<default-tunnel-tos>inherit<\/default-tunnel-tos>/
521       )
522     }
523   else
524     it {
525       should contain_file('genius-itm-config.xml').with(
526         'ensure'  => 'file',
527         'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/genius-itm-config.xml',
528         'owner'   => 'odl',
529         'group'   => 'odl',
530         'content' => /<default-tunnel-tos>0<\/default-tunnel-tos>/
531       )
532     }
533   end
534 end
535
536 # Shared tests that specialize in testing VPP routing node config
537 def vpp_routing_node_tests(options = {})
538   # Extract params
539   # NB: This default list should be the same as the one in opendaylight::params
540   routing_node = options.fetch(:routing_node, '')
541
542   if routing_node.empty?
543     it { should_not contain_file('org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg') }
544     it { should_not contain_file_line('routing-node') }
545   else
546     # Confirm properties of Karaf config file
547     # NB: These hashes don't work with Ruby 1.8.7, but we
548     #   don't support 1.8.7 so that's okay. See issue #36.
549     it {
550       should contain_file('org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg').with(
551         'ensure'      => 'file',
552         'path'        => '/opt/opendaylight/etc/org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg',
553         'owner'   => 'odl',
554         'group'   => 'odl',
555       )
556     }
557     it {
558       should contain_file_line('routing-node').with(
559         'path'  => '/opt/opendaylight/etc/org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.startup.cfg',
560         'line'  => "routing-node=#{routing_node}",
561         'match' => '^routing-node=.*$',
562       )
563     }
564   end
565 end
566
567 # ODL username/password tests
568 def username_password_tests(username, password)
569
570   it {
571     should contain_odl_user(username).with(
572       :password => password
573     )
574   }
575 end
576
577 # ODL websocket address tests
578 def odl_websocket_address_tests(options = {})
579   # Extract params
580   # NB: This default value should be the same as one in opendaylight::params
581   odl_bind_ip = options.fetch(:odl_bind_ip, '0.0.0.0')
582   # Confirm properties of ODL REST port config file
583   # NB: These hashes don't work with Ruby 1.8.7, but we
584   #   don't support 1.8.7 so that's okay. See issue #36.
585
586   if not odl_bind_ip.eql? '0.0.0.0'
587     it {
588       should contain_file('/opt/opendaylight/etc/org.opendaylight.restconf.cfg').with(
589         'ensure'      => 'file',
590         'path'        => '/opt/opendaylight/etc/org.opendaylight.restconf.cfg',
591         'owner'   => 'odl',
592         'group'   => 'odl',
593       )
594     }
595     it {
596         should contain_file_line('websocket-address').with(
597           'path'    => '/opt/opendaylight/etc/org.opendaylight.restconf.cfg',
598           'line'    => "websocket-address=#{odl_bind_ip}",
599           'match'   => '^websocket-address=.*$',
600       )
601     }
602   else
603     it {
604       should_not contain_file_line('websocket-address')
605     }
606   end
607 end
608
609 def odl_tls_tests(options = {})
610   enable_tls = options.fetch(:enable_tls, false)
611   tls_keystore_password = options.fetch(:tls_keystore_password, nil)
612   tls_trusted_certs = options.fetch(:tls_trusted_certs, [])
613   tls_keystore_password = options.fetch(:tls_keystore_password, nil)
614   tls_key_file = options.fetch(:tls_key_file, nil)
615   tls_cert_file = options.fetch(:tls_cert_file, nil)
616   tls_ca_cert_file = options.fetch(:tls_ca_cert_file, nil)
617   odl_rest_port = options.fetch(:odl_rest_port, 8181)
618
619   if enable_tls
620     if tls_keystore_password.nil?
621       it { expect { should contain_class('opendaylight::config') }.to raise_error(Puppet::PreformattedError) }
622       return
623     end
624
625     if tls_key_file or tls_cert_file
626       if tls_key_file and tls_cert_file
627         it {
628           should contain_odl_keystore('controller')
629         }
630       else
631         it { expect { should contain_class('opendaylight::config') }.to raise_error(Puppet::PreformattedError) }
632       end
633     end
634     it {
635       should contain_augeas('Remove HTTP ODL REST Port')
636       should contain_augeas('ODL SSL REST Port')
637       should contain_file_line('set pax TLS port').with(
638         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
639         'line'   => "org.osgi.service.http.port.secure = #{odl_rest_port}",
640         'match'  => '^#?org.osgi.service.http.port.secure.*$',
641       )
642       should contain_file_line('set pax TLS keystore location').with(
643         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
644         'line'   => 'org.ops4j.pax.web.ssl.keystore = configuration/ssl/ctl.jks',
645         'match'  => '^#?org.ops4j.pax.web.ssl.keystore.*$',
646       )
647       should contain_file_line('set pax TLS keystore integrity password').with(
648         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
649         'line'   => "org.ops4j.pax.web.ssl.password = #{tls_keystore_password}",
650         'match'  => '^#?org.ops4j.pax.web.ssl.password.*$',
651       )
652       should contain_file_line('set pax TLS keystore password').with(
653         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
654         'line'   => "org.ops4j.pax.web.ssl.keypassword = #{tls_keystore_password}",
655         'match'  => '^#?org.ops4j.pax.web.ssl.keypassword.*$',
656       )
657       should contain_file('aaa-cert-config.xml').with(
658         'ensure'  => 'file',
659         'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/aaa-cert-config.xml',
660         'owner'   => 'odl',
661         'group'   => 'odl',
662       )
663       should contain_file('org.opendaylight.ovsdb.library.cfg').with(
664         'ensure'  => 'file',
665         'path'    => '/opt/opendaylight/etc/org.opendaylight.ovsdb.library.cfg',
666         'owner'   => 'odl',
667         'group'   => 'odl',
668         'content' =>  /use-ssl = true/
669       )
670       should contain_file('/opt/opendaylight/configuration/ssl').with(
671         'ensure' => 'directory',
672         'path'   => '/opt/opendaylight/configuration/ssl',
673         'owner'  => 'odl',
674         'group'  => 'odl',
675         'mode'   => '0755'
676       )
677       should contain_file_line('enable pax TLS').with(
678         'ensure' => 'present',
679         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
680         'line'   => 'org.osgi.service.http.secure.enabled = true',
681         'match'  => '^#?org.osgi.service.http.secure.enabled.*$',
682       )
683       should contain_file_line('disable pax HTTP').with(
684         'ensure' => 'present',
685         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
686         'line'   => 'org.osgi.service.http.enabled = false',
687         'match'  => '^#?org.osgi.service.http.enabled.*$',
688       )
689       should contain_file('org.ops4j.pax.web.cfg').with(
690         'ensure' => 'file',
691         'path'   => '/opt/opendaylight/etc/org.ops4j.pax.web.cfg',
692         'owner'  => 'odl',
693         'group'  => 'odl',
694       )
695       should contain_file('default-openflow-connection-config.xml').with(
696         'ensure'  => 'file',
697         'path'    => '/opt/opendaylight/etc/opendaylight/datastore/initial/config/default-openflow-connection-config.xml',
698         'owner'   => 'odl',
699         'group'   => 'odl',
700         'content' =>  /<transport-protocol>TLS<\/transport-protocol>/
701       )
702     }
703   end
704 end
705
706 def stats_polling_enablement_tests(options = {})
707   # Extract params
708   # NB: This default value should be the same as one in opendaylight::params
709   stats_polling_enabled = options.fetch(:stats_polling_enabled, false)
710   # Confirm properties of ODL REST port config file
711   # NB: These hashes don't work with Ruby 1.8.7, but we
712   #   don't support 1.8.7 so that's okay. See issue #36.
713   it {
714     should contain_file('openflowplugin.cfg').with(
715       'ensure' => 'file',
716       'path'   => '/opt/opendaylight/etc/org.opendaylight.openflowplugin.cfg',
717       'owner'  => 'odl',
718       'group'  => 'odl',
719     )
720     should contain_file_line('stats-polling').with(
721       'ensure' => 'present',
722       'path'   => '/opt/opendaylight/etc/org.opendaylight.openflowplugin.cfg',
723       'line'   => "is-statistics-polling-on=#{stats_polling_enabled}",
724       'match'  => '^is-statistics-polling-on=.*$',
725     )
726   }
727 end