-
Notifications
You must be signed in to change notification settings - Fork 263
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
✨Infer port network from subnet #1519
Conversation
✅ Deploy Preview for kubernetes-sigs-cluster-api-openstack ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
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.
It looks quite complicated for a simple change, a few ideas inline.
networkID, err := func() (string, error) { | ||
networkingService, err := s.getNetworkingService() | ||
if err != nil { | ||
return nil, err | ||
return "", err | ||
} | ||
|
||
netIDs, err := networkingService.GetNetworkIDsByFilter(port.Network.ToListOpt()) | ||
if err != nil { | ||
return nil, err | ||
for i, fixedIP := range port.FixedIPs { | ||
if fixedIP.Subnet == nil { | ||
continue | ||
} | ||
|
||
subnetOpts := fixedIP.Subnet.ToListOpt() | ||
subnets, err := networkingService.GetSubnetsByFilter(&subnetOpts) | ||
if err != nil { | ||
return "", err | ||
} | ||
for len(subnets) > 1 { | ||
s.scope.Logger().V(4).Info("Can't infer network from subnet %d: multiple subnets match filter", i) | ||
continue | ||
} | ||
for _, subnet := range subnets { | ||
s.scope.Logger().V(4).Info("Inferred network %s from subnet %s", subnet.NetworkID, subnet.ID) | ||
return subnet.NetworkID, 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.
Feels like a pattern we often have, I'd at least extract it into a named function for code clarity.
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.
Looks like we use this pattern everywhere we call GetSubnetsByFilter() 🤔
...except in getServerNetworks(), which I'm hoping to delete shortly.
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 started pulling this out, btw. I kept the non-related parts in a separate commit.
I agree, but there are a few things going on here. Firstly is the stated change itself. This is itself more complex than it sounds because:
So you have to loop over it until you find one which works. Incidentally, documenting this behaviour isn't going to be fun, and I still need to do that Secondly I've refactored it a bit because it's complex enough to require its own unit tests, which I haven't written yet. Hence pulling out the Lastly there's a slightly hidden agenda here. I'm writing this in the context of removing Networks, so I'm going to be throwing away the non-Ports part of I want to backport this PR to version 0.7, though, so I can't fully do that here. This is to help anybody who needs to manually update their ports in v0.7 before upgrading to v0.8. |
Alright, let's see the completed version then! |
That isn't going to come in this PR, btw. I need to remove Networks first, which I'm doing in #1518. However, this PR now has tests and docs. Hopefully ready to roll. |
/cherry-pick release-0.7 |
@mdbooth: once the present PR merges, I will cherry-pick it on top of release-0.7 in a new PR and assign it to you. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
22d0be8
to
9680b33
Compare
I'm working on this in parallel with the Networks removal PR, btw, which is why I keep updating it. I don't want to move this code twice, so I'm effectively pulling Network removal requirements back into this PR. I'm now at the point where I might move the entire 'use PortOpts natively' thing into this PR instead. The defaulting behaviour of ports is currently spread untidily across |
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.
Looks great, tiny suggestion inline.
func (s *Service) constructNetworks(openStackCluster *infrav1.OpenStackCluster, instanceSpec *InstanceSpec) ([]infrav1.Network, error) { | ||
trunkRequired := false | ||
// normalizePortTarget ensures that the port has a network ID. | ||
func (s *Service) normalizePortTarget(port *infrav1.PortOpts, openStackCluster *infrav1.OpenStackCluster, portIdx int) error { |
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.
normalizePortTarget()
sounds a bit confusing if it's just normalizePortNetwork()
.
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 would update this, but I plan to refactor this code a fair bit anyway after backporting this to 0.7.
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: dulek, 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 |
/lgtm It has hold, so /lgtm is safe. |
|
||
`fixedIPs`, including all fields available in the `subnet` filter, are described in [the CRD](https://doc.crds.dev/github.com/kubernetes-sigs/cluster-api-provider-openstack/infrastructure.cluster.x-k8s.io/OpenStackMachine/v1alpha6@v0.7.1#spec-ports-fixedIPs). | ||
|
||
If no `fixedIPs` are specified, the port will get an address from every subnet in the 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.
every subnet
=> is this first subnet of the network? This seems to be the way I provide my openstack to my end user..
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 tested this few days ago, if network has multiple subnets, creating a port specifying just the network gives you a port with address in every of the network's subnets:
A POST with:
{
"port": {
"admin_state_up": true,
"name": "test",
"network_id": "6acb08e4-86a1-47fa-a806-2f79a0b48abb"
}
}
Will get you:
{
"port": {
<SNIP>
"fixed_ips": [
{
"ip_address": "192.168.25.127",
"subnet_id": "4b73762e-8fbb-4555-9df6-fcd2b8fe2734"
},
{
"ip_address": "2001:db8::2c8",
"subnet_id": "d808f460-99b0-4356-b158-92c3b6f97efd"
}
],
"id": "f5d15252-9f61-4d95-885b-9c3346fa2608",
<SNIP>
"name": "test",
"network_id": "6acb08e4-86a1-47fa-a806-2f79a0b48abb",
<SNIP>
}
}
I'm going to rework this a bit because it was starting to combine a refactor of the port creation code with a behavioural change. I'm going to try to separate them into 2 separate PRs. |
NetworkID is a required field when creating a neutron port. We previously passed on this requirement in the Ports API. However we didn't have this restriction in the Networks API and inferred the network from a subnet if one was defined. This change eases the transition from Networks to Ports by removing this restriction for Ports.
I've changed my mind on this. I want to backport this change, but it was getting too invasive and too big. I'd like to land this version after all, and I'll do any refactoring on top of it in main. |
/lgtm Question inline, feel free to unhold this if that TODO is supposed to stay there. |
// TODO: These are spec errors: they should set the machine to failed | ||
if len(netIDs) > 1 { | ||
return fmt.Errorf("network filter for port %d returns more than one result", portIdx) | ||
} else if len(netIDs) == 0 { | ||
return fmt.Errorf("network filter for port %d returns no networks", portIdx) | ||
} |
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.
Do we allow this to be TODO?
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.
It's already the case: I'm just adding the TODO because I noticed it. However, fixing these requires the refactor I'm trying to avoid here. I want to split the validation of ports such that everything which needs to be looked up is done for all ports before we start to create any of them. It just involves a ton of code motion.
/hold cancel |
@mdbooth: #1519 failed to apply on top of branch "release-0.7":
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
NetworkID is a required field when creating a neutron port. We previously passed on this requirement in the Ports API. However we didn't have this restriction in the Networks API and inferred the network from a subnet if one was defined. This change eases the transition from Networks to Ports by removing this restriction for Ports.
TODOs:
/hold