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

🏃 Refactor all network client calls into networking package #950

Merged

Conversation

macaptain
Copy link
Contributor

@macaptain macaptain commented Jul 22, 2021

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

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, the getOrCreatePort function in instance.go has simply moved to GetOrCreatePort 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!

  • squashed commits

/hold

@k8s-ci-robot k8s-ci-robot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jul 22, 2021
@k8s-ci-robot
Copy link
Contributor

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 /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

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.

@k8s-ci-robot k8s-ci-robot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jul 22, 2021
@macaptain
Copy link
Contributor Author

Hi @hidekazuna, thanks for reviewing and merging #935. I saw you closed #883. Hopefully this PR does the same thing after #935.

/assign @hidekazuna

@macaptain macaptain changed the title 🏃 Refactor all networking into networking package 🏃 Refactor all network client calls into networking package Jul 22, 2021
@jichenjc
Copy link
Contributor

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jul 23, 2021
@jichenjc
Copy link
Contributor

I am not sure how big trouble this can cause to other ongoing PR
maybe we need let those functional PRs merge then do the refactory all-in-one..
ok to any suggestions instead

@macaptain
Copy link
Contributor Author

I am not sure how big trouble this can cause to other ongoing PR
maybe we need let those functional PRs merge then do the refactory all-in-one..
ok to any suggestions instead

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.

@hidekazuna
Copy link
Contributor

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.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 30, 2021
@macaptain
Copy link
Contributor Author

Now I'm just waiting for #934 to be merged and then I'll rebase and this PR will be ready for review again.

@hidekazuna
Copy link
Contributor

@macaptain Now that #934 has been merged, rebase please, if you do not mind.

@macaptain macaptain force-pushed the move-ports-to-networking branch from d4f968c to 94d5f53 Compare September 9, 2021 07:41
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 9, 2021
@macaptain macaptain force-pushed the move-ports-to-networking branch from 94d5f53 to 7910b69 Compare September 9, 2021 12:01
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
@macaptain macaptain force-pushed the move-ports-to-networking branch from 7910b69 to bd0e3cb Compare September 9, 2021 13:06

// 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) {
Copy link
Contributor Author

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.

Copy link
Contributor

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.

@macaptain
Copy link
Contributor Author

@macaptain Now that #934 has been merged, rebase please, if you do not mind.

@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!

@hidekazuna
Copy link
Contributor

@macaptain Now that #934 has been merged, rebase please, if you do not mind.

@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.

@hidekazuna
Copy link
Contributor

/approve

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 14, 2021
@hidekazuna
Copy link
Contributor

@jichenjc PTAL

@jichenjc
Copy link
Contributor

I see some issue reported #993
which likely to be a regression of #935 and this PR seems to be a follow up of #935

not sure whether this PR will make things worse or has conflict to the proposed fix of #993
need more time to read the code and maybe @macaptain @mdbooth can help us in understand more

before that, I Think how about let's hold this?

@hidekazuna
Copy link
Contributor

hidekazuna commented Sep 14, 2021

before that, I Think how about let's hold this?

@jichenjc I agree to hold this PR. revisit this PR after #993 fixed.

@mdbooth
Copy link
Contributor

mdbooth commented Sep 14, 2021

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.

Copy link
Contributor

@mdbooth mdbooth left a 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) {
Copy link
Contributor

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())
Copy link
Contributor

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.

retryIntervalTrunkDelete = 5 * time.Second
)

func (s *Service) GetTrunkSupport() (bool, error) {
Copy link
Contributor

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.

return mc.ObserveRequest(trunks.Delete(c.serviceClient, id).ExtractErr())
}

func (c networkClient) ListTrunk(opts trunks.ListOptsBuilder) ([]trunks.Trunk, error) {
Copy link
Contributor

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.

}

func (s *Service) replaceAllAttributesTags(eventObject runtime.Object, trunkID string, tags []string) error {
mc := metrics.NewMetricPrometheusContext("trunk", "update")
Copy link
Contributor

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.

return nil
}

func (s *Service) DeletePorts(eventObject runtime.Object, nets []servers.Network) error {
Copy link
Contributor

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.


func (s *Service) GarbageCollectErrorInstancesPort(eventObject runtime.Object, instanceName string) error {
portList, err := s.client.ListPort(ports.ListOpts{
Name: instanceName,
Copy link
Contributor

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.

@@ -33,7 +33,6 @@ type Service struct {
projectID string
computeClient *gophercloud.ServiceClient
identityClient *gophercloud.ServiceClient
networkClient *gophercloud.ServiceClient
Copy link
Contributor

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 {
Copy link
Contributor

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.

@jichenjc
Copy link
Contributor

/approve
/hold cancel

ok, let's merge this given agreement and clearance of regression issue
and for all the nits, I guess we have chance to submit follow up PRs

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Sep 15, 2021
@jichenjc
Copy link
Contributor

/lgtm

@k8s-ci-robot
Copy link
Contributor

[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:
  • OWNERS [hidekazuna,jichenjc]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 15, 2021
@k8s-ci-robot k8s-ci-robot merged commit c773ca0 into kubernetes-sigs:master Sep 15, 2021
Copy link
Contributor Author

@macaptain macaptain left a 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.

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.

@@ -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.

}

func (s *Service) replaceAllAttributesTags(eventObject runtime.Object, trunkID string, tags []string) error {
mc := metrics.NewMetricPrometheusContext("trunk", "update")

This comment was marked as duplicate.

}

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.


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.

retryIntervalTrunkDelete = 5 * time.Second
)

func (s *Service) GetTrunkSupport() (bool, error) {

This comment was marked as duplicate.

@macaptain macaptain deleted the move-ports-to-networking branch September 15, 2021 07:10
@macaptain
Copy link
Contributor Author

@jichenjc oops, I managed to hide all my comments in response to @mdbooth 😆. I don't have permission to unhide them, so if you can unhide for me, that would be great.

@jichenjc
Copy link
Contributor

@macaptain I don't know how to unhide them :(
@hidekazuna do you know ?

macaptain added a commit to Nordix/cluster-api-provider-openstack that referenced this pull request Sep 21, 2021
Following up on kubernetes-sigs#950, this moves the deletePorts function back to the
compute package where it can be made a private function.
pierreprinetti pushed a commit to shiftstack/cluster-api-provider-openstack that referenced this pull request Apr 22, 2024
Following up on kubernetes-sigs#950, this moves the deletePorts function back to the
compute package where it can be made a private function.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants