-
Notifications
You must be signed in to change notification settings - Fork 261
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
✨ Modify OpenStackCluster.Spec.Network API #1836
✨ Modify OpenStackCluster.Spec.Network API #1836
Conversation
✅ Deploy Preview for kubernetes-sigs-cluster-api-openstack ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
b347263
to
43d8f89
Compare
43d8f89
to
c48fa08
Compare
c48fa08
to
380f8d2
Compare
/test pull-cluster-api-provider-openstack-e2e-test |
/test pull-cluster-api-provider-openstack-e2e-full-test |
/lgtm |
// It returns an error in case it failed to retrieve the network. | ||
func (s *Service) PopulateCAPONetworkFromSubnet(subnets []subnets.Subnet, openStackCluster *infrav1.OpenStackCluster) error { | ||
if openStackCluster.Status.Network.ID == "" && len(subnets) > 0 { | ||
if len(subnets) > 1 && subnets[0].NetworkID != subnets[1].NetworkID { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just curious why this has subnet[0] and [1] ? some case we have 2 subnets and only 2 subnet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case a dual-stack cluster is desired, one IPv4 and IPv6 subnet needs to be specified. The API already enforces the max number of subnets to be 2.
/hold cancel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're doing a very similar dance in normalizePortTarget: we are getting a network a subnets from a NetworkFilter and []SubnetFilter and we infer the network from the subnets if it's not specified. Is there any opportunity to refactor that code to be used in both places?
if err != nil { | ||
return err | ||
} | ||
|
||
var subnets []infrav1.Subnet | ||
for subnet := range filteredSubnets { | ||
subnets = networking.ConvertOpenStackSubnetToCAPOSubnet(subnets, &filteredSubnets[subnet]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please could you rename this function to something like AppendOpenStackSubnetToCAPOSubnets
. I had to double-take this in review because without checking the implementation it looks like it overwrites previous subnets on each iteration.
if len(networkList) > 1 { | ||
handleUpdateOSCError(openStackCluster, fmt.Errorf("found multiple networks (result: %v)", networkList)) | ||
return fmt.Errorf("found multiple networks (result: %v)", networkList) | ||
} | ||
if openStackCluster.Status.Network == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A potential issue here is that we're now telling people they can omit the network section, but we're still executing an empty list operation above. This is going to list all networks. I know how long this takes on PSI, and we should probably avoid it.
I wonder if we should not execute the network query if the network spec is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack, I added a condition checking if the filter is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack, I added a condition checking if the filter is empty.
Where?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please can you move all of these functions, including the existing ConvertOpenStackSubnetToCAPOSubnet
, to unexported functions in the cluster controller. They're not really service methods and with them having side-effects (they modify their arguments) they're not really independent library functions. Having them in a different file just breaks up readability.
If any have only a single caller you might consider inlining them at the point of use, tbh.
The scenario I'm handling is a bit different because I need the hole Network and not just the ID in order to populate the |
380f8d2
to
14ecbda
Compare
func populateCAPONetworkFromSubnet(networkingService *networking.Service, subnets []subnets.Subnet, openStackCluster *infrav1.OpenStackCluster) error { | ||
if openStackCluster.Status.Network.ID == "" && len(subnets) > 0 { | ||
if len(subnets) > 1 && subnets[0].NetworkID != subnets[1].NetworkID { | ||
return fmt.Errorf("unable to identify the Network to use. NetworkID from Subnets differ: %s, %s", subnets[0].NetworkID, subnets[1].NetworkID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we improve the logging maybe? Here is an example (can be improved):
return fmt.Errorf("unable to identify the Network to use. NetworkID from Subnets differ: %s, %s", subnets[0].NetworkID, subnets[1].NetworkID) | |
return fmt.Errorf("unable to identify the Network to use. NetworkID %s from subnet %s does not match NetworkID %s from subnet %s", subnets[0].NetworkID, subnets[0].ID, subnets[1].NetworkID, subnets[1].ID) |
return nil | ||
} | ||
|
||
// getCAPONetwork gets a network based on a filter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: add a bit more doc into this function. Yes indeed, we get a network based on the filter and return errors if not found. But if found, we will update the status (by calling convertOpenStackNetworkToCAPONetwork). Also we return no error if Spec.Network is empty because we now try to find the Network specs by the Subnets field.
handleUpdateOSCError(openStackCluster, fmt.Errorf("failed to find any network")) | ||
return fmt.Errorf("failed to find any network") | ||
} | ||
if len(networkList) == 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll like to see a switch probably, and return an error if more than one network is found maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My proposal is intentional. If multiple networks are found, we won't fail and will give another chance to look up the network by the subnet later on on populateCAPONetworkFromSubnet
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧠 💥
return filteredSubnets, nil | ||
} | ||
|
||
// convertOpenStackNetworkToCAPONetwork converts an OpenStack network to a capo network. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still convinced that we want to move these new functions into network.go
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pure API manipulation. I think it's best done here, but it's not a hill I would die on.
14ecbda
to
9709a58
Compare
func populateCAPONetworkFromSubnet(networkingService *networking.Service, subnets []subnets.Subnet, openStackCluster *infrav1.OpenStackCluster) error { | ||
if openStackCluster.Status.Network.ID == "" && len(subnets) > 0 { | ||
if len(subnets) > 1 && subnets[0].NetworkID != subnets[1].NetworkID { | ||
return fmt.Errorf("unable to identify the Network to use. NetworkID %s from subnet %s does not match NetworkID %s from subnet %s", subnets[0].NetworkID, subnets[0].ID, subnets[1].NetworkID, subnets[1].ID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the error message can be improved a little bit, because we also check for the length of subnets.
also please s/Network/network/ to be consistent with subnet.
9709a58
to
0efefe8
Compare
return filteredSubnets, nil | ||
} | ||
|
||
// convertOpenStackNetworkToCAPONetwork converts an OpenStack network to a capo network. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pure API manipulation. I think it's best done here, but it's not a hill I would die on.
@@ -544,6 +546,45 @@ var _ = Describe("OpenStackCluster controller", func() { | |||
Expect(err).To(BeNil()) | |||
Expect(len(testCluster.Status.Network.Subnets)).To(Equal(2)) | |||
}) | |||
|
|||
It("should allow fetch network by subnet", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great test, thanks.
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: MaysaMacedo, mdbooth The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
For the BYO scenario, when the `OpenStackCluster.Spec.Network` is not specified the query to OpenStack would return all the Networks available in the cloud and fail the reconciliation. To avoid this, if any Subnets were specified under `OpenStackCluster.Spec.Subnets` this can be used to identify which Network to use.
0efefe8
to
2e4ca73
Compare
/test pull-cluster-api-provider-openstack-e2e-full-test |
/hold cancel |
For the BYO scenario, when the
OpenStackCluster.Spec.Network
is not specified the query to OpenStack will return all the
Networks available in the cloud and fail the reconciliation.
To avoid this, if any Subnets were specified under
OpenStackCluster.Spec.Subnets
this can used to identifywhich Network to use.
Note, this pattern to infer a field based on another field has already been used by the
OpenStackCluster.Spec.Subnets
and also when no Network is defined in a Port.TODOs:
/hold