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

feat(schema): use netplan python api for schema validation annotation #4767

Conversation

blackboxsw
Copy link
Collaborator

@blackboxsw blackboxsw commented Jan 11, 2024

Leverage netplan API to perform schema validation when on a system with python3-netplan package.

feat(schema): use netplan API to validate network-config schema
    
    Validation of network-config version: 2 will be performed on systems
    with python3-netplan installed which delivers a python API
    netplan.Parser which allows cloud-init to parse and determine specific
    netplan schema errors.
    
    The netplan API is only present on Ubuntu Noble in the python3-netplan
    deb package.
    
    Add netplan_validate_network_config function to use netplan API when
    present. Wire this function into runtime schema validation at initial
    boot to warn about network-config invalid version: 2 schema.
    
    Also wire this function into cloud-init schema command to warn and
    annotate specific schema errors by line in datasource provided
    network-config.

Context:

  • unittests are challenging and heavily mocked because the netplan project https://github.com/canonical/netplan/ is not easily consumable as test dependency for tox as pip cannot cleanly determine that this is a python project and netplan is not published to pypi. There is significant mocking in unit tests yet integration tests cover netplan-based schema validation of network version: 2 config.

Checklist before ready for review:

  • unit test coverage for new schema functionality
  • integration testing for netplan-based schema validation of version: 2 network config

Additional Context

Test Steps

CLOUD_INIT_CLOUD_INIT_SOURCE=IN_PLACE CLOUD_INIT_OS_IMAGE=noble tox -e integration-tests -- tests/integration_tests/cmd/test_schema.py
CLOUD_INIT_CLOUD_INIT_SOURCE=IN_PLACE CLOUD_INIT_OS_IMAGE=lunar tox -e integration-tests --  tests/integration_tests/cmd/test_schema.py

# Also tests/integration_tests/test_networking.py

Checklist

Merge type

  • Squash merge using "Proposed Commit Message"
  • Rebase and merge unique commits. Requires commit messages per-commit each referencing the pull request number (#<PR_NUM>)

@blackboxsw blackboxsw added the wip Work in progress, do not land label Jan 11, 2024
@TheRealFalcon TheRealFalcon self-assigned this Jan 11, 2024
Copy link
Member

@TheRealFalcon TheRealFalcon left a comment

Choose a reason for hiding this comment

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

Overall nice add. I didn't really look at the tests since you're still working those though I'd suggest having a test that includes a deprecation warning, just to ensure we're handling it correctly.

I left some inline comments (mostly nits). Additionally, a few strings/comments mention python3-netplan, but that is an ubuntu-specific package name. It's really just the netplan API doing the validation, so I think it'd be better to just refer to netplan rather than python3-netplan.

cloudinit/config/schema.py Show resolved Hide resolved
cloudinit/config/schema.py Outdated Show resolved Hide resolved
# network-config it generates, so create a <tmp_dir>/etc/netplan
# to validate only our network-config.
parse_dir = mkdtemp()
netplan_file = os.path.join(parse_dir, "etc/netplan/network-config.yaml")
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Is the etc/netplan/ prefix necessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Unfortunately, yes it is. netplan Parser.load_yaml_hierarchy only looks under the subdir path etc/netplan/ to process yaml parts. Otherwise it happily ignores files in the root subdir of a path

@@ -1002,7 +1098,14 @@ def validate_cloudconfig_file(
if not netcfg:
print("Skipping network-config schema validation on empty config.")
return False
elif netcfg.get("version") != 1:
elif netcfg.get("version") == 2:
Copy link
Member

Choose a reason for hiding this comment

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

If we're validating userdata or network config v1 we call "validate_cloudconfig_schema", but for network config v2 call "netplan_validate_network_config". I think we could a little refactoring as this comes out a little confusing.

I think it's also a little odd that the caller has to check the version number and determine which thing to call. Ideally, we'd have something like "validate_schema" that we pass our configuration to along with some relevant options, and based on what it is, it calls the right validation function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point I refactored netplan_validate_network_config to accept just the network_config dict instead of dealing with files. This simplified callsites sigificantly and allowed dealing with version 2 vs version 1 vs netplan API availability inside netplan_validate_network_schema function. If unable to perform netplan_validate.... we fallthrough and use cloud-init's schema for validation if present. Since we don't have JSON schema version 2 yet, we will still emit Skipping schema validation messages when not netplan and not network schema version: 1.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

+1 I was avoiding the refactor to validate_cloudconfig_schema that would require adding a config path. But, I've since refactored this code to simplify call-sites and like cloudinit.stages

@blackboxsw blackboxsw force-pushed the SC-1374-use-netplan-python-api-for-schema-validation-annotation branch 2 times, most recently from ffdadc3 to 6e23c4e Compare January 19, 2024 02:45
@blackboxsw blackboxsw removed the wip Work in progress, do not land label Jan 19, 2024
@blackboxsw blackboxsw force-pushed the SC-1374-use-netplan-python-api-for-schema-validation-annotation branch 3 times, most recently from 45757c5 to d5ff050 Compare January 19, 2024 04:17
@blackboxsw blackboxsw marked this pull request as ready for review January 19, 2024 04:17
blackboxsw added a commit to blackboxsw/cloud-init that referenced this pull request Jan 19, 2024
)

Validation of network-config version: 2 will be performed on systems
with python3-netplan installed which delivers a python API
netplan.Parser which allows cloud-init to parse and determine specific
netplan schema errors.

The netplan API is only present on Ubuntu Noble in the python3-netplan
deb package.

Add netplan_validate_network_config function to use netplan API when
present. Wire this function into runtime schema validation at initial
boot to warn about network-config invalid version: 2 schema.

Also wire this function into cloud-init schema command to warn and
annotate specific schema errors by line in datasource provided
network-config.
blackboxsw added a commit to blackboxsw/cloud-init that referenced this pull request Jan 19, 2024
)

