Skip to content

fix: warn about unknown manifest fields - #918

Open
zhhuabj wants to merge 1 commit into
canonical:mainfrom
zhhuabj:invalid_manifest_keys
Open

zhhuabj wants to merge 1 commit into
canonical:mainfrom
zhhuabj:invalid_manifest_keys

Conversation

@zhhuabj

@zhhuabj zhhuabj commented Sep 16, 2026 •

Copy link
Copy Markdown

Warn when unrecognized fields occur in fixed manifest schemas so misspelled or misplaced configuration is not silently ignored.

Ignore unknown fields and feature names after warning while preserving validation failures for invalid known values. Keep intentional charm and storage extension points unchanged, and avoid mutating manifest input while parsing.

Closes-Bug: #2162969
Jira card: https://warthogs.atlassian.net/browse/SI-4781

@zhhuabj

zhhuabj commented Sep 16, 2026

Copy link
Copy Markdown
Author

##Self-test result

#Test 1: Top level and nested unknown fields
cat > "$HOME/manifest-warning-and-error.yaml" <<'EOF'
preseed:
user:
remote_access_location: remote
core:
config:
user:
remote_access_locaion: remote
external-network:
network_type: invalid
EOF
ubuntu@sunbeam:~$ sunbeam configure --manifest "$HOME/manifest-warning-and-error.yaml"
Unknown manifest key: preseed
Unknown manifest key: remote_access_locaion
...

#Test 2: Error alias
cat > "$HOME/manifest-alias-warning.yaml" <<'EOF'
core:
config:
k8s_addons:
loadbalancer: metallb
external-network:
network_type: invalid
EOF
ubuntu@sunbeam:~$ sunbeam configure --manifest "$HOME/manifest-alias-warning.yaml"
Unknown manifest key: k8s_addons
...

#Test 3: Unknown Features
cat > "$HOME/manifest-feature-warning.yaml" <<'EOF'
features:
loadbalncer: {}
loadbalancer:
config:
lb_mgmt_secgroup_ids: invalid
EOF
ubuntu@sunbeam:~$ sunbeam configure --manifest "$HOME/manifest-feature-warning.yaml"
Feature loadbalncer is not found in feature manager
...

@hmlanigan
hmlanigan self-requested a review September 17, 2026 15:55

@hmlanigan hmlanigan left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please add the jira card to the PR description per the template.

@hmlanigan hmlanigan left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Given how hard clean up can be, and after discussions with the team. These warnings should be failures instead. Listing all known bad manifest data to start.

Unknown keys in fixed manifest schemas were silently ignored, because the
schemas relied on pydantic's default extra="ignore". A misspelled or misplaced
field was therefore dropped without any feedback, leaving configuration that is
hard to detect and clean up. Reject such keys instead.

Unknown top level, nested and alias-only field names now raise a pydantic
ValidationError. Unknown feature names, which were previously logged as
warnings and skipped, now raise a ValueError. Intentional charm and storage
extension points are unchanged, and manifest input is still not mutated while
parsing.

Closes-Bug: #2162969
@zhhuabj
zhhuabj force-pushed the invalid_manifest_keys branch from 0aa841c to ce13066 Compare September 29, 2026 11:16
@zhhuabj

zhhuabj commented Sep 29, 2026

Copy link
Copy Markdown
Author

Please add the jira card to the PR description per the template.

done, add 'Jira card: https://warthogs.atlassian.net/browse/SI-4781' now

@zhhuabj

zhhuabj commented Sep 29, 2026

Copy link
Copy Markdown
Author

**hmlanigan **

Hi @hmlanigan , agreed, and changed. Unknown manifest data is now failured instead of warned, here is my self-test result - https://pastebin.com/hHjv7jmU

@gboutry gboutry left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for this change, it's overall in great shape.

Except the part of loading the manifest, I'm not sure the new addition is actually helpful, if you care to comment why, please.

client = self.get_client()
override_manifest = self.parse_manifest(
yaml.safe_load(client.cluster.get_latest_manifest()["data"])
manifest_data = yaml.safe_load(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm really not a fan of

try:
  ...
else:
  ...

Does this addition help the code make more sense?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Hi @gboutry , thanks for the review. This else is needed, see the following code:

try:
client = self.get_client()
manifest_data = yaml.safe_load(
client.cluster.get_latest_manifest()["data"]
)
except ClusterServiceUnavailableException:
...
except ConfigItemNotFoundException:
...
except ValueError:
LOG.debug("Failed to get clusterd client, might no be bootstrapped, ...")
else:
override_manifest = self.parse_manifest(manifest_data)
LOG.debug("Manifest loaded from clusterd")

Because parse_manifest() now raises ValueError for
unknown feature names, while the existing except ValueError is there to catch
get_client() failing (e.g. MAAS raising Clusterd address not set.).

If the parse stayed inside the try, a ValueError from an unknown feature in
the clusterd manifest would be swallowed by that handler and the code would
silently fall back to the embedded manifest — exactly the "silently ignored"
behaviour this PR removes.

So try covers "get a client and read the manifest", else covers "parse it".

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.

3 participants