From 619cac068440949a8b3242456b22001a72acdcbd Mon Sep 17 00:00:00 2001 From: artaasadi Date: Wed, 13 Nov 2024 18:22:17 +0100 Subject: [PATCH] fix: add more logs for compliance summarizer --- pkg/compliance/summarizer/job.go | 54 +++----- pkg/compliance/summarizer/types/job_docs.go | 120 ++---------------- .../benchmark_summary.go | 24 ++-- .../opengovernance-client/cost.go | 48 +++---- .../opengovernance-client/finding.go | 2 +- .../opengovernance-client/lookup_resource.go | 44 +++---- ...le_opengovernance_api_benchmark_summary.go | 16 +-- .../table_opengovernance_cost.go | 6 +- .../table_opengovernance_lookup.go | 2 +- 9 files changed, 94 insertions(+), 222 deletions(-) diff --git a/pkg/compliance/summarizer/job.go b/pkg/compliance/summarizer/job.go index f0800af0c..802ef3c2a 100644 --- a/pkg/compliance/summarizer/job.go +++ b/pkg/compliance/summarizer/job.go @@ -5,17 +5,13 @@ import ( "encoding/json" "fmt" "github.com/opengovern/og-util/pkg/api" + es2 "github.com/opengovern/og-util/pkg/es" "github.com/opengovern/og-util/pkg/httpclient" "github.com/opengovern/og-util/pkg/opengovernance-es-sdk" - "strings" - - es2 "github.com/opengovern/og-util/pkg/es" "github.com/opengovern/opengovernance/pkg/compliance/es" types2 "github.com/opengovern/opengovernance/pkg/compliance/summarizer/types" es3 "github.com/opengovern/opengovernance/pkg/describe/es" - inventoryApi "github.com/opengovern/opengovernance/pkg/inventory/api" "github.com/opengovern/opengovernance/pkg/types" - integrationApi "github.com/opengovern/opengovernance/services/integration/api/models" "go.uber.org/zap" ) @@ -65,30 +61,6 @@ func (w *Worker) RunJob(ctx context.Context, j types2.Job) error { }, ResourcesFindings: make(map[string]types.ResourceFinding), ResourcesFindingsIsDone: make(map[string]bool), - - ResourceCollectionCache: map[string]inventoryApi.ResourceCollection{}, - IntegrationCache: map[string]integrationApi.Integration{}, - } - - resourceCollections, err := w.inventoryClient.ListResourceCollections(&httpclient.Context{Ctx: ctx, UserRole: api.AdminRole}) - if err != nil { - w.logger.Error("failed to list resource collections", zap.Error(err)) - return err - } - for _, rc := range resourceCollections { - rc := rc - jd.ResourceCollectionCache[rc.ID] = rc - } - - integrations, err := w.integrationClient.ListIntegrations(&httpclient.Context{Ctx: ctx, UserRole: api.AdminRole}, nil) - if err != nil { - w.logger.Error("failed to list integrations", zap.Error(err)) - return err - } - for _, c := range integrations.Integrations { - c := c - // use provider id instead of opengovernance id because we need that to check resource collections - jd.IntegrationCache[strings.ToLower(c.ProviderID)] = c } for page := 1; paginator.HasNext(); page++ { @@ -116,24 +88,28 @@ func (w *Worker) RunJob(ctx context.Context, j types2.Job) error { for _, f := range page { var resource *es2.LookupResource potentialResources := lookupResourcesMap[f.PlatformResourceID] - for _, r := range potentialResources { - r := r - w.logger.Info("potential resources", zap.Any("potentialResources", potentialResources), - zap.String("f.ResourceType", f.ResourceType), zap.String("r.ResourceType", r.ResourceType)) - if strings.ToLower(r.ResourceType) == strings.ToLower(f.ResourceType) { - resource = &r - break - } - } - + //for _, r := range potentialResources { + // r := r + // w.logger.Info("potential resources", zap.Any("potentialResources", potentialResources), + // zap.String("f.ResourceType", f.ResourceType), zap.String("r.ResourceType", r.ResourceType)) + // if strings.ToLower(r.ResourceType) == strings.ToLower(f.ResourceType) { + // resource = &r + // break + // } + //} + resource = &potentialResources[0] + w.logger.Info("Before adding resource finding", zap.String("platform_resource_id", f.PlatformResourceID), + zap.Any("resource", resource)) jd.AddComplianceResult(w.logger, j, f, resource) } var docs []es2.Doc for resourceIdType, isReady := range jd.ResourcesFindingsIsDone { if !isReady { + w.logger.Info("resource NOT DONE", zap.String("platform_resource_id", resourceIdType)) continue } + w.logger.Info("resource DONE", zap.String("platform_resource_id", resourceIdType)) resourceFinding := jd.SummarizeResourceFinding(w.logger, jd.ResourcesFindings[resourceIdType]) keys, idx := resourceFinding.KeysAndIndex() resourceFinding.EsID = es2.HashOf(keys...) diff --git a/pkg/compliance/summarizer/types/job_docs.go b/pkg/compliance/summarizer/types/job_docs.go index 3bf7fe452..5b26c1429 100644 --- a/pkg/compliance/summarizer/types/job_docs.go +++ b/pkg/compliance/summarizer/types/job_docs.go @@ -1,13 +1,8 @@ package types import ( - "fmt" - "strings" - "github.com/opengovern/og-util/pkg/es" - inventoryApi "github.com/opengovern/opengovernance/pkg/inventory/api" "github.com/opengovern/opengovernance/pkg/types" - integrationApi "github.com/opengovern/opengovernance/services/integration/api/models" "go.uber.org/zap" ) @@ -18,9 +13,6 @@ type JobDocs struct { // these are used to track if the resource finding is done so we can remove it from the map and send it to queue to save memory ResourcesFindingsIsDone map[string]bool `json:"-"` LastResourceIdType string `json:"-"` - // caches, these are not marshalled and only used - ResourceCollectionCache map[string]inventoryApi.ResourceCollection `json:"-"` - IntegrationCache map[string]integrationApi.Integration `json:"-"` } func (jd *JobDocs) AddComplianceResult(logger *zap.Logger, job Job, @@ -53,12 +45,15 @@ func (jd *JobDocs) AddComplianceResult(logger *zap.Logger, job Job, } if jd.LastResourceIdType == "" { - jd.LastResourceIdType = fmt.Sprintf("%s-%s", resource.ResourceType, resource.PlatformID) - } else if jd.LastResourceIdType != fmt.Sprintf("%s-%s", resource.ResourceType, resource.PlatformID) { + jd.LastResourceIdType = resource.PlatformID + } else if jd.LastResourceIdType != resource.PlatformID { jd.ResourcesFindingsIsDone[jd.LastResourceIdType] = true - jd.LastResourceIdType = fmt.Sprintf("%s-%s", resource.ResourceType, resource.PlatformID) + jd.LastResourceIdType = resource.PlatformID } - resourceFinding, ok := jd.ResourcesFindings[fmt.Sprintf("%s-%s", resource.ResourceType, resource.PlatformID)] + + logger.Info("creating the resource finding", zap.String("platform_resource_id", resource.PlatformID), + zap.Any("resource", resource)) + resourceFinding, ok := jd.ResourcesFindings[resource.PlatformID] if !ok { resourceFinding = types.ResourceFinding{ PlatformResourceID: resource.PlatformID, @@ -71,7 +66,7 @@ func (jd *JobDocs) AddComplianceResult(logger *zap.Logger, job Job, JobId: job.ID, EvaluatedAt: job.CreatedAt.UnixMilli(), } - jd.ResourcesFindingsIsDone[fmt.Sprintf("%s-%s", resource.ResourceType, resource.PlatformID)] = false + jd.ResourcesFindingsIsDone[resource.PlatformID] = false } else { resourceFinding.JobId = job.ID resourceFinding.EvaluatedAt = job.CreatedAt.UnixMilli() @@ -84,101 +79,12 @@ func (jd *JobDocs) AddComplianceResult(logger *zap.Logger, job Job, } resourceFinding.ComplianceResults = append(resourceFinding.ComplianceResults, complianceResult) - for rcId, rc := range jd.ResourceCollectionCache { - // check if resource is in this resource collection - isIn := false - for _, filter := range rc.Filters { - found := false - - for _, integrationType := range filter.Connectors { - if strings.ToLower(integrationType) == strings.ToLower(complianceResult.IntegrationType.String()) { - found = true - break - } - } - if !found && len(filter.Connectors) > 0 { - continue - } - - found = false - for _, resourceType := range filter.ResourceTypes { - if strings.ToLower(resourceType) == strings.ToLower(complianceResult.ResourceType) { - found = true - break - } - } - if !found && len(filter.ResourceTypes) > 0 { - continue - } - - found = false - for _, accountId := range filter.AccountIDs { - if integration, ok := jd.IntegrationCache[strings.ToLower(accountId)]; ok { - if strings.ToLower(integration.IntegrationID) == strings.ToLower(complianceResult.IntegrationID) { - found = true - break - } - } - } - if !found && len(filter.AccountIDs) > 0 { - continue - } - - found = false - for k, v := range filter.Tags { - k := strings.ToLower(k) - v := strings.ToLower(v) - - isMatch := false - for _, resourceTag := range resource.Tags { - if strings.ToLower(resourceTag.Key) == k { - if strings.ToLower(resourceTag.Value) == v { - isMatch = true - break - } - } - } - if !isMatch { - found = false - break - } - found = true - } - - if !found && len(filter.Tags) > 0 { - continue - } - - isIn = true - break - } - if !isIn { - continue - } - - resourceFinding.ResourceCollectionMap[rcId] = true - if job.BenchmarkID == complianceResult.BenchmarkID { - benchmarkSummaryRc, ok := jd.BenchmarkSummary.ResourceCollections[rcId] - if !ok { - benchmarkSummaryRc = BenchmarkSummaryResult{ - BenchmarkResult: ResultGroup{ - Result: Result{ - QueryResult: map[types.ComplianceStatus]int{}, - SeverityResult: map[types.ComplianceResultSeverity]int{}, - SecurityScore: 0, - }, - ResourceTypes: map[string]Result{}, - Controls: map[string]ControlResult{}, - }, - Integrations: map[string]ResultGroup{}, - } - } - benchmarkSummaryRc.addComplianceResult(complianceResult) - jd.BenchmarkSummary.ResourceCollections[rcId] = benchmarkSummaryRc - } + if _, ok := jd.ResourcesFindingsIsDone[resource.PlatformID]; !ok { + jd.ResourcesFindingsIsDone[resource.PlatformID] = false } - - jd.ResourcesFindings[fmt.Sprintf("%s-%s", resource.ResourceType, resource.PlatformID)] = resourceFinding + logger.Info("adding the resource finding", zap.String("platform_resource_id", resource.PlatformID), + zap.Any("resource", resource)) + jd.ResourcesFindings[resource.PlatformID] = resourceFinding } func (jd *JobDocs) SummarizeResourceFinding(logger *zap.Logger, resourceFinding types.ResourceFinding) types.ResourceFinding { diff --git a/pkg/steampipe-plugin-opengovernance/opengovernance-client/benchmark_summary.go b/pkg/steampipe-plugin-opengovernance/opengovernance-client/benchmark_summary.go index 66866a278..ec41a6f33 100644 --- a/pkg/steampipe-plugin-opengovernance/opengovernance-client/benchmark_summary.go +++ b/pkg/steampipe-plugin-opengovernance/opengovernance-client/benchmark_summary.go @@ -28,19 +28,19 @@ func GetBenchmarkSummary(ctx context.Context, d *plugin.QueryData, _ *plugin.Hyd if d.Quals["time_at"] != nil { timeAt = utils.GetPointer(d.EqualsQuals["time_at"].GetTimestampValue().AsTime()) } - var connectionIds []string - if d.EqualsQuals["connection_id"] != nil { - q := d.EqualsQuals["connection_id"] + var integrationIds []string + if d.EqualsQuals["integration_id"] != nil { + q := d.EqualsQuals["integration_id"] if q.GetListValue() != nil { for _, v := range q.GetListValue().Values { - connectionIds = append(connectionIds, v.GetStringValue()) + integrationIds = append(integrationIds, v.GetStringValue()) } } else { - connectionIds = []string{d.EqualsQuals["connection_id"].GetStringValue()} + integrationIds = []string{d.EqualsQuals["integration_id"].GetStringValue()} } } - res, err := complianceClient.GetBenchmarkSummary(&httpclient.Context{UserRole: api.AdminRole}, benchmarkId, connectionIds, timeAt) + res, err := complianceClient.GetBenchmarkSummary(&httpclient.Context{UserRole: api.AdminRole}, benchmarkId, integrationIds, timeAt) if err != nil { plugin.Logger(ctx).Error("GetBenchmarkSummary compliance client call failed", "error", err) return nil, err @@ -73,19 +73,19 @@ func ListBenchmarkControls(ctx context.Context, d *plugin.QueryData, _ *plugin.H if d.Quals["time_at"] != nil { timeAt = utils.GetPointer(d.EqualsQuals["time_at"].GetTimestampValue().AsTime()) } - var connectionIds []string - if d.EqualsQuals["connection_id"] != nil { - q := d.EqualsQuals["connection_id"] + var integrationIds []string + if d.EqualsQuals["integration_id"] != nil { + q := d.EqualsQuals["integration_id"] if q.GetListValue() != nil { for _, v := range q.GetListValue().Values { - connectionIds = append(connectionIds, v.GetStringValue()) + integrationIds = append(integrationIds, v.GetStringValue()) } } else { - connectionIds = []string{d.EqualsQuals["connection_id"].GetStringValue()} + integrationIds = []string{d.EqualsQuals["integration_id"].GetStringValue()} } } - apiRes, err := complianceClient.GetBenchmarkControls(&httpclient.Context{UserRole: api.AdminRole}, benchmarkId, connectionIds, timeAt) + apiRes, err := complianceClient.GetBenchmarkControls(&httpclient.Context{UserRole: api.AdminRole}, benchmarkId, integrationIds, timeAt) if err != nil { plugin.Logger(ctx).Error("GetBenchmarkSummary compliance client call failed", "error", err) return nil, err diff --git a/pkg/steampipe-plugin-opengovernance/opengovernance-client/cost.go b/pkg/steampipe-plugin-opengovernance/opengovernance-client/cost.go index ca0a70cef..30ead7a89 100644 --- a/pkg/steampipe-plugin-opengovernance/opengovernance-client/cost.go +++ b/pkg/steampipe-plugin-opengovernance/opengovernance-client/cost.go @@ -133,18 +133,18 @@ func ListCostSummary(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydrate plugin.Logger(ctx).Warn("ListCostSummary: Page", v) for _, connRes := range v.Integrations { row := OpenGovernanceCostTableRow{ - ConnectionID: connRes.IntegrationID, - ConnectionName: connRes.IntegrationName, - Connector: connRes.IntegrationType.String(), - Date: v.Date, - DateEpoch: v.DateEpoch, - Month: v.Month, - Year: v.Year, - MetricID: v.MetricID, - MetricName: v.MetricName, - CostValue: connRes.CostValue, - PeriodStart: time.UnixMilli(v.PeriodStart), - PeriodEnd: time.UnixMilli(v.PeriodEnd), + IntegrationID: connRes.IntegrationID, + IntegrationName: connRes.IntegrationName, + IntegrationType: connRes.IntegrationType.String(), + Date: v.Date, + DateEpoch: v.DateEpoch, + Month: v.Month, + Year: v.Year, + MetricID: v.MetricID, + MetricName: v.MetricName, + CostValue: connRes.CostValue, + PeriodStart: time.UnixMilli(v.PeriodStart), + PeriodEnd: time.UnixMilli(v.PeriodEnd), } d.StreamListItem(ctx, row) } @@ -156,16 +156,16 @@ func ListCostSummary(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydrate } type OpenGovernanceCostTableRow struct { - ConnectionID string `json:"connection_id"` - ConnectionName string `json:"connection_name"` - Connector string `json:"connector"` - Date string `json:"date"` - DateEpoch int64 `json:"date_epoch"` - Month string `json:"month"` - Year string `json:"year"` - MetricID string `json:"metric_id"` - MetricName string `json:"metric_name"` - CostValue float64 `json:"cost_value"` - PeriodStart time.Time `json:"period_start"` - PeriodEnd time.Time `json:"period_end"` + IntegrationID string `json:"integration_id"` + IntegrationName string `json:"integration_name"` + IntegrationType string `json:"integration_type"` + Date string `json:"date"` + DateEpoch int64 `json:"date_epoch"` + Month string `json:"month"` + Year string `json:"year"` + MetricID string `json:"metric_id"` + MetricName string `json:"metric_name"` + CostValue float64 `json:"cost_value"` + PeriodStart time.Time `json:"period_start"` + PeriodEnd time.Time `json:"period_end"` } diff --git a/pkg/steampipe-plugin-opengovernance/opengovernance-client/finding.go b/pkg/steampipe-plugin-opengovernance/opengovernance-client/finding.go index d41c4760d..627e9389a 100644 --- a/pkg/steampipe-plugin-opengovernance/opengovernance-client/finding.go +++ b/pkg/steampipe-plugin-opengovernance/opengovernance-client/finding.go @@ -81,7 +81,7 @@ var listFindingFilters = map[string]string{ "id": "ID", "benchmark_id": "benchmarkID", "policy_id": "policyID", - "connection_id": "connectionID", + "integration_id": "integrationID", "described_at": "describedAt", "evaluated_at": "evaluatedAt", "state_active": "stateActive", diff --git a/pkg/steampipe-plugin-opengovernance/opengovernance-client/lookup_resource.go b/pkg/steampipe-plugin-opengovernance/opengovernance-client/lookup_resource.go index 2b0493b1d..8473fc210 100644 --- a/pkg/steampipe-plugin-opengovernance/opengovernance-client/lookup_resource.go +++ b/pkg/steampipe-plugin-opengovernance/opengovernance-client/lookup_resource.go @@ -2,11 +2,11 @@ package opengovernance_client import ( "context" + "github.com/opengovern/og-util/pkg/integration" steampipesdk "github.com/opengovern/og-util/pkg/steampipe" "runtime" es "github.com/opengovern/og-util/pkg/opengovernance-es-sdk" - "github.com/opengovern/og-util/pkg/source" "github.com/opengovern/opengovernance/pkg/steampipe-plugin-opengovernance/opengovernance-sdk/config" "github.com/turbot/steampipe-plugin-sdk/v5/plugin" ) @@ -21,36 +21,26 @@ type Tag struct { } type LookupResource struct { + // PlatformID is the unique Global ID of the resource inside the platform + PlatformID string `json:"platform_id"` // ResourceID is the globally unique ID of the resource. ResourceID string `json:"resource_id"` - // Name is the name of the resource. - Name string `json:"name"` - // SourceType is the type of the source of the resource, i.e. AWS Cloud, Azure Cloud. - SourceType source.Type `json:"source_type"` + // ResourceName is the name of the resource. + ResourceName string `json:"resource_name"` + // IntegrationType is the type of the integration source of the resource, i.e. AWS Cloud, Azure Cloud. + IntegrationType integration.Type `json:"integration_type"` // ResourceType is the type of the resource. ResourceType string `json:"resource_type"` - // ServiceName is the service of the resource. - ServiceName string `json:"service_name"` - // Category is the category of the resource. - Category string `json:"category"` - // ResourceGroup is the group of resource (Azure only) - ResourceGroup string `json:"resource_group"` - // Location is location/region of the resource - Location string `json:"location"` - // SourceID is aws account id or azure subscription id - SourceID string `json:"source_id"` - // ResourceJobID is the DescribeResourceJob ID that described this resource - ResourceJobID uint `json:"resource_job_id"` - // SourceJobID is the DescribeSourceJob ID that the ResourceJobID was created for - SourceJobID uint `json:"source_job_id"` - // ScheduleJobID - ScheduleJobID uint `json:"schedule_job_id"` - // CreatedAt is when the DescribeSourceJob is created - CreatedAt int64 `json:"created_at"` + // IntegrationID is aws account id or azure subscription id + IntegrationID string `json:"integration_id"` // IsCommon IsCommon bool `json:"is_common"` // Tags - Tags []Tag `json:"tags"` + Tags []Tag `json:"canonical_tags"` + // DescribedBy is the resource describe job id + DescribedBy string `json:"described_by"` + // DescribedAt is when the DescribeSourceJob is created + DescribedAt int64 `json:"described_at"` } type LookupResourceHit struct { @@ -121,9 +111,9 @@ func (p LookupResourcePaginator) NextPage(ctx context.Context) ([]LookupResource } var lookupMapping = map[string]string{ - "connector": "source_type", - "region": "location", - "connection_id": "source_id", + "integration_type": "integration_type", + "region": "location", + "integration_id": "integration_id", } func ListLookupResources(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (any, error) { diff --git a/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_api_benchmark_summary.go b/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_api_benchmark_summary.go index d6872e5d7..f3fb450bd 100644 --- a/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_api_benchmark_summary.go +++ b/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_api_benchmark_summary.go @@ -31,7 +31,7 @@ func tablePlatformApiBenchmarkSummary(_ context.Context) *plugin.Table { Require: plugin.Optional, }, { - Name: "connection_id", + Name: "integration_id", Operators: []string{quals.QualOperatorEqual}, Require: plugin.Optional, }, @@ -46,10 +46,10 @@ func tablePlatformApiBenchmarkSummary(_ context.Context) *plugin.Table { Transform: transform.FromQual("benchmark_id"), }, { - Name: "connection_id", + Name: "integration_id", Type: proto.ColumnType_STRING, - Description: "The connection IDs included in the benchmark summary", - Transform: transform.FromQual("connection_id"), + Description: "The integration IDs included in the benchmark summary", + Transform: transform.FromQual("integration_id"), }, { Name: "time_at", @@ -245,15 +245,15 @@ func tablePlatformApiBenchmarkSummary(_ context.Context) *plugin.Table { Transform: transform.FromField("ResourcesSeverityStatus.None.PassedCount"), }, { - Name: "connections_result_compliance_status_passed_count", + Name: "integrations_result_compliance_status_passed_count", Type: proto.ColumnType_INT, - Description: "The number of checks that passed in the benchmark summary for the connection", + Description: "The number of checks that passed in the benchmark summary for the integration", Transform: transform.FromField("IntegrationsStatus.PassedCount"), }, { - Name: "connections_result_compliance_status_total_count", + Name: "integrations_result_compliance_status_total_count", Type: proto.ColumnType_INT, - Description: "The total number of checks in the benchmark summary for the connection", + Description: "The total number of checks in the benchmark summary for the integration", Transform: transform.FromField("IntegrationsStatus.TotalCount"), }, { diff --git a/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_cost.go b/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_cost.go index 47186c857..dde9415ec 100644 --- a/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_cost.go +++ b/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_cost.go @@ -18,9 +18,9 @@ func tablePlatformCost(_ context.Context) *plugin.Table { Hydrate: og_client.ListCostSummary, }, Columns: []*plugin.Column{ - {Name: "connection_id", Type: proto.ColumnType_STRING}, - {Name: "connection_name", Type: proto.ColumnType_STRING}, - {Name: "connector", Type: proto.ColumnType_STRING}, + {Name: "integration_id", Type: proto.ColumnType_STRING}, + {Name: "integration_name", Type: proto.ColumnType_STRING}, + {Name: "integration_type", Type: proto.ColumnType_STRING}, {Name: "date", Type: proto.ColumnType_STRING}, {Name: "date_epoch", Type: proto.ColumnType_INT}, {Name: "month", Type: proto.ColumnType_STRING}, diff --git a/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_lookup.go b/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_lookup.go index 5d4c41fca..a582f13e2 100644 --- a/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_lookup.go +++ b/pkg/steampipe-plugin-opengovernance/opengovernance/table_opengovernance_lookup.go @@ -19,7 +19,7 @@ func tablePlatformLookup(_ context.Context) *plugin.Table { Hydrate: og_client.ListLookupResources, }, Columns: []*plugin.Column{ - {Name: "platform_id", Type: proto.ColumnType_STRING}, + {Name: "platform_resource_id", Transform: transform.FromField("PlatformId"), Type: proto.ColumnType_STRING}, {Name: "resource_id", Type: proto.ColumnType_STRING}, {Name: "name", Type: proto.ColumnType_STRING}, {Name: "integration_type", Transform: transform.FromField("IntegrationType"), Type: proto.ColumnType_STRING},