Skip to content

Disallow "network generic data" with type options.Generic#48906

Merged
thaJeztah merged 1 commit intomoby:masterfrom
robmry:network_generic_opts
Nov 25, 2024
Merged

Disallow "network generic data" with type options.Generic#48906
thaJeztah merged 1 commit intomoby:masterfrom
robmry:network_generic_opts

Conversation

@robmry
Copy link
Copy Markdown
Contributor

@robmry robmry commented Nov 19, 2024

- What I did

Field generic in libnetwork.Network is used to store driver options, it has type options.Generic, which is map[string]any.

In that map, there may be a key netlabel.GenericData holding options known as "network generic options", used for options like:

-o com.docker.network.bridge.name=br-foo

The value type for key netlabel.GenericData is always map[string]string when created via an API request. But, some unit tests use type options.Generic

That works because the bridge, ipvlan and macvlan drivers look for type options.Generic as well as map[string]string If they find options.Generic Go reflection is used to map keys to fields of the config struct with the expectation that the value has the same type as that field. But, that's only used in unit tests (so the tests aren't testing the same code path as the API would use).

The options.Generic form of the bridge name option is this, because "BridgeName" is the name of the field in the bridge driver's network config struct:

"BridgeName": "br-foo"

The libnetwork code expects "network generic options" to have type map[string]string and makes no provision for options.Generic. So, for example, function Network.DriverOptions will panic if called when Network.generic[netlabel.GenericData] has type options.Generic

The type of Network.generic[netlabel.GenericData] can't be statically checked, because it's just a field in a map[string]any.

- How I did it

Removed the driver code that converts "network generic options" from type options.Generic, as it's only used in tests and just makes things more confusing.

This should reduce the chances of things appearing to work when the type is wrong, and converting unit tests to use map[string]string means they're testing the right thing.

- How to verify it

Existing tests.

- Description for the changelog

n/a

Field 'generic' in 'libnetwork.Network' is used to store driver options,
it has type 'options.Generic', which is 'map[string]any'.

In that map, there may be a key 'netlabel.GenericData' holding options
known as "network generic options", used for options like:
  -o com.docker.network.bridge.name=br-foo

The value type for key 'netlabel.GenericData' is always 'map[string]string'
when created via an API request. But, some unit tests use type
'options.Generic'.

That works because the bridge, ipvlan and macvlan drivers look for type
'options.Generic' as well as 'map[string]string'. If they find
'options.Generic', Go reflection is used to map keys to fields of the
config struct with the expectation that the value has the same type as
that field. But, that's only used in unit tests (so the tests aren't
testing the same code path as the API would use). The 'options.Generic'
form of the bridge name option is:
  "BridgeName": "br-foo"
(Because "BridgeName" is the name of the field in the bridge driver's
network config struct.)

The libnetwork code expects "network generic options" to have type
'map[string]string', and makes no provision for 'options.Generic'. So,
for example, function Network.DriverOptions will panic if called when
'Network.generic[netlabel.GenericData]' has type 'options.Generic'.

The type of 'Network.generic[netlabel.GenericData]' can't be statically
checked, because it's just a field in a 'map[string]any'.

So - remove the driver code that converts "network generic options"
from type 'options.Generic', as it's only used in tests and just makes
things more confusing.

This should reduce the chances of things appearing to work when the
type is wrong, and converting unit tests to use 'map[string]string'
means they're testing the right thing.

Signed-off-by: Rob Murray <[email protected]>
@robmry robmry force-pushed the network_generic_opts branch from b80b9fc to b656cff Compare November 19, 2024 20:13
@robmry robmry self-assigned this Nov 19, 2024
@robmry robmry added area/networking Networking kind/refactor PR's that refactor, or clean-up code labels Nov 19, 2024
@robmry robmry added this to the 28.0.0 milestone Nov 19, 2024
@robmry robmry marked this pull request as ready for review November 20, 2024 09:17
@robmry robmry requested a review from akerouanton November 20, 2024 09:17
Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

@thaJeztah thaJeztah merged commit 54fff36 into moby:master Nov 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/networking Networking kind/refactor PR's that refactor, or clean-up code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants