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

fix: kubectl expose fails for apps with same-port, different-protocol #114909

Merged
merged 1 commit into from
Jul 6, 2023

Conversation

aimuz
Copy link
Contributor

@aimuz aimuz commented Jan 9, 2023

Fixed: #114402
Signed-off-by: aimuz [email protected]

What type of PR is this?

/kind bug

What this PR does / why we need it:

Which issue(s) this PR fixes:

Fixes #114402

Special notes for your reviewer:

Does this PR introduce a user-facing change?

Kubectl expose supports the creation of different protocol service on the same port

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:


@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. kind/bug Categorizes issue or PR as related to a bug. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Jan 9, 2023
@aimuz
Copy link
Contributor Author

aimuz commented Jan 9, 2023

/sig cli

@k8s-ci-robot k8s-ci-robot added sig/cli Categorizes an issue or PR as relevant to SIG CLI. area/kubectl and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Jan 9, 2023
@aimuz
Copy link
Contributor Author

aimuz commented Jan 9, 2023

/assign anggao

Can you review the code for me

@k8s-ci-robot
Copy link
Contributor

@aimuz: GitHub didn't allow me to assign the following users: anggao.

Note that only kubernetes members with read permissions, repo collaborators and people who have commented on this issue/PR can be assigned. Additionally, issues/PRs can only have 10 assignees at the same time.
For more information please see the contributor guide

In response to this:

/assign anggao

Can you review the code for me

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.

