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

[JUJU-163]create openstack FIPs on networks on AZ to match the server's addresses. #13478

Merged
merged 9 commits into from
Nov 9, 2021
Prev Previous commit
Next Next commit
Update how to choose network in AllocatePublicIP.
Choose an external network for a FIP based on the AZ of the instance
if an external-network has not been configured.
  • Loading branch information
hmlanigan committed Nov 3, 2021
commit 6f9ee090fa2e995a05de725c1e5dcbe3f1f4e4c5
47 changes: 16 additions & 31 deletions provider/openstack/networking.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,13 @@ func newNetworking(e *Environ) Networking {
}

// AllocatePublicIP is part of the Networking interface.
func (n *NeutronNetworking) AllocatePublicIP(_ instance.Id) (*string, error) {
// Look for an external network to use for the FIP.
extNetworkIds, err := n.getExternalNetworkIDs()
func (n *NeutronNetworking) AllocatePublicIP(id instance.Id) (*string, error) {
// Look for external networks, in the same AZ as the server, to use for the FIP.
detail, err := n.env.nova().GetServer(string(id))
if err != nil {
return nil, errors.Trace(err)
}
extNetworkIds, err := n.getExternalNetworkIDs(detail.AvailabilityZone)
if err != nil {
return nil, errors.Trace(err)
}
Expand Down Expand Up @@ -152,7 +156,7 @@ func (n *NeutronNetworking) AllocatePublicIP(_ instance.Id) (*string, error) {
}
}

// allocate a new IP and use it
// No unused FIPs exist, allocate a new IP and use it.
var lastErr error
for _, extNetId := range extNetworkIds {
var newfip *neutron.FloatingIPV2
Expand All @@ -169,9 +173,9 @@ func (n *NeutronNetworking) AllocatePublicIP(_ instance.Id) (*string, error) {

// getExternalNetworkIDs returns a slice of external network IDs.
// If specified, the configured external network is returned.
// Otherwise search for an external network in the same
// availability zone as the private network.
func (n *NeutronNetworking) getExternalNetworkIDs() ([]string, error) {
// Otherwise search for an external network in the provided
// availability zone.
func (n *NeutronNetworking) getExternalNetworkIDs(availabilityZone string) ([]string, error) {
extNetworkIds := make([]string, 0)
neutronClient := n.env.neutron()
externalNetwork := n.env.ecfg().externalNetwork()
Expand All @@ -194,28 +198,9 @@ func (n *NeutronNetworking) getExternalNetworkIDs() ([]string, error) {
// Create slice of network.Ids for external networks in the same AZ as
// the instance's network, to find an existing floating ip in, or allocate
// a new floating ip from.
configNetwork := n.env.ecfg().network()
netId, err := resolveNeutronNetwork(neutronClient, configNetwork, false)
if err != nil {
return nil, errors.Trace(err)
}
netDetails, err := neutronClient.GetNetworkV2(netId)
if err != nil {
return nil, errors.Trace(err)
}

availabilityZones := netDetails.AvailabilityZones
if len(availabilityZones) == 0 {
// No availability zones is valid, check for empty string
// to ensure we still find the external network with no
// AZ specified. lp: 1891227
availabilityZones = []string{""}
}
for _, az := range availabilityZones {
extNetIds, _ := getExternalNeutronNetworksByAZ(n.env, az)
if len(extNetIds) > 0 {
extNetworkIds = append(extNetworkIds, extNetIds...)
}
extNetIds, _ := getExternalNeutronNetworksByAZ(n.env, availabilityZone)
if len(extNetIds) > 0 {
extNetworkIds = append(extNetworkIds, extNetIds...)
}

// We have an external network ID, no need for specific error message.
Expand All @@ -224,11 +209,11 @@ func (n *NeutronNetworking) getExternalNetworkIDs() ([]string, error) {
}

var returnErr error
if len(netDetails.AvailabilityZones) == 0 {
if availabilityZone == "" {
returnErr = errors.NotFoundf("could not find an external network, network availability zones not in use")
} else {
returnErr = errors.NotFoundf(
"could not find an external network in availability zone(s) %s", netDetails.AvailabilityZones)
"could not find an external network in availability zone %s", availabilityZone)
}
return nil, returnErr
}
Expand Down