Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dev] support multiple addresses / shadow addresses in interface info #10942

Merged

Conversation

achilleasa
Copy link
Contributor

Description of change

This PR changes the network.InterfaceInfo struct so that instead of a single Address field, it contains two lists:

  • Addresses: a list of provider addresses that encodes the IPs (typically but not necessarily private) assigned to the NIC. The majority of providers supporting networking only provide a single private IP. However, some providers (e.g. ec2 and gce) seem to support multiple private IPs where one is always tagged as primary.
  • ShadowAddresses. A list of shadow/virtual IPs that are associated with this interface. These IPs are usually not visible to the machine that hosts the NIC.

This split will allow us to pair shadow IPs with individual NICs and will be used by the upcoming instance-poller changes to detect public IPs.

As part of this PR the following networking-capable providers have been updated to populate the shadow address list:

  • ec2. public IP associations are pulled with the help of the go-amz changes introduced by Add association field for private IPs go-amz/amz#75
  • gce.
  • oci.
  • oracle. Unfortunately, our credentials have expired so I haven't been able to test this. The classic API docs are horrible and don't include complete REST responses. I assumed that the Ipassociations field contains IP association URNs so the provider will try to look their details up via the API and populate the shadow IP field.
  • maas. One peculiarity about maas (both 1 and 2) is that even though NICs are allowed to have multiple links, we seem to use a last-write-wins policy for populating the NIC address. The changes from this PR preserve this behavior but I have added TODOs to the relevant places so we can revisit this in the future should the need arise.

QA steps

As this is an internal change and the ShadowAddresses field is not currently used there isn't a clear way to QA this. I have however manually verified that it works (i.e. we get both the private and the public IP) on ec2, gce and oci by bootstrapping a patched juju that logs the obtained interfaces.

I have not been able to test the old oracle provider as I don't have access to credentials.

Given that we may potentially have multiple addresses for an interface,
the general convention is to place the *primary* address at the top of
the address list. The PrimaryAddress method on the InterfaceInfo can be
used to fetch the primary address (if defined).

The majority of providers only support a single address so this change
is backwards-compatible. The ec2 and gce providers in particular seem to
support assigning multiple private IPs to a NIC although only one can be
flagged as the primary.
The updated package version allows us to access IP associations for
private IP addresses when fetching NIC information.
MAAS NICs seem to support the concept of multiple links. However,
throughout the code it seems that we apply a last-write-wins policy.

The changes from this commit preserve this functionality but I have
added TODOs in the relevant locations so we can revisit (if required) in
the future.
Copy link
Member

@manadart manadart left a comment

Choose a reason for hiding this comment

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

This looks great.

@@ -230,7 +230,11 @@ func (env *maasEnviron) deviceInterfaceInfo(deviceID instance.Id, nameToParentNa
}

nicInfo.CIDR = link.Subnet.CIDR
nicInfo.Address = corenetwork.NewProviderAddressInSpace(link.Subnet.Space, link.IPAddress)
// NOTE(achilleasa): the original code used a last-write-wins
Copy link
Member

Choose a reason for hiding this comment

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

This might be a little misleading to someone unfamiliar reading it.
Maybe something like:

This preserves the long-standing last-write-wins behaviour...

@@ -254,7 +254,12 @@ func maasObjectNetworkInterfaces(
} else {
// We set it here initially without a space, just so we don't
// lose it when we have no linked subnet below.
nicInfo.Address = corenetwork.NewProviderAddress(link.IPAddress)
//
// NOTE(achilleasa): the original code used a last-write-wins
Copy link
Member

Choose a reason for hiding this comment

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

And here.

@achilleasa
Copy link
Contributor Author

$$merge$$

@jujubot jujubot merged commit 9fb1e6d into juju:develop Nov 26, 2019
@achilleasa achilleasa deleted the dev-support-mutliple-address-in-interface-info branch November 26, 2019 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants