As discussed in a proposed PR, multi-match makes sense when origin is
specified and matched, but otherwise it feels "loose" to multi-match.
And in fact it was hiding bugs in declarative validation tests and real
bugs (in subsequent commits) in implementation.
Now we allow multi-match if and only if:
1) ErrorMatcher.ByOrigin() was specified
2) The origin string is not empty
3) The multiple "got" errors are not exactly identical
This last part is key -- if some change to DV codegens logic which
(errantly) calls the same function twice, we want to know about it.
Given the following:
```
type Struct type {
TypeMeta int
// +k8s:validateFalse="embedded"
OtherStruct
}
```
What should the field-path be for the error?
or:
```
type Struct type {
TypeMeta int
OtherStruct // embedded
}
// +k8s:validateFalse="otherstruct"
type OtherStruct {
I int
}
```
Conclusion: If we find an embedded field, we look for a nil fldPath, and
if so we set it to the type name. Embedded values in root types (e.g.
above `spec`) should not be a things we actually do.
Implementation: Add `safe.Value(*T, func() *T)`
For some packages (in particular the code DRA), all allocator implementations
can handle the testcases. Some other packages are for less stable features and
work with fewer implementations. Now all unit tests are run with all suitable
implementations, to increase code coverage.
Benchmarks are fixed to the most mature implementation because they would be
costly to run in more than one. When promoting an allocation implementation we
can do before/after comparisons to detect potential performance regressions.
The downside of this approach is that we need to remember to extend the list
of supported implementations when promoting features, otherwise testing will miss
some new supported implementation.
Without this, the effect of the following feature gate config would be random:
featureGates:
AllBeta: false
SomeBetaFeature: true
That's random because the order of iterating of the map is randomized by Go and
`AllBeta: false` would disable `SomeBetaFeature` if (and only if) applied last.
Now by sorting alphabetically, AllAlpha/Beta come first in practice. It's not a
complete solution, some future feature gate name might come before it.
This prevents the mistake from 1.34 where the default-on
DRAResourceClaimDeviceStatus feature caused the use of the experimental
allocator implementation. The test fails without a fix for that.
In 1.34, the default feature gate selection picked the "experimental" allocator
implementation when it should have used the "incubating" allocator. No harm
came from that because the experimental allocator has all the necessary if
checks to disable the extra code and no bugs were introduced when implementing
it, but it means that our safety net wasn't there when we expected it to be.
The reason is that the "DRAResourceClaimDeviceStatus" feature gate is on by
default and was only listed as supported by the experimental implementation.
This could be fixed by listing it as supported also by the other
implementation, but that would be a bit odd because there is nothing to support
for it (the reason why this was missed in 1.34!). Instead, the allocator
features are now only indirectly related to feature gates, with a single
boolean controlling the implementation of binding conditions.
Copying from feature.Features to new fields in the plugin got a bit silly with
the long list of features that we have now. Embedding feature.Features is
simpler.
Two fields in feature.Features weren't named according to the feature gate, now
they are named consistently and the fields are sorted.
The ability to get these values was deleted by #129472 which removed
the public function audit.AuditEventFrom. The new getters return copies
of the underlying objects to prevent external mutations of the objects
held by the audit events.
The newControlPlane flag has been historically problematic, since
it implies that the function FetchInitConfigurationFromCluster
cannot handle the cases where a node is worker node but
we still want to fetch its NodeRegistrationOptions conditionally,
in cases such as "upgrade node" for workers.
To fix this issue, replace the flag newControlPlaneNode with
two new flags getNodeRegistration and getAPIEndpoint.
If getNodeRegistration is true, we fetch the NRO, and if
getAPIEndpoint is true, we fetch the API endpoint for
that node.
Additionally, rename skipComponentConfigs to getComponentConfigs
for consistency and flip its value accordingly everywhere.
- Deprecate IsDNS1123SubdomainCaseless to avoid caseless validation issues.
- Warn when ResourceSlice driver names contain uppercase characters.
- Clarify driver names must be DNS subdomains and use only lowercase letters.
- Update tests, staging code, and OpenAPI spec to reflect the changes.
The boilerplate for running declarative validation was duplicated across multiple resource strategies. This included feature gate checks, metric identifier generation, error comparison, and conditional merging logic, which made the code verbose and difficult to maintain.
This commit introduces a new helper function, `rest.ValidateDeclarativelyWithMigrationChecks`, to encapsulate this common logic. All relevant strategies have been refactored to use this new function, resulting in cleaner and more concise code.