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

#47037 - Create Remote Dialer Proxy #90

Merged
merged 16 commits into from
Feb 17, 2025
Merged

#47037 - Create Remote Dialer Proxy #90

merged 16 commits into from
Feb 17, 2025

Conversation

gehrkefc
Copy link
Contributor

maxsokolovsky and others added 3 commits November 8, 2024 12:12
* Add a port-forward type

* Add support for automatic reconnects when pods are terminated

* List clients

* Add a Dockerfile for the proxy

* Add proxy

* Update go.mod

* Update package name

* Add config parsing

* Immediately close connection when there are no clients

Verified

This commit was signed with the committer’s verified signature.
ljharb Jordan Harband

Verified

This commit was signed with the committer’s verified signature.
ljharb Jordan Harband
@gehrkefc gehrkefc changed the title added proxy client and server working impl, also some examples #47037 - Create Remote Dialer Proxy Jan 28, 2025

Verified

This commit was signed with the committer’s verified signature.
ljharb Jordan Harband
@gehrkefc gehrkefc marked this pull request as ready for review January 28, 2025 20:02
@gehrkefc gehrkefc requested a review from a team as a code owner January 28, 2025 20:02
@tomleb tomleb requested a review from joshmeranda January 28, 2025 21:52
Copy link
Contributor

@joshmeranda joshmeranda left a comment

Choose a reason for hiding this comment

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

LGTM from an integration with imperative api perspective, but have some smaller comments


if failed {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

We can probably get rid of failed and use err in the same way

var readyErr error

...
                if err := r.runForwarder(ctx, r.readyCh, r.stopCh, r.Ports); err != nil {
if errors.Is(err, portforward.ErrLostConnectionToPod) {
                    logrus.Errorf("Lost connection to pod (no automatic retry in this refactor): %v", err)
                } else {
                    logrus.Errorf("Non-restartable error: %v", err)
                    readyErr = err
                    r.readyCh <- struct{}{}
                    return
					}
                }
...

if readyErr != nil {
return err
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, just changed it. Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this will trigger a race condition with the race detector because we have:

G1: write readyErr (init)
G2: write readyErr
G1: read readyErr

Copy link
Contributor

Choose a reason for hiding this comment

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

Unresolving this due to my comment above^ Do you disagree @joshmeranda / @gehrkefc

@tomleb
Copy link
Contributor

tomleb commented Jan 29, 2025

@gehrkefc Currently this PR points to imperative-api branch, but we should target the main branch of remotedialer. The imperative-api branch was a quick branch without review since Max was leaving. So let's review the entirety of the changes instead.

@gehrkefc gehrkefc changed the base branch from imperative-api to main January 29, 2025 15:18
joshmeranda
joshmeranda previously approved these changes Jan 29, 2025
Copy link
Contributor

@tomleb tomleb left a comment

Choose a reason for hiding this comment

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

First set of comments, reviewed mostly the core functionality.


if failed {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this will trigger a race condition with the race detector because we have:

G1: write readyErr (init)
G2: write readyErr
G1: read readyErr

logrus.Infoln("Goroutine stopped.")
return
default:
err := r.runForwarder(ctx, r.readyCh, r.stopCh, r.Ports)
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we replace r.stopCh with ctx.Done() ?

Copy link
Contributor Author

@gehrkefc gehrkefc Jan 31, 2025

Choose a reason for hiding this comment

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

Sure. Replaced it! Thanks!

Comment on lines 99 to 112
secret, err := secretController.Get(namespace, certSecretName, metav1.GetOptions{})
if err != nil {
return nil, err
}

crtData, exists := secret.Data["tls.crt"]
if !exists {
return nil, fmt.Errorf("secret %s/%s missing tls.crt field", namespace, certSecretName)
}

rootCAs := x509.NewCertPool()
if ok := rootCAs.AppendCertsFromPEM(crtData); !ok {
return nil, fmt.Errorf("failed to parse tls.crt from secret into a CA pool")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The certs will be rotated by dynamiclistener before they expire (or at least that's the intention) so we should react to changes for this. We can add that functionality in the next PR, same as we're doing with @joshmeranda 's PR. We do need that though as part of the GH 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.

I've implemented this. Please check it. I tested it modifying a local copy of dynamic listener to generate a new cert at each 20s. Please check the image below to see both working.

In the lower terminal you'll see the server regenerating the secret and updating it. Then in the upper terminal you'll see the client receiving the event with the new cert.

image

@gehrkefc
Copy link
Contributor Author

First set of comments, reviewed mostly the core functionality.

I've made another change in the server in the runProxyListener function because of a high cpu usage.

gehrkefc and others added 4 commits February 14, 2025 13:57
Co-authored-by: Tom Lebreux <tom.lebreux@suse.com>
@gehrkefc gehrkefc requested a review from tomleb February 14, 2025 21:56
Copy link
Contributor

@tomleb tomleb left a comment

Choose a reason for hiding this comment

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

LGTM. Given the amount of changes, we should make this v0.5.0 once that's in.

I'll create some GH issues to address the nits / add tests for this.

Transport: roundTripper,
}, http.MethodPost, &serverURL)

stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
Copy link
Contributor

Choose a reason for hiding this comment

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

stdout and sterr aren't actually used. Meaning we're going to be adding to the buffer but those aren't being read from anywhere.

I'm not exactly sure what information goes into them, but I assume we'd want to print that information somewhere. We can figure this out in another iteration.

if newSecret.Name == c.certSecretName && newSecret.Namespace == c.namespace {
rootCAs, err := buildCertFromSecret(c.namespace, c.certSecretName, newSecret)
if err != nil {
logrus.Errorf("build certificate failed: %s", err.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: We're already returning the error so wrangler will also print it, meaning we'll print the error twice.

I'd suggest just wrapping the error and returning it.

@gehrkefc gehrkefc merged commit 69cb968 into main Feb 17, 2025
2 checks passed
@tomleb tomleb deleted the feat/47037 branch February 17, 2025 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants