-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: only run against enabled apis, add explain-project command
- Loading branch information
Showing
31 changed files
with
315 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package project | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/urfave/cli/v2" | ||
|
||
"github.com/ekristen/gcp-nuke/pkg/commands/global" | ||
"github.com/ekristen/gcp-nuke/pkg/common" | ||
"github.com/ekristen/gcp-nuke/pkg/gcputil" | ||
) | ||
|
||
type CredentialsJSON struct { | ||
Type string `json:"type"` | ||
ProjectID string `json:"project_id"` | ||
PrivateKeyID string `json:"private_key_id"` | ||
ClientEmail string `json:"client_email"` | ||
ClientID string `json:"client_id"` | ||
Audience string `json:"audience"` | ||
SubjectTokenType string `json:"subject_token_type"` | ||
TokenURL string `json:"token_url"` | ||
ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"` | ||
CredentialSource struct { | ||
File string `json:"file"` | ||
Format struct { | ||
Type string `json:"type"` | ||
} `json:"format"` | ||
} `json:"credential_source"` | ||
} | ||
|
||
func execute(c *cli.Context) error { | ||
project, err := gcputil.New(c.Context, c.String("project-id"), c.String("impersonate-service-account")) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println("Details") | ||
fmt.Println("--------------------------------------------------") | ||
fmt.Println(" Project ID:", project.ID()) | ||
fmt.Printf(" Enabled APIs: %d\n", len(project.GetEnabledAPIs())) | ||
fmt.Printf(" Regions: %d\n", len(project.Regions)) | ||
|
||
creds, err := project.GetCredentials(c.Context) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var parsed CredentialsJSON | ||
if err := json.Unmarshal(creds.JSON, &parsed); err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println("") | ||
fmt.Println("Authentication:") | ||
fmt.Println("--------------------------------------------------") | ||
fmt.Println("> Type:", parsed.Type) | ||
|
||
if parsed.Type == "service_account" { | ||
fmt.Println("> Client Email:", parsed.ClientEmail) | ||
fmt.Println("> Client ID:", parsed.ClientID) | ||
fmt.Println("> Private Key ID:", parsed.PrivateKeyID) | ||
} else if parsed.Type == "external_account" { | ||
fmt.Println("> Audience:", parsed.Audience) | ||
fmt.Println("> Service Account:", | ||
strings.Replace( | ||
parsed.ServiceAccountImpersonationURL, | ||
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/", "", -1)) | ||
fmt.Println("> Source.File:", parsed.CredentialSource.File) | ||
fmt.Println("> Source.Format:", parsed.CredentialSource.Format.Type) | ||
if c.String("impersonate-service-account") != "" { | ||
fmt.Println("> Impersonating:", c.String("impersonate-service-account")) | ||
} | ||
} | ||
|
||
if c.Bool("with-regions") { | ||
fmt.Println("") | ||
fmt.Println("Regions:") | ||
fmt.Println("--------------------------------------------------") | ||
for _, region := range project.Regions { | ||
fmt.Println("-", region) | ||
} | ||
} else { | ||
fmt.Println("") | ||
fmt.Println("Regions: use --with-regions to include regions in the output") | ||
} | ||
|
||
if c.Bool("with-apis") { | ||
fmt.Println("") | ||
fmt.Println("Enabled APIs:") | ||
fmt.Println("--------------------------------------------------") | ||
fmt.Println("**Note:** any resource that matches an API that is not enabled will be automatically skipped") | ||
fmt.Println("") | ||
for _, api := range project.GetEnabledAPIs() { | ||
fmt.Println("-", api) | ||
} | ||
} else { | ||
fmt.Println("") | ||
fmt.Println("Enabled APIs: use --with-apis to include enabled APIs in the output") | ||
} | ||
|
||
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: "project-id", | ||
Usage: "which GCP project should be nuked", | ||
EnvVars: []string{"GCP_NUKE_PROJECT_ID"}, | ||
Required: true, | ||
}, | ||
&cli.StringFlag{ | ||
Name: "impersonate-service-account", | ||
Usage: "impersonate a service account for all API calls", | ||
EnvVars: []string{"GCP_NUKE_IMPERSONATE_SERVICE_ACCOUNT"}, | ||
}, | ||
&cli.BoolFlag{ | ||
Name: "with-regions", | ||
Usage: "include regions in the output", | ||
}, | ||
&cli.BoolFlag{ | ||
Name: "with-apis", | ||
Usage: "include enabled APIs in the output", | ||
}, | ||
} | ||
|
||
cmd := &cli.Command{ | ||
Name: "explain-project", | ||
Usage: "explain the project and authentication method used to authenticate against GCP", | ||
Description: `explain the project and authentication method used to authenticate against GCP`, | ||
Flags: append(flags, global.Flags()...), | ||
Before: global.Before, | ||
Action: execute, | ||
} | ||
|
||
common.RegisterCommand(cmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,54 @@ | ||
package nuke | ||
|
||
import ( | ||
"fmt" | ||
liberror "github.com/ekristen/libnuke/pkg/errors" | ||
"github.com/sirupsen/logrus" | ||
"google.golang.org/api/option" | ||
"slices" | ||
|
||
"github.com/ekristen/libnuke/pkg/registry" | ||
) | ||
|
||
type Geography string | ||
|
||
const ( | ||
Workspace registry.Scope = "workspace" | ||
Organization registry.Scope = "organization" | ||
Project registry.Scope = "project" | ||
|
||
Global Geography = "global" | ||
Regional Geography = "regional" | ||
Zonal Geography = "zonal" | ||
) | ||
|
||
type ListerOpts struct { | ||
Project *string | ||
Region *string | ||
Zones []string | ||
EnabledAPIs []string | ||
ClientOptions []option.ClientOption | ||
} | ||
|
||
func (o *ListerOpts) BeforeList(geo Geography, service string) error { | ||
log := logrus.WithField("geo", geo). | ||
WithField("service", service). | ||
WithField("hooke", "true") | ||
|
||
if geo == Global && *o.Region != "global" { | ||
log.Trace("before-list: skipping resource, global") | ||
return liberror.ErrSkipRequest("resource is global") | ||
} else if geo == Regional && *o.Region == "global" { | ||
log.Trace("before-list: skipping resource, regional") | ||
return liberror.ErrSkipRequest("resource is regional") | ||
} | ||
|
||
if !slices.Contains(o.EnabledAPIs, service) { | ||
log.Trace("before-list: skipping resource, api not enabled") | ||
return liberror.ErrSkipRequest(fmt.Sprintf("api '%s' not enabled", service)) | ||
} | ||
|
||
log.Trace("before-list: called") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.