On Noble, python netplan bindings are available in python3-netplan deb
package. The presence of they python bindings and netplan.Parser import
allow cloud-int for parse and validate network-config version 2 schema.

Add an integration tests asserting both schema validation and
annotation of invalid network configuration on Ubuntu Noble.

On non-Noble environments, expect Skipping of network-config version: 2
message.
@blackboxsw blackboxsw force-pushed the SC-1374-use-netplan-python-api-for-schema-validation-annotation branch from d5ff050 to 8897c93 Compare January 19, 2024 04:22
Copy link
Member

@TheRealFalcon TheRealFalcon left a comment

Choose a reason for hiding this comment

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

Just some minor issues left inline.

Did you miss this comment from my last review?

Additionally, a few strings/comments mention python3-netplan, but that is an ubuntu-specific package name. It's really just the netplan API doing the validation, so I think it'd be better to just refer to netplan rather than python3-netplan.

cloudinit/config/schema.py Outdated Show resolved Hide resolved
tests/integration_tests/test_networking.py Outdated Show resolved Hide resolved
tests/integration_tests/cmd/test_schema.py Outdated Show resolved Hide resolved
blackboxsw added a commit to blackboxsw/cloud-init that referenced this pull request Jan 25, 2024
)

Validation of network-config version: 2 will be performed on systems
with python3-netplan installed which delivers a python API
netplan.Parser which allows cloud-init to parse and determine specific
netplan schema errors.

The netplan API is only present on Ubuntu Noble in the python3-netplan
deb package.

Add netplan_validate_network_config function to use netplan API when
present. Wire this function into runtime schema validation at initial
boot to warn about network-config invalid version: 2 schema.

Also wire this function into cloud-init schema command to warn and
annotate specific schema errors by line in datasource provided
network-config.
@blackboxsw blackboxsw force-pushed the SC-1374-use-netplan-python-api-for-schema-validation-annotation branch from 8897c93 to 28f23f3 Compare January 25, 2024 15:58
blackboxsw added a commit to blackboxsw/cloud-init that referenced this pull request Jan 25, 2024
)

On Noble, python netplan bindings are available in python3-netplan deb
package. The presence of they python bindings and netplan.Parser import
allow cloud-int for parse and validate network-config version 2 schema.

