Skip to content
This repository has been archived by the owner on Jun 19, 2020. It is now read-only.

(FACT-2553) Quote special string in YAML format #471

Merged
merged 1 commit into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 3 additions & 8 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config --exclude-limit 1000`
# on 2020-05-06 13:07:31 +0300 using RuboCop version 0.74.0.
# on 2020-05-07 16:13:14 +0300 using RuboCop version 0.74.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand Down Expand Up @@ -110,7 +110,7 @@ RSpec/LeakyConstantDeclaration:
- 'spec/facter/resolvers/macosx/mountpoints_resolver_spec.rb'
- 'spec/facter/resolvers/utils/windows/network_utils_spec.rb'

# Offense count: 114
# Offense count: 108
# Configuration parameters: EnforcedStyle.
# SupportedStyles: have_received, receive
RSpec/MessageSpies:
Expand Down Expand Up @@ -146,7 +146,6 @@ RSpec/MessageSpies:
- 'spec/facter/facts/windows/dmi/product/name_spec.rb'
- 'spec/facter/facts/windows/dmi/product/serial_number_spec.rb'
- 'spec/facter/facts/windows/dmi/product/uuid_spec.rb'
- 'spec/facter/facts/windows/fips_enabled_spec.rb'
- 'spec/facter/facts/windows/identity/user_spec.rb'
- 'spec/facter/facts/windows/ipaddress6_interfaces_spec.rb'
- 'spec/facter/facts/windows/ipaddress_interfaces_spec.rb'
Expand Down Expand Up @@ -176,7 +175,6 @@ RSpec/MessageSpies:
- 'spec/facter/facts/windows/ruby/sitedir_spec.rb'
- 'spec/facter/facts/windows/scope6_interfaces_spec.rb'
- 'spec/facter/resolvers/utils/aix/odm_query_spec.rb'
- 'spec/framework/core/fact_loaders/external_fact_loader_spec.rb'

# Offense count: 26
RSpec/SubjectStub:
Expand All @@ -189,7 +187,7 @@ RSpec/SubjectStub:
- 'spec/custom_facts/util/fact_spec.rb'
- 'spec/custom_facts/util/resolution_spec.rb'

# Offense count: 162
# Offense count: 132
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
RSpec/VerifiedDoubles:
Exclude:
Expand Down Expand Up @@ -217,7 +215,6 @@ RSpec/VerifiedDoubles:
- 'spec/facter/facts/windows/networking/dhcp_spec.rb'
- 'spec/facter/facts/windows/networking/interfaces_spec.rb'
- 'spec/facter/facts/windows/networking/mtu_spec.rb'
- 'spec/facter/facts/windows/networking/primary_spec.rb'
- 'spec/facter/facts/windows/processors/models_spec.rb'
- 'spec/facter/facts/windows/virtualization/is_virtual_spec.rb'
- 'spec/facter/facts/windows/virtualization/virtual_spec.rb'
Expand All @@ -236,11 +233,9 @@ RSpec/VerifiedDoubles:
- 'spec/facter/resolvers/windows/identity_resolver_spec.rb'
- 'spec/facter/resolvers/windows/kernel_resolver_spec.rb'
- 'spec/facter/resolvers/windows/memory_resolver_spec.rb'
- 'spec/facter/resolvers/windows/networking_resolver_spec.rb'
- 'spec/facter/resolvers/windows/processors_resolver_spec.rb'
- 'spec/facter/resolvers/windows/system32_resolver_spec.rb'
- 'spec/facter/resolvers/windows/uptime_resolver_spec.rb'
- 'spec/facter/resolvers/windows/virtualization_resolver_spec.rb'
- 'spec/facter/resolvers/windows/win_os_description_resolver_spec.rb'
- 'spec/framework/core/fact_loaders/external_fact_loader_spec.rb'
- 'spec/framework/core/fact_loaders/fact_loader_spec.rb'
Expand Down
2 changes: 1 addition & 1 deletion lib/facts/windows/networking/primary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Primary
FACT_NAME = 'networking.primary'

def call_the_resolver
fact_value = Facter::Resolvers::Networking.resolve(:primary)
fact_value = Facter::Resolvers::Networking.resolve(:primary_interface)

Facter::ResolvedFact.new(FACT_NAME, fact_value)
end
Expand Down
54 changes: 50 additions & 4 deletions lib/framework/formatters/yaml_fact_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,59 @@ def initialize
@log = Log.new(self)
end

def format(fact_hash)
yaml_pretty = YAML.dump(JSON.parse(JsonFactFormatter.new.format(fact_hash)))
def format(resolved_facts)
user_queries = resolved_facts.uniq(&:user_query).map(&:user_query)

facts_to_display = if user_queries.count == 1 && user_queries.first.empty?
FormatterHelper.retrieve_fact_collection(resolved_facts)
else
FormatterHelper.retrieve_facts_to_display_for_user_query(user_queries, resolved_facts)
end

facts_to_display = Psych.parse_stream(facts_to_display.to_yaml)
facts_to_display.children[0].tag_directives = []
yaml_pretty = quote_special_strings(facts_to_display)
oanatmaria marked this conversation as resolved.
Show resolved Hide resolved

@log.debug('Replace single backslash with double backslashes')
yaml_pretty.gsub!(/\\/, '\&\&')
@log.debug('Replace --- from yaml beginning, to keep it compatible with C facter')
yaml_pretty.gsub(/^---[\r\n]+/, '')
end

private

def quote_special_strings(fact_hash)
require 'psych'

fact_hash.grep(Psych::Nodes::Scalar).each do |node|
next unless needs_quote?(node.value)

node.plain = false
node.quoted = true
node.style = Psych::Nodes::Scalar::DOUBLE_QUOTED
end

fact_hash = unquote_keys(fact_hash)
fact_hash.yaml
end

def unquote_keys(fact_hash)
fact_hash.grep(Psych::Nodes::Mapping).each do |node|
node.children.each_slice(2) do |k, _|
k.plain = true
k.quoted = false
k.style = Psych::Nodes::Scalar::ANY
end
end
fact_hash
end

def needs_quote?(value)
return false if value =~ /true|false/
return false if value[/^[0-9]+$/]
return true if value =~ /y|Y|yes|Yes|YES|n|N|no|No|NO|True|TRUE|False|FALSE|on|On|ON|off|Off|OFF|:/
return false if value[/[a-zA-Z]/]
return false if value[/[0-9]+\.[0-9]+\./]

true
end
end
end
2 changes: 1 addition & 1 deletion lib/resolvers/windows/ffi/network_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def build_binding(addr, mask_length)
else
IPAddr.new('255.255.255.255').mask(mask_length)
end
{ address: addr, netmask: mask, network: ip.mask(mask_length) }
{ address: addr, netmask: mask.to_s, network: ip.mask(mask_length).to_s }
end

def get_scope(sockaddr)
Expand Down
15 changes: 8 additions & 7 deletions lib/resolvers/windows/networking_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def read_network_information(fact_name)

iterate_list(adapter_addresses)
set_interfaces_other_facts if @fact_list[:interfaces]
@fact_list[:primary_interface] = @fact_list[:primary_interface].to_s
@fact_list[fact_name]
end

Expand Down Expand Up @@ -112,8 +113,8 @@ def add_ip_data(addr, unicast, sock_addr, bindings)
result = find_bindings(sock_addr, unicast, addr)
return unless result

bindings[:ipv6] << result if result[:network].ipv6?
bindings[:ipv4] << result if result[:network].ipv4?
bindings[:ipv6] << result if sock_addr[:sa_family] == NetworkingFFI::AF_INET6
bindings[:ipv4] << result if sock_addr[:sa_family] == NetworkingFFI::AF_INET
end

def find_bindings(sock_addr, unicast, addr)
Expand All @@ -126,7 +127,7 @@ def find_primary_interface(sock_addr, name, addr)
if !@fact_list[:primary_interface] &&
([NetworkingFFI::AF_INET, NetworkingFFI::AF_INET6].include?(sock_addr[:sa_family]) &&
!NetworkUtils.ignored_ip_address(addr))
@fact_list[:primary] = name
@fact_list[:primary_interface] = name
end
end

Expand All @@ -138,7 +139,7 @@ def set_interfaces_other_facts
end
if value[:bindings6]
binding = find_valid_binding(value[:bindings6])
populate_interface(binding, value)
populate_interface(binding, value, true)
end
set_networking_other_facts(value, interface_name)
end
Expand All @@ -151,10 +152,10 @@ def find_valid_binding(bindings)
bindings.empty? ? nil : bindings.first
end

def populate_interface(bind, interface)
def populate_interface(bind, interface, ipv6 = false)
return if !bind || bind.empty?

if bind[:network].ipv6?
if ipv6
interface[:ip6] = bind[:address]
interface[:netmask6] = bind[:netmask]
interface[:network6] = bind[:network]
Expand All @@ -167,7 +168,7 @@ def populate_interface(bind, interface)
end

def set_networking_other_facts(value, interface_name)
return unless @fact_list[:primary] == interface_name
return unless @fact_list[:primary_interface] == interface_name

%i[mtu dhcp mac ip ip6 scope6 netmask netmask6 network network6].each do |key|
@fact_list[key] = value[key]
Expand Down
9 changes: 5 additions & 4 deletions lib/resolvers/windows/virtualization_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class << self
# Virtual
# Is_Virtual

MODEL_HASH = { 'VirtualBox' => 'virtualbox', 'VMware' => 'vmware', 'KVM' => 'kvm',
'Bochs' => 'bochs', 'Google' => 'gce', 'OpenStack' => 'openstack' }.freeze

private

def post_resolve(fact_name)
Expand All @@ -31,9 +34,7 @@ def read_fact_from_computer_system(fact_name)
end

def determine_hypervisor_by_model(comp)
model_hash = { 'VirtualBox' => 'virtualbox', 'VMware' => 'vmware', 'KVM' => 'kvm',
'Bochs' => 'bochs', 'Google' => 'gce', 'OpenStack' => 'openstack' }
model_hash[model_hash.keys.find { |key| comp.Model =~ /^#{key}/ }]
MODEL_HASH[MODEL_HASH.keys.find { |key| comp.Model =~ /^#{key}/ }]
end

def determine_hypervisor_by_manufacturer(comp)
Expand All @@ -57,7 +58,7 @@ def build_fact_list(comp)
hypervisor = determine_hypervisor_by_model(comp) || determine_hypervisor_by_manufacturer(comp)

@fact_list[:virtual] = hypervisor
@fact_list[:is_virtual] = (!hypervisor.include?('physical')).to_s
@fact_list[:is_virtual] = hypervisor.include?('physical') ? false : true
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/facter/facts/windows/fips_enabled_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
end

it 'calls Facter::Windows::Resolvers::Fips' do
expect(Facter::Resolvers::Windows::Fips).to receive(:resolve).with(:fips_enabled)
fact.call_the_resolver
expect(Facter::Resolvers::Windows::Fips).to have_received(:resolve).with(:fips_enabled)
end

it 'returns true if fips enabled' do
Expand Down
21 changes: 15 additions & 6 deletions spec/facter/facts/windows/networking/primary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@

describe Facts::Windows::Networking::Primary do
describe '#call_the_resolver' do
it 'returns a fact' do
expected_fact = double(Facter::ResolvedFact, name: 'networking.primary', value: 'value')
allow(Facter::Resolvers::Networking).to receive(:resolve).with(:primary).and_return('value')
allow(Facter::ResolvedFact).to receive(:new).with('networking.primary', 'value').and_return(expected_fact)
subject(:fact) { Facts::Windows::Networking::Primary.new }

fact = Facts::Windows::Networking::Primary.new
expect(fact.call_the_resolver).to eq(expected_fact)
let(:value) { 'Ethernet0' }

before do
allow(Facter::Resolvers::Networking).to receive(:resolve).with(:primary_interface).and_return(value)
end

it 'calls Facter::Windows::Resolvers::Fips' do
fact.call_the_resolver
expect(Facter::Resolvers::Networking).to have_received(:resolve).with(:primary_interface)
end

it 'returns true if fips enabled' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact).and \
have_attributes(name: 'networking.primary', value: value)
end
end
end
22 changes: 13 additions & 9 deletions spec/facter/resolvers/utils/windows/network_utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
describe NetworkUtils do
describe '#address_to_strig' do
let(:logger) { instance_spy(Facter::Log) }
let(:addr) { double('SocketAddress') }
let(:size) { double(FFI::MemoryPointer) }
let(:buffer) { double(FFI::MemoryPointer) }
let(:addr) { instance_spy('SocketAddress') }
let(:size) { instance_spy(FFI::MemoryPointer) }
let(:buffer) { instance_spy(FFI::MemoryPointer) }
let(:length) { 32 }

before do
Expand All @@ -31,7 +31,7 @@
end

context 'when error code is zero' do
let(:address) { double(FFI::MemoryPointer) }
let(:address) { instance_spy(FFI::MemoryPointer) }
let(:error) { 0 }

it 'returns an address' do
Expand All @@ -40,7 +40,7 @@
end

context 'when error code is not zero' do
let(:address) { double(FFI::MemoryPointer) }
let(:address) { instance_spy(FFI::MemoryPointer) }
let(:error) { 1 }

it 'returns nil and logs debug message' do
Expand Down Expand Up @@ -90,8 +90,8 @@

describe '#build_binding' do
context 'when input is ipv4 address' do
let(:netmask) { IPAddr.new('255.255.240.0/255.255.240.0') }
let(:network) { IPAddr.new('10.16.112.0/255.255.240.0') }
let(:netmask) { IPAddr.new('255.255.240.0/255.255.240.0').to_s }
let(:network) { IPAddr.new('10.16.112.0/255.255.240.0').to_s }
let(:addr) { '10.16.121.248' }

it 'returns ipv4 binding' do
Expand All @@ -100,8 +100,12 @@
end

context 'when input is ipv6 address' do
let(:network) { IPAddr.new('fe80:0000:0000:0000:0000:0000:0000:0000/ffff:ffff:ffff:ffff:0000:0000:0000:0000') }
let(:netmask) { IPAddr.new('ffff:ffff:ffff:ffff:0000:0000:0000:0000/ffff:ffff:ffff:ffff:0000:0000:0000:0000') }
let(:network) do
IPAddr.new('fe80:0000:0000:0000:0000:0000:0000:0000/ffff:ffff:ffff:ffff:0000:0000:0000:0000').to_s
end
let(:netmask) do
IPAddr.new('ffff:ffff:ffff:ffff:0000:0000:0000:0000/ffff:ffff:ffff:ffff:0000:0000:0000:0000').to_s
end
let(:addr) { 'fe80::dc20:a2b9:5253:9b46' }

it 'returns ipv6 binding' do
Expand Down