Skip to content

Commit

Permalink
feat: new explain commands for debugging and informational purposes (#86
Browse files Browse the repository at this point in the history
)

* feat: account command to show what you are authenticated against and how

* feat: new explain-config and renamed explain-account commands

* docs: adding documentation for new commands and options
  • Loading branch information
ekristen authored Feb 23, 2024
1 parent e9c8f48 commit dd910da
Show file tree
Hide file tree
Showing 8 changed files with 481 additions and 6 deletions.
14 changes: 13 additions & 1 deletion docs/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@

This is not a comprehensive list of options, but rather a list of features that I think are worth highlighting.

## Cloud Control API

`--cloud-control` will allow you to use the Cloud Control API for specific resource types. This is useful if you want to use the Cloud Control API for specific resource types.

## Skip Alias Checks

`--no-alias-check` will skip the check for the AWS account alias. This is useful if you are running in an account that does not have an alias.

## Skip Prompts

`--no-prompt` will skip the prompt to verify you want to run the command. This is useful if you are running in a CI/CD environment.
`--no-prompt` will skip the prompt to verify you want to run the command. This is useful if you are running in a CI/CD environment.
`--prompt-delay` will set the delay before the command runs. This is useful if you want to give yourself time to cancel the command.

## Logging

- `--log-level` will set the log level. This is useful if you want to see more or less information in the logs.
- `--log-caller` will log the caller (aka line number and file). This is useful if you are debugging.
- `--log-disable-color` will disable log coloring. This is useful if you are running in an environment that does not support color.
- `--log-full-timestamp` will force log output to always show full timestamp. This is useful if you want to see the full timestamp in the logs.
105 changes: 103 additions & 2 deletions docs/cli-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ USAGE:
aws-nuke [global options] command [command options]

VERSION:
3.0.0-beta.2
3.0.0-dev

AUTHOR:
Erik Kristensen <[email protected]>

COMMANDS:
run, nuke run nuke against an aws account and remove everything from it
account-details, account list details about the AWS account that the tool is authenticated to
config-details explain the configuration file and the resources that will be nuked
resource-types, list-resources list available resources to nuke
help, h Shows a list of commands or help for one command

Expand Down Expand Up @@ -50,4 +52,103 @@ OPTIONS:
--log-disable-color disable log coloring (default: false)
--log-full-timestamp force log output to always show full timestamp (default: false)
--help, -h show help
```
```

## aws-nuke explain-account

This command shows you details of how you are authenticated to AWS.

```console
NAME:
aws-nuke explain-account - explain the account and authentication method used to authenticate against AWS

USAGE:
aws-nuke explain-account [command options] [arguments...]

DESCRIPTION:
explain the account and authentication method used to authenticate against AWS

OPTIONS:
--config value, -c value path to config file (default: "config.yaml")
--default-region value the default aws region to use when setting up the aws auth session [$AWS_DEFAULT_REGION]
--access-key-id value the aws access key id to use when setting up the aws auth session [$AWS_ACCESS_KEY_ID]
--secret-access-key value the aws secret access key to use when setting up the aws auth session [$AWS_SECRET_ACCESS_KEY]
--session-token value the aws session token to use when setting up the aws auth session, typically used for temporary credentials [$AWS_SESSION_TOKEN]
--profile value the aws profile to use when setting up the aws auth session, typically used for shared credentials files [$AWS_PROFILE]
--assume-role-arn value the role arn to assume using the credentials provided in the profile or statically set [$AWS_ASSUME_ROLE_ARN]
--assume-role-session-name value the session name to provide for the assumed role [$AWS_ASSUME_ROLE_SESSION_NAME]
--assume-role-external-id value the external id to provide for the assumed role [$AWS_ASSUME_ROLE_EXTERNAL_ID]
--log-level value, -l value Log Level (default: "info") [$LOGLEVEL]
--log-caller log the caller (aka line number and file) (default: false)
--log-disable-color disable log coloring (default: false)
--log-full-timestamp force log output to always show full timestamp (default: false)
--help, -h show help
```

### explain-account example output

```console
Overview:
> Account ID: 123456789012
> Account ARN: arn:aws:iam::123456789012:root
> Account UserID: AKIAIOSFODNN7EXAMPLE:root
> Account Alias: no-alias-123456789012
> Default Region: us-east-2
> Enabled Regions: [global ap-south-1 ca-central-1 eu-central-1 us-west-1 us-west-2 eu-north-1 eu-west-3 eu-west-2 eu-west-1 ap-northeast-3 ap-northeast-2 ap-northeast-1 sa-east-1 ap-southeast-1 ap-southeast-2 us-east-1 us-east-2]

Authentication:
> Method: Static Keys
> Access Key ID: AKIAIOSFODNN7EXAMPLE
```

