-
Notifications
You must be signed in to change notification settings - Fork 30
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
Add console subcommand #93
base: master
Are you sure you want to change the base?
Conversation
console.go
Outdated
) | ||
|
||
var ( | ||
ErrInvalidTemporaryCredentials = errors.New("Invalid temporary session credentials present, permanent credentials are required.\nPermanent credentials can be used be specifying a vault name") |
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.
This message should probably be tweaked. First, "invalid temporary session credentials present" isn't accurate. It has nothing to do with the validity of the creds, they're simply not capable of invoking the console. Second, I think we can explain the permanent credentials / vault option a little cleaner.
console.go
Outdated
|
||
var ( | ||
ErrInvalidTemporaryCredentials = errors.New("Invalid temporary session credentials present, permanent credentials are required.\nPermanent credentials can be used be specifying a vault name") | ||
ErrInvalidDuration = errors.New("Minimum console duration must be at least 15 min") |
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.
We should either not abbreviate "minutes" or abbreviate it more in line with other messages we post about duration - "15m"
console.go
Outdated
if err != nil { | ||
return nil, nil, err | ||
} | ||
awsCreds, err = awsCreds.GetFederationToken(*fedDuration) |
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.
What if there are no AWS credentials in the vault?
console.go
Outdated
} | ||
} | ||
} else { | ||
tempCreds, err := session.AWSCreds.GetLoadedOrDefaultCreds() |
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.
What happens here if it is unable to load default creds from the environment? Does it error, or does it simply set the values to empty string or nil?
console.go
Outdated
} | ||
|
||
if c.Role != "" { | ||
awsCreds, err = session.AWSCreds.AssumeRole(c.Role, *fedDuration) |
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.
Perhaps we can try to merge some of these checks / assumes? We seem to be repeating certain actions between vault and no-vault, I think we can wrap them a bit cleaner.
console.go
Outdated
return nil, nil, err | ||
} | ||
} else { | ||
awsCreds, err = session.AWSCreds.GetFederationToken(*fedDuration) |
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.
What happens if we were unable to load credentials by this point?
doc/vaulted-console.1.md
Outdated
A role to assume can be specified either in a vault's configuration (via | ||
`vaulted edit`) or specified via the `--assume` option. | ||
|
||
Vaulted first opens the specified vault to retrieve the appropriate credentials. If a role is specified in the vault's configuration it will use that unless a role is explicitely passed in through the `--asume` option. |
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.
Couple typos:
- --assume
- explicitly
lib/aws_credentials.go
Outdated
"fmt" | ||
// "io/ioutil" |
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.
Should this have been removed?
bdf1167
to
bd677cb
Compare
bd677cb
to
f55532f
Compare
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 pretty good! Just a couple nits.
} | ||
|
||
return creds.GetSigninToken(&duration) | ||
|
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: line gap
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.
done
console.go
Outdated
} | ||
|
||
func (c *Console) getSigninToken(store vaulted.Store) (string, error) { | ||
// Setup default values (may be overwritten by values from vault) |
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.
Future work: Perhaps we should allow this to be passed via command line as well?
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.
done
doc/vaulted-console.1.md
Outdated
|
||
Opens the AWS console in the default web browser. Uses either the credentials in the current environment or the credentials in the specified vault. Console sessions either use the provided vault's duration or defaults to 1 hour. | ||
|
||
Durations must be at least 15 min and less than 12 hours. |
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: s/min/minutes
f55532f
to
d34b43f
Compare
command_test.go
Outdated
@@ -445,6 +449,30 @@ var ( | |||
Args: []string{"-V"}, | |||
Command: &Version{}, | |||
}, | |||
// Console |
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.
Do we have any tests for "duration"?
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.
done
console.go
Outdated
} | ||
|
||
// If duration was provided through the command line overwrite with that | ||
if c.Duration != 0 && (c.Duration < 15*time.Minute || c.Duration > 12*time.Hour) { |
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.
Should we be checking if the Duration is valid when we receive the command, rather than in the console handling?
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.
done
console.go
Outdated
) | ||
|
||
const ( | ||
CONSOLE_URL = "https://console.aws.amazon.com/console/home" |
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.
We shouldn't be mixing UPPER_CASE and CamelCase types here.
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.
done
console.go
Outdated
CONSOLE_URL = "https://console.aws.amazon.com/console/home" | ||
SIGNIN_URL = "https://signin.aws.amazon.com/federation" | ||
|
||
MinConsoleDuration = 15 * time.Minute |
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.
These should probably begin with "Console" like the above consts, just to keep a consistent namespace.
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.
done
console.go
Outdated
} | ||
} | ||
|
||
// If duration was provided through the command line overwrite with that |
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.
Also, 15*time.Minute
and 12*time.Hour
should be used as consts when we do these checks.
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.
done
console.go
Outdated
if tokenErr != nil { | ||
return "", tokenErr | ||
} | ||
creds, err = creds.AssumeRoleWithMFA(awsKey.MFA, tokenCode, awsKey.Role, 15*time.Minute) |
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.
15*time.Minute feels like it should be used as a const.
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.
done
console.go
Outdated
} | ||
creds, err = creds.AssumeRoleWithMFA(awsKey.MFA, tokenCode, awsKey.Role, 15*time.Minute) | ||
} else { | ||
creds, err = creds.AssumeRole(awsKey.Role, 15*time.Minute) |
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.
15*time.Minute feels like it should be used as a const.
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.
done
doc/vaulted.1.md
Outdated
@@ -28,6 +28,9 @@ COMMANDS | |||
`add` / `create` / `new` | |||
Interactively creates the content of a new vault. See vaulted-add(1). | |||
|
|||
`console` | |||
Opens the AWS console in the default web browser. See vauled-console(1). |
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.
s/vauled/vaulted
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.
This is still wrong.
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.
done
doc/vaulted-console.1.md
Outdated
DESCRIPTION | ||
----------- | ||
|
||
Opens the AWS console in the default web browser. Uses either the credentials in the current environment or the credentials in the specified vault. Console sessions either use the passed in duration, the provided vault's duration, or defaults to 1 hour. |
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 feel like this description can use a little work. For starters, "uses either the credentials in the current environment or the credentials in the specified vault" doesn't really capture the order of preference.
Second, "Console sessions use" seems unnecessary, given that this is a document on the console command, so the duration is implied to correspond to the console. Additionally, it feels a bit disjointed in how we are going about describing the methods by which a duration is supplied, made worse when we seem to take on the duration range after the rest.
Perhaps we should take a pass on this and see if we can improve the wording a bit?
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.
done
8957a3c
to
08ccf83
Compare
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.
Interesting thing I noticed when I pulled this down to check something - I ran vaulted console
on two different vaults containing credentials for two different AWS accounts. The first attempt worked, the second attempt went to an error page informing me that I was logged into a different account. We should see if this can be rectified, or at least document the case in which this is occurring. In this case I had already closed out of the console window for the other account, so it felt odd.
Also, were you able to apply any further error handling around the case where we receive permission errors?
doc/vaulted.1.md
Outdated
@@ -28,6 +28,9 @@ COMMANDS | |||
`add` / `create` / `new` | |||
Interactively creates the content of a new vault. See vaulted-add(1). | |||
|
|||
`console` | |||
Opens the AWS console in the default web browser. See vauled-console(1). |
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.
This is still wrong.
command_test.go
Outdated
@@ -544,6 +579,11 @@ var ( | |||
Args: []string{"upgrade", "one"}, | |||
}, | |||
|
|||
// Console |
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.
You should alphabetize this with the rest of the commands.
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.
Done
command_test.go
Outdated
@@ -544,6 +579,11 @@ var ( | |||
Args: []string{"upgrade", "one"}, | |||
}, | |||
|
|||
// Console | |||
{ | |||
Args: []string{"Console", "one", "two"}, |
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.
Why is Console capitalized here?
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.
In our fail test cases here we should probably test --duration min/max values outside of the accepted range, like:
Args: []string{"console", "one", "--duration", "14m"},
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.
done
command_test.go
Outdated
Args: []string{"console", "--duration", "15m", "one"}, | ||
Command: &Console{ | ||
VaultName: "one", | ||
Duration: ConsoleMinDuration, |
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.
It feels weird to specify it as "15m" in the args string and "ConsoleMinDuration" in the Command. The above string is meant to represent an entered command, so it seems wrong to then correlate their input to a const duration, particularly if the test isn't explicitly meant to test the ConsoleMinDuration (which, if this is, we need to be testing the ConsoleMaxDuration as well, including testing that values outside of those ranges do not work)
command_test.go
Outdated
@@ -445,6 +449,37 @@ var ( | |||
Args: []string{"-V"}, | |||
Command: &Version{}, | |||
}, | |||
// Console |
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.
We should include this in the command list alphabetically.
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.
done
console.go
Outdated
if err != nil { | ||
if err != credentials.ErrNoValidProvidersFoundInChain { | ||
return nil, err | ||
} else if err == credentials.ErrNoValidProvidersFoundInChain || !awsCreds.Valid() { |
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.
err == credentials.ErrNoValidProvidersFoundInChain ||
is unnecessary, right? We effectively did this check in the above part of the if statement.
Plus, we're never actually checking !awsCreds.Valid()
since we will trigger on the ErrNoValidProvidersFoundInChain piece.
console.go
Outdated
} else if err == credentials.ErrNoValidProvidersFoundInChain || !awsCreds.Valid() { | ||
return nil, ErrNoCredentialsFound | ||
} | ||
} else if awsCreds.ValidSession() { |
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.
The else if
statement here can probably be pulled out of the transition statement and just be checked before return awsCreds, nil
at the end, right?
The above check confirms that the creds are Valid, but does not check if its a session, we should probably always be checking that.
console.go
Outdated
} | ||
|
||
func (c *Console) getSigninToken(store vaulted.Store) (string, error) { | ||
vault, err := c.getVault(store) |
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.
It feels like we really should not be storing and passing on a vault to everything in this function.
It feels like we should be calling OpenVault when necessary and pulling the requisite pieces (Key, Duration, etc) long enough to store those but not holding and sharing the vault with everything else to get their piece from it.
It feels like this level should have some sort of control flow on if c.VaultName != ""
, rather than doing this down in another method.
console.go
Outdated
|
||
awsKey := c.getAWSKey(vault) | ||
|
||
awsCreds, err := c.getCredentials(vault, awsKey) |
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.
awsCreds feels wrong here. iirc You can use AWSKey.Credentials() to get the creds from a key, so we don't need to keep passing them along separately.
duration = ConsoleDefaultDuration | ||
} | ||
|
||
return capDuration(duration) |
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.
Even if we've validated the Duration when we received the command, it still feels like we shouldn't be calling capDuration on the command flag duration. capDuration really only belongs with the Vault duration.
b6f3a18
to
bfb11b8
Compare
bfb11b8
to
a955792
Compare
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.
Drive-by ping, still wish I had this feature sometimes.
vaultName := "" | ||
assume, _ := flag.GetString("assume") | ||
duration, _ := flag.GetDuration("duration") | ||
if duration != 0 && (duration < ConsoleMinDuration || duration > ConsoleMaxDuration) { |
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.
Console*Duration
constants aren't specific to the console, but to the underlying Role. These should probably be named/refactored accordingly.
Vaulted console uses an access key to open an AWS console in the
default browser.