Module: ForemanInventoryUpload::Generators::FactHelpers
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/foreman_inventory_upload/generators/fact_helpers.rb
Constant Summary collapse
- CLOUD_AMAZON =
'aws'- CLOUD_GOOGLE =
'gcp'- CLOUD_AZURE =
'azure'- CLOUD_ALIBABA =
'alibaba'- UUID_REGEX =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
Instance Method Summary collapse
- #account_id(organization) ⇒ Object
- #bios_uuid(host) ⇒ Object
- #cloud_provider(host) ⇒ Object
- #fact_value(host, fact_name) ⇒ Object
- #fqdn(host) ⇒ Object
- #host_ips(host) ⇒ Object
- #hostname_match ⇒ Object
- #kilobytes_to_bytes(kilobytes) ⇒ Object
- #obfuscate_fqdn(fqdn) ⇒ Object
- #obfuscate_hostname?(host) ⇒ Boolean
- #obfuscate_ip(ip, ips_dict) ⇒ Object
- #obfuscate_ips?(host) ⇒ Boolean
- #obfuscated_ips(host) ⇒ Object
- #uuid_value(value) ⇒ Object
- #uuid_value!(value) ⇒ Object
Instance Method Details
#account_id(organization) ⇒ Object
26 27 28 29 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 26 def account_id(organization) @organization_accounts ||= {} @organization_accounts[organization.id] ||= organization.pools.where.not(account_number: nil).pluck(:account_number).first end |
#bios_uuid(host) ⇒ Object
188 189 190 191 192 193 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 188 def bios_uuid(host) return nil if host.nil? value = fact_value(host, 'dmi::system::uuid') || '' uuid_value(value) end |
#cloud_provider(host) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 31 def cloud_provider(host) bios_version = fact_value(host, 'dmi::bios::version') if bios_version return CLOUD_AMAZON if bios_version.downcase['amazon'] return CLOUD_GOOGLE if bios_version.downcase['google'] end chassis_asset_tag = fact_value(host, 'dmi::chassis::asset_tag') return CLOUD_AZURE if chassis_asset_tag && chassis_asset_tag['7783-7084-3265-9085-8269-3286-77'] system_manufacturer = fact_value(host, 'dmi::system::manufacturer') return CLOUD_ALIBABA if system_manufacturer && system_manufacturer.downcase['alibaba cloud'] product_name = fact_value(host, 'dmi::system::product_name') return CLOUD_ALIBABA if product_name && product_name.downcase['alibaba cloud ecs'] nil end |
#fact_value(host, fact_name) ⇒ Object
15 16 17 18 19 20 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 15 def fact_value(host, fact_name) value_record = host.fact_values.find do |fact_value| fact_value.fact_name_id == ForemanInventoryUpload::Generators::Queries.fact_names[fact_name] end value_record&.value end |
#fqdn(host) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 64 def fqdn(host) if obfuscate_hostname?(host) # If obfuscation is enabled, attempt to retrieve an already obfuscated hostname # from the 'insights_client::obfuscated_hostname' fact. # Example format of `parsed_insights_array`: # [{"original"=>"host.example.com", "obfuscated"=>"0dd449d0a027.example.com"}, # {"original"=>"satellite.example.com", "obfuscated"=>"host2.example.com"}] begin parsed_insights_array = JSON.parse(fact_value(host, 'insights_client::obfuscated_hostname') || '[]') rescue JSON::ParserError parsed_insights_array = [] end # Obfuscate using the following hierarchy: # 1. the obfuscated_hostname fact sent by insights_client parsed_insights_item = parsed_insights_array.find { |item| item['original'] == host.fqdn } # 2. our own helper method parsed_insights_item&.[]('obfuscated') || obfuscate_fqdn(host.fqdn) else # If hostname obfuscation is not enabled for this host, return the host's original FQDN. host.fqdn end end |
#host_ips(host) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 107 def host_ips(host) # Determines and returns the IP addresses associated with a host, applying obfuscation if enabled. return {} if host.nil? # If IP obfuscation is enabled for the host return a representation of obfuscated IP addresses. return (host) if obfuscate_ips?(host) # If IP obfuscation is NOT needed, return a special kind of Hash. # where when you try to access a key in it # if the key doesn't exist, it simply returns the key itself. # This is useful because it means if you try to get an IP from this hash, # you'll just get the original IP back. It allows the calling code to # use the same interface whether obfuscation is applied or not. Hash.new { |h, k| k } end |
#hostname_match ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 157 def hostname_match bash_hostname = `uname -n`.chomp foreman_host = ForemanRhCloud.foreman_host # If bash hostname matches foreman_host, use fqdn if foreman_host && bash_hostname == foreman_host.name return fqdn(foreman_host) end # If no foreman_host, try foreman_host_name from Setting[:foreman_url] unless foreman_host foreman_hostname_from_setting = ForemanRhCloud.foreman_host_name if foreman_hostname_from_setting # Apply obfuscation if enabled return obfuscate_fqdn(foreman_hostname_from_setting) if Setting[:obfuscate_inventory_hostnames] return foreman_hostname_from_setting end # Otherwise fall through to bash_hostname below # NOTE: Containerized foremanctl setups must configure Setting[:foreman_url] # as bash hostname may not be available or meaningful in containers end # Fallback to bash hostname (with obfuscation if enabled) if Setting[:obfuscate_inventory_hostnames] obfuscate_fqdn(bash_hostname) else bash_hostname end end |
#kilobytes_to_bytes(kilobytes) ⇒ Object
22 23 24 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 22 def kilobytes_to_bytes(kilobytes) kilobytes * 1024 end |
#obfuscate_fqdn(fqdn) ⇒ Object
87 88 89 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 87 def obfuscate_fqdn(fqdn) "#{Digest::SHA1.hexdigest(fqdn)}.example.com" end |
#obfuscate_hostname?(host) ⇒ Boolean
51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 51 def obfuscate_hostname?(host) # Returns true if hostname obfuscation should be applied for a given host, based on hierarchy: # 1. Global setting for hostname obfuscation. return true if Setting[:obfuscate_inventory_hostnames] && !ForemanRhCloud.with_iop_smart_proxy? insights_client_setting = fact_value(host, 'insights_client::obfuscate_hostname_enabled') insights_client_setting = ActiveModel::Type::Boolean.new.cast(insights_client_setting) # 2. host fact reported by insights_client # 3. if neither of the above, don't obfuscate. insights_client_setting.nil? ? false : insights_client_setting end |
#obfuscate_ip(ip, ips_dict) ⇒ Object
149 150 151 152 153 154 155 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 149 def obfuscate_ip(ip, ips_dict) # Produce a new, unique obfuscated IP that is # numerically one greater than the highest existing obfuscated IP = ips_dict.values.map { |v| IPAddr.new(v).to_i }.max || IPAddr.new('10.230.230.0').to_i IPAddr.new( + 1, Socket::AF_INET).to_s end |
#obfuscate_ips?(host) ⇒ Boolean
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 91 def obfuscate_ips?(host) # Returns true if IP obfuscation should be applied for a given host, based on hierarchy: # 1. Global setting for IP obfuscation. return true if Setting[:obfuscate_inventory_ips] && !ForemanRhCloud.with_iop_smart_proxy? insights_client_ipv4_setting = fact_value(host, 'insights_client::obfuscate_ipv4_enabled') insights_client_ipv6_setting = fact_value(host, 'insights_client::obfuscate_ipv6_enabled') cast_ipv4_setting = ActiveModel::Type::Boolean.new.cast(insights_client_ipv4_setting) cast_ipv6_setting = ActiveModel::Type::Boolean.new.cast(insights_client_ipv6_setting) # 2. The host's IPv4 or IPv6 obfuscation fact value is true # 3. If neither of the above, don't obfuscate. cast_ipv4_setting || cast_ipv6_setting || false end |
#obfuscated_ips(host) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 123 def (host) # Example format of `parsed_insights_array`: # [{"original": "192.168.1.10", "obfuscated": "10.230.230.1"}, # {"original": "192.168.1.11", "obfuscated": "10.230.230.2"}] begin parsed_insights_array = JSON.parse(fact_value(host, 'insights_client::obfuscated_ipv4') || '[]') rescue JSON::ParserError parsed_insights_array = [] end # Create a new Hash to store the mapping from original IP addresses to their obfuscated versions. # where the 'original' IP is the key and the 'obfuscated' IP is the value. = Hash[ parsed_insights_array.map { |ip_record| [ip_record['original'], ip_record['obfuscated']] } ] # Sets a default proc for the obfuscated_ips hash. # When a key is accessed that does not exist in the hash, this proc is called. # It assigns the result of obfuscate_ip(key, hash) to the missing key in the hash. # This ensures that any missing IP address key will be obfuscated and stored automatically. .default_proc = proc do |hash, key| hash[key] = obfuscate_ip(key, hash) end end |
#uuid_value(value) ⇒ Object
195 196 197 198 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 195 def uuid_value(value) uuid_match = UUID_REGEX.match(value) uuid_match&.to_s end |
#uuid_value!(value) ⇒ Object
200 201 202 203 204 205 |
# File 'lib/foreman_inventory_upload/generators/fact_helpers.rb', line 200 def uuid_value!(value) uuid = uuid_value(value) raise Foreman::Exception.new(N_('Value %{value} is not a valid UUID') % { value: value }) if value && uuid.empty? uuid end |