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: add configurable http client #96

Open
wants to merge 1 commit 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
46 changes: 38 additions & 8 deletions connect/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type Client interface {
LoadStruct(config interface{}) error
}

type httpClient interface {
type HTTClient interface {
Do(req *http.Request) (*http.Response, error)
}

Expand All @@ -67,6 +67,27 @@ const (
envTokenVariable = "OP_CONNECT_TOKEN"
)

type Opts struct {
UserAgent string
Client HTTClient
}

type ClientOptsFn func(opts *Opts)

// WithUserAgent configures the userAgent for the client.
func WithUserAgent(userAgent string) ClientOptsFn {
return func(opts *Opts) {
opts.UserAgent = userAgent
}
}

// WithClient configures the underlying http connection for the client.
func WithClient(client HTTClient) ClientOptsFn {
return func(opts *Opts) {
opts.Client = client
}
}

// NewClientFromEnvironment Returns a Secret Service client assuming that your
// jwt is set in the OP_TOKEN environment variable
func NewClientFromEnvironment() (Client, error) {
Expand All @@ -84,17 +105,26 @@ func NewClientFromEnvironment() (Client, error) {
}

// NewClient Returns a Secret Service client for a given url and jwt
func NewClient(url string, token string) Client {
return NewClientWithUserAgent(url, token, fmt.Sprintf(defaultUserAgent, SDKVersion))
func NewClient(url string, token string, opts ...ClientOptsFn) Client {
return NewClientWithUserAgent(url, token, fmt.Sprintf(defaultUserAgent, SDKVersion), opts...)
}

// NewClientWithUserAgent Returns a Secret Service client for a given url and jwt and identifies with userAgent
func NewClientWithUserAgent(url string, token string, userAgent string) Client {
func NewClientWithUserAgent(url string, token string, userAgent string, opts ...ClientOptsFn) Client {
defaultOpts := &Opts{
UserAgent: userAgent,
Client: http.DefaultClient,
}

for _, opt := range opts {
opt(defaultOpts)
}

if !opentracing.IsGlobalTracerRegistered() {
cfg := jaegerClientConfig.Configuration{}
zipkinPropagator := zipkin.NewZipkinB3HTTPHeaderPropagator()
cfg.InitGlobalTracer(
userAgent,
defaultOpts.UserAgent,
jaegerClientConfig.Injector(opentracing.HTTPHeaders, zipkinPropagator),
jaegerClientConfig.Extractor(opentracing.HTTPHeaders, zipkinPropagator),
jaegerClientConfig.ZipkinSharedRPCSpan(true),
Expand All @@ -105,10 +135,10 @@ func NewClientWithUserAgent(url string, token string, userAgent string) Client {
URL: url,
Token: token,

userAgent: userAgent,
userAgent: defaultOpts.UserAgent,
tracer: opentracing.GlobalTracer(),

client: http.DefaultClient,
client: defaultOpts.Client,
}
}

Expand All @@ -117,7 +147,7 @@ type restClient struct {
Token string
userAgent string
tracer opentracing.Tracer
client httpClient
client HTTClient
}

// GetVaults Get a list of all available vaults
Expand Down
30 changes: 30 additions & 0 deletions connect/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,36 @@ func TestNewClientWithUserAgent(t *testing.T) {

}

type dummyClient struct {
testClient bool
}

func (t *dummyClient) Do(req *http.Request) (*http.Response, error) {
return nil, nil
}

func TestNewClientWithOpts(t *testing.T) {
d := &dummyClient{testClient: true}
client := NewClient(validHost, validToken, WithUserAgent(testUserAgent), WithClient(d))

restClient, ok := client.(*restClient)
if !ok {
t.Log("Unable to cast client to rest client. Was expecting restClient")
t.FailNow()
}

if _, ok := restClient.client.(*dummyClient); !ok {
t.Logf("Expected client to be of type dummyclient, got %T", restClient.client)
t.FailNow()
}

if restClient.userAgent != testUserAgent {
t.Logf("Expected user-agent of %q, got %q", testUserAgent, restClient.userAgent)
t.FailNow()
}

}

func Test_restClient_GetVaults(t *testing.T) {
mockHTTPClient.Dofunc = listVaults
vaults, err := testClient.GetVaults()
Expand Down