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(bindle push): add basic auth support #407

Merged
merged 7 commits into from
Apr 28, 2022

Conversation

vdice
Copy link
Member

@vdice vdice commented Apr 27, 2022

I see at least two follow-ups if we want to add support for bindle server basic auth across Spin (or, could perhaps be persuaded to tackle one or more in this effort):

1. Adding basic auth config for spin deploy added in 633e0cd
2. Updating the loader crate which still appears to use a No Auth approach (For our current tests, this still works because thus far, bindle server allows anonymous GETs even when running with basic auth). See #411

Thoughts?

Closes #305

@vdice vdice changed the title Feat/bindle basic auth feat(bindle push): add basic auth support Apr 27, 2022
Copy link
Contributor

@itowlson itowlson left a comment

Choose a reason for hiding this comment

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

This looks really nice and clean. Some minor suggestions but nothing blocking.

) -> Result<()> {
let reader = StandaloneRead::new(&path, bindle_id).await?;
reader
.push(client)
.push(&bindle_connection_info.client()?)
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be good to have a context/with_context here - this can help users understand the error

Copy link
Member Author

Choose a reason for hiding this comment

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

@itowlson Are you envisioning something like this?

        .push(
            &bindle_connection_info.client()
            .context(
                format!(
                    "Failed to create a bindle client from provided connection info '{}'",
                    bindle_connection_info.display()
                )
            )?
        )
        .await
        .with_context(|| push_failed_msg(path, &bindle_connection_info.base_url))

(Where, if so, or if on the right track, I'd add a display() function to BindleConnectionInfo for printing)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that sort of thing. Though for readability I would probably pull it out into e.g.

let client = &bci.client().with_context(...);
...
.push(&client)

rather than having the massive with_context block breaking up the flow

Copy link
Member Author

Choose a reason for hiding this comment

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

@itowlson updated in 55c3f95 -- how does this look? Happy to tweak some more...

Copy link
Member Author

Choose a reason for hiding this comment

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

(I thought it best not to print the entire bci struct as it may contain sensitive info like the un/pw values for basic auth)

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks great! Thanks!

Self {
base_url: base_url.into(),
allow_insecure,
token_manager: AnyAuth {
Copy link
Contributor

Choose a reason for hiding this comment

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

The get side currently uses a different idiom for this (mostly because I foolishly reinvented the wheel). Medium term - outside the scope of this PR - we should replace BindleTokenManager on the get side with AnyAuth.

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 Agreed. It sounds like it'll be okay to do this work in a follow-up; I've created #411

#[structopt(
name = BINDLE_HTTP_PASSWORD,
long = "bindle-http-password",
env = BINDLE_HTTP_PASSWORD,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this and BINDLE_HTTP_USER require each other?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, added in bfb7385

let client = crate::create_bindle_client(true, &self.bindle_server_url)?;
let bindle_connection_info = spin_publish::BindleConnectionInfo::new(
&self.bindle_server_url,
// TODO: do we want to add insecure and http user/pw opts for this deploy cmd?
Copy link
Contributor

Choose a reason for hiding this comment

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

It should support the same things bindle push does I think, though could leave out of scope for this PR if you want.

Copy link
Member Author

Choose a reason for hiding this comment

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

This should be straightforward enough to add in this PR, so I'll do so.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added in 633e0cd (cc @michelleN )

@@ -81,10 +87,53 @@ mod integration_tests {
Ok(())
}

#[tokio::test]
async fn test_bindle_roundtrip_basic_auth() -> Result<()> {
// start the Bindle registry.
Copy link
Contributor

Choose a reason for hiding this comment

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

Love how convenient the test setup is here.

@@ -13,6 +13,7 @@ futures = "0.3.14"
itertools = "0.10.3"
mime_guess = { version = "2.0" }
path-absolutize = "3.0.11"
reqwest = "0.11"
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this needed? Not sure why the Bindle client doesn't handle it all for us.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea, not sure... without this, I'm seeing:

$ make build
cargo build --release
   Compiling spin-cli v0.1.0 (/Users/vdice/go/src/github.com/fermyon/spin)
   Compiling spin-publish v0.1.0 (/Users/vdice/go/src/github.com/fermyon/spin/crates/publish)
error[E0433]: failed to resolve: use of undeclared crate or module `reqwest`
  --> crates/publish/src/lib.rs:73:18
   |
73 |         builder: reqwest::RequestBuilder,
   |                  ^^^^^^^ use of undeclared crate or module `reqwest`

error[E0433]: failed to resolve: use of undeclared crate or module `reqwest`
  --> crates/publish/src/lib.rs:74:33
   |
74 |     ) -> bindle::client::Result<reqwest::RequestBuilder> {
   |                                 ^^^^^^^ use of undeclared crate or module `reqwest`

For more information about this error, try `rustc --explain E0433`.
error: could not compile `spin-publish` due to 2 previous errors

But maybe there's another way to go about this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Eh, I guess it's needed then grin - leave it.

#[structopt(
name = BINDLE_HTTP_USER,
long = "bindle-http-user",
env = BINDLE_HTTP_USER,
Copy link
Member

Choose a reason for hiding this comment

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

Not blocking this PR: we should make username and password environment variables consistent across commands. Like spin deploy requires a hippo user name and password and the env vars look a little diff there.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point; updated in 1fe2964

Signed-off-by: Vaughn Dice <vaughn.dice@fermyon.com>
…test

Signed-off-by: Vaughn Dice <vaughn.dice@fermyon.com>
Signed-off-by: Vaughn Dice <vaughn.dice@fermyon.com>
… hippo auth

Signed-off-by: Vaughn Dice <vaughn.dice@fermyon.com>
Signed-off-by: Vaughn Dice <vaughn.dice@fermyon.com>
Copy link
Contributor

@itowlson itowlson left a comment

Choose a reason for hiding this comment

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

LGTM

name = BINDLE_USERNAME,
long = "bindle-username",
env = BINDLE_USERNAME,
requires(BINDLE_PASSWORD)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: can we not write requires = ... for consistency? I thought this worked elsewhere but could be wrong.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh certainly, good call.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated in 6311a2d

Signed-off-by: Vaughn Dice <vaughn.dice@fermyon.com>
Signed-off-by: Vaughn Dice <vaughn.dice@fermyon.com>
@vdice vdice merged commit 469925b into fermyon:main Apr 28, 2022
@vdice vdice deleted the feat/bindle-basic-auth branch April 28, 2022 21:53
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.

bindle push: add basic http auth username/password support
3 participants