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

Introduce machine and package platform conditionals to Bash remediations #6061

Merged
merged 5 commits into from
Sep 14, 2020

Conversation

yuumasato
Copy link
Member

@yuumasato yuumasato commented Sep 8, 2020

Description:

  • Trickle down the CPE Platform to the Bash remediations
    • When a rule has a platform be it machine or a Package CPE platform, the whole Bash remediation is wrapped around an if condition
    • Also adds conditionals for machine platform

Rationale:

When a rule has a Package CPE platform, like platform: dconf for example.
It is meant to be evaluated and remediated when the systems has dconf package installed.
Evaluation and remediation done with OpenSCAP respects these CPEs, as the scanner understands the CPE and the XCCDF:Platform field.
But when the Bash scripts are generated, the Package applicability of the remediation is lost.

Rationale:

@pep8speaks
Copy link

pep8speaks commented Sep 8, 2020

Hello @yuumasato! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

Line 315:100: E501 line too long (101 > 99 characters)

Comment last updated at 2020-09-10 15:27:00 UTC

@yuumasato yuumasato changed the title Introduce package conditionals to Bash remediations Introduce machine and package platform conditionals to Bash remediations Sep 9, 2020
@matejak matejak self-assigned this Sep 9, 2020
Copy link
Member

@matejak matejak left a comment

Choose a reason for hiding this comment

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

Well done, there are some minor remarks, but the functionality works as expected.

The {} in format strings can be probably replaced by {0} to keep the code working on Python<2.7.
I see potential problems with tests, as I can imagine that sometest scenarios may misbehave due to the newly introduced "do nothing when it's not my business" functionality, but I see this as unlikely - OVALs are already platform-aware.

platform_conditionals.append(pkg_check_command.format(platform))

if platform_conditionals:
platform_fix_text = "# Remediation is applicable only in certain platforms\n"
Copy link
Member

Choose a reason for hiding this comment

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

It is advisable to construct a multi-line string by creating a list of lines and then joining it. The primary aspect are performance reasons, but I believe that it would be nicer as well.
Next, I would suggest placing a blank line between the header and the remediation body for greater readability.

platform_fix_text += "if {}".format(cond)
for cond in platform_conditionals:
platform_fix_text += " && {}".format(cond)
platform_fix_text += '; then\n{}\nelse\necho "Remediation is not applicable, nothing was done"\nfi'.format(result.contents)
Copy link
Member

Choose a reason for hiding this comment

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

  1. I would use textwrap. indent to indent the innner original body of the remediation if it doesn't break our dark remediation generation magic.
  2. What do you think of redirecting the echo to stderr?

Copy link
Member Author

@yuumasato yuumasato Sep 10, 2020

Choose a reason for hiding this comment

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

Indenting the body of the the remediation didn't break the build nor the behavior.
Unfortunately, not everything is indented.
When the scanner performs the XCCDF substitutions, the Bash remediation functions are not properly indented.
Main issue being that they have multiple lines, and can be used "platform wrapped" or not.

Copy link
Member Author

Choose a reason for hiding this comment

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

@matejak indent is not available in python2.
Do you know of a trivial substitute?

Copy link
Member

@matejak matejak Sep 10, 2020

Choose a reason for hiding this comment

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

Oh, that Python2 not being able to do this - that's a surprise. We can have an indent as an optional feature in the try-except block.
However, I wouldn't do it now, as it conflicts with those XCCDF substitutions as you have pointed out, and there is a small likelihood that some remediations may not be indent-safe - consider here-docs.

Copy link
Member Author

Choose a reason for hiding this comment

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

Interesting find. I'll drop adcb827 for now.

platform_fix_text = "# Remediation is applicable only in certain platforms\n"

cond = platform_conditionals.pop(0)
platform_fix_text += "if {}".format(cond)
Copy link
Member

Choose a reason for hiding this comment

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

I think that it could be slightly more elegant to join the platform_conditionals list by &&.

@@ -691,24 +738,27 @@ def expand_xccdf_subs(fix, remediation_type, remediation_functions):
patcomp = re.compile(pattern, re.DOTALL)
fixparts = re.split(patcomp, fix.text)
if fixparts[0] is not None:
Copy link
Member

Choose a reason for hiding this comment

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

I can't wait for the moment when we take some of the existing magic out and simplify this function.

Copy link
Member Author

Choose a reason for hiding this comment

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

I suspect that when all bash remediation functions are converted to Jinja macros expand_xccdf_subs won't be needed anymore.

@jan-cerny
Copy link
Collaborator

Can you show us an example of the conditional?

@matejak
Copy link
Member

matejak commented Sep 10, 2020

Can you show us an example of the conditional?

That's easy - compile e.g. Fedora and then grep build/fixes/bash with &&, and you will see all sorts of platforms.

Regarding the PR, I gave a second thought on the indentation, and I suggest to put there a comment that there is such possibility, but there is a Python2/3 catch, plus a small risk for remediations themselves.

@matejak
Copy link
Member

matejak commented Sep 10, 2020

It may be that if you rebase against master, OCP tests will start to pass :-)

Wraps the remediation of rules with Packager CPE Platform
with an if condition that checks for the respective
platforms's package.
Adjust expansion of subs and variables not to remove the whole beginning
of the fix test. This was removing the package conditional wrapping.
@mildas
Copy link
Contributor

mildas commented Sep 10, 2020

Changes identified:
Others:
 Python abstract syntax tree change found in ssg/build_remediations.py.

Recommended tests to execute:
 (cd build && cmake ../ && ctest -j4)

@matejak
Copy link
Member

matejak commented Sep 11, 2020

/retest

wrapped_fix_text.append("{0}".format(result.contents))
wrapped_fix_text.append("")
wrapped_fix_text.append("else")
wrapped_fix_text.append(" >&2 echo 'Remediation is not applicable, nothing was done'")
Copy link
Member

Choose a reason for hiding this comment

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

Is this leading >&2 intentional? I would place it after the echo.

Copy link
Member Author

@yuumasato yuumasato Sep 14, 2020

Choose a reason for hiding this comment

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

Yes, it follows syntax similar to what OpenSCAP does when generating Bash fixes.
https://github.com/OpenSCAP/openscap/blob/maint-1.3/src/XCCDF_POLICY/xccdf_policy_remediate.c#L631

Copy link
Member

Choose a reason for hiding this comment

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

Apparently you can place redirects before of after "simple commands" in Bash. Interesting!

@matejak
Copy link
Member

matejak commented Sep 14, 2020

This is a great step and historic moment for the project - our most common remediations are now platform-aware, and therefore consistent with OVALs and Ansible, who became fully platform-aware recently.
Great work!

@matejak matejak merged commit 1e73f5e into ComplianceAsCode:master Sep 14, 2020
@matejak matejak added this to the 0.1.53 milestone Sep 14, 2020
@matejak matejak added Bash Bash remediation update. Highlight This PR/Issue should make it to the featured changelog. labels Sep 14, 2020
@yuumasato
Copy link
Member Author

@matejak Thank you very much for the review!

@yuumasato yuumasato deleted the bash-platforms branch September 14, 2020 14:28
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bash Bash remediation update. Highlight This PR/Issue should make it to the featured changelog.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants