@@ -11,12 +11,32 @@ import (
11
11
"github.com/google/go-tpm-tools/launcher/verifier"
12
12
13
13
v1alpha1 "google.golang.org/api/confidentialcomputing/v1alpha1"
14
- "google.golang.org/api/googleapi"
15
14
"google.golang.org/api/option"
16
15
)
17
16
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
+
18
37
// 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.
20
40
func NewClient (ctx context.Context , projectID string , region string , opts ... option.ClientOption ) (verifier.Client , error ) {
21
41
service , err := v1alpha1 .NewService (ctx , opts ... )
22
42
if err != nil {
@@ -26,27 +46,28 @@ func NewClient(ctx context.Context, projectID string, region string, opts ...opt
26
46
projectName := fmt .Sprintf ("projects/%s" , projectID )
27
47
locationName := fmt .Sprintf ("%s/locations/%v" , projectName , region )
28
48
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 {
31
51
return & restClient {service , location }, nil
32
52
}
33
53
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 )
47
59
}
48
60
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
+ }
50
71
}
51
72
52
73
type restClient struct {
0 commit comments