Add an integration tests asserting both schema validation and
annotation of invalid network configuration on Ubuntu Noble.

On non-Noble environments, expect Skipping of network-config version: 2
message.
blackboxsw added a commit to blackboxsw/cloud-init that referenced this pull request Jan 25, 2024
)

Validation of network-config version: 2 will be performed on systems
with python3-netplan installed which delivers a python API
netplan.Parser which allows cloud-init to parse and determine specific
netplan schema errors.

The netplan API is only present on Ubuntu Noble in the python3-netplan
deb package.

Add netplan_validate_network_config function to use netplan API when
present. Wire this function into runtime schema validation at initial
boot to warn about network-config invalid version: 2 schema.

Also wire this function into cloud-init schema command to warn and
annotate specific schema errors by line in datasource provided
network-config.
blackboxsw added a commit to blackboxsw/cloud-init that referenced this pull request Jan 25, 2024
)

On Noble, python netplan bindings are available in python3-netplan deb
package. The presence of they python bindings and netplan.Parser import
allow cloud-int for parse and validate network-config version 2 schema.

Add an integration tests asserting both schema validation and
annotation of invalid network configuration on Ubuntu Noble.

On non-Noble environments, expect Skipping of network-config version: 2
message.
@blackboxsw blackboxsw force-pushed the SC-1374-use-netplan-python-api-for-schema-validation-annotation branch from 28f23f3 to 8aa0ee0 Compare January 25, 2024 15:59
)

Validation of network-config version: 2 will be performed on systems
with python3-netplan installed which delivers a python API
netplan.Parser which allows cloud-init to parse and determine specific
netplan schema errors.

The netplan API is only present on Ubuntu Noble in the python3-netplan
deb package.

Add netplan_validate_network_config function to use netplan API when
present. Wire this function into runtime schema validation at initial
boot to warn about network-config invalid version: 2 schema.

Also wire this function into cloud-init schema command to warn and
annotate specific schema errors by line in datasource provided
network-config.
blackboxsw added a commit to blackboxsw/cloud-init that referenced this pull request Jan 25, 2024
)

On Noble, python netplan bindings are available in python3-netplan deb
package. The presence of they python bindings and netplan.Parser import
allow cloud-int for parse and validate network-config version 2 schema.

Add an integration tests asserting both schema validation and
annotation of invalid network configuration on Ubuntu Noble.

On non-Noble environments, expect Skipping of network-config version: 2
message.
@blackboxsw blackboxsw force-pushed the SC-1374-use-netplan-python-api-for-schema-validation-annotation branch from 8aa0ee0 to 30f05a0 Compare January 25, 2024 16:02
)

On Noble, python netplan bindings are available in python3-netplan deb
package. The presence of they python bindings and netplan.Parser import
allow cloud-int for parse and validate network-config version 2 schema.

Add an integration tests asserting both schema validation and
annotation of invalid network configuration on Ubuntu Noble.

On non-Noble environments, expect Skipping of network-config version: 2
message.
@blackboxsw blackboxsw force-pushed the SC-1374-use-netplan-python-api-for-schema-validation-annotation branch from 30f05a0 to ac1f870 Compare January 25, 2024 16:04
Copy link
Member

@TheRealFalcon TheRealFalcon left a comment

Choose a reason for hiding this comment

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

LGTM! I'll leave to you to merge

@blackboxsw blackboxsw merged commit 39c5781 into canonical:main Jan 26, 2024
29 checks passed
blackboxsw added a commit that referenced this pull request Jan 26, 2024
Validation of network-config version: 2 will be performed on systems
with python3-netplan installed which delivers a python API
netplan.Parser which allows cloud-init to parse and determine specific
netplan schema errors.

The netplan API is only present on Ubuntu Noble in the python3-netplan
deb package.

Add netplan_validate_network_config function to use netplan API when
present. Wire this function into runtime schema validation at initial
boot to warn about network-config invalid version: 2 schema.

Also wire this function into cloud-init schema command to warn and
annotate specific schema errors by line in datasource provided
network-config.
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.

2 participants