-
Notifications
You must be signed in to change notification settings - Fork 28
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: support cloning over SSH via private key auth #170
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an alternative would be to pass in the SSH key as a base64-encoded file (similar to known_hosts) and clean it up after the build completes.
I think this would be a solid first step at least. We can always iterate/add support for other use-cases later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments but mostly are for my own learning 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Mostly nits
func TestCloneRepoSSH(t *testing.T) { | ||
t.Parallel() | ||
|
||
t.Run("AuthSuccess", func(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: maybe I'm missing something but since all of these tests share a basic structure, you could reduce them down to table tests to more clearly express the intent of what each test is doing and what its result should be; the boilerplate impedes readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed in principle; but I'd prefer to do this when I have more test cases from which to abstract.
I've simplifed the logic by removing the need to parse the git URL at all and removing the known_hosts business; if folks need to validate host keys they can simply mount in a known_hosts file and set SSH_KNOWN_HOSTS. |
Bonus points: SSH_AUTH_SOCK also works!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slick! Love the changes, last comment from me
func TestParseGitURL(t *testing.T) { | ||
t.Parallel() | ||
// nolint:paralleltest // t.Setenv for SSH_AUTH_SOCK | ||
func TestSetupRepoAuth(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
options.Logger(codersdk.LogLevelError, "#1: ❌ Failed to connect to SSH agent: %s", err.Error()) | ||
return nil // nothing else we can do | ||
} | ||
if os.Getenv("SSH_KNOWN_HOSTS") == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: If this was moved higher up, we could avoid duplicating it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried doing this, but we need to either return *gitssh.PublicKeys
or *gitssh.PublicKeysCallback
. We can't just assign HostKeyCallback
to transport.AuthMethods
as it's an interface type :(
require.Nil(t, auth) | ||
}) | ||
|
||
t.Run("HTTP/NoAuth", func(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: could avoid prefix if these were nested in an otherwise empty t.Run
. Feel free to disregard if you don't want to do the change. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think one level of nesting is as deep as we need here in the test :-)
Relates to #31
Currently running into issues with testing end-to-end flow.
However, I've tested with a private git repo:
One potential issue for which I don't have a solution is that passing an SSH key in as a volume will result in the file being available in the resulting workspace. This may not be desirable; an alternative would be to pass in the SSH key as a base64-encoded file (similar to known_hosts) and clean it up after the build completes.
After this is merged, I'd like to do a follow-up PR to refactor some of the envbuilder setup code.