Skip to content

Commit

Permalink
Introduce origin to network interface info
Browse files Browse the repository at this point in the history
In order to propagate network.Origin throughout we need to propagate the
origin via the api server. To do this correctly means updating all the
call sites to spit out the origin. That way we can then consume the
interface info correctly for futher processing.

This is a somewhat drastic change in that you have to touch all
providers and container sites.

I'm unclear as to what the origin type for the containers should be, but
considering they act as providers in that sense and the machiner is the
one checking for the observeable network interfaces that seemed to make
sense.

I've not put any tests up yet as I'm unsure if this is the way we
actually want to go, but for me this is the cleaner design.
  • Loading branch information
SimonRichardson committed Apr 23, 2020
1 parent c2d91cd commit 8544e6f
Show file tree
Hide file tree
Showing 18 changed files with 63 additions and 6 deletions.
8 changes: 6 additions & 2 deletions api/common/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func GetObservedNetworkConfig(source NetworkConfigSource) ([]params.NetworkConfi
sysClassNetPath := source.SysClassNetPath()
for _, nic := range interfaces {
nicType := network.ParseInterfaceType(sysClassNetPath, nic.Name)
nicConfig := interfaceToNetworkConfig(nic, nicType)
nicConfig := interfaceToNetworkConfig(nic, nicType, corenetwork.OriginMachine)
if nicConfig.InterfaceName == defaultRouteDevice {
nicConfig.IsDefaultGateway = true
nicConfig.GatewayAddress = defaultRoute.String()
Expand Down Expand Up @@ -168,7 +168,10 @@ func GetObservedNetworkConfig(source NetworkConfigSource) ([]params.NetworkConfi
return observedConfig, nil
}

func interfaceToNetworkConfig(nic net.Interface, nicType corenetwork.InterfaceType) params.NetworkConfig {
func interfaceToNetworkConfig(nic net.Interface,
nicType corenetwork.InterfaceType,
networkOrigin corenetwork.Origin,
) params.NetworkConfig {
configType := corenetwork.ConfigManual // assume manual initially, until we parse the address.
isUp := nic.Flags&net.FlagUp > 0
isLoopback := nic.Flags&net.FlagLoopback > 0
Expand All @@ -191,6 +194,7 @@ func interfaceToNetworkConfig(nic net.Interface, nicType corenetwork.InterfaceTy
InterfaceType: string(nicType),
NoAutoStart: !isUp,
Disabled: !isUp,
NetworkOrigin: params.NetworkOrigin(networkOrigin),
}
}

Expand Down
15 changes: 15 additions & 0 deletions api/common/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigNoInterfaceAddresses(c *gc.C)
InterfaceName: "br-eth1",
InterfaceType: "bridge",
ConfigType: "manual",
NetworkOrigin: params.NetworkOrigin("machine"),
}})

s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
Expand All @@ -237,6 +238,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigLoopbackInferred(c *gc.C) {
InterfaceName: "lo",
InterfaceType: "loopback", // inferred from the flags.
ConfigType: "loopback", // since it is a loopback
NetworkOrigin: params.NetworkOrigin("machine"),
}, {
DeviceIndex: 1,
CIDR: "::1/128",
Expand All @@ -245,6 +247,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigLoopbackInferred(c *gc.C) {
InterfaceName: "lo",
InterfaceType: "loopback",
ConfigType: "loopback",
NetworkOrigin: params.NetworkOrigin("machine"),
}})

s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
Expand All @@ -270,6 +273,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigVLANInferred(c *gc.C) {
InterfaceName: "eth0.100",
InterfaceType: "802.1q",
ConfigType: "manual", // the IPv6 address treated as empty.
NetworkOrigin: params.NetworkOrigin("machine"),
}, {
DeviceIndex: 13,
CIDR: "10.100.19.0/24",
Expand All @@ -279,6 +283,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigVLANInferred(c *gc.C) {
InterfaceName: "eth0.100",
InterfaceType: "802.1q",
ConfigType: "static",
NetworkOrigin: params.NetworkOrigin("machine"),
}})

s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
Expand All @@ -298,6 +303,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigEthernetInfrerred(c *gc.C) {
InterfaceName: "eth0",
InterfaceType: "ethernet",
ConfigType: "manual", // the IPv6 address treated as empty.
NetworkOrigin: params.NetworkOrigin("machine"),
}})

s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
Expand All @@ -323,6 +329,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigBridgePortsHaveParentSet(c *g
InterfaceType: "ethernet",
ParentInterfaceName: "br-eth0",
ConfigType: "manual",
NetworkOrigin: params.NetworkOrigin("machine"),
}, {
DeviceIndex: 10,
CIDR: "10.20.19.0/24",
Expand All @@ -332,6 +339,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigBridgePortsHaveParentSet(c *g
InterfaceName: "br-eth0",
InterfaceType: "bridge",
ConfigType: "static",
NetworkOrigin: params.NetworkOrigin("machine"),
}, {
DeviceIndex: 10,
CIDR: "10.20.19.0/24",
Expand All @@ -341,13 +349,15 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigBridgePortsHaveParentSet(c *g
InterfaceName: "br-eth0",
InterfaceType: "bridge",
ConfigType: "static",
NetworkOrigin: params.NetworkOrigin("machine"),
}, {
DeviceIndex: 10,
MACAddress: "aa:bb:cc:dd:ee:f0",
MTU: 1500,
InterfaceName: "br-eth0",
InterfaceType: "bridge",
ConfigType: "manual",
NetworkOrigin: params.NetworkOrigin("machine"),
}, {
DeviceIndex: 11,
CIDR: "10.20.19.0/24",
Expand All @@ -357,13 +367,15 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigBridgePortsHaveParentSet(c *g
InterfaceName: "br-eth1",
InterfaceType: "bridge",
ConfigType: "static",
NetworkOrigin: params.NetworkOrigin("machine"),
}, {
DeviceIndex: 11,
MACAddress: "aa:bb:cc:dd:ee:f1",
MTU: 1500,
InterfaceName: "br-eth1",
InterfaceType: "bridge",
ConfigType: "manual",
NetworkOrigin: params.NetworkOrigin("machine"),
}, {
DeviceIndex: 3,
MACAddress: "aa:bb:cc:dd:ee:f1",
Expand All @@ -374,6 +386,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigBridgePortsHaveParentSet(c *g
ConfigType: "manual",
GatewayAddress: "1.2.3.4",
IsDefaultGateway: true,
NetworkOrigin: params.NetworkOrigin("machine"),
}})

s.stubConfigSource.CheckCallNames(c,
Expand Down Expand Up @@ -410,6 +423,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigAddressNotInCIDRFormat(c *gc.
InterfaceName: "eth0",
InterfaceType: "ethernet",
ConfigType: "static",
NetworkOrigin: params.NetworkOrigin("machine"),
}})

s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
Expand All @@ -432,6 +446,7 @@ func (s *NetworkSuite) TestGetObservedNetworkConfigEmptyAddressValue(c *gc.C) {
InterfaceName: "eth0",
InterfaceType: "ethernet",
ConfigType: "manual",
NetworkOrigin: params.NetworkOrigin("machine"),
}})

