Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(1093) - Fix unresolved fact error #1094

Merged
merged 1 commit into from
Dec 6, 2022
Merged

Conversation

jordanbreen28
Copy link
Contributor

@jordanbreen28 jordanbreen28 commented Nov 29, 2022

Fix for #1093

Prior to this PR, work was carried out on this module to update all instances of the now deprecated Facter::Util::Resolution, and replace all with its newer and supported counterpart Facter::Core::Execution.
However, these do not behave exactly the same.

Facter::Util::Resolution initially ran a which to locate the binary before executing, preventing any errors from occuring. The newer Facter::Core::Execution method did not do this, instead it attempted to execute.

This commit aims to introduce an "on_fail:false" flag to each execute statement, so that a failed execute will return false (boolean) and not generate an error.

@jordanbreen28 jordanbreen28 requested a review from a team as a code owner November 29, 2022 12:30
david22swan
david22swan previously approved these changes Dec 2, 2022
Copy link
Member

@david22swan david22swan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rtib
Copy link

rtib commented Dec 5, 2022

Wouldn't it be better to confine the evaluation of facts to those nodes having the required commands installed? IMO, nodes haven't installed iptables are not required to report firewall facts at all.

@jordanbreen28 jordanbreen28 force-pushed the 1093-fix_unresolved_fact_error branch 5 times, most recently from 14fc6bf to 74270c3 Compare December 5, 2022 17:50
@kjetilho
Copy link
Contributor

kjetilho commented Dec 5, 2022

Wouldn't it be better to confine the evaluation of facts to those nodes having the required commands installed? IMO, nodes haven't installed iptables are not required to report firewall facts at all.

There is no support for such a confine as far as I know. The alternative is to run some kind of which function, but even that should happen within the setcode block, so that the test is not run when the other confines are not satisfied. (In this case, kernel=Linux.)

@rtib
Copy link

rtib commented Dec 6, 2022

You can confine a fact to a command or there is a confine block also available. I do such facts like, e.g.

Facter.add(:cassandra_info, type: :aggregate) do
  nodetool = ''
  confine do
    nodetool, _err, status = Open3.capture3('nodetool info')
    status.success?
  end

  chunk(:dc) { { dc: nodetool.match(%r{^Data Center *: (.*)$})[1] } }
  chunk(:rack) { { rack: nodetool.match(%r{^Rack *: (.*)$})[1] } }
end

In the case the command fails or cannot be executed, the confine block returns false and the fact won't be reported at all, while there isn't even a warning on the agent.

@jordanbreen28 jordanbreen28 force-pushed the 1093-fix_unresolved_fact_error branch 13 times, most recently from e8e6dc2 to 87e5827 Compare December 6, 2022 10:20
@jordanbreen28
Copy link
Contributor Author

You can confine a fact to a command or there is a confine block also available. I do such facts like, e.g.

Facter.add(:cassandra_info, type: :aggregate) do
  nodetool = ''
  confine do
    nodetool, _err, status = Open3.capture3('nodetool info')
    status.success?
  end

  chunk(:dc) { { dc: nodetool.match(%r{^Data Center *: (.*)$})[1] } }
  chunk(:rack) { { rack: nodetool.match(%r{^Rack *: (.*)$})[1] } }
end

In the case the command fails or cannot be executed, the confine block returns false and the fact won't be reported at all, while there isn't even a warning on the agent.

Thanks for the suggestion @rtib, when implementing a confine statement such as

confine { Facter::Core::Execution.which('iptables') }

this introduces spec test failures on nodes that do not have the package installed.

@kjetilho
Copy link
Contributor

kjetilho commented Dec 6, 2022

Thanks for the suggestion @rtib, when implementing a confine statement such as

confine { Facter::Core::Execution.which('iptables') }

this introduces spec test failures on nodes that do not have the package installed.

You need to mock the .which method, too:

      allow(Facter::Core::Execution).to receive(:which).with('iptables')
                                                         .and_return('/usr/sbin/iptables')

This worked in my rspec environment without iptables installed.

@rtib
Copy link

rtib commented Dec 6, 2022

I assume you mean spec checks like spec/unit/facter/iptables_persistent_version_spec.rb#L34. That's because, these checks assume the fact being reported contain a nil, but a confined fact won't be reported. On these nodes the spec should expect the fact missing.

IMO, this would be the desired behaviour. Imagine an environment running a large number of nodes, but only a few need firewall. There is no need to report facts with value nil from nodes which doesn't configure a firewall. This could also reduce the utilisation of PuppetDB. It is not a big difference within the DSL if a fact doesn't exists or exists but its value is unset, since for those nodes the firewall module is not included in their manifest.

@jordanbreen28 jordanbreen28 force-pushed the 1093-fix_unresolved_fact_error branch 3 times, most recently from 7d2bedc to 7f1b30a Compare December 6, 2022 11:05
@jordanbreen28
Copy link
Contributor Author

Changes applied, thanks @rtib & @kjetilho!

@jordanbreen28 jordanbreen28 force-pushed the 1093-fix_unresolved_fact_error branch 2 times, most recently from 8b27323 to 3fe4e97 Compare December 6, 2022 11:39
Prior to this commit, work was carried out on this module to update all instances of the now deprecated Facter::Util::Resolution, and replace all with its newer and supported counterpart Facter::Core::Execution.
However, these do not behave exactly the same. Facter::Util::Resolution initially ran a which to locate the binary before executing, preventing any errors from occuring. The newer Facter::Core::Execution method did not do this, instead it attempted to execut>

This commit aims to introduce an "on_fail:false" flag to each execute statement, so that a failed execute will return false (boolean) as oppose to an error, which can then be used for further logic.
Copy link
Contributor

@LukasAud LukasAud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, GJ

@LukasAud LukasAud merged commit ad7de8e into main Dec 6, 2022
@LukasAud LukasAud deleted the 1093-fix_unresolved_fact_error branch December 6, 2022 15:34
@canihavethisone
Copy link

Excellent collaboration here to address the issue quickly and professionally, thanks all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants