-
Notifications
You must be signed in to change notification settings - Fork 125
feat: added verify method to gcp provider #690
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -321,8 +321,7 @@ func (p *OrganizationProvider) Resources(ctx context.Context) (*schema.Resources | |
| func (p *OrganizationProvider) getAllAssets(ctx context.Context, parent string) (*schema.Resources, error) { | ||
| gologger.Info().Msgf("Starting Asset API discovery for parent: %s", parent) | ||
|
|
||
| // Define asset types that provide IP addresses or DNS names | ||
| assetTypes := []string{ | ||
| var assetTypesGcpListAPI = []string{ | ||
| "compute.googleapis.com/Instance", | ||
| "compute.googleapis.com/GlobalAddress", | ||
| "compute.googleapis.com/Address", | ||
|
|
@@ -337,7 +336,8 @@ func (p *OrganizationProvider) getAllAssets(ctx context.Context, parent string) | |
| "file.googleapis.com/Instance", | ||
| } | ||
|
|
||
| batchResources, err := p.getAssetsForTypes(ctx, parent, assetTypes) | ||
| // Define asset types that provide IP addresses or DNS names | ||
| batchResources, err := p.getAssetsForTypes(ctx, parent, assetTypesGcpListAPI) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
@@ -660,3 +660,78 @@ func (p *OrganizationProvider) extractFilestoreIP(data *structpb.Struct, resourc | |
| resource.PublicIPv4 = ipList.Values[0].GetStringValue() | ||
| } | ||
| } | ||
|
|
||
| // Verify checks if the GCP provider credentials are valid | ||
| func (p *Provider) Verify(ctx context.Context) error { | ||
| if len(p.projects) == 0 { | ||
| return errorutil.New("no accessible GCP projects found with provided credentials") | ||
| } | ||
|
|
||
| // For extra verification, try a minimal API call on one service | ||
| var err error | ||
| for _, project := range p.projects { | ||
| var success bool | ||
| if p.compute != nil { | ||
| if _, err = p.compute.Regions.List(project).Do(); err == nil { | ||
| success = true | ||
| } | ||
| } else if p.dns != nil { | ||
| if _, err = p.dns.ManagedZones.List(project).Do(); err == nil { | ||
| success = true | ||
| } | ||
| } else if p.storage != nil { | ||
| if _, err = p.storage.Buckets.List(project).Do(); err == nil { | ||
| success = true | ||
| } | ||
| } else if p.functions != nil { | ||
| if _, err = p.functions.Projects.Locations.List(project).Do(); err == nil { | ||
| success = true | ||
| } | ||
| } else if p.run != nil { | ||
| if _, err = p.run.Projects.Locations.List(project).Do(); err == nil { | ||
| success = true | ||
| } | ||
| } else if p.gke != nil { | ||
| if _, err = p.gke.Projects.Locations.Clusters.List(project).Do(); err == nil { | ||
| success = true | ||
| } | ||
| } | ||
| // For any one service to be successful, we can return nil | ||
| if success { | ||
| return nil | ||
| } | ||
| } | ||
| if err != nil { | ||
| return errorutil.NewWithErr(err).Msgf("failed to verify GCP services") | ||
| } | ||
| return errorutil.New("no accessible GCP services found with provided credentials") | ||
| } | ||
|
|
||
| func (p *OrganizationProvider) Verify(ctx context.Context) error { | ||
| var assetTypesGcpListAPI = []string{ | ||
| "compute.googleapis.com/Instance", | ||
| "compute.googleapis.com/Address", | ||
| "compute.googleapis.com/ForwardingRule", | ||
| "dns.googleapis.com/ManagedZone", | ||
| "dns.googleapis.com/ResourceRecordSet", | ||
| "storage.googleapis.com/Bucket", | ||
| "run.googleapis.com/Service", | ||
| "cloudfunctions.googleapis.com/CloudFunction", | ||
| "container.googleapis.com/Cluster", | ||
| "tpu.googleapis.com/Node", | ||
| "file.googleapis.com/Instance", | ||
| } | ||
|
|
||
| // For extra verification, try a minimal API call on one service | ||
| iter := p.assetClient.SearchAllResources(ctx, &assetpb.SearchAllResourcesRequest{ | ||
| Scope: "organizations/" + p.organizationID, | ||
| AssetTypes: assetTypesGcpListAPI, | ||
| PageSize: 1, | ||
| }) | ||
|
|
||
| _, err := iter.Next() | ||
| if err != nil && !errors.Is(err, iterator.Done) { | ||
| return errorutil.NewWithErr(err).Msgf("failed to verify GCP Asset API access for organization %s", p.organizationID) | ||
| } | ||
| return nil | ||
| } | ||
|
Comment on lines
+710
to
+737
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Extract duplicated asset types list to avoid maintenance issues. The Extract the asset types list as a package-level variable: // At the package level, after line 57
var assetTypesGcpListAPI = []string{
"compute.googleapis.com/Instance",
"compute.googleapis.com/GlobalAddress",
"compute.googleapis.com/Address",
"compute.googleapis.com/ForwardingRule",
"dns.googleapis.com/ManagedZone",
"dns.googleapis.com/ResourceRecordSet",
"storage.googleapis.com/Bucket",
"run.googleapis.com/Service",
"cloudfunctions.googleapis.com/CloudFunction",
"container.googleapis.com/Cluster",
"tpu.googleapis.com/Node",
"file.googleapis.com/Instance",
}Then update both methods to use this shared variable:
Note: The asset type 🤖 Prompt for AI Agents |
||
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.
Fix error handling to preserve meaningful error messages.
The current implementation only preserves the last error, which might not be the most informative. Consider collecting errors from all attempts to provide better diagnostics.
Apply this diff to improve error handling:
func (p *Provider) Verify(ctx context.Context) error { if len(p.projects) == 0 { return errorutil.New("no accessible GCP projects found with provided credentials") } // For extra verification, try a minimal API call on one service - var err error + var lastErr error for _, project := range p.projects { - var success bool if p.compute != nil { - if _, err = p.compute.Regions.List(project).Do(); err == nil { - success = true + if _, err := p.compute.Regions.List(project).Do(); err == nil { + return nil + } else { + lastErr = err } } else if p.dns != nil { - if _, err = p.dns.ManagedZones.List(project).Do(); err == nil { - success = true + if _, err := p.dns.ManagedZones.List(project).Do(); err == nil { + return nil + } else { + lastErr = err } } else if p.storage != nil { - if _, err = p.storage.Buckets.List(project).Do(); err == nil { - success = true + if _, err := p.storage.Buckets.List(project).Do(); err == nil { + return nil + } else { + lastErr = err } } else if p.functions != nil { - if _, err = p.functions.Projects.Locations.List(project).Do(); err == nil { - success = true + if _, err := p.functions.Projects.Locations.List(project).Do(); err == nil { + return nil + } else { + lastErr = err } } else if p.run != nil { - if _, err = p.run.Projects.Locations.List(project).Do(); err == nil { - success = true + if _, err := p.run.Projects.Locations.List(project).Do(); err == nil { + return nil + } else { + lastErr = err } } else if p.gke != nil { - if _, err = p.gke.Projects.Locations.Clusters.List(project).Do(); err == nil { - success = true + if _, err := p.gke.Projects.Locations.Clusters.List(project).Do(); err == nil { + return nil + } else { + lastErr = err } } - // For any one service to be successful, we can return nil - if success { - return nil - } } - if err != nil { - return errorutil.NewWithErr(err).Msgf("failed to verify GCP services") + if lastErr != nil { + return errorutil.NewWithErr(lastErr).Msgf("failed to verify GCP services") } return errorutil.New("no accessible GCP services found with provided credentials") }📝 Committable suggestion
🤖 Prompt for AI Agents