Skip to content

Comments

restructure templates#6303

Merged
jan-cerny merged 17 commits intoComplianceAsCode:masterfrom
vojtapolasek:friendlier_templates_2
Nov 25, 2020
Merged

restructure templates#6303
jan-cerny merged 17 commits intoComplianceAsCode:masterfrom
vojtapolasek:friendlier_templates_2

Conversation

@vojtapolasek
Copy link
Collaborator

@vojtapolasek vojtapolasek commented Oct 27, 2020

Description:

  • for each existing template:

    • create a new directory within shared/templates named after the template

    • move template files to the directory and name them according to the language (oval, bash etc.)

    • create a file template.py and move the preprocessing function (formerly decorated function in ssg/templates.py) into this file, call the function preprocess. If there is no real preprocessing needed, just skip this step.

    • create file template.yml and declare supported languages within this file. This prevents situation with missing files for language implementation etc.

  • rewrite the file ssg/templates.py:

    • create a new Class "template" for holding of some data, currently very simple, will be glad to extend it

    • remove decorated functions

    • modify the function "preprocess_data" to use new way of loading preprocessing functions

  • drop the "permissions" template, it was no longer used and it was even lacking the decorated function

  • update the part about creating of templates within the developer guide

Rationale:

This restructuring has the following benefits:

  • easier template creation - no modification of ssg/templates.py needed

  • the directory structure is easier to navigate

  • I believe this can lead to effective testing of templates with SSG test suite, not implemented yet

@vojtapolasek vojtapolasek added this to the 0.1.53 milestone Oct 27, 2020
@openshift-ci-robot
Copy link
Collaborator

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci-robot openshift-ci-robot added the do-not-merge/work-in-progress Used by openshift-ci bot. label Oct 27, 2020
@pep8speaks
Copy link

pep8speaks commented Oct 27, 2020

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

Line 47:17: E128 continuation line under-indented for visual indent
Line 51:17: E128 continuation line under-indented for visual indent
Line 57:35: E261 at least two spaces before inline comment

Comment last updated at 2020-11-23 17:53:15 UTC

@openscap-ci
Copy link
Collaborator

openscap-ci commented Oct 27, 2020

Changes identified:
Others:
 Changes in Python files.

Show details

Others:
 Python file shared/templates/accounts_password/template.py is newly added.
 Python file shared/templates/audit_file_contents/template.py is newly added.
 Python file shared/templates/audit_rules_login_events/template.py is newly added.
 Python file shared/templates/audit_rules_path_syscall/template.py is newly added.
 Python file shared/templates/audit_rules_privileged_commands/template.py is newly added.
 Python file shared/templates/audit_rules_usergroup_modification/template.py is newly added.
 Python file shared/templates/auditd_lineinfile/template.py is newly added.
 Python file shared/templates/file_groupowner/template.py is newly added.
 Python file shared/templates/file_owner/template.py is newly added.
 Python file shared/templates/file_permissions/template.py is newly added.
 Python file shared/templates/grub2_bootloader_argument/template.py is newly added.
 Python file shared/templates/mount/template.py is newly added.
 Python file shared/templates/mount_option/template.py is newly added.
 Python file shared/templates/mount_option_remote_filesystems/template.py is newly added.
 Python file shared/templates/package_installed/template.py is newly added.
 Python file shared/templates/sebool/template.py is newly added.
 Python file shared/templates/service_disabled/template.py is newly added.
 Python file shared/templates/service_enabled/template.py is newly added.
 Python file shared/templates/shell_lineinfile/template.py is newly added.
 Python file shared/templates/sshd_lineinfile/template.py is newly added.
 Python file shared/templates/sysctl/template.py is newly added.
 Python file shared/templates/timer_enabled/template.py is newly added.
 Python file shared/templates/yamlfile_value/template.py is newly added.
 Python abstract syntax tree change found in ssg/templates.py.

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

@vojtapolasek
Copy link
Collaborator Author

/test all

@redhatrises
Copy link
Contributor

I like this idea, but I would wouldn't follow the existing rule concepts of having separate directories for OVAL, bash, ansible, etc. Those directories make the project less approachable and readable. Not having the separate directories would make this easier for people. @carlosmmatos would you agree?

@yuumasato
Copy link
Member

I like this idea, but I would wouldn't follow the existing rule concepts of having separate directories for OVAL, bash, ansible, etc.

They are not in directories, the files are just called oval, bash, ansible, ANACONDA, ignition, ...
BTW, @vojtapolasek the templates for Anaconda are all caps, :)

I think I'd name the files oval.template, ...

@openshift-ci-robot openshift-ci-robot added the needs-rebase Used by openshift-ci bot. label Oct 29, 2020
@vojtapolasek vojtapolasek force-pushed the friendlier_templates_2 branch 2 times, most recently from 8932403 to bfb2d8f Compare October 29, 2020 11:15
@openshift-ci-robot openshift-ci-robot removed the needs-rebase Used by openshift-ci bot. label Oct 29, 2020
@vojtapolasek
Copy link
Collaborator Author