## aws-nuke explain-config

This command will explain the configuration file and the resources that will be nuked for the targeted account.

```console
NAME:
aws-nuke explain-config - explain the configuration file and the resources that will be nuked for an account

USAGE:
aws-nuke explain-config [command options] [arguments...]

DESCRIPTION:
explain the configuration file and the resources that will be nuked for an account that
is defined within the configuration. You may either specific an account using the --account-id flag or
leave it empty to use the default account that can be authenticated against. If you want to see the
resource types that will be nuked, use the --with-resource-types flag. If you want to see the resources
that have filters defined, use the --with-resource-filters flag.

OPTIONS:
--config value, -c value path to config file (default: "config.yaml")
--account-id value the account id to check against the configuration file, if empty, it will use whatever account
can be authenticated against
--with-resource-filters include resource with filters defined in the output (default: false)
--with-resource-types include resource types defined in the output (default: false)
--default-region value the default aws region to use when setting up the aws auth session [$AWS_DEFAULT_REGION]
--access-key-id value the aws access key id to use when setting up the aws auth session [$AWS_ACCESS_KEY_ID]
--secret-access-key value the aws secret access key to use when setting up the aws auth session [$AWS_SECRET_ACCESS_KEY]
--session-token value the aws session token to use when setting up the aws auth session, typically used for temporary credentials [$AWS_SESSION_TOKEN]
--profile value the aws profile to use when setting up the aws auth session, typically used for shared credentials files [$AWS_PROFILE]
--assume-role-arn value the role arn to assume using the credentials provided in the profile or statically set [$AWS_ASSUME_ROLE_ARN]
--assume-role-session-name value the session name to provide for the assumed role [$AWS_ASSUME_ROLE_SESSION_NAME]
--assume-role-external-id value the external id to provide for the assumed role [$AWS_ASSUME_ROLE_EXTERNAL_ID]
--log-level value, -l value Log Level (default: "info") [$LOGLEVEL]
--log-caller log the caller (aka line number and file) (default: false)
--log-disable-color disable log coloring (default: false)
--log-full-timestamp force log output to always show full timestamp (default: false)
--help, -h show help
```

### explain-config example output

```console
Configuration Details

Resource Types: 426
Filter Presets: 2
Resource Filters: 24

Note: use --with-resource-filters to see resources with filters defined
Note: use --with-resource-types to see included resource types that will be nuked
```
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (

"github.com/ekristen/aws-nuke/pkg/common"

_ "github.com/ekristen/aws-nuke/pkg/commands/account"
_ "github.com/ekristen/aws-nuke/pkg/commands/config"
_ "github.com/ekristen/aws-nuke/pkg/commands/list"
_ "github.com/ekristen/aws-nuke/pkg/commands/nuke"

Expand Down
1 change: 0 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ nav:
- Usage: cli-usage.md
- Options: cli-options.md
- Experimental: cli-experimental.md
- Feature Flags: cli-feature-flags.md
- Examples: cli-examples.md
- Config:
- Overview: config.md
Expand Down
14 changes: 14 additions & 0 deletions pkg/awsutil/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type Account struct {
Credentials

id string
arn string
userID string
aliases []string
regions []string
disabledRegions []string
Expand Down Expand Up @@ -92,6 +94,8 @@ func NewAccount(creds Credentials, endpoints config.CustomEndpoints) (*Account,
}

account.id = ptr.ToString(identityOutput.Account)
account.arn = ptr.ToString(identityOutput.Arn)
account.userID = ptr.ToString(identityOutput.UserId)
account.aliases = aliases
account.regions = regions
account.disabledRegions = disabledRegions
Expand All @@ -104,6 +108,16 @@ func (a *Account) ID() string {
return a.id
}

// ARN returns the STS Authenticated ARN for the account
func (a *Account) ARN() string {
return a.arn
}

// UserID returns the authenticated user ID
func (a *Account) UserID() string {
return a.userID
}

// Alias returns the first alias for the account
func (a *Account) Alias() string {
if len(a.aliases) == 0 {
Expand Down
152 changes: 152 additions & 0 deletions pkg/commands/account/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package account

import (
"fmt"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/ekristen/aws-nuke/pkg/awsutil"
"github.com/ekristen/aws-nuke/pkg/config"
libconfig "github.com/ekristen/libnuke/pkg/config"
"github.com/ekristen/libnuke/pkg/registry"
"github.com/sirupsen/logrus"

"github.com/urfave/cli/v2"

"github.com/ekristen/aws-nuke/pkg/commands/global"
"github.com/ekristen/aws-nuke/pkg/commands/nuke"
"github.com/ekristen/aws-nuke/pkg/common"
)

func execute(c *cli.Context) error {
defaultRegion := c.String("default-region")
creds := nuke.ConfigureCreds(c)

if err := creds.Validate(); err != nil {
return err
}

// Parse the user supplied configuration file to pass in part to configure the nuke process.
parsedConfig, err := config.New(libconfig.Options{
Path: c.Path("config"),
Deprecations: registry.GetDeprecatedResourceTypeMapping(),
})
if err != nil {
logrus.Errorf("Failed to parse config file %s", c.Path("config"))
return err
}

// Set the default region for the AWS SDK to use.
if defaultRegion != "" {
awsutil.DefaultRegionID = defaultRegion
switch defaultRegion {
case endpoints.UsEast1RegionID, endpoints.UsEast2RegionID, endpoints.UsWest1RegionID, endpoints.UsWest2RegionID:
awsutil.DefaultAWSPartitionID = endpoints.AwsPartitionID
case endpoints.UsGovEast1RegionID, endpoints.UsGovWest1RegionID:
awsutil.DefaultAWSPartitionID = endpoints.AwsUsGovPartitionID
default:
if parsedConfig.CustomEndpoints.GetRegion(defaultRegion) == nil {
err = fmt.Errorf("the custom region '%s' must be specified in the configuration 'endpoints'", defaultRegion)
logrus.Error(err.Error())
return err
}
}
}

// Create the AWS Account object. This will be used to get the account ID and aliases for the account.
account, err := awsutil.NewAccount(creds, parsedConfig.CustomEndpoints)
if err != nil {
return err
}

fmt.Println("Overview:")
fmt.Println("> Account ID: ", account.ID())
fmt.Println("> Account ARN: ", account.ARN())
fmt.Println("> Account UserID: ", account.UserID())
fmt.Println("> Account Alias: ", account.Alias())
fmt.Println("> Default Region: ", defaultRegion)
fmt.Println("> Enabled Regions: ", account.Regions())

fmt.Println("")
fmt.Println("Authentication:")
if creds.HasKeys() {
fmt.Println("> Method: Static Keys")
fmt.Println("> Access Key ID: ", creds.AccessKeyID)
}
if creds.HasProfile() {
fmt.Println("> Method: Shared Credentials")
fmt.Println("> Profile: ", creds.Profile)
}
if creds.AssumeRoleArn != "" {
fmt.Println("> Method: Assume Role")
fmt.Println("> Role ARN: ", creds.AssumeRoleArn)
if creds.RoleSessionName != "" {
fmt.Println("> Session Name: ", creds.RoleSessionName)
}
if creds.ExternalId != "" {
fmt.Println("> External ID: ", creds.ExternalId)
}
}

return nil
}

func init() {
flags := []cli.Flag{
&cli.PathFlag{
Name: "config",
Aliases: []string{"c"},
Usage: "path to config file",
Value: "config.yaml",
},
&cli.StringFlag{
Name: "default-region",
EnvVars: []string{"AWS_DEFAULT_REGION"},
Usage: "the default aws region to use when setting up the aws auth session",
},
&cli.StringFlag{
Name: "access-key-id",
EnvVars: []string{"AWS_ACCESS_KEY_ID"},
Usage: "the aws access key id to use when setting up the aws auth session",
},
&cli.StringFlag{
Name: "secret-access-key",
EnvVars: []string{"AWS_SECRET_ACCESS_KEY"},
Usage: "the aws secret access key to use when setting up the aws auth session",
},
&cli.StringFlag{
Name: "session-token",
EnvVars: []string{"AWS_SESSION_TOKEN"},
Usage: "the aws session token to use when setting up the aws auth session, typically used for temporary credentials",
},
&cli.StringFlag{
Name: "profile",
EnvVars: []string{"AWS_PROFILE"},
Usage: "the aws profile to use when setting up the aws auth session, typically used for shared credentials files",
},
&cli.StringFlag{
Name: "assume-role-arn",
EnvVars: []string{"AWS_ASSUME_ROLE_ARN"},
Usage: "the role arn to assume using the credentials provided in the profile or statically set",
},
&cli.StringFlag{
Name: "assume-role-session-name",
EnvVars: []string{"AWS_ASSUME_ROLE_SESSION_NAME"},
Usage: "the session name to provide for the assumed role",
},
&cli.StringFlag{
Name: "assume-role-external-id",
EnvVars: []string{"AWS_ASSUME_ROLE_EXTERNAL_ID"},
Usage: "the external id to provide for the assumed role",
},
}

cmd := &cli.Command{
Name: "explain-account",
Usage: "explain the account and authentication method used to authenticate against AWS",
Description: `explain the account and authentication method used to authenticate against AWS`,
Flags: append(flags, global.Flags()...),
Before: global.Before,
Action: execute,
}

common.RegisterCommand(cmd)
}
Loading

0 comments on commit dd910da

Please sign in to comment.