s.stubConfigSource.CheckCallNames(c, "Interfaces", "DefaultRoute", "SysClassNetPath", "InterfaceAddresses")
Expand Down
5 changes: 3 additions & 2 deletions api/provisioner/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,9 @@ func (st *State) GetContainerInterfaceInfo(containerTag names.MachineTag) ([]cor
// the method and the network.InterfaceInfo type to be called
// InterfaceConfig.
func (st *State) prepareOrGetContainerInterfaceInfo(
containerTag names.MachineTag, allocateNewAddress bool) (
[]corenetwork.InterfaceInfo, error) {
containerTag names.MachineTag,
allocateNewAddress bool,
) ([]corenetwork.InterfaceInfo, error) {
var result params.MachineNetworkConfigResults
args := params.Entities{
Entities: []params.Entity{{Tag: containerTag.String()}},
Expand Down
4 changes: 2 additions & 2 deletions apiserver/common/networkingcommon/networkconfigapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,9 @@ func (api *NetworkConfigAPI) getOneMachineProviderNetworkConfig(m *state.Machine
}

func (api *NetworkConfigAPI) setLinkLayerDevicesAndAddresses(
m *state.Machine, ifaces []network.InterfaceInfo,
m *state.Machine, interfaceInfos []network.InterfaceInfo,
) error {
devicesArgs, devicesAddrs := NetworkInterfacesToStateArgs(ifaces)
devicesArgs, devicesAddrs := NetworkInterfacesToStateArgs(interfaceInfos)

logger.Debugf("setting devices: %+v", devicesArgs)
if err := m.SetParentLinkLayerDevicesBeforeTheirChildren(devicesArgs); err != nil {
Expand Down
13 changes: 13 additions & 0 deletions apiserver/params/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ type NetworkRoute struct {
Metric int `json:"metric"`
}

// NetworkOrigin specifies where an address comes from, whether it was reported
// by a provider or by a machine.
type NetworkOrigin string

// NetworkConfig describes the necessary information to configure
// a single network interface on a machine. This mostly duplicates
// network.InterfaceInfo type and it's defined here so it can be kept
Expand Down Expand Up @@ -185,6 +189,13 @@ type NetworkConfig struct {

// IsDefaultGateway marks an interface that is a default gateway for a machine.
IsDefaultGateway bool `json:"is-default-gateway,omitempty"`

// NetworkOrigin represents the authoritative source of the NetworkConfig.
// It is expected that either the provider gave us this info or the
// machine gave us this info.
// Giving us this information allows us to reason about when a InterfaceInfo
// is in use.
NetworkOrigin NetworkOrigin `json:"origin,omitempty"`
}

// NetworkConfigFromInterfaceInfo converts a slice of network.InterfaceInfo into
Expand Down Expand Up @@ -234,6 +245,7 @@ func NetworkConfigFromInterfaceInfo(interfaceInfos []network.InterfaceInfo) []Ne
GatewayAddress: v.GatewayAddress.Value,
Routes: routes,
IsDefaultGateway: v.IsDefaultGateway,
NetworkOrigin: NetworkOrigin(v.Origin),
}
}
return result
Expand Down Expand Up @@ -278,6 +290,7 @@ func InterfaceInfoFromNetworkConfig(configs []NetworkConfig) []network.Interface
GatewayAddress: network.NewProviderAddress(v.GatewayAddress),
Routes: routes,
IsDefaultGateway: v.IsDefaultGateway,
Origin: network.Origin(v.NetworkOrigin),
}

// Compatibility layer for older clients that do not populate
Expand Down
1 change: 1 addition & 0 deletions container/lxd/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ func InterfaceInfoFromDevices(nics map[string]device) ([]corenetwork.InterfaceIn
ParentInterfaceName: device["parent"],
MACAddress: device["hwaddr"],
ConfigType: corenetwork.ConfigDHCP,
Origin: corenetwork.OriginProvider,
}
if device["mtu"] != "" {
mtu, err := strconv.Atoi(device["mtu"])
Expand Down
7 changes: 7 additions & 0 deletions core/network/nic.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ type InterfaceInfo struct {

// IsDefaultGateway is set if this device is a default gw on a machine.
IsDefaultGateway bool

// Origin represents the authoritative source of the InterfaceInfo.
// It is expected that either the provider gave us this info or the
// machine gave us this info.
// Giving us this information allows us to reason about when a InterfaceInfo
// is in use.
Origin Origin
}

type interfaceInfoSlice []InterfaceInfo
Expand Down
1 change: 1 addition & 0 deletions provider/dummy/environs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,7 @@ func (env *environ) NetworkInterfaces(ctx context.ProviderCallContext, ids []ins
GatewayAddress: corenetwork.NewProviderAddress(
fmt.Sprintf("0.%d.0.1", (i+1)*10+idIndex),
),
Origin: corenetwork.OriginProvider,
}
}

Expand Down
3 changes: 3 additions & 0 deletions provider/dummy/environs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ func (s *suite) TestNetworkInterfaces(c *gc.C) {
Addresses: corenetwork.ProviderAddresses{corenetwork.NewProviderAddress("0.10.0.2")},
DNSServers: corenetwork.NewProviderAddresses("ns1.dummy", "ns2.dummy"),
GatewayAddress: corenetwork.NewProviderAddress("0.10.0.1"),
Origin: corenetwork.OriginProvider,
}, {
ProviderId: "dummy-eth1",
ProviderSubnetId: "dummy-public",
Expand All @@ -268,6 +269,7 @@ func (s *suite) TestNetworkInterfaces(c *gc.C) {
Addresses: corenetwork.ProviderAddresses{corenetwork.NewProviderAddress("0.20.0.2")},
DNSServers: corenetwork.NewProviderAddresses("ns1.dummy", "ns2.dummy"),
GatewayAddress: corenetwork.NewProviderAddress("0.20.0.1"),
Origin: corenetwork.OriginProvider,
}, {
ProviderId: "dummy-eth2",
ProviderSubnetId: "dummy-disabled",
Expand All @@ -283,6 +285,7 @@ func (s *suite) TestNetworkInterfaces(c *gc.C) {
Addresses: corenetwork.ProviderAddresses{corenetwork.NewProviderAddress("0.30.0.2")},
DNSServers: corenetwork.NewProviderAddresses("ns1.dummy", "ns2.dummy"),
GatewayAddress: corenetwork.NewProviderAddress("0.30.0.1"),
Origin: corenetwork.OriginProvider,
}}
infoList, err := e.NetworkInterfaces(s.callCtx, []instance.Id{instance.Id("i-42")})
c.Assert(err, jc.ErrorIsNil)
Expand Down
1 change: 1 addition & 0 deletions provider/ec2/environ.go
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,7 @@ func mapNetworkInterface(iface ec2.NetworkInterface, subnet ec2.Subnet) corenetw
Addresses: corenetwork.ProviderAddresses{
corenetwork.NewScopedProviderAddress(iface.PrivateIPAddress, corenetwork.ScopeCloudLocal),
},
Origin: corenetwork.OriginProvider,
}

for _, privAddr := range iface.PrivateIPs {
Expand Down
1 change: 1 addition & 0 deletions provider/ec2/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1719,6 +1719,7 @@ func (t *localServerSuite) assertInterfaceLooksValid(c *gc.C, expIfaceID, expDev
),
},
AvailabilityZones: zones,
Origin: corenetwork.OriginProvider,
}
c.Assert(iface, gc.DeepEquals, expectedInterface)
}
Expand Down
1 change: 1 addition & 0 deletions provider/gce/environ_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ func (e *environ) NetworkInterfaces(ctx context.ProviderCallContext, ids []insta
Disabled: false,
NoAutoStart: false,
ConfigType: corenetwork.ConfigDHCP,
Origin: corenetwork.OriginProvider,
})
}
}
Expand Down
2 changes: 2 additions & 0 deletions provider/maas/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ func (env *maasEnviron) deviceInterfaceInfo(deviceID instance.Id, nameToParentNa
Disabled: !nic.Enabled,
NoAutoStart: !nic.Enabled,
ParentInterfaceName: nameToParentName[nic.Name],
Origin: corenetwork.OriginProvider,
}

