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: k8s auth token instead of kube conffig #600

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion e2e/basic/suite_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (s *Suite) SetupSuite() {
logger = logrus.New()
)

k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger)
k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger, s.K8sDefaultOptions()...)
s.Require().NoError(err)

minioClient, err := minio.New(ctx, k8sClient, logger)
Expand All @@ -46,6 +46,7 @@ func (s *Suite) SetupSuite() {
K8sClient: k8sClient,
MinioClient: minioClient,
Timeout: testTimeout,
Logger: logger,
})
s.Require().NoError(err)

Expand Down
13 changes: 11 additions & 2 deletions e2e/netshaper/suite_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"context"
"testing"

"github.com/sirupsen/logrus"
"github.com/stretchr/testify/suite"

"github.com/celestiaorg/knuu/e2e"
"github.com/celestiaorg/knuu/pkg/k8s"
"github.com/celestiaorg/knuu/pkg/knuu"
)

Expand All @@ -19,11 +21,18 @@ func TestRunSuite(t *testing.T) {
}

func (s *Suite) SetupSuite() {
ctx := context.Background()
var (
ctx = context.Background()
logger = logrus.New()
)

k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger, s.K8sDefaultOptions()...)
s.Require().NoError(err)

var err error
s.Knuu, err = knuu.New(ctx, knuu.Options{
ProxyEnabled: true,
K8sClient: k8sClient,
Logger: logger,
})
s.Require().NoError(err)
s.T().Logf("Scope: %s", s.Knuu.Scope)
Expand Down
9 changes: 7 additions & 2 deletions e2e/sidecars/suite_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/celestiaorg/knuu/e2e"
"github.com/celestiaorg/knuu/pkg/instance"
"github.com/celestiaorg/knuu/pkg/k8s"
"github.com/celestiaorg/knuu/pkg/knuu"
)

Expand All @@ -33,9 +34,13 @@ func (s *Suite) SetupSuite() {
err error
)

k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger, s.K8sDefaultOptions()...)
s.Require().NoError(err)

s.Knuu, err = knuu.New(ctx, knuu.Options{
Timeout: testTimeout,
Logger: logger,
K8sClient: k8sClient,
Timeout: testTimeout,
Logger: logger,
})
s.Require().NoError(err)

Expand Down
21 changes: 21 additions & 0 deletions e2e/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package e2e
import (
"context"
"fmt"
"os"
"sync"
"sync/atomic"
"time"
Expand All @@ -11,6 +12,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"

"github.com/celestiaorg/knuu/pkg/instance"
"github.com/celestiaorg/knuu/pkg/k8s"
"github.com/celestiaorg/knuu/pkg/knuu"
)

Expand All @@ -21,6 +23,10 @@ const (

nginxImage = "docker.io/nginx:latest"
nginxVolumeOwner = 0

envK8sHost = "K8S_HOST"
envK8sCACert = "K8S_CA_CERT"
envK8sAuthToken = "K8S_AUTH_TOKEN"
)

type Suite struct {
Expand Down Expand Up @@ -93,3 +99,18 @@ func (s *Suite) RetryOperation(operation func() error, maxRetries int) error {
}
return fmt.Errorf("operation failed after %d retries: %w", maxRetries, err)
}

func (s *Suite) K8sDefaultOptions() []k8s.Option {
if os.Getenv(envK8sAuthToken) == "" || os.Getenv(envK8sCACert) == "" || os.Getenv(envK8sHost) == "" {
s.T().Logf("%s, %s and/or %s are not set, using default cluster config from ~/.kube/config", envK8sAuthToken, envK8sCACert, envK8sHost)
return nil
}

return []k8s.Option{
k8s.WithAuthToken(
os.Getenv(envK8sHost),
os.Getenv(envK8sCACert),
os.Getenv(envK8sAuthToken),
),
}
}
3 changes: 2 additions & 1 deletion e2e/system/suite_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (s *Suite) SetupSuite() {
logger = logrus.New()
)

k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger)
k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger, s.K8sDefaultOptions()...)
s.Require().NoError(err, "Error creating k8s client")

