Skip to content

Commit

Permalink
Fix the current product properties
Browse files Browse the repository at this point in the history
  • Loading branch information
matejak committed May 25, 2023
1 parent 9a35ef6 commit 75ce8e8
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 32 deletions.
4 changes: 4 additions & 0 deletions docs/manual/developer/06_contributing_with_content.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ so you can use only product properties in the content.
In other words, use this functionality to avoid referencing product versions in macros used in checks or remediations.
Instead, use properties that directly relate to configurations being checked or set, and that help to reveal the intention of the check or remediation code.

As Jinja2 conditionals are prone to errors, products can be protected by product stability tests.
If a product sample is present in `tests/data/product_stability/`, it is compared to the actual compiled product,
and if there is a difference that is not only cosmetic, a product stability test will fail.

Rules are unselected by default - even if the scanner reads rule
definitions, they are effectively ignored during the scan or
remediation. A rule may be selected by any number of profiles, so when
Expand Down
23 changes: 21 additions & 2 deletions product_properties/10-grub.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@

grub2_boot_path: "/boot/grub2"
grub2_uefi_boot_path: "/boot/grub2"
default:
grub2_boot_path: "/boot/grub2"
grub2_uefi_boot_path: "/boot/grub2"

overrides:
{{% if product in ("rhel7", "ol7", "rhel8", "ol8") %}}
grub2_uefi_boot_path: "/boot/efi/EFI/redhat"
{{% elif product == "sle12" %}}
grub2_uefi_boot_path: "/boot/efi/EFI/sles"
{{% elif "debian" in product %}}
grub2_boot_path: "/boot/grub"
{{% endif %}}
{{% if "ubuntu" in product %}}
{{% if product <= "ubuntu1804" %}}
grub2_boot_path: "/boot/grub"
grub2_uefi_boot_path: "/boot/efi/EFI/ubuntu"
{{% else %}}
grub2_boot_path: "/boot/grub"
grub2_uefi_boot_path: "/boot/grub"
{{% endif %}}
{{% endif %}}
12 changes: 7 additions & 5 deletions product_properties/10-ids.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
gid_min: 1000
uid_min: 1000
nobody_gid: 65534
nobody_uid: 65534
auid: 1000

default:
gid_min: 1000
uid_min: 1000
nobody_gid: 65534
nobody_uid: 65534
auid: 1000
8 changes: 6 additions & 2 deletions product_properties/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Product properties

YAML files contained here are processed in lexicographic order, and they allow to define product properties in a efficient way.
Processing of those files can use `jinja2`, and macros or conditionals have access to product properties defined previously and in the `product.yml`.
Properties read from these yaml files can be overriden by properties from files processed later, while the properties specified in the `product.yml` override all previous definitions.

Conventionally, use the filename prefix `10-` to define defaults, and use subsequent prefixes to override those defaults based on products.
Properties in a file are expressed in two mappings - obligatory `default` and optional `overrides`.
Properties defined in a mapping nested below `default` can be overriden in a mapping nested below `overrides`.
A property can be set only in one file, so the default-override pattern implemented by Jinja macros can be accomplished, but it has to take place in one file.
Properties specified in the `product.yml` can't be overriden by this mechanism, and attempting to do so will result in an error.

Conventionally, use the filename numerical prefix e.g. `10-` to ensure that some symbols are available before they are used in a definition of other symbols.
28 changes: 19 additions & 9 deletions ssg/products.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,24 +148,34 @@ def expand_by_acquired_data(self, property_dict):
self._acquired_data.update(property_dict)

@staticmethod
def transform_list_of_mappings_to_mapping(mappings):
def transform_default_and_overrides_mappings_to_mapping(mappings):
result = dict()
for index, mapping in enumerate(mappings):
if not isinstance(mapping, dict):
msg = (
"Expected a list of key-value pairs, got '{val}' at index {index}."
.format(val=mapping, index=index))
raise ValueError(msg)
if not isinstance(mappings, dict):
msg = (
"Expected a mapping, got {type}."
.format(type=str(type(mappings))))
raise ValueError(msg)

mapping = mappings.pop("default")
if mapping:
result.update(mapping)
mapping = mappings.pop("overrides", dict())
if mapping:
result.update(mapping)
if len(mappings):
msg = (
"The dictionary contains unwanted keys: {keys}"
.format(keys=list(mappings.keys())))
raise ValueError(msg)
return result

def read_properties_from_directory(self, path):
filenames = glob(path + "/*.yml")
for f in sorted(filenames):
substitutions_dict = dict()
substitutions_dict.update(self)
list_of_new_symbols = open_and_expand(f, substitutions_dict)
new_symbols = self.transform_list_of_mappings_to_mapping(list_of_new_symbols)
new_defs = open_and_expand(f, substitutions_dict)
new_symbols = self.transform_default_and_overrides_mappings_to_mapping(new_defs)
self.expand_by_acquired_data(new_symbols)


Expand Down
11 changes: 6 additions & 5 deletions tests/unit/ssg-module/data/properties/00-default.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

- property_one: one
default:
property_one: one

{{% if product == "rhel7" %}}
- rhel_version: "seven"
{{% else %}}
- rhel_version: "not_seven"
{{%- if product == "rhel7" %}}
rhel_version: "seven"
{{%- else %}}
rhel_version: "not_seven"
{{% endif %}}
8 changes: 5 additions & 3 deletions tests/unit/ssg-module/data/properties/10-property_two.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
default:
property_two: one

overrides:
{{% if property_one == "one" %}}
- property_two: two
{{% else %}}
- property_two: one
property_two: two
{{% endif %}}

14 changes: 8 additions & 6 deletions tests/unit/ssg-module/test_products.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ def product_with_updated_properties(testing_product, testing_datadir):
return testing_product


def test_list_of_mappings_to_mapping():
converter = ssg.products.Product.transform_list_of_mappings_to_mapping
assert converter([]) == dict()
assert converter([dict(one=1)]) == dict(one=1)
assert converter([dict(one=2), dict(one=1)]) == dict(one=1)
def test_default_and_overrides_mappings_to_mapping():
converter = ssg.products.Product.transform_default_and_overrides_mappings_to_mapping
assert converter(dict(default=[])) == dict()
assert converter(dict(default=dict(one=1))) == dict(one=1)
assert converter(dict(default=dict(one=2), overrides=dict(one=1))) == dict(one=1)
with pytest.raises(ValueError):
assert converter([dict(one=2), 5])
converter([dict(one=2), 5])
with pytest.raises(KeyError):
converter(dict(deflaut=dict(one=2)))


def test_get_all(ssg_root):
Expand Down

0 comments on commit 75ce8e8

Please sign in to comment.