Skip to content

Commit 6b74ec9

Browse files
authored
Improve rest.NewClient error handling. (#218)
We now get better error messages. For example: No credentials: ``` Getting HTTP Client: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information. ``` Credentials, but invalid project: ``` Creating Verifier Client: listing regions in project "confidentialcomputing-e2eee": googleapi: Error 403: Permission denied on resource project confidentialcomputing-e2eee. Details: [ { "@type": "type.googleapis.com/google.rpc.Help", "links": [ { "description": "Google developer console API key", "url": "https://console.developers.google.com/project/confidentialcomputing-e2eee/apiui/credential" } ] }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "googleapis.com", "metadata": { "consumer": "projects/confidentialcomputing-e2eee", "service": "confidentialcomputing.googleapis.com" }, "reason": "CONSUMER_INVALID" } ] , forbidden ``` Credentials, valid project, invalid region: ``` Creating Verifier Client: invalid region "us-central3", avaiable regions are [us-central1]: googleapi: Error 403: Location us-central3 is not found or access is unauthorized., forbidden ``` Creaentials with valid project/region passes: ``` Got Token: |eyJhbGciOiJSUzI1NiIsImtpZCI6IjluRmdNWWVCZ1A2U1N4V19kZGpiQndJSFB2WEVNTGdZQVh2dU1iS1JrV0EiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL3N0cy5nb29nbGVhcGlzLmNvbSIsImV4cCI6MTY1NzE0NjE0NSwiaWF0IjoxNjU3MTM4OTQ1LCJpc3MiOiJodHRwczovL2NvbmZpZGVudGlhbGNvbXB1dGluZy5nb29nbGVhcGlzLmNvbSIsIm5iZiI6MTY1NzEzODk0NSwic3ViIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vY29tcHV0ZS92MS9wcm9qZWN0cy9iaXRsb2NrZXItZGFuY2UtZGVtby96b25lcy91cy13ZXN0Mi1jL2luc3RhbmNlcy91YnUyMCIsInRlZSI6eyJ2ZXJzaW9uIjp7Im1ham9yIjowLCJtaW5vciI6MX0sInBsYXRmb3JtIjp7ImhhcmR3YXJlX3RlY2hub2xvZ3kiOiJBTURfU0VWIn0sImNvbnRhaW5lciI6eyJpbWFnZV9yZWZlcmVuY2UiOiJsYXVuY2hlci5nY3IuaW8vZ29vZ2xlL2RlYmlhbjEwOmxhdGVzdCIsImltYWdlX2RpZ2VzdCI6InNoYTI1NjpmZjE2NGE2NzY2YmQ4YmQyZDdkNWU5NGRiNDE4NjQ2NDI2ZTU4NzJjNjY0YzZhMjcwYzY4OWYwYjFkMjhmODZmIiwicmVzdGFydF9wb2xpY3kiOiJOZXZlciIsImltYWdlX2lkIjoic2hhMjU2OjMwZTM4MDUyNDJlNTAyMjMyM2E5N2Y4YjZkZWVjODRmZTU4MzIwYzNjYzFlNzE3NDI5ZGY3ZjQ3YjViMzE3YmUiLCJlbnYiOnsiRk9PIjoiQkFSIiwiUEFUSCI6Ii91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL2JpbiIsIlNPTUVfTkFNRSI6IlNPTUVfVkFMVUUifSwiYXJncyI6WyItLWZvbyIsImJhciIsImJheiJdfSwiZ2NlIjp7InpvbmUiOiJ1cy13ZXN0Mi1jIiwicHJvamVjdF9pZCI6ImJpdGxvY2tlci1kYW5jZS1kZW1vIiwicHJvamVjdF9udW1iZXIiOjU2NzA0NTA1Mzg3OCwiaW5zdGFuY2VfbmFtZSI6InVidTIwIiwiaW5zdGFuY2VfaWQiOiIyOTk0MDE1NTM3NjgyNTU0NzA5In0sImVtYWlscyI6WyJjeWhhbmlzaEBnb29nbGUuY29tIiwiamVzc2llcWxpdUBnb29nbGUuY29tIl19fQ.EpDSQqR5E9rS6FWsX2CeS2HVfvcITG3vScpyNPV7OSLR7uBFVh6RZTPqOOu5qPRT_Wox2jxRwDTAa8uqQyCwPAJnpJbMSXSD4qkOK72osYVfW-h6nanAsM8pFOYY4xyW9jhqegIopken6yBmhxzvH9sMsslDRbNXRN1OQZ0rhp0Sb3uJNfXRx52ewJepuNSaq-uV4SbqphwnkqkrxgewmgdNYlNFeHhP2krZXqfyWpjeFkQzQzcZf-epoIGAC-DSoPGLZKvXyyDz1vufW7SdB5pmOK0eEADCzeTPyaSN-RJm1hKaWL2YmkvsLwdOaLPystIGqsy8oScZVffB1Z5ESQ| ``` Signed-off-by: Joe Richey <[email protected]>
1 parent abc4da0 commit 6b74ec9

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

launcher/verifier/rest/rest.go

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,32 @@ import (
1111
"github.com/google/go-tpm-tools/launcher/verifier"
1212

1313
v1alpha1 "google.golang.org/api/confidentialcomputing/v1alpha1"
14-
"google.golang.org/api/googleapi"
1514
"google.golang.org/api/option"
1615
)
1716

17+
// BadRegionError indicates that:
18+
// - the requested Region cannot be used with this API
19+
// - other Regions _can_ be used with this API
20+
type BadRegionError struct {
21+
RequestedRegion string
22+
AvailableRegions []string
23+
err error
24+
}
25+
26+
func (e *BadRegionError) Error() string {
27+
return fmt.Sprintf(
28+
"invalid region %q, available regions are [%s]: %v",
29+
e.RequestedRegion, strings.Join(e.AvailableRegions, ", "), e.err,
30+
)
31+
}
32+
33+
func (e *BadRegionError) Unwrap() error {
34+
return e.err
35+
}
36+
1837
// NewClient creates a new REST client which is configured to perform
19-
// attestations in a particular project and region.
38+
// attestations in a particular project and region. Returns a *BadRegionError
39+
// if the requested project is valid, but the region is invalid.
2040
func NewClient(ctx context.Context, projectID string, region string, opts ...option.ClientOption) (verifier.Client, error) {
2141
service, err := v1alpha1.NewService(ctx, opts...)
2242
if err != nil {
@@ -26,27 +46,28 @@ func NewClient(ctx context.Context, projectID string, region string, opts ...opt
2646
projectName := fmt.Sprintf("projects/%s", projectID)
2747
locationName := fmt.Sprintf("%s/locations/%v", projectName, region)
2848

29-
location, err := service.Projects.Locations.Get(locationName).Do()
30-
if err == nil {
49+
location, getErr := service.Projects.Locations.Get(locationName).Do()
50+
if getErr == nil {
3151
return &restClient{service, location}, nil
3252
}
3353

34-
// Check if the error was due to a bad region name
35-
if apiErr, ok := err.(*googleapi.Error); ok && apiErr.Code == 403 {
36-
// In this case, inform the user about the allowed regions
37-
if list, listErr := service.Projects.Locations.List(projectName).Do(); listErr == nil {
38-
locations := make([]string, len(list.Locations))
39-
for i, loc := range list.Locations {
40-
locations[i] = loc.LocationId
41-
}
42-
return nil, fmt.Errorf(
43-
"unable to find region %q, available regions are [%s]: %w",
44-
region, strings.Join(locations, ", "), err,
45-
)
46-
}
54+
// If we can't get the location, try to list the locations. This handles
55+
// situations where the projectID is invalid.
56+
list, listErr := service.Projects.Locations.List(projectName).Do()
57+
if listErr != nil {
58+
return nil, fmt.Errorf("listing regions in project %q: %w", projectID, listErr)
4759
}
4860

49-
return nil, fmt.Errorf("unable to use project %q and region %q: %w", projectID, region, err)
61+
// The project is valid, but can't get the desired region.
62+
regions := make([]string, len(list.Locations))
63+
for i, loc := range list.Locations {
64+
regions[i] = loc.LocationId
65+
}
66+
return nil, &BadRegionError{
67+
RequestedRegion: region,
68+
AvailableRegions: regions,
69+
err: getErr,
70+
}
5071
}
5172

5273
type restClient struct {

0 commit comments

Comments
 (0)