minioClient, err := minio.New(ctx, k8sClient, logger)
Expand All @@ -47,6 +47,7 @@ func (s *Suite) SetupSuite() {
K8sClient: k8sClient,
MinioClient: minioClient, // needed for build from git tests
Timeout: testTimeout,
Logger: logger,
})
s.Require().NoError(err)

Expand Down
10 changes: 7 additions & 3 deletions e2e/tshark/tshark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/api/resource"

"github.com/celestiaorg/knuu/e2e"
"github.com/celestiaorg/knuu/pkg/k8s"
"github.com/celestiaorg/knuu/pkg/knuu"
"github.com/celestiaorg/knuu/pkg/minio"
Expand All @@ -32,10 +33,13 @@ func TestTshark(t *testing.T) {
t.Parallel()
// Setup

ctx := context.Background()
var (
ctx = context.Background()
logger = logrus.New()
s = e2e.Suite{}
)

logger := logrus.New()
k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger)
k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger, s.K8sDefaultOptions()...)
require.NoError(t, err, "error creating k8s client")

minioClient, err := minio.New(ctx, k8sClient, logger)
Expand Down
43 changes: 43 additions & 0 deletions pkg/k8s/clinet_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package k8s

import "k8s.io/client-go/rest"

type ClientOptions struct {
clusterDomain string
clusterHost string
authToken string
cert string
clusterConfig *rest.Config
}

type Option func(*ClientOptions)

func WithClusterDomain(clusterDomain string) Option {
return func(o *ClientOptions) {
o.clusterDomain = clusterDomain
}
}

func WithAuthToken(host, cert, authToken string) Option {
return func(o *ClientOptions) {
o.clusterHost = host
o.authToken = authToken
o.cert = cert
}
}
mojtaba-esk marked this conversation as resolved.
Show resolved Hide resolved

func WithClusterConfig(clusterConfig *rest.Config) Option {
return func(o *ClientOptions) {
o.clusterConfig = clusterConfig
}
}

func getAppliedOptions(options ...Option) *ClientOptions {
opts := &ClientOptions{
clusterDomain: defaultClusterDomain,
}
for _, opt := range options {
opt(opts)
}
return opts
}
2 changes: 2 additions & 0 deletions pkg/k8s/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,6 @@ var (
ErrNoPortsFoundForService = errors.New("NoPortsFoundForService", "no ports found for service %s")
ErrNoValidNodeIPFound = errors.New("NoValidNodeIPFound", "no valid node IP found for service %s")
ErrInvalidClusterDomain = errors.New("InvalidClusterDomain", "invalid cluster domain `%s`")
ErrEmptyClusterHostOrAuthTokenOrCert = errors.New("EmptyClusterHostOrAuthTokenOrCert", "cluster host, auth token or cert is not set")
ErrClusterConfigNotSet = errors.New("ClusterConfigNotSet", "cluster config is not set")
)
28 changes: 7 additions & 21 deletions pkg/k8s/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

