Skip to content

Commit

Permalink
Add exec provider support
Browse files Browse the repository at this point in the history
Add support for fetching token from external provider configured through kubeconfig's ExecConfig api.
  • Loading branch information
sayan-biswas committed Mar 15, 2024
1 parent e7553c3 commit 10a036e
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 172 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ kubectl krew install test/tekton

| Name | Group | Default | Description |
|--------------------------|--------|---------|----------------------------------------|
| host | client | | Host address for the client to connect |
| client-type | client | REST | Type of client can be GRPC or REST |
| host | client | | Host address for the client to connect |
| api-path | client | | API path to add to request |
| insecure-skip-tls-verify | client | false | Skip host name verification |
| timeout | client | 1m | Client context timeout |
| certificate-authority | tls | | CA file path to use |
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/config/results/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (o *Options) Run(_ *cobra.Command, args []string) (err error) {

switch {
case o.View:
return o.PrinterFunc(o.Config.RawConfig(), o.IOStreams.Out)
return o.PrinterFunc(o.Config.GetObject(), o.IOStreams.Out)
case o.Reset:
return o.Config.Reset()
case len(args) == 0:
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// TODO: remove this hard coding.
const clientVersion = "v0.1.0"
const clientVersion = "v0.1.1"
const serverVersion = "v0.9.0"

var (
Expand Down
33 changes: 10 additions & 23 deletions internal/results/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
resultsv1alpha2 "github.com/tektoncd/results/proto/v1alpha2/results_go_proto"
"google.golang.org/grpc/status"
"k8s.io/client-go/transport"
"net/url"
"time"
)

Expand All @@ -20,34 +21,20 @@ type Client interface {
}

type Config struct {
ClientType string
Host string
ImpersonationConfig *transport.ImpersonationConfig
Timeout time.Duration
TLSConfig *transport.TLSConfig
Token string
ClientType string
URL *url.URL
Timeout time.Duration
Transport *transport.Config
}

func NewClient(c *Config) (Client, error) {
c.SetDefault()

switch c.ClientType {
func NewClient(config *Config) (Client, error) {
switch config.ClientType {
case GRPC:
return NewGRPCClient(c)
return NewGRPCClient(config)
case REST:
return NewRESTClient(c)
return NewRESTClient(config)
default:
return nil, errors.New("invalid client type")
}
}

func (c *Config) SetDefault() {
if c.ClientType == "" {
c.ClientType = REST
}

if c.Timeout == 0 {
c.Timeout = time.Minute
return NewRESTClient(config)
}
}

Expand Down
33 changes: 16 additions & 17 deletions internal/results/client/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,23 @@ func NewGRPCClient(c *Config) (Client, error) {
ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
defer cancel()

u, err := url.Parse(c.Host)
if err != nil {
return nil, err
if c.Timeout == 0 {
ctx = context.Background()
}

if u.Port() == "" {
switch u.Scheme {
if c.URL.Port() == "" {
switch c.URL.Scheme {
case "https":
u.Host = u.Host + ":443"
c.URL.Host = c.URL.Host + ":443"
case "http":
u.Host = u.Host + ":80"
c.URL.Host = c.URL.Host + ":80"
default:
return nil, errors.New("port or scheme missing in host")
}
}

tc := insecure.NewCredentials()
if c.TLSConfig != nil && u.Scheme == "https" {
if c.URL.Scheme == "https" {
tls, err := c.ClientTLSConfig()
if err != nil {
return nil, err
Expand All @@ -54,10 +53,10 @@ func NewGRPCClient(c *Config) (Client, error) {
cos := []grpc.CallOption{
grpc.PerRPCCredentials(&Credentials{
TokenSource: transport.NewCachedTokenSource(oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: c.Token,
AccessToken: c.Transport.BearerToken,
})),
ImpersonationConfig: c.ImpersonationConfig,
SkipTransportSecurity: u.Scheme != "https",
ImpersonationConfig: &c.Transport.Impersonate,
SkipTransportSecurity: c.URL.Scheme != "https",
}),
}

Expand All @@ -66,7 +65,7 @@ func NewGRPCClient(c *Config) (Client, error) {
grpc.WithTransportCredentials(tc),
}

clientConn, err := grpc.DialContext(ctx, u.Host, dos...)
clientConn, err := grpc.DialContext(ctx, c.URL.Host, dos...)
if err != nil {
return nil, err
}
Expand All @@ -79,18 +78,18 @@ func NewGRPCClient(c *Config) (Client, error) {

func (c *Config) ClientTLSConfig() (*tls.Config, error) {
tc := &tls.Config{
InsecureSkipVerify: c.TLSConfig.Insecure,
InsecureSkipVerify: c.Transport.TLS.Insecure,
}

if c.TLSConfig.CertFile != "" && c.TLSConfig.KeyFile != "" {
keyPair, err := tls.LoadX509KeyPair(c.TLSConfig.CertFile, c.TLSConfig.KeyFile)
if c.Transport.TLS.CertFile != "" && c.Transport.TLS.KeyFile != "" {
keyPair, err := tls.LoadX509KeyPair(c.Transport.TLS.CertFile, c.Transport.TLS.KeyFile)
if err != nil {
return nil, fmt.Errorf("could not load client key pair: %v", err)
}
tc.Certificates = []tls.Certificate{keyPair}
} else if c.TLSConfig.CAFile != "" {
} else if c.Transport.TLS.CAFile != "" {
cp := x509.NewCertPool()
ca, err := os.ReadFile(c.TLSConfig.CAFile)
ca, err := os.ReadFile(c.Transport.TLS.CAFile)
if err != nil {
return nil, fmt.Errorf("could not read CA certificate: %v", err)
}
Expand Down
35 changes: 13 additions & 22 deletions internal/results/client/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package client
import (
"bytes"
"context"
"errors"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
v1alpha2 "github.com/tektoncd/results/proto/v1alpha2/results_go_proto"
"google.golang.org/genproto/googleapis/api/httpbody"
Expand All @@ -15,44 +16,34 @@ import (
"k8s.io/client-go/transport"
"net/http"
"net/url"
"path"
)

const (
basePath = "/apis/results.tekton.dev/v1alpha2/parents"
pathPrefix = "parents"
)

type RESTClient struct {
httpClient *http.Client
url *url.URL
url *url.URL
client *http.Client
}

// NewRESTClient creates a new REST client.
func NewRESTClient(c *Config) (Client, error) {
u, err := url.Parse(c.Host)
if err != nil {
return nil, err
}

u.Path = basePath
c.URL.Path = path.Join(c.URL.Path, pathPrefix)

rt, err := transport.New(&transport.Config{
BearerToken: c.Token,
TLS: *c.TLSConfig,
Impersonate: *c.ImpersonationConfig,
})
rt, err := transport.New(c.Transport)
if err != nil {
return nil, err
}

rc := &RESTClient{
httpClient: &http.Client{
return &RESTClient{
url: c.URL,
client: &http.Client{
Transport: rt,
Timeout: c.Timeout,
},
url: u,
}

return rc, nil
}, nil
}

// TODO: Get these methods from a generated client
Expand Down Expand Up @@ -216,15 +207,15 @@ func (c *RESTClient) send(ctx context.Context, method string, values []string, i
return nil, err
}

res, err := c.httpClient.Do(req)
res, err := c.client.Do(req)
if err != nil {
return nil, err
}

if res.StatusCode != http.StatusOK {
return nil, &runtime.HTTPStatusError{
HTTPStatus: res.StatusCode,
Err: err,
Err: errors.New(res.Status),
}
}

Expand Down
Loading

0 comments on commit 10a036e

Please sign in to comment.