-
Notifications
You must be signed in to change notification settings - Fork 260
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
🏃 Refactor all network client calls into networking package #950
🏃 Refactor all network client calls into networking package #950
Conversation
Hi @macaptain. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. 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. |
Hi @hidekazuna, thanks for reviewing and merging #935. I saw you closed #883. Hopefully this PR does the same thing after #935. /assign @hidekazuna |
/ok-to-test |
I am not sure how big trouble this can cause to other ongoing PR |
I agree with this, there is a lot of discussion on those other PRs and I don't want to complicate them any further. I am happy to hold the refactor until they are merged. |
@macaptain Sorry late. Thank you for taking my PR into account. This PR looks fine for me as of now. It is OK to wait for other PRs not to bother them. |
Now I'm just waiting for #934 to be merged and then I'll rebase and this PR will be ready for review again. |
@macaptain Now that #934 has been merged, rebase please, if you do not mind. |
d4f968c
to
94d5f53
Compare
94d5f53
to
7910b69
Compare
This refactors all networking client behavior into the networking package. The network client has been removed from the compute Service struct, instead, we use the networking Service. Ports and trunking logic have been moved out of instance.go in the compute package into port.go and trunk.go in the networking package. The process for refactoring is simple enough: 1. Delete network client from compute package 2. Move any functions using the network client to the networking package 3. Refactor the functions to call the networking client interface instead of gophercloud directly
7910b69
to
bd0e3cb
Compare
|
||
// GetPortFromInstanceIP returns at most one port attached to the instance with given ID | ||
// and with the IP address provided. | ||
func (s *Service) GetPortFromInstanceIP(instanceID string, ip string) ([]ports.Port, 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.
This is the only function I had to create (to avoid a circular dependency with GetManagementPort
). All other functions in this file are moved from instance.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 looks fine to me.
@hidekazuna - I've rebased and this is ready for review again. Although the diff is quite large, the steps to make this change were not so complicated (they are in the PR description). I think the side-by-side diff will show what has moved. Thanks! |
@macaptain Thank s rebasing and advising to review. I will review in a few days. |
/approve |
@jichenjc PTAL |
I see some issue reported #993 not sure whether this PR will make things worse or has conflict to the proposed fix of #993 before that, I Think how about let's hold this? |
I haven't yet reviewed properly, but in general I'm very much in favour of continuing the refactor started by #935. The regression it introduced was caused by 2 very minor additions (checks for a zero length result) to a couple of networking functions which weren't strictly part of the refactor. However, it enables a pattern of unit testing which we can use to catch exactly this kind of bug in the future. I would like to see the same refactor in the compute package. I suspect this change is going to conflict with everything, so I'd personally be in favour of merging it asap. I will try to review today. |
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 mostly looks good to me. Just some minor issues which should be addressed before merging. Nits and bikesheds are up to you 😉
I would personally be in favour of merging this quickly despite the merge conflicts it will inevitably cause.
|
||
// GetPortFromInstanceIP returns at most one port attached to the instance with given ID | ||
// and with the IP address provided. | ||
func (s *Service) GetPortFromInstanceIP(instanceID string, ip string) ([]ports.Port, 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.
This looks fine to me.
} | ||
|
||
func (c networkClient) DeletePort(id string) error { | ||
return ports.Delete(c.serviceClient, id).ExtractErr() | ||
mc := metrics.NewMetricPrometheusContext("port", "delete") | ||
return mc.ObserveRequest(ports.Delete(c.serviceClient, id).ExtractErr()) |
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 would be a regression because we're now logging an error in prometheus on delete of an object which has already been deleted where we previously were not. I think we need to make this, and all Delete* methods in this interface, call ObserveRequestsIgnoreNotFound.
We have the same issue in all Delete* methods.
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
retryIntervalTrunkDelete = 5 * time.Second | ||
) | ||
|
||
func (s *Service) GetTrunkSupport() (bool, 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.
Aside: I wonder how expensive this call is. We call it on every create and delete, but it doesn't seem like it's ever going to change. And if it did change, would it break inter-op with servers created before the change? What if it changed between create and delete? 🤔
Not for this PR!
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
return mc.ObserveRequest(trunks.Delete(c.serviceClient, id).ExtractErr()) | ||
} | ||
|
||
func (c networkClient) ListTrunk(opts trunks.ListOptsBuilder) ([]trunks.Trunk, 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.
Bikeshed: This should be plural: ListTrunks (along with all the other List* methods).
Leave it for now unless you want to change all the others in a separate commit, and it's obviously not super important! It does make me wince, though 😉
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
} | ||
|
||
func (s *Service) replaceAllAttributesTags(eventObject runtime.Object, trunkID string, tags []string) error { | ||
mc := metrics.NewMetricPrometheusContext("trunk", "update") |
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 inconsistent. We should move this prometheus logging into the client, consistent with all the other logging.
That is going to inevitably change the logging from "trunk", "update" to something like "attributetags", "update" 🤔 I personally think that's ok, certainly less serious than the difference between logging errors and not logging errors on delete. Interested in other opinions, though.
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
return nil | ||
} | ||
|
||
func (s *Service) DeletePorts(eventObject runtime.Object, nets []servers.Network) 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.
nit: I personally wouldn't have moved this method. Its function is to iterate over servers.Network, which is a compute thing. Honestly I'd inline it in createInstance.
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
|
||
func (s *Service) GarbageCollectErrorInstancesPort(eventObject runtime.Object, instanceName string) error { | ||
portList, err := s.client.ListPort(ports.ListOpts{ | ||
Name: instanceName, |
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.
Not for this PR, but I'm pretty sure this is broken. This is listing ports which have the same name as the instance, but we don't create ports with the same name as the instance. I wonder if we should be deleting these by DeviceID instead 🤔
NOT FOR THIS PR!
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
@@ -33,7 +33,6 @@ type Service struct { | |||
projectID string | |||
computeClient *gophercloud.ServiceClient | |||
identityClient *gophercloud.ServiceClient | |||
networkClient *gophercloud.ServiceClient |
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.
🥳
@@ -211,7 +196,7 @@ func (s *Service) createInstance(eventObject runtime.Object, clusterName string, | |||
} | |||
|
|||
if instanceSpec.Subnet != "" && accessIPv4 == "" { | |||
if err := s.deletePorts(eventObject, portList); err != nil { | |||
if err := s.networkingService.DeletePorts(eventObject, portList); err != 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.
nit: As mentioned elsewhere, I would personally have left this method here.
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
/approve ok, let's merge this given agreement and clearance of regression issue |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: hidekazuna, jichenjc, macaptain 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 |
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.
Thanks for the thoughtful review @mdbooth ! I'll be addressing your points in follow-up PRs. I've raised #997 for making the metrics usage consistent.
@jichenjc - thanks for merging. This refactor means it's now possible to write unit tests for some of the network and ports logic, which will make this logic easier to maintain in future.
return nil | ||
} | ||
|
||
func (s *Service) DeletePorts(eventObject runtime.Object, nets []servers.Network) error { |
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
return mc.ObserveRequest(trunks.Delete(c.serviceClient, id).ExtractErr()) | ||
} | ||
|
||
func (c networkClient) ListTrunk(opts trunks.ListOptsBuilder) ([]trunks.Trunk, error) { |
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
@@ -211,7 +196,7 @@ func (s *Service) createInstance(eventObject runtime.Object, clusterName string, | |||
} | |||
|
|||
if instanceSpec.Subnet != "" && accessIPv4 == "" { | |||
if err := s.deletePorts(eventObject, portList); err != nil { | |||
if err := s.networkingService.DeletePorts(eventObject, portList); err != nil { |
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
} | ||
|
||
func (s *Service) replaceAllAttributesTags(eventObject runtime.Object, trunkID string, tags []string) error { | ||
mc := metrics.NewMetricPrometheusContext("trunk", "update") |
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
} | ||
|
||
func (c networkClient) DeletePort(id string) error { | ||
return ports.Delete(c.serviceClient, id).ExtractErr() | ||
mc := metrics.NewMetricPrometheusContext("port", "delete") | ||
return mc.ObserveRequest(ports.Delete(c.serviceClient, id).ExtractErr()) |
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
|
||
func (s *Service) GarbageCollectErrorInstancesPort(eventObject runtime.Object, instanceName string) error { | ||
portList, err := s.client.ListPort(ports.ListOpts{ | ||
Name: instanceName, |
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
retryIntervalTrunkDelete = 5 * time.Second | ||
) | ||
|
||
func (s *Service) GetTrunkSupport() (bool, error) { |
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
@macaptain I don't know how to unhide them :( |
Following up on kubernetes-sigs#950, this moves the deletePorts function back to the compute package where it can be made a private function.
Following up on kubernetes-sigs#950, this moves the deletePorts function back to the compute package where it can be made a private function.
This refactors all networking client behavior into the networking package. The network client has been removed from the compute Service struct, instead, we use the networking Service. Ports and trunking logic have been moved out of instance.go in the compute package into port.go and trunk.go in the networking package.
The process for refactoring is simple enough:
What this PR does / why we need it:
This will allow us to write unit tests for ports and trunk functionality using the mocks in the networking package. It also considerably tidies up instance.go, since now all networking client calls are made in the networking package only.
Which issue(s) this PR fixes:
Continuing work on #843, finishes #883 after #935 was merged.
Special notes for your reviewer:
This is going to cause some rebasing to be required on open PRs around trunks and port security features, namely #934, #914, #921, but will at least allow these features to have unit tests written for them. I think the rebase should be straightforward, thegetOrCreatePort
function in instance.go has simply moved toGetOrCreatePort
in the networking package. Alternatively, I don't mind waiting and rebasing this PR if those features are ready to go in.PR is ready to go!
/hold