const (
Expand Down Expand Up @@ -40,6 +41,7 @@ const (
type Client struct {
clientset kubernetes.Interface
discoveryClient discovery.DiscoveryInterface
clusterConfig *rest.Config
dynamicClient dynamic.Interface
namespace string
clusterDomain string
Expand All @@ -49,22 +51,10 @@ type Client struct {
maxPendingDuration time.Duration
}

type ClientOptions struct {
clusterDomain string
}

type Option func(*ClientOptions)

func WithClusterDomain(clusterDomain string) Option {
return func(o *ClientOptions) {
o.clusterDomain = clusterDomain
}
}

var _ KubeManager = &Client{}

func NewClient(ctx context.Context, namespace string, logger *logrus.Logger, options ...Option) (*Client, error) {
config, err := getClusterConfig()
config, err := getClusterConfig(getAppliedOptions(options...))
if err != nil {
return nil, ErrRetrievingKubernetesConfig.Wrap(err)
}
Expand All @@ -88,7 +78,8 @@ func NewClient(ctx context.Context, namespace string, logger *logrus.Logger, opt
return nil, ErrCreatingDynamicClient.Wrap(err)
}

return NewClientCustom(ctx, cs, dc, dC, namespace, logger, options...)
return NewClientCustom(ctx, cs, dc, dC, namespace, logger,
append(options, WithClusterConfig(config))...)
}

func NewClientCustom(
Expand All @@ -100,13 +91,7 @@ func NewClientCustom(
logger *logrus.Logger,
options ...Option,
) (*Client, error) {
opts := &ClientOptions{
clusterDomain: defaultClusterDomain,
}
for _, opt := range options {
opt(opts)
}

opts := getAppliedOptions(options...)
if err := validateDNS1123Subdomain(
opts.clusterDomain,
ErrInvalidClusterDomain.WithParams(opts.clusterDomain),
Expand All @@ -122,6 +107,7 @@ func NewClientCustom(
logger: logger,
terminated: false,
maxPendingDuration: defaultMaxPendingDuration,
clusterConfig: opts.clusterConfig,
}
kc.namespace = SanitizeName(namespace)
if err := kc.CreateNamespace(ctx, kc.namespace); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/k8s/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (c *Client) CreateNamespace(ctx context.Context, name string) error {
_, err := c.clientset.CoreV1().Namespaces().Create(ctx, namespace, metav1.CreateOptions{})
if err != nil {
if !apierrs.IsAlreadyExists(err) {
return ErrCreatingNamespace.WithParams(name).Wrap(err)
return err
}
c.logger.WithField("name", name).Debug("namespace already exists, continuing")
return nil
Expand Down
14 changes: 6 additions & 8 deletions pkg/k8s/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,10 @@ func (c *Client) RunCommandInPod(
}, scheme.ParameterCodec)

// Create an executor for the command execution
k8sConfig, err := getClusterConfig()
if err != nil {
return "", ErrGettingK8sConfig.Wrap(err)
if c.clusterConfig == nil {
return "", ErrClusterConfigNotSet
}
exec, err := remotecommand.NewSPDYExecutor(k8sConfig, http.MethodPost, req.URL())
exec, err := remotecommand.NewSPDYExecutor(c.clusterConfig, http.MethodPost, req.URL())
if err != nil {
return "", ErrCreatingExecutor.Wrap(err)
}
Expand Down Expand Up @@ -283,9 +282,8 @@ func (c *Client) PortForwardPod(
return ErrGettingPod.WithParams(podName).Wrap(err)
}

restConfig, err := getClusterConfig()
if err != nil {
return ErrGettingClusterConfig.Wrap(err)
if c.clusterConfig == nil {
return ErrClusterConfigNotSet
}

url := c.clientset.CoreV1().RESTClient().Post().
Expand All @@ -295,7 +293,7 @@ func (c *Client) PortForwardPod(
SubResource("portforward").
URL()

transport, upgrader, err := spdy.RoundTripperFor(restConfig)
transport, upgrader, err := spdy.RoundTripperFor(c.clusterConfig)
if err != nil {
return ErrCreatingRoundTripper.Wrap(err)
}
Expand Down
24 changes: 23 additions & 1 deletion pkg/k8s/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,35 @@ func fileExists(path string) bool {
}

// getClusterConfig returns the appropriate Kubernetes cluster configuration.
func getClusterConfig() (*rest.Config, error) {
func getClusterConfig(opts *ClientOptions) (*rest.Config, error) {
if opts.clusterConfig != nil {
return opts.clusterConfig, nil
}

if isClusterEnvironment() {
return rest.InClusterConfig()
}

if opts.authToken != "" {
return getClusterConfigWithToken(opts)
}
mojtaba-esk marked this conversation as resolved.
Show resolved Hide resolved
return clientcmd.BuildConfigFromFlags("", kubeconfig)
}

func getClusterConfigWithToken(opts *ClientOptions) (*rest.Config, error) {
if opts.clusterHost == "" || opts.authToken == "" || opts.cert == "" {
return nil, ErrEmptyClusterHostOrAuthTokenOrCert
}

return &rest.Config{
Host: opts.clusterHost,
BearerToken: opts.authToken,
TLSClientConfig: rest.TLSClientConfig{
CAData: []byte(opts.cert),
},
}, nil
}

// precompile the regular expression to avoid recompiling it on every function call
var invalidCharsRegexp = regexp.MustCompile(`[^a-z0-9-]+`)

Expand Down
Loading
Loading