Skip to content

Commit 4f45fbb

Browse files
committed
fix: add platform_artifact_sbom table
1 parent e055820 commit 4f45fbb

File tree

3 files changed

+212
-0
lines changed

3 files changed

+212
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package opengovernance_client
2+
3+
import (
4+
"context"
5+
"runtime"
6+
7+
steampipesdk "github.com/opengovern/og-util/pkg/steampipe"
8+
9+
es "github.com/opengovern/og-util/pkg/opengovernance-es-sdk"
10+
"github.com/opengovern/opensecurity/pkg/cloudql/sdk/config"
11+
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
12+
)
13+
14+
const (
15+
ArtifactSbomsIndex = "artifact_sbom"
16+
)
17+
18+
type ArtifactSbom struct {
19+
ImageURL string `json:"imageUrl"`
20+
ArtifactID string `json:"artifactId"`
21+
SbomFormat string `json:"sbomFormat"`
22+
Sbom interface{} `json:"sbom"`
23+
}
24+
25+
type ArtifactSbomResult struct {
26+
PlatformID string `json:"platform_id"`
27+
ResourceID string `json:"resource_id"`
28+
ResourceName string `json:"resource_name"`
29+
Description ArtifactSbom `json:"description"`
30+
TaskType string `json:"task_type"`
31+
ResultType string `json:"result_type"`
32+
Metadata map[string]string `json:"metadata"`
33+
DescribedBy string `json:"described_by"`
34+
DescribedAt int64 `json:"described_at"`
35+
}
36+
37+
type ArtifactSbomHit struct {
38+
ID string `json:"_id"`
39+
Score float64 `json:"_score"`
40+
Index string `json:"_index"`
41+
Type string `json:"_type"`
42+
Version int64 `json:"_version,omitempty"`
43+
Source ArtifactSbomResult `json:"_source"`
44+
Sort []any `json:"sort"`
45+
}
46+
47+
type ArtifactSbomHits struct {
48+
Total es.SearchTotal `json:"total"`
49+
Hits []ArtifactSbomHit `json:"hits"`
50+
}
51+
52+
type ArtifactSbomSearchResponse struct {
53+
PitID string `json:"pit_id"`
54+
Hits ArtifactSbomHits `json:"hits"`
55+
}
56+
57+
type ArtifactSbomPaginator struct {
58+
paginator *es.BaseESPaginator
59+
}
60+
61+
func (k Client) NewArtifactSbomPaginator(filters []es.BoolFilter, limit *int64) (ArtifactSbomPaginator, error) {
62+
paginator, err := es.NewPaginator(k.ES.ES(), ArtifactSbomsIndex, filters, limit)
63+
if err != nil {
64+
return ArtifactSbomPaginator{}, err
65+
}
66+
67+
p := ArtifactSbomPaginator{
68+
paginator: paginator,
69+
}
70+
71+
return p, nil
72+
}
73+
74+
func (p ArtifactSbomPaginator) HasNext() bool {
75+
return !p.paginator.Done()
76+
}
77+
78+
func (p ArtifactSbomPaginator) Close(ctx context.Context) error {
79+
return p.paginator.Deallocate(ctx)
80+
}
81+
82+
func (p ArtifactSbomPaginator) NextPage(ctx context.Context) ([]ArtifactSbomResult, error) {
83+
var response ArtifactSbomSearchResponse
84+
err := p.paginator.SearchWithLog(ctx, &response, true)
85+
if err != nil {
86+
return nil, err
87+
}
88+
89+
var values []ArtifactSbomResult
90+
for _, hit := range response.Hits.Hits {
91+
values = append(values, hit.Source)
92+
}
93+
94+
hits := int64(len(response.Hits.Hits))
95+
if hits > 0 {
96+
p.paginator.UpdateState(hits, response.Hits.Hits[hits-1].Sort, response.PitID)
97+
} else {
98+
p.paginator.UpdateState(hits, nil, "")
99+
}
100+
101+
return values, nil
102+
}
103+
104+
var artifactSbomsMapping = map[string]string{
105+
"image_url": "Description.imageUrl",
106+
"artifact_digest": "Description.artifactDigest",
107+
}
108+
109+
func ListArtifactSboms(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (any, error) {
110+
plugin.Logger(ctx).Trace("ListArtifactSboms", d)
111+
runtime.GC()
112+
// create service
113+
cfg := config.GetConfig(d.Connection)
114+
ke, err := config.NewClientCached(cfg, d.ConnectionCache, ctx)
115+
if err != nil {
116+
plugin.Logger(ctx).Error("ListArtifactSboms NewClientCached", "error", err)
117+
return nil, err
118+
}
119+
k := Client{ES: ke}
120+
121+
sc, err := steampipesdk.NewSelfClientCached(ctx, d.ConnectionCache)
122+
if err != nil {
123+
plugin.Logger(ctx).Error("ListArtifactSboms NewSelfClientCached", "error", err)
124+
return nil, err
125+
}
126+
encodedResourceCollectionFilters, err := sc.GetConfigTableValueOrNil(ctx, steampipesdk.OpenGovernanceConfigKeyResourceCollectionFilters)
127+
if err != nil {
128+
plugin.Logger(ctx).Error("ListArtifactSboms GetConfigTableValueOrNil for resource_collection_filters", "error", err)
129+
return nil, err
130+
}
131+
clientType, err := sc.GetConfigTableValueOrNil(ctx, steampipesdk.OpenGovernanceConfigKeyClientType)
132+
if err != nil {
133+
plugin.Logger(ctx).Error("ListLookupResources GetConfigTableValueOrNil for client_type", "error", err)
134+
return nil, err
135+
}
136+
137+
plugin.Logger(ctx).Trace("Columns", d.FetchType)
138+
paginator, err := k.NewArtifactSbomPaginator(
139+
es.BuildFilterWithDefaultFieldName(ctx, d.QueryContext, artifactSbomsMapping,
140+
nil, encodedResourceCollectionFilters, clientType, true),
141+
d.QueryContext.Limit)
142+
if err != nil {
143+
plugin.Logger(ctx).Error("ListArtifactSboms NewArtifactSbomPaginator", "error", err)
144+
return nil, err
145+
}
146+
147+
for paginator.HasNext() {
148+
page, err := paginator.NextPage(ctx)
149+
if err != nil {
150+
plugin.Logger(ctx).Error("ListArtifactSboms NextPage", "error", err)
151+
return nil, err
152+
}
153+
plugin.Logger(ctx).Trace("ListArtifactSboms", "next page")
154+
155+
for _, v := range page {
156+
d.StreamListItem(ctx, v)
157+
}
158+
}
159+
160+
err = paginator.Close(ctx)
161+
if err != nil {
162+
return nil, err
163+
}
164+
165+
return nil, nil
166+
}

pkg/cloudql/tables/plugin.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
2727
"platform_api_benchmark_summary": tablePlatformApiBenchmarkSummary(ctx),
2828
"platform_api_benchmark_controls": tablePlatformApiBenchmarkControls(ctx),
2929
"platform_artifact_vulnerabilities": tablePlatformArtifactVulnerabilities(ctx),
30+
"platform_artifact_sbom": tablePlatformArtifactSboms(ctx),
3031
},
3132
}
3233

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package opengovernance
2+
3+
import (
4+
"context"
5+
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"
6+
7+
og_client "github.com/opengovern/opensecurity/pkg/cloudql/client"
8+
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
9+
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
10+
)
11+
12+
func tablePlatformArtifactSboms(_ context.Context) *plugin.Table {
13+
return &plugin.Table{
14+
Name: "platform_artifact_sbom",
15+
Description: "Platform Artifact SBOMs",
16+
Cache: &plugin.TableCacheOptions{
17+
Enabled: false,
18+
},
19+
List: &plugin.ListConfig{
20+
Hydrate: og_client.ListArtifactSboms,
21+
},
22+
Columns: []*plugin.Column{
23+
{
24+
Name: "image_url",
25+
Transform: transform.FromField("Description.imageUrl"),
26+
Type: proto.ColumnType_STRING,
27+
},
28+
{
29+
Name: "artifact_id",
30+
Transform: transform.FromField("Description.artifactId"),
31+
Type: proto.ColumnType_STRING,
32+
},
33+
{
34+
Name: "sbom_format",
35+
Transform: transform.FromField("Description.sbomFormat"),
36+
Type: proto.ColumnType_STRING,
37+
},
38+
{
39+
Name: "sbom",
40+
Transform: transform.FromField("Description.sbom"),
41+
Type: proto.ColumnType_JSON,
42+
},
43+
},
44+
}
45+
}

0 commit comments

Comments
 (0)