if len(nic.Links) == 0 {
Expand Down Expand Up @@ -282,6 +283,7 @@ func (env *maasEnviron) deviceInterfaceInfo2(
Disabled: !nic.Enabled(),
NoAutoStart: !nic.Enabled(),
ParentInterfaceName: nameToParentName[nic.Name()],
Origin: corenetwork.OriginProvider,
}
for _, link := range nic.Links() {
subnet := link.Subnet()
Expand Down
2 changes: 2 additions & 0 deletions provider/maas/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ func maasObjectNetworkInterfaces(
ParentInterfaceName: parentName,
Disabled: !iface.Enabled,
NoAutoStart: !iface.Enabled,
Origin: corenetwork.OriginProvider,
}

if len(iface.Links) == 0 {
Expand Down Expand Up @@ -357,6 +358,7 @@ func maas2NetworkInterfaces(
ParentInterfaceName: parentName,
Disabled: !iface.Enabled(),
NoAutoStart: !iface.Enabled(),
Origin: corenetwork.OriginProvider,
}

if len(iface.Links()) == 0 {
Expand Down
1 change: 1 addition & 0 deletions provider/oci/networking.go
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,7 @@ func (e *Environ) networkInterfacesForInstance(ctx envcontext.ProviderCallContex
InterfaceType: corenetwork.EthernetInterface,
ProviderSubnetId: corenetwork.Id(*iface.Vnic.SubnetId),
CIDR: *subnet.CidrBlock,
Origin: corenetwork.OriginProvider,
}
if iface.Vnic.PublicIp != nil {
nic.ShadowAddresses = append(nic.ShadowAddresses,
Expand Down
1 change: 1 addition & 0 deletions provider/openstack/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,7 @@ func (e *Environ) networksForInstance(
MACAddress: port.MACAddress,
Addresses: corenetwork.NewProviderAddresses(ips...),
ConfigType: corenetwork.ConfigDHCP,
Origin: corenetwork.OriginProvider,
}
}

Expand Down
1 change: 1 addition & 0 deletions provider/oracle/network/environ.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ func (e Environ) networkInterfacesForInstance(ctx context.ProviderCallContext, i
corenetwork.NewScopedProviderAddress(ip, corenetwork.ScopeCloudLocal),
},
InterfaceType: corenetwork.EthernetInterface,
Origin: corenetwork.OriginProvider,
}

for _, ipAssocName := range deviceAttributes.Ipassociations {
Expand Down
2 changes: 2 additions & 0 deletions provider/vsphere/environ_broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ func (env *sessionEnviron) newRawInstance(
MACAddress: internalMac,
InterfaceType: corenetwork.EthernetInterface,
ConfigType: corenetwork.ConfigDHCP,
Origin: corenetwork.OriginProvider,
}}
networkDevices := []vsphereclient.NetworkDevice{{MAC: internalMac, Network: env.ecfg.primaryNetwork()}}

Expand All @@ -171,6 +172,7 @@ func (env *sessionEnviron) newRawInstance(
MACAddress: externalMac,
InterfaceType: corenetwork.EthernetInterface,
ConfigType: corenetwork.ConfigDHCP,
Origin: corenetwork.OriginProvider,
})
networkDevices = append(networkDevices, vsphereclient.NetworkDevice{MAC: externalMac, Network: externalNetwork})
}
Expand Down

0 comments on commit 8544e6f

Please sign in to comment.