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

oxide: refactor exported client API #180

Merged

Conversation

sudomateo
Copy link
Contributor

@sudomateo sudomateo commented Dec 22, 2023

Previously, there were two exported functions to create an Oxide API
client.

  • func NewClient(token, userAgent, host string) (*Client, error)
  • func NewClientFromEnv(userAgent string) (*Client, error)

These two functions required a user agent to be passed as an argument,
which should be an optional argument instead. Additionally, having two
separate functions means a user must switch functions when they wish to
switch to or from using an environment to configure the client.

The code always created a custom http.RoundTripper to be used as the
transport for the underlying HTTP client. The only function of this
custom tranport was to add HTTP headers to the request.

This patch updates the SDK to export a single function to create an
Oxide API client.

  • func NewClient(cfg *Config) (*Client, error)

This new function uses a new Config type to accept optional
configuration for the client. Now, a user can not only build an API
client from their environment, but also override the user agent or HTTP
client used.

The custom transport was removed and the logic to set HTTP headers for
the request was moved into the buildRequest method where it will have
access to the user agent string and the request to set the headers.

Closes: #165, #166

oxide/lib.go Outdated Show resolved Hide resolved
@karencfv
Copy link
Collaborator

karencfv commented Jan 8, 2024

Heya @sudomateo thanks a bunch for taking this on! Sorry for the late reply, I was out for the holidays and just returned. I'll take a good look this week.

Thanks again! 🙇‍♀️

Copy link
Collaborator

@karencfv karencfv left a comment

Choose a reason for hiding this comment

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

Thanks a bunch for working on this! I've left a few comments below.

Could you also add a small entry for the changelog here https://github.com/oxidecomputer/oxide.go/blob/main/.changelog/v0.1.0-beta3.toml? There are some good examples in the file for the last release https://github.com/oxidecomputer/oxide.go/blob/main/.changelog/v0.1.0-beta2.toml

oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib_test.go Show resolved Hide resolved
@sudomateo sudomateo force-pushed the sudomateo/functional-options-client branch 3 times, most recently from cf8dc0f to 37ca32c Compare January 17, 2024 03:01
Copy link
Collaborator

@karencfv karencfv left a comment

Choose a reason for hiding this comment

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

Thanks for addressing my comments @sudomateo, this is looking great!

Just a few things here and there, but overall looks almost ready 🎉

.changelog/v0.1.0-beta3.toml Outdated Show resolved Hide resolved
.changelog/v0.1.0-beta3.toml Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib.go Show resolved Hide resolved
@karencfv
Copy link
Collaborator

Related: #164

@sudomateo sudomateo force-pushed the sudomateo/functional-options-client branch from 37ca32c to 6bb54f5 Compare January 19, 2024 01:38
Previously, there were two exported functions to create an Oxide API
client.

- `func NewClient(token, userAgent, host string) (*Client, error)`
- `func NewClientFromEnv(userAgent string) (*Client, error)`

These two functions required a user agent to be passed as an argument,
which should be an optional argument instead. Additionally, having two
separate functions means a user must switch functions when they wish to
switch to or from using an environment to configure the client.

The code always created a custom `http.RoundTripper` to be used as the
transport for the underlying HTTP client. The only function of this
custom tranport was to add HTTP headers to the request.

This patch updates the SDK to export a single function to create an
Oxide API client.

- `func NewClient(cfg *Config) (*Client, error)`

This new function uses a new `Config` type to accept optional
configuration for the client. Now, a user can not only build an API
client from their environment, but also override the user agent or HTTP
client used.

The custom transport was removed and the logic to set HTTP headers for
the request was moved into the `buildRequest` method where it will have
access to the user agent string and the request to set the headers.

Closes: oxidecomputer#165, oxidecomputer#166
@sudomateo sudomateo force-pushed the sudomateo/functional-options-client branch from 6bb54f5 to df497c1 Compare January 19, 2024 02:05
Copy link
Collaborator