I added the .template extension to files in the template folder as requested. Also anaconda remediations are now in lower case.

@vojtapolasek vojtapolasek marked this pull request as ready for review October 29, 2020 11:18
@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Used by openshift-ci bot. label Oct 29, 2020
@carlosmmatos
Copy link
Contributor

I like this approach and using the .template file name syntax. It's more in line with a current control structure so this should be fairly simple to follow from a user or dev perspective.

ssg/templates.py Outdated

def preprocess(self, parameters, lang):
preprocess_mod = None # temporarily imported module containing preprocessing function
spec = importlib.util.spec_from_file_location(
Copy link
Member

Choose a reason for hiding this comment

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

I have an idea about the templates.py file in the template directory. When I don't want to preprocess the data aka I don't need to change the input in any way, why not to just skip this logic (e.g capturing some exception that the file doesn't exist) and input the raw data to the jinja template? This way we don't need to have dummy templates.py in every template directory.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not against this idea. But can't we use these files also for documentation purposes? I am talking about your readthedocs initiative.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if it adds real value having an empty function without any comments

Copy link
Member

Choose a reason for hiding this comment

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

I like the idea of being able to skip e.g. the Python file, and I think that concerning documentation, we could aim at having e.g. a template.rst file that would contain the relevant snippet. In other words, I think that we don't need a function as a carrier of documentation.

@ggbecker
Copy link
Member

Regarding the CI failure in RHEL7:

    import importlib.util
ImportError: No module named util

The function importlib.utilmodule_from_spec was introduced in python 3.5 according to https://docs.python.org/3/library/importlib.html#importlib.util.module_from_spec

So we cannot use it in RHEL7 (it has python-2.7.5). Maybe this can help:

import imp
 module = imp.load_source(module_name.split('.')[-1], filename)
 return module

from: https://stackoverflow.com/questions/45350363/backport-of-importlib-for-python-2-7-from-3-6

Copy link
Member

@yuumasato yuumasato left a comment

Choose a reason for hiding this comment

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

Looks pretty good.

Comment on lines +52 to +53
# TODO: Remove this right after the variables in templates are renamed
# to lowercase
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, are the uppercase variables in the template intentional or a remnant of the past?

Copy link
Member

Choose a reason for hiding this comment

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

I would assume that the intention was to avoid naming conflicting and that the variable came from the input template data. But back then the templating system was different. I don't think it makes much sense nowadays.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, it's a remainder from the previous system. We can rename the variables in the templates to lowercase now and then we will be able to remove this part of the code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I see. I propose to remove this obsolete thing in a subsequent PR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes

@vojtapolasek vojtapolasek force-pushed the friendlier_templates_2 branch from 40b9f47 to 242aaeb Compare October 30, 2020 15:45
import sys
import re
from xml.sax.saxutils import unescape
import imp
Copy link
Collaborator

Choose a reason for hiding this comment

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

The docs say that it's deprecated: https://docs.python.org/3/library/imp.html

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Well, that's the problem of being compatible with older versions of Python.So far it works.

Copy link
Member

Choose a reason for hiding this comment

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

what if we detect which version of python is being executed and have a separate code for each version. I know that it sounds cumbersome, but when we stop using python2 we can just get rid of the older implementation.

Comment on lines +52 to +53
# TODO: Remove this right after the variables in templates are renamed
# to lowercase
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, it's a remainder from the previous system. We can rename the variables in the templates to lowercase now and then we will be able to remove this part of the code.

Comment on lines +85 to +90
# scan directory structure and dynamically create list of templates
for item in os.listdir(self.templates_dir):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Currently there is a mechanism implemented by @template decorator that was created to prevent situation that a template should exist but it doesn't exist. I assume with your changes this situation isn't prevented and it can happen.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hm, you are right. In my implementation, languages supported by a template are determined based on the fact if certain files exist / do not exist. Maybe every template could have a small yaml file (template.yml). There could be list of supported languages and documentation. What do you think?

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 detection based on existence of actual files is more robust. The decorator, on the other hand, was easier to implement, and it could be used in generating documentation.

Brainstorming: I think that there is room for a decorator that could take care of template arguments. Imagine that you omit an essential argument - it would get a descriptive error, and if you make a typo in a name of optional template argument, you would also get an error that an unknown argument was supplied.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@vojtapolasek In other words in depends on whether we think that the situation that a template is expected to exist but doesn't exist is likely to happen and is believed to cause problems to content authors and developers. In the original PR #4809 it was a concern (see #4809 (comment)) and since we discussed that it is a problem we introduced #4834 that prevents this situation.

I personally thought that it isn't a big problem because unwanted removal of template files can be prevented by good PR reviews so we don't need such a mechanism. But, I would like to have opinions of @yuumasato and @matejak who were concerned about it back then.

@matejak I think you're confused. Can you explain what do you mean by "I think that detection based on existence of actual files is more robust"?

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 I was worried that we would run into issues when silently failing to generate content while migrating to the new templating issue.

I personally thought that it isn't a big problem because unwanted removal of template files can be prevented by good PR reviews so we don't need such a mechanism.

I agree with that, but another aspect to consider is that people may have their own templates locally.
Basing the template generation on the existence of the file makes it simple to add new languages too.
One just needs to drop the file into the directory, no need to edit any python code.

Would it make sense to add debug messages for the languages detected for each template?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Another problem was that people when use the template in the rule.yml they expect that if they use a template which isn't available they will get an error message.

Copy link
Collaborator Author

@vojtapolasek vojtapolasek Nov 6, 2020

Choose a reason for hiding this comment

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

OK let me summarize and propose solutions:

  • currently, we do not expect rule authors to specify particular languages which they want to use with the template. We assume they want to use all available languages and they somehow know which of them are available. This information was tracked in the documentation and also in the function decorator.
  • Currently, we try to blindly build all templates for all languages and if it fails, it is okay and we silently skip it because these cases were covered by the decorator. We fail only in the case when the language was mentioned in the decorator but the language file is missing.

This PR removes the explicit naming of supported languages within the decorator and automatically finds out which languages are supported by examining the directory structure. It expects that rule authors are aware of the fact that if a file is not available, the language variant is simply not built. I don't know if it is acceptable. I think that the case where template somewhere claims which exact languages it supports is desired and we should keep it. It is kind of contract between template authors and rule authors.
I see two options how to solve this:

  1. Ask rule authors to be explicit while naming languages used with the template. Then we would just check if the template has the right language files and if not, fail the build.
  2. If we want to keep this automagic way of detecting which languages are available, we should somewhere keep track of supported languages. This will detect the case when a language file for a template is removed but the template claims it supports it.

I am inclining to the option 1. It just makes things crystal clear.

Copy link
Member

@matejak matejak Nov 11, 2020

Choose a reason for hiding this comment

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

I don't like the option 1, as the aim of the templates is to provide scalable functionality - if you write a rule that is templated, your work is done, and as new languages are added current ones are improved, the rule gets improved for free, without any action needed.
If I get it correctly, option 1 means that if a new language is introduced, a massive PR is to be expected, adding that language to rule yamls that use the template.

At the same time, I think that it is useful to throw an error if a support for a particular language was requested, but the corresponding template doesn't exist, or if a support for a particular language was not excluded, but the template instantiation failed.

Therefore, I would lean towards option 2, as it is more scalable, and I don't recall any problems related to discrepancies between author expectations and template availability.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm also leaning forward to option 2 and I agree with @matejak. How do you imagine " somewhere keep track of supported languages"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We could have a template.yml for each templat in its directory where these languages would be listed. Any additional data for the template could be listed there later.

@jan-cerny
Copy link
Collaborator

I like the effort very much.

I think in future we can also move the documentation closer to the template code.

@matejak
Copy link
Member

matejak commented Nov 3, 2020

I like this PR very much as well.

I think in future we can also move the documentation closer to the template code.

Certainly, especially when #6299 is merged. But that would be a topic for another PR.

@yuumasato yuumasato modified the milestones: 0.1.53, 0.1.54 Nov 5, 2020
@jan-cerny
Copy link
Collaborator

@vojtapolasek you have conflicts

@vojtapolasek vojtapolasek force-pushed the friendlier_templates_2 branch from 242aaeb to b6533e6 Compare November 6, 2020 14:32
@openshift-ci-robot openshift-ci-robot added the needs-rebase Used by openshift-ci bot. label Nov 20, 2020
remove template function callbacks
rewrite data preprocessing to use new structure
@vojtapolasek vojtapolasek force-pushed the friendlier_templates_2 branch from 31ff0a8 to 3a0cc88 Compare November 23, 2020 09:04
@openshift-ci-robot openshift-ci-robot removed the needs-rebase Used by openshift-ci bot. label Nov 23, 2020
@vojtapolasek
Copy link
Collaborator Author

Now every template needs to declare which languages it supports within the template.yml file.

@vojtapolasek
Copy link
Collaborator Author

Updated documentation. I copied the new chapter also into the newer developer guide which is connected with readthedocs.

@jan-cerny jan-cerny self-assigned this Nov 25, 2020
@jan-cerny
Copy link
Collaborator

/test e2e-aws-ocp4-cis-node

@jan-cerny
Copy link
Collaborator

@vojtapolasek Excellent!

@jan-cerny jan-cerny merged commit e9c47c0 into ComplianceAsCode:master Nov 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants