restructure templates#6303
Conversation
|
Skipping CI for Draft Pull Request. |
|
Hello @vojtapolasek! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:
Comment last updated at 2020-11-23 17:53:15 UTC |
|
Changes identified: Show detailsOthers: Recommended tests to execute: |
|
/test all |
|
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? |
They are not in directories, the files are just called I think I'd name the files |
8932403 to
bfb2d8f
Compare
|
I added the .template extension to files in the template folder as requested. Also anaconda remediations are now in lower case. |
|
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( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I am not against this idea. But can't we use these files also for documentation purposes? I am talking about your readthedocs initiative.
There was a problem hiding this comment.
I'm not sure if it adds real value having an empty function without any comments
There was a problem hiding this comment.
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.
|
Regarding the CI failure in RHEL7: The function So we cannot use it in RHEL7 (it has python-2.7.5). Maybe this can help: from: https://stackoverflow.com/questions/45350363/backport-of-importlib-for-python-2-7-from-3-6 |
| # TODO: Remove this right after the variables in templates are renamed | ||
| # to lowercase |
There was a problem hiding this comment.
Hmm, are the uppercase variables in the template intentional or a remnant of the past?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I see. I propose to remove this obsolete thing in a subsequent PR.
40b9f47 to
242aaeb
Compare
| import sys | ||
| import re | ||
| from xml.sax.saxutils import unescape | ||
| import imp |
There was a problem hiding this comment.
The docs say that it's deprecated: https://docs.python.org/3/library/imp.html
There was a problem hiding this comment.
Well, that's the problem of being compatible with older versions of Python.So far it works.
There was a problem hiding this comment.
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.
| # TODO: Remove this right after the variables in templates are renamed | ||
| # to lowercase |
There was a problem hiding this comment.
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.
| # scan directory structure and dynamically create list of templates | ||
| for item in os.listdir(self.templates_dir): |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
@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"?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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:
- 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.
- 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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I'm also leaning forward to option 2 and I agree with @matejak. How do you imagine " somewhere keep track of supported languages"?
There was a problem hiding this comment.
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.
|
I like the effort very much. I think in future we can also move the documentation closer to the template code. |
|
I like this PR very much as well.
Certainly, especially when #6299 is merged. But that would be a topic for another PR. |
|
@vojtapolasek you have conflicts |
242aaeb to
b6533e6
Compare
remove template function callbacks rewrite data preprocessing to use new structure
add .template extension e.g. oval.template
if no preprocessing of template parameters is needed, template.py does not need to be present
31ff0a8 to
3a0cc88
Compare
|
Now every template needs to declare which languages it supports within the template.yml file. |
|
Updated documentation. I copied the new chapter also into the newer developer guide which is connected with readthedocs. |
|
/test e2e-aws-ocp4-cis-node |
|
@vojtapolasek Excellent! |
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