-
Notifications
You must be signed in to change notification settings - Fork 583
Problem with Unmarshalling Extensions #300
Description
I wanted to add the port_security_enabled extension and ran into some problems...
The extension adds support for extra fields in the request and extra fields in the results. I wanted to tackle the latter first, thinking it would be as simple as the other extensions (volume tenants, server availability zones) that were recently added. Reconfiguring the networks package to account for the modified Extract functions/methods caused other network extension packages to break.
Things were going well with fixing the broken extensions until I ran into the provider extension which requires UnmarshalJSON to smooth over the SegmentationID field.
It looks like there's difficulties triggering UnmarshalJSON on anonymous/nested structs:
- golang github issue 17877
- this might also be relevant.
The result is that the following pattern no longer works:
type NetworkWithExt struct {
networks.Network
provider.NetworkProviderExt
}UnmarshalJSON is triggered, but it strips out the Network struct. This can be worked around by embedding networks.Network in the provider.NetworkProviderExt struct, but that breaks the above pattern and might possibly break when someone wants to add another extension (portsbinding) to the mix.
The latest 4 commits of this branch are my attempt to cleanly show the problem. There are some notes in provider's unit tests with some additional information.
I'm not sure what the best solution would be here. I like the ability to compose structures with extended fields, but if it only works on extensions that don't require type modifications, that makes things a bit complicated.
I think the magical best solution would be if there was a way to retrieve a network or server result and it automatically included all of the extensions, but I have no idea how that would work. Each extension somehow register itself as an extension to its parent. When the parent is unmarshalled, it applies an extract on each registered extension. Since extract would only grab the fields configured in its struct, it would ignore all other fields, which is kind of what's done here. Of course, there's been the discovery of two resources that place arbitrary fields in the JSON body.
In any case, I'm stuck. It's entirely possible I'm overlooking something really simple, too.