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

feat(ec_join): update handler to return tcp connections required #5004

Merged
merged 9 commits into from
Nov 26, 2024

Conversation

JGAntunes
Copy link
Member

@JGAntunes JGAntunes commented Nov 13, 2024

What this PR does / why we need it:

On join, return all the TCP endpoints the joining node needs to preflight for to ensure a successful connection to the cluster

Which issue(s) this PR fixes:

https://app.shortcut.com/replicated/story/113015/preflight-remote-access-on-join

Does this PR require a test?

Yes, added tests to the handler and to the newly added method

Also run some manual tests on an EC local dev deployment:

root@node1:/replicatedhq/embedded-cluster# curl -k -v "https://172.17.0.2:30000/api/v1/embedded-cluster/join?token=FGjr0qVT2dRHrMialHJk7zd8" | jq .
(...)
{
  "clusterID": "19750e22-03ff-44ae-8fcb-c41e70ca4db5",
  "k0sJoinCommand": "/usr/local/bin/k0s install controller --enable-worker --no-taints --labels kots.io/embedded-cluster-role=total-1,kots.io/embedded-cluster-role-0=controller-test,controller-label=controller-label-value",
  "k0sToken": "...",
  "embeddedClusterVersion": "1.19.0+k8s-1.30-11-gbb2a7ab9-jgantunes",
  "airgapRegistryAddress": "",
  "tcpConnectionsRequired": [
    "172.17.0.2:6443",
    "172.17.0.2:9443",
    "172.17.0.2:2380",
    "172.17.0.2:10250"
  ],
  "installationSpec": {
    (...)
  }
}

Does this PR require a release note?

Enable embedded cluster node joins to preflight Node to Node communications

Does this PR require documentation?

NONE

@JGAntunes JGAntunes self-assigned this Nov 13, 2024
@JGAntunes JGAntunes added the type::feature New feature or request label Nov 13, 2024
@JGAntunes JGAntunes marked this pull request as ready for review November 15, 2024 14:30
Comment on lines +1 to +35
package kubeclient

import (
"context"

"github.com/replicatedhq/kots/pkg/k8sutil"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
)

var _ KubeClientBuilder = (*Builder)(nil)
var _ KubeClientBuilder = (*MockBuilder)(nil)

// KubeClientBuilder interface is used as an abstraction to get a kube client. Useful to mock the client in tests.
type KubeClientBuilder interface {
GetKubeClient(ctx context.Context) (kbclient.Client, error)
}

// Builder is the default implementation of KubeClientBuilder. It returns a regular kube client.
type Builder struct{}

// GetKubeClient returns a regular kube client.
func (b *Builder) GetKubeClient(ctx context.Context) (kbclient.Client, error) {
return k8sutil.GetKubeClient(ctx)
}

// MockBuilder is a mock implementation of KubeClientBuilder. It returns the client that was set in the struct allowing
// you to set a fakeClient for example.
type MockBuilder struct {
Client kbclient.Client
}

// GetKubeClient returns the client that was set in the struct.
func (b *MockBuilder) GetKubeClient(ctx context.Context) (kbclient.Client, error) {
return b.Client, nil
}
Copy link
Member Author

Choose a reason for hiding this comment

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

The general idea is to allow us to get a new k8s client on the fly within the handler VS the alternative which would be to have a single client instantiated when the handler is created and shared between all the endpoints. This ensures we keep functionality as is while having the ability to stub/mock the kube client.

Comment on lines +47 to +70
name: "not an embedded cluster",
httpStatus: http.StatusBadRequest,
embeddedClusterID: "",
},
{
name: "store returns error",
httpStatus: http.StatusInternalServerError,
embeddedClusterID: "cluster-id",
getRoles: func(*testing.T, string) ([]string, error) {
return nil, fmt.Errorf("some error")
},
},
{
name: "store gets passed the provided token",
httpStatus: http.StatusInternalServerError,
embeddedClusterID: "cluster-id",
token: "some-token",
getRoles: func(t *testing.T, token string) ([]string, error) {
require.Equal(t, "some-token", token)
return nil, fmt.Errorf("some error")
},
},
{
name: "bootstrap token secret creation succeeds and it matches returned K0SToken",
Copy link
Member Author

Choose a reason for hiding this comment

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

Went a bit overboard with testing other (unrelated) scenarios, but thought would be useful + it was a good opportunity for me to see how the join process works. Happy to move these to a separate PR if folks prefer.

@JGAntunes JGAntunes force-pushed the jgantunes/sc-113015/preflight-remote-access-on-join branch from 55b851e to 715977a Compare November 25, 2024 15:20
@JGAntunes JGAntunes changed the title feat(ec_join): update handler to return node ips feat(ec_join): update handler to return tcp connections required Nov 25, 2024
@JGAntunes JGAntunes merged commit 7eacbb7 into main Nov 26, 2024
156 checks passed
@JGAntunes JGAntunes deleted the jgantunes/sc-113015/preflight-remote-access-on-join branch November 26, 2024 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type::feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants