Skip to content

Commit 98436c2

Browse files
tas50claude
andcommitted
✨ Add GCP Backup & DR, Vertex AI, and Cloud Armor enhancements
Add three new GCP service categories and enhance existing Cloud Armor resources: - Backup & DR: management servers, backup vaults, data sources, backup plans - Vertex AI: models, endpoints, pipeline jobs, datasets, feature online stores - Cloud Armor: add fingerprint and userDefinedFields to security policies Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f2644a0 commit 98436c2

File tree

8 files changed

+3630
-3
lines changed

8 files changed

+3630
-3
lines changed

providers/gcp/go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ go 1.25.6
66

77
require (
88
cloud.google.com/go/accessapproval v1.8.8
9+
cloud.google.com/go/aiplatform v1.120.0
910
cloud.google.com/go/alloydb v1.21.0
1011
cloud.google.com/go/artifactregistry v1.20.0
12+
cloud.google.com/go/backupdr v1.8.0
1113
cloud.google.com/go/bigquery v1.74.0
1214
cloud.google.com/go/bigtable v1.42.0
1315
cloud.google.com/go/cloudtasks v1.13.7
@@ -41,7 +43,7 @@ require (
4143
go.mondoo.com/mql/v13 v13.0.0-rc7
4244
go.mondoo.com/ranger-rpc v0.8.0
4345
golang.org/x/oauth2 v0.36.0
44-
google.golang.org/api v0.269.0
46+
google.golang.org/api v0.270.0
4547
google.golang.org/genproto v0.0.0-20260226221140-a57be14db171
4648
google.golang.org/protobuf v1.36.11
4749
)

providers/gcp/go.sum

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
3333
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
3434
cloud.google.com/go/accessapproval v1.8.8 h1:gq8OS+rQWgGRo91D2qztN+ion6AZ2T1CxBIu0ifCmVo=
3535
cloud.google.com/go/accessapproval v1.8.8/go.mod h1:RFwPY9JDKseP4gJrX1BlAVsP5O6kI8NdGlTmaeDefmk=
36+
cloud.google.com/go/aiplatform v1.120.0 h1:jKWTpEs+xoUhDa1FMdSuhMcEQYyUiMdufGyX3zvtLVQ=
37+
cloud.google.com/go/aiplatform v1.120.0/go.mod h1:6mDthfmy0oS1EQhVFdijoxkVdI2+HIZkpuGTBpedeCg=
3638
cloud.google.com/go/alloydb v1.21.0 h1:f8udyaV5PmAKcsTOOsIlgJdLBf4DrO+ML5o/iJvdCLY=
3739
cloud.google.com/go/alloydb v1.21.0/go.mod h1:efq3vWn7CuGn+BHuts4QxyvcAR8qZ0+H+I43ebguhzY=
3840
cloud.google.com/go/artifactregistry v1.20.0 h1:j/XQiQfaeTyQeNj3HNk4iDFREVnY/fxkHIjsxpaDs8A=
@@ -41,6 +43,8 @@ cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM=
4143
cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M=
4244
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
4345
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
46+
cloud.google.com/go/backupdr v1.8.0 h1:J7aSguR1XRhdyBpc2Sa0hWLxH14K3aJrwftYrjhobTw=
47+
cloud.google.com/go/backupdr v1.8.0/go.mod h1:iZd2+yYgMibQGfH+IAlitdUfuFa4aYM/Eruxpj2Tz+0=
4448
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
4549
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
4650
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -1352,8 +1356,8 @@ google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdr
13521356
google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
13531357
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
13541358
google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
1355-
google.golang.org/api v0.269.0 h1:qDrTOxKUQ/P0MveH6a7vZ+DNHxJQjtGm/uvdbdGXCQg=
1356-
google.golang.org/api v0.269.0/go.mod h1:N8Wpcu23Tlccl0zSHEkcAZQKDLdquxK+l9r2LkwAauE=
1359+
google.golang.org/api v0.270.0 h1:4rJZbIuWSTohczG9mG2ukSDdt9qKx4sSSHIydTN26L4=
1360+
google.golang.org/api v0.270.0/go.mod h1:5+H3/8DlXpQWrSz4RjGGwz5HfJAQSEI8Bc6JqQNH77U=
13571361
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
13581362
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
13591363
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
// Copyright (c) Mondoo, Inc.
2+
// SPDX-License-Identifier: BUSL-1.1
3+
4+
package resources
5+
6+
import (
7+
"context"
8+
"errors"
9+
"fmt"
10+
11+
backupdr "cloud.google.com/go/backupdr/apiv1"
12+
"cloud.google.com/go/backupdr/apiv1/backupdrpb"
13+
"go.mondoo.com/mql/v13/llx"
14+
"go.mondoo.com/mql/v13/providers-sdk/v1/plugin"
15+
"go.mondoo.com/mql/v13/providers-sdk/v1/util/convert"
16+
"go.mondoo.com/mql/v13/providers/gcp/connection"
17+
"go.mondoo.com/mql/v13/types"
18+
"google.golang.org/api/iterator"
19+
"google.golang.org/api/option"
20+
)
21+
22+
func (g *mqlGcpProject) backupdr() (*mqlGcpProjectBackupdrService, error) {
23+
if g.Id.Error != nil {
24+
return nil, g.Id.Error
25+
}
26+
res, err := CreateResource(g.MqlRuntime, "gcp.project.backupdrService", map[string]*llx.RawData{
27+
"projectId": llx.StringData(g.Id.Data),
28+
})
29+
if err != nil {
30+
return nil, err
31+
}
32+
return res.(*mqlGcpProjectBackupdrService), nil
33+
}
34+
35+
func initGcpProjectBackupdrService(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) {
36+
if len(args) > 0 {
37+
return args, nil, nil
38+
}
39+
conn, ok := runtime.Connection.(*connection.GcpConnection)
40+
if !ok {
41+
return nil, nil, errors.New("invalid connection provided, it is not a GCP connection")
42+
}
43+
args["projectId"] = llx.StringData(conn.ResourceID())
44+
return args, nil, nil
45+
}
46+
47+
func (g *mqlGcpProjectBackupdrService) id() (string, error) {
48+
if g.ProjectId.Error != nil {
49+
return "", g.ProjectId.Error
50+
}
51+
return fmt.Sprintf("gcp.project/%s/backupdrService", g.ProjectId.Data), nil
52+
}
53+
54+
func (g *mqlGcpProjectBackupdrService) managementServers() ([]any, error) {
55+
if g.ProjectId.Error != nil {
56+
return nil, g.ProjectId.Error
57+
}
58+
projectId := g.ProjectId.Data
59+
60+
conn := g.MqlRuntime.Connection.(*connection.GcpConnection)
61+
creds, err := conn.Credentials(backupdr.DefaultAuthScopes()...)
62+
if err != nil {
63+
return nil, err
64+
}
65+
66+
ctx := context.Background()
67+
client, err := backupdr.NewClient(ctx, option.WithCredentials(creds))
68+
if err != nil {
69+
return nil, err
70+
}
71+
defer client.Close()
72+
73+
it := client.ListManagementServers(ctx, &backupdrpb.ListManagementServersRequest{
74+
Parent: fmt.Sprintf("projects/%s/locations/-", projectId),
75+
})
76+
77+
var res []any
78+
for {
79+
server, err := it.Next()
80+
if err == iterator.Done {
81+
break
82+
}
83+
if err != nil {
84+
return nil, err
85+
}
86+
87+
networks := make([]any, 0, len(server.Networks))
88+
for _, n := range server.Networks {
89+
d, err := protoToDict(n)
90+
if err != nil {
91+
return nil, err
92+
}
93+
networks = append(networks, d)
94+
}
95+
96+
managementUri, err := protoToDict(server.ManagementUri)
97+
if err != nil {
98+
return nil, err
99+
}
100+
101+
mqlServer, err := CreateResource(g.MqlRuntime, "gcp.project.backupdrService.managementServer", map[string]*llx.RawData{
102+
"name": llx.StringData(server.Name),
103+
"description": llx.StringData(server.Description),
104+
"state": llx.StringData(server.State.String()),
105+
"type": llx.StringData(server.Type.String()),
106+
"networks": llx.ArrayData(networks, types.Dict),
107+
"managementUri": llx.DictData(managementUri),
108+
"oauth2ClientId": llx.StringData(server.Oauth2ClientId),
109+
"satisfiesPzs": llx.BoolData(server.GetSatisfiesPzs().GetValue()),
110+
"etag": llx.StringData(server.Etag),
111+
"labels": llx.MapData(convert.MapToInterfaceMap(server.Labels), types.String),
112+
"createdAt": llx.TimeDataPtr(timestampAsTimePtr(server.CreateTime)),
113+
"updatedAt": llx.TimeDataPtr(timestampAsTimePtr(server.UpdateTime)),
114+
})
115+
if err != nil {
116+
return nil, err
117+
}
118+
res = append(res, mqlServer)
119+
}
120+
return res, nil
121+
}
122+
123+
func (g *mqlGcpProjectBackupdrServiceManagementServer) id() (string, error) {
124+
return g.Name.Data, g.Name.Error
125+
}
126+
127+
func (g *mqlGcpProjectBackupdrService) backupVaults() ([]any, error) {
128+
if g.ProjectId.Error != nil {
129+
return nil, g.ProjectId.Error
130+
}
131+
projectId := g.ProjectId.Data
132+
133+
conn := g.MqlRuntime.Connection.(*connection.GcpConnection)
134+
creds, err := conn.Credentials(backupdr.DefaultAuthScopes()...)
135+
if err != nil {
136+
return nil, err
137+
}
138+
139+
ctx := context.Background()
140+
client, err := backupdr.NewClient(ctx, option.WithCredentials(creds))
141+
if err != nil {
142+
return nil, err
143+
}
144+
defer client.Close()
145+
146+
it := client.ListBackupVaults(ctx, &backupdrpb.ListBackupVaultsRequest{
147+
Parent: fmt.Sprintf("projects/%s/locations/-", projectId),
148+
})
149+
150+
var res []any
151+
for {
152+
vault, err := it.Next()
153+
if err == iterator.Done {
154+
break
155+
}
156+
if err != nil {
157+
return nil, err
158+
}
159+
160+
mqlVault, err := CreateResource(g.MqlRuntime, "gcp.project.backupdrService.backupVault", map[string]*llx.RawData{
161+
"name": llx.StringData(vault.Name),
162+
"description": llx.StringData(vault.GetDescription()),
163+
"state": llx.StringData(vault.State.String()),
164+
"backupMinimumEnforcedRetentionDuration": llx.StringData(vault.BackupMinimumEnforcedRetentionDuration.String()),
165+
"deletable": llx.BoolData(vault.GetDeletable()),
166+
"etag": llx.StringData(vault.GetEtag()),
167+
"effectiveTime": llx.TimeDataPtr(timestampAsTimePtr(vault.EffectiveTime)),
168+
"backupCount": llx.IntData(vault.GetBackupCount()),
169+
"serviceAccount": llx.StringData(vault.ServiceAccount),
170+
"totalStoredBytes": llx.IntData(vault.GetTotalStoredBytes()),
171+
"accessRestriction": llx.StringData(vault.AccessRestriction.String()),
172+
"annotations": llx.MapData(convert.MapToInterfaceMap(vault.Annotations), types.String),
173+
"labels": llx.MapData(convert.MapToInterfaceMap(vault.Labels), types.String),
174+
"createdAt": llx.TimeDataPtr(timestampAsTimePtr(vault.CreateTime)),
175+
"updatedAt": llx.TimeDataPtr(timestampAsTimePtr(vault.UpdateTime)),
176+
})
177+
if err != nil {
178+
return nil, err
179+
}
180+
res = append(res, mqlVault)
181+
}
182+
return res, nil
183+
}
184+
185+
func (g *mqlGcpProjectBackupdrServiceBackupVault) id() (string, error) {
186+
return g.Name.Data, g.Name.Error
187+
}
188+
189+
func (g *mqlGcpProjectBackupdrServiceBackupVault) dataSources() ([]any, error) {
190+
if g.Name.Error != nil {
191+
return nil, g.Name.Error
192+
}
193+
vaultName := g.Name.Data
194+
195+
conn := g.MqlRuntime.Connection.(*connection.GcpConnection)
196+
creds, err := conn.Credentials(backupdr.DefaultAuthScopes()...)
197+
if err != nil {
198+
return nil, err
199+
}
200+
201+
ctx := context.Background()
202+
client, err := backupdr.NewClient(ctx, option.WithCredentials(creds))
203+
if err != nil {
204+
return nil, err
205+
}
206+
defer client.Close()
207+
208+
it := client.ListDataSources(ctx, &backupdrpb.ListDataSourcesRequest{
209+
Parent: vaultName,
210+
})
211+
212+
var res []any
213+
for {
214+
ds, err := it.Next()
215+
if err == iterator.Done {
216+
break
217+
}
218+
if err != nil {
219+
return nil, err
220+
}
221+
222+
gcpResource, err := protoToDict(ds.GetDataSourceGcpResource())
223+
if err != nil {
224+
return nil, err
225+
}
226+
backupApplianceApp, err := protoToDict(ds.GetDataSourceBackupApplianceApplication())
227+
if err != nil {
228+
return nil, err
229+
}
230+
231+
mqlDs, err := CreateResource(g.MqlRuntime, "gcp.project.backupdrService.dataSource", map[string]*llx.RawData{
232+
"name": llx.StringData(ds.Name),
233+
"state": llx.StringData(ds.State.String()),
234+
"labels": llx.MapData(convert.MapToInterfaceMap(ds.Labels), types.String),
235+
"dataSourceGcpResource": llx.DictData(gcpResource),
236+
"dataSourceBackupApplianceApplication": llx.DictData(backupApplianceApp),
237+
"totalStoredBytes": llx.IntData(ds.GetTotalStoredBytes()),
238+
"backupCount": llx.IntData(ds.GetBackupCount()),
239+
"etag": llx.StringData(ds.GetEtag()),
240+
"configState": llx.StringData(ds.ConfigState.String()),
241+
"createdAt": llx.TimeDataPtr(timestampAsTimePtr(ds.CreateTime)),
242+
"updatedAt": llx.TimeDataPtr(timestampAsTimePtr(ds.UpdateTime)),
243+
})
244+
if err != nil {
245+
return nil, err
246+
}
247+
res = append(res, mqlDs)
248+
}
249+
return res, nil
250+
}
251+
252+
func (g *mqlGcpProjectBackupdrServiceDataSource) id() (string, error) {
253+
return g.Name.Data, g.Name.Error
254+
}
255+
256+
func (g *mqlGcpProjectBackupdrService) backupPlans() ([]any, error) {
257+
if g.ProjectId.Error != nil {
258+
return nil, g.ProjectId.Error
259+
}
260+
projectId := g.ProjectId.Data
261+
262+
conn := g.MqlRuntime.Connection.(*connection.GcpConnection)
263+
creds, err := conn.Credentials(backupdr.DefaultAuthScopes()...)
264+
if err != nil {
265+
return nil, err
266+
}
267+
268+
ctx := context.Background()
269+
client, err := backupdr.NewClient(ctx, option.WithCredentials(creds))
270+
if err != nil {
271+
return nil, err
272+
}
273+
defer client.Close()
274+
275+
it := client.ListBackupPlans(ctx, &backupdrpb.ListBackupPlansRequest{
276+
Parent: fmt.Sprintf("projects/%s/locations/-", projectId),
277+
})
278+
279+
var res []any
280+
for {
281+
plan, err := it.Next()
282+
if err == iterator.Done {
283+
break
284+
}
285+
if err != nil {
286+
return nil, err
287+
}
288+
289+
backupRules := make([]any, 0, len(plan.BackupRules))
290+
for _, rule := range plan.BackupRules {
291+
d, err := protoToDict(rule)
292+
if err != nil {
293+
return nil, err
294+
}
295+
backupRules = append(backupRules, d)
296+
}
297+
298+
mqlPlan, err := CreateResource(g.MqlRuntime, "gcp.project.backupdrService.backupPlan", map[string]*llx.RawData{
299+
"name": llx.StringData(plan.Name),
300+
"description": llx.StringData(plan.Description),
301+
"state": llx.StringData(plan.State.String()),
302+
"resourceType": llx.StringData(plan.ResourceType),
303+
"backupVault": llx.StringData(plan.BackupVault),
304+
"backupVaultServiceAccount": llx.StringData(plan.BackupVaultServiceAccount),
305+
"labels": llx.MapData(convert.MapToInterfaceMap(plan.Labels), types.String),
306+
"backupRules": llx.ArrayData(backupRules, types.Dict),
307+
"etag": llx.StringData(plan.Etag),
308+
"createdAt": llx.TimeDataPtr(timestampAsTimePtr(plan.CreateTime)),
309+
"updatedAt": llx.TimeDataPtr(timestampAsTimePtr(plan.UpdateTime)),
310+
})
311+
if err != nil {
312+
return nil, err
313+
}
314+
res = append(res, mqlPlan)
315+
}
316+
return res, nil
317+
}
318+
319+
func (g *mqlGcpProjectBackupdrServiceBackupPlan) id() (string, error) {
320+
return g.Name.Data, g.Name.Error
321+
}

providers/gcp/resources/compute.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,6 +2567,15 @@ func (g *mqlGcpProjectComputeService) securityPolicies() ([]any, error) {
25672567
return err
25682568
}
25692569

2570+
userDefinedFields := make([]any, 0, len(policy.UserDefinedFields))
2571+
for _, udf := range policy.UserDefinedFields {
2572+
d, err := convert.JsonToDict(udf)
2573+
if err != nil {
2574+
return err
2575+
}
2576+
userDefinedFields = append(userDefinedFields, d)
2577+
}
2578+
25702579
policyId := strconv.FormatUint(policy.Id, 10)
25712580
mqlPolicy, err := CreateResource(g.MqlRuntime, "gcp.project.computeService.securityPolicy", map[string]*llx.RawData{
25722581
"id": llx.StringData(policyId),
@@ -2578,6 +2587,8 @@ func (g *mqlGcpProjectComputeService) securityPolicies() ([]any, error) {
25782587
"advancedOptionsConfig": llx.DictData(advancedOptionsConfig),
25792588
"ddosProtectionConfig": llx.DictData(ddosProtectionConfig),
25802589
"recaptchaOptionsConfig": llx.DictData(recaptchaOptionsConfig),
2590+
"fingerprint": llx.StringData(policy.Fingerprint),
2591+
"userDefinedFields": llx.ArrayData(userDefinedFields, types.Dict),
25812592
"regionUrl": llx.StringData(policy.Region),
25822593
"selfLink": llx.StringData(policy.SelfLink),
25832594
"createdAt": llx.TimeDataPtr(parseTime(policy.CreationTimestamp)),

0 commit comments

Comments
 (0)