@karencfv karencfv left a comment

Choose a reason for hiding this comment

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

Just a few more bits.

Thanks for bearing with me! 😅

oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib.go Outdated Show resolved Hide resolved
oxide/lib_test.go Outdated Show resolved Hide resolved
oxide/lib_test.go Outdated Show resolved Hide resolved
oxide/lib_test.go Outdated Show resolved Hide resolved
oxide/lib_test.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@karencfv karencfv left a comment

Choose a reason for hiding this comment

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

Thanks for updating the PR!

I ran some manual tests with a little client I built which uses the this branch as a dependency, and I get an authorization error using both a nil config with environment variables and setting the host and token directly through the Config.

$ go run main.go
2024/01/22 16:10:42 GET https://oxide.sys.rack2.eng.oxide.computer/v1/vpc-firewall-rules?vpc=a06093b1-0984-47f9-b895-b7a6304b5d2c
----------- RESPONSE -----------
Status: 401 Unauthorized
Message: credentials missing or invalid
RequestID: 420453ee-242b-4123-b749-f962734c79a8
------- RESPONSE HEADERS -------
Content-Type: [application/json]
X-Request-Id: [420453ee-242b-4123-b749-f962734c79a8]
Date: [Mon, 22 Jan 2024 03:10:41 GMT]
Content-Length: [137]
exit status 1

I confirmed my token and host were valid by running the same code with the current SDK as a dependency.

Additionally, I think I missed this last time around, but I realised you deleted the RoundTrip() method. Could you please revert that change (and any change that is not related to retrieving token and host from the config) please?

http.RoundTripper is an interface, so we need to implement it.

Perhaps it may be a good idea to test functionality of a code change before setting it as ready to review.

oxide/lib.go Outdated Show resolved Hide resolved
When the authorization header was moved to the `buildRequest` function,
the `Bearer` part was left out. That meant the total header was:
Authorization: TOKEN

Instead of:
Authorization: Bearer TOKEN

This commit fixes that.
@sudomateo
Copy link
Contributor Author

I ran some manual tests with a little client I built which uses the this branch as a dependency, and I get an authorization error using both a nil config with environment variables and setting the host and token directly through the Config.

Sorry about that! It's not the http.RoundTripper, but rather the fact that I forgot to add Bearer in the authorization header.

The header should have been:

Authorization: Bearer TOKEN

But the code had it as:

Authorization: TOKEN

I fixed that in my latest commit.

Perhaps it may be a good idea to test functionality of a code change before setting it as ready to review.

Is there a process I could use to test against an Oxide API, mocked or otherwise? I had access to a demo environment but that was spun down and provisioned anew. I'd love to do more testing before marking the pull request ready.

Copy link
Collaborator

@karencfv karencfv left a comment

Choose a reason for hiding this comment

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

Is there a process I could use to test against an Oxide API, mocked or otherwise? I had access to a demo environment but that was spun down and provisioned anew. I'd love to do more testing before marking the pull request ready.

Gargh! sorry about that! At the moment we don't really have any other way of manually testing other than using one of our racks. Don't worry about it, I've tested it myself. All good now .

Thanks a bunch for the PR, and for bearing with me :)

🙇‍♀️

@karencfv karencfv merged commit 172bbb1 into oxidecomputer:main Jan 22, 2024
1 check passed
@sudomateo
Copy link
Contributor Author

Gargh! sorry about that! At the moment we don't really have any other way of manually testing other than using one of our racks. Don't worry about it, I've tested it myself. All good now .

Thanks a bunch for the PR, and for bearing with me :)

🙇‍♀️

It's not a burden at all! I know there was a lot of back and forth, but I really appreciate the reviews and discussions. It helps make the code better for everyone. Plus you get to know the style of the codebase and meet cool people!

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.

userAgent shouldn't be required for creating new client
2 participants