Comment on lines 391 to 394
serviceName := o.Name
if len(serviceName) == 0 {
serviceName = o.DefaultName
if len(serviceName) == 0 {
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 to avoid the misunderstanding of duplicate names. In the loop, name is also used. To avoid misunderstanding, I renamed it

Comment on lines 453 to 456
name := servicePortName
if len(portStringSlice) > 1 {
name = fmt.Sprintf("%s-%d", strings.ToLower(protocol), port)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compared with the naming of prot-i, this method may be easier to understand, which is also to distinguish between different protocols on the same port

@aimuz
Copy link
Contributor Author

aimuz commented Jan 9, 2023

/assign @anggao

@k8s-ci-robot
Copy link
Contributor

@aimuz: GitHub didn't allow me to assign the following users: anggao.

Note that only kubernetes members with read permissions, repo collaborators and people who have commented on this issue/PR can be assigned. Additionally, issues/PRs can only have 10 assignees at the same time.
For more information please see the contributor guide

In response to this:

/assign @anggao

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 size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jan 9, 2023
@aimuz aimuz force-pushed the fix-114402 branch 2 times, most recently from f6b61cc to 4cabc1e Compare January 9, 2023 06:33
@@ -1722,8 +1756,8 @@ func TestGenerateService(t *testing.T) {
service, err := exposeServiceOptions.createService()
if test.expectErr == "" {
require.NoError(t, err)
if !apiequality.Semantic.DeepEqual(service, test.expected) {
t.Errorf("\nexpected:\n%#v\ngot:\n%#v", test.expected, service)
if diff := cmp.Diff(test.expected, service); diff != "" {
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 will output more intuitive differences

@aimuz
Copy link
Contributor Author

aimuz commented Jan 9, 2023

/test pull-kubernetes-integration

Copy link
Member

@ardaguclu ardaguclu 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 fix and the effort you invested.

Maybe it is better to do less changes to fix that issue without touching generated files.

to prevent accidental merging;
/hold

}
selector, err := parseLabels(o.Selector)
obj, err := versioned.GenerateService(opts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks unusual. What is the reason of this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetitive code implementation, which I extract as a public method

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment above. We don't want to use the generators.

portProtocolMap[portProtocol[0]] = portProtocol[1]
}
return portProtocolMap, nil
return obj, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason of these changes with respect to the referenced issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repetitive code implementation, which I extract as a public method

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something required for fixing the bug or is this refactoring?.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring was done while fixing the bug

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you start with just fixing the bug, with minimal or no refactoring at first? Then maybe do the refactor later if needed.

It's more complicated to review a bug fix and refactor together.

@@ -67,7 +67,7 @@ var MapBasedSelectorForObjectFn MapBasedSelectorForObjectFunc = mapBasedSelector

// ProtocolsForObjectFunc will call the provided function on the protocols for the object,
// return nil-map if no protocols for the object, or return an error.
type ProtocolsForObjectFunc func(object runtime.Object) (map[string]string, error)
type ProtocolsForObjectFunc func(object runtime.Object) (map[string][]string, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this backward compatible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but I don't think this change will have any impact. Only kubectl will use this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is public and it looks like people are using it (via github search, but possibly more elsewhere)...
https://github.com/search?q=ProtocolsForObjectFunc&type=code

Can we leave the existing function as-is and create a new one with the new behavior?

Perhaps mark the old one as deprecated, with an explanation that it doesn't support multiple protocols per port, and that code should use the new function instead?

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 9, 2023
@ardaguclu
Copy link
Member

As far as I can see, integration test failure is real.

@aimuz
Copy link
Contributor Author

aimuz commented Jan 9, 2023

Maybe it is better to do less changes to fix that issue without touching generated files.

Yes, the best way is to complete the bug repair with the least code

For example, I can roll back the changes to the portname, which will reduce the number of changes, but this will result in inconsistent portname naming.

For example, for public method extraction, I can roll back this part and only modify the required part, but it will be difficult to maintain. For the same logic code, modify and maintain multiple copies.

@ardaguclu If you need to do so, please let me know at any time, and it will be rolled back

@aimuz aimuz requested a review from ardaguclu January 26, 2023 03:29
@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all PRs.

This bot triages PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the PR is closed

You can:

  • Mark this PR as fresh with /remove-lifecycle stale
  • Close this PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Apr 26, 2023
@aimuz
Copy link
Contributor Author

aimuz commented Apr 26, 2023

/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Apr 26, 2023
@aimuz
Copy link
Contributor Author

aimuz commented Jun 12, 2023

/pin @brianpursley

@aimuz
Copy link
Contributor Author

aimuz commented Jun 14, 2023

/ping @brianpursley @ardaguclu

expected: map[string][]string{"101": {"TCP"}},
},
{
name: "unsupported object",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does portsforobject also return expectErr true?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

This is the code for portsforobject

func portsForObject(object runtime.Object) ([]string, error) {
	switch t := object.(type) {
	case *corev1.ReplicationController:
		return getPorts(t.Spec.Template.Spec), nil

	case *corev1.Pod:
		return getPorts(t.Spec), nil

	case *corev1.Service:
		return getServicePorts(t.Spec), nil

	case *extensionsv1beta1.Deployment:
		return getPorts(t.Spec.Template.Spec), nil
	case *appsv1.Deployment:
		return getPorts(t.Spec.Template.Spec), nil
	case *appsv1beta2.Deployment:
		return getPorts(t.Spec.Template.Spec), nil
	case *appsv1beta1.Deployment:
		return getPorts(t.Spec.Template.Spec), nil

	case *extensionsv1beta1.ReplicaSet:
		return getPorts(t.Spec.Template.Spec), nil
	case *appsv1.ReplicaSet:
		return getPorts(t.Spec.Template.Spec), nil
	case *appsv1beta2.ReplicaSet:
		return getPorts(t.Spec.Template.Spec), nil
	default:
		return nil, fmt.Errorf("cannot extract ports from %T", object)
	}
}

for _, port := range container.Ports {
// Empty protocol must be defaulted (TCP)
if len(port.Protocol) == 0 {
port.Protocol = corev1.ProtocolTCP
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although port.Protocol is value type(it looks safe), I think, we should avoid such assignments to objects inside corev1.PodSpec.
Instead, I'd rather prefer;

protocol := corev1.ProtocolTCP
if len(port.Protocol) > 0 {
protocol = port.Protocol
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ardaguclu done

for _, servicePort := range spec.Ports {
// Empty protocol must be defaulted (TCP)
if len(servicePort.Protocol) == 0 {
servicePort.Protocol = corev1.ProtocolTCP
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same above

@ardaguclu
Copy link
Member

Thanks @aimuz

/lgtm
/triage accepted
/priority backlog

I'm deferring to @brianpursley for last approval, if he wants to check.

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. priority/backlog Higher priority than priority/awaiting-more-evidence. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Jul 3, 2023
@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jul 3, 2023
@k8s-ci-robot
Copy link
Contributor

LGTM label has been added.

Git tree hash: c399785bd6ad0c6770a0bab6a2abd7a85a4f843f

@aimuz
Copy link
Contributor Author

aimuz commented Jul 3, 2023

/pin @brianpursley

Do you have time for a code review, thank you

@aojea
Copy link
Member

aojea commented Jul 6, 2023

great 👏

@ardaguclu
Copy link
Member

/hold cancel
/approve

@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 Jul 6, 2023
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: aimuz, ardaguclu

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 6, 2023
@k8s-ci-robot k8s-ci-robot merged commit 2075b20 into kubernetes:master Jul 6, 2023
12 checks passed
@k8s-ci-robot k8s-ci-robot added this to the v1.28 milestone Jul 6, 2023
@aimuz
Copy link
Contributor Author

aimuz commented Jul 6, 2023

Thank you all for your hard work!

@aimuz
Copy link
Contributor Author

aimuz commented Jul 7, 2023

Does this need to be Cherry-picked to another branch?

@ardaguclu @aojea

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. area/kubectl cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/backlog Higher priority than priority/awaiting-more-evidence. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/cli Categorizes an issue or PR as relevant to SIG CLI. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

kubectl expose fails for apps with same-port, different-protocol
6 participants