comparison modules/apache/util/apache_mod_platform_support.rb @ 437:b8d6ada284dd

Update Apache module to latest version Also converted some params to ints to match
author IBBoard <dev@ibboard.co.uk>
date Sun, 14 Aug 2022 11:30:13 +0100
parents
children adf6fe9bbc17
comparison
equal deleted inserted replaced
436:6293839019d0 437:b8d6ada284dd
1 # frozen_string_literal: true
2
3 require 'json'
4 # Helper class to facilitate exclusion of tests that use an Apache MOD on platforms it isn't supported on.
5 # All Apache MOD classes are defined under 'manifests/mod'. The exclusion should be in the format:
6 #
7 # @note Unsupported platforms: OS: ver, ver; OS: ver, ver, ver; OS: all'
8 # class apache::mod::foobar {
9 # ...
10 #
11 # For example:
12 # @note Unsupported platforms: RedHat: 5, 6; Ubuntu: 14.04; SLES: all; Scientific: 11 SP1'
13 # class apache::mod::actions {
14 # apache::mod { 'actions': }
15 # }
16 #
17 # Filtering is then performed during the test using RSpec's filtering, like so:
18 #
19 # describe 'auth_oidc', unless: mod_unsupported_on_platform('apache::mod::auth_openidc') do
20 # ...
21 # it 'applies cleanly', unless: mod_unsupported_on_platform('apache::mod::auth_openidc') do
22 # ...
23 class ApacheModPlatformCompatibility
24 ERROR_MSG = {
25 tag_parse: 'OS and version information in incorrect format:',
26 os_parse: 'OS name is not present in metadata.json:',
27 }.freeze
28
29 def initialize
30 @os = {}
31 @mapping = {}
32 @manifest_errors = []
33 @compatible_platform_versions = {}
34 @mod_platform_compatibility_mapping = {}
35 end
36
37 def register_running_platform(os)
38 @os = { family: os[:family], release: os[:release].to_i }
39 end
40
41 def generate_supported_platforms_versions
42 metadata = JSON.parse(File.read('metadata.json'))
43 metadata['operatingsystem_support'].each do |os|
44 @compatible_platform_versions[os['operatingsystem'].downcase] = os['operatingsystemrelease'].map(&:to_i)
45 end
46 end
47
48 # Class to hold the details of an error whilst parsing an unsupported tag
49 class ManifestError
50 attr_reader :manifest, :line_num, :error_type, :error_detail
51
52 def initialize(manifest, line_num, error_type, error_detail)
53 @manifest = manifest
54 @line_num = line_num
55 @error_type = error_type
56 @error_detail = error_detail
57 end
58 end
59
60 def print_parsing_errors
61 return if @manifest_errors.empty?
62 $stderr.puts "The following errors were encountered when trying to parse the 'Unsupported platforms' tag(s) in 'manifests/mod':\n"
63 @manifest_errors.each do |manifest_error|
64 $stderr.puts " * #{manifest_error.manifest} (line #{manifest_error.line_num}): #{ERROR_MSG[manifest_error.error_type]} #{manifest_error.error_detail}"
65 end
66 File.readlines('util/_resources/tag_format_help_msg.txt').each do |line|
67 $stderr.puts line
68 end
69 end
70
71 def valid_os?(os)
72 @compatible_platform_versions.key?(os)
73 end
74
75 def register_error(manifest, line_num, error_type, error_detail)
76 @manifest_errors << ManifestError.new(manifest, line_num, error_type, error_detail)
77 end
78
79 def register_unsupported_platforms(manifest, line_num, mod, platforms_versions)
80 platforms_versions.each_key do |os|
81 unless valid_os?(os)
82 register_error(manifest, line_num, :os_parse, os)
83 next
84 end
85 if @mod_platform_compatibility_mapping.key? mod
86 @mod_platform_compatibility_mapping[mod].merge!(platforms_versions)
87 else
88 @mod_platform_compatibility_mapping[mod] = platforms_versions
89 end
90 end
91 end
92
93 def extract_os_ver_pairs(line)
94 platforms_versions = {}
95 os_ver_groups = line.delete(' ').downcase
96 # E.g. "debian:5,6;centos:5;sles:11sp1,12;scientific:all;ubuntu:14.04,16.04"
97 if %r{^((?:\w+:(?:(?:\d+(?:\.\d+|sp\d+)?|all),?)+;?)+)$}i.match?(os_ver_groups)
98 os_ver_groups.split(';').each do |os_vers|
99 os, vers = os_vers.split(':')
100 vers.gsub!(%r{sp\d+}, '') # Remove SP ver as we cannot determine this level of granularity from values from Litmus
101 platforms_versions[os] = vers.split(',').map(&:to_i) # 'all' will be converted to 0
102 end
103 end
104 platforms_versions
105 end
106
107 def process_line(line)
108 data = {}
109 return data unless %r{@note\sUnsupported\splatforms?:\s?|class\sapache::mod}i.match?(line)
110 if (match = %r{@note\sUnsupported\splatforms?:\s?(?<os_vers>.*)$}i.match(line))
111 data[:type] = :unsupported_platform_declaration
112 data[:value] = match[:os_vers]
113 elsif (match = %r{class\s(?<mod>apache::mod::\w+)}i.match(line))
114 data[:type] = :class_declaration
115 data[:value] = match[:mod]
116 end
117 data
118 end
119
120 def generate_mod_platform_exclusions
121 Dir.glob('manifests/mod/*.pp').each do |manifest|
122 platforms_versions = []
123 line_num = 0
124 File.readlines(manifest).each do |line|
125 line_num += 1
126 data = process_line(line)
127 next if data.empty?
128 if data[:type] == :unsupported_platform_declaration
129 platforms_versions = extract_os_ver_pairs(data[:value])
130 register_error(manifest, line_num, :tag_parse, line) if platforms_versions.empty?
131 next
132 elsif data[:type] == :class_declaration
133 register_unsupported_platforms(manifest, line_num, data[:value], platforms_versions) unless platforms_versions.empty?
134 break # Once we detect the class declaration, we can move on
135 end
136 end
137 end
138 end
139
140 # Called from within the context of a test run, making use of RSpec's filtering, e.g.:
141 # it 'should do some test', if: mod_supported_on_platform('apache::mod::foobar')
142 def mod_supported_on_platform?(mod)
143 return true if @mod_platform_compatibility_mapping.empty?
144 return true unless @mod_platform_compatibility_mapping.key? mod
145 return true unless @mod_platform_compatibility_mapping[mod].key? @os[:family]
146 return false if @mod_platform_compatibility_mapping[mod][@os[:family]] == [0]
147 !@mod_platform_compatibility_mapping[mod][@os[:family]].include? @os[:release]
148 end
149 end