You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(snapshot): add service filtering flags to cloud-run command (#4986)
Slice 4 of the snapshot cloud-run feature. Adds --services,
--services-regex, --exclude, and --exclude-regex, mirroring the ECS
service filtering shape and reusing the existing
filters.ResourceFilterOptions struct. PreRunE rejects the four
include/exclude mutex pairs.
Filtering is applied in the command after cloudrun.ListServices
returns. Services excluded by name still incur their per-revision
API round-trips; pushing the filter into the GCP wrapper to skip
those calls is a tractable follow-up if the round-trip cost becomes
a bottleneck.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: cmd/kosli/root.go
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -176,6 +176,10 @@ The ^.kosli_ignore^ will be treated as part of the artifact like any other file,
176
176
ecsServicesRegexFlag="[optional] The comma-separated list of ECS service name regex patterns to snapshot. Can't be used together with --exclude-services or --exclude-services-regex."
177
177
ecsExcludeServicesFlag="[optional] The comma-separated list of ECS service names to exclude. Can't be used together with --services or --services-regex."
178
178
ecsExcludeServicesRegexFlag="[optional] The comma-separated list of ECS service name regex patterns to exclude. Can't be used together with --services or --services-regex."
179
+
cloudRunServicesFlag="[optional] The comma-separated list of Cloud Run service names to snapshot. Can't be used together with --exclude or --exclude-regex."
180
+
cloudRunServicesRegexFlag="[optional] The comma-separated list of Cloud Run service name regex patterns to snapshot. Can't be used together with --exclude or --exclude-regex."
181
+
cloudRunExcludeFlag="[optional] The comma-separated list of Cloud Run service names to exclude. Can't be used together with --services or --services-regex."
182
+
cloudRunExcludeRegexFlag="[optional] The comma-separated list of Cloud Run service name regex patterns to exclude. Can't be used together with --services or --services-regex."
179
183
kubeconfigFlag="[defaulted] The kubeconfig path for the target cluster."
180
184
namespacesFlag="[optional] The comma separated list of namespaces names to report artifacts info from. Can't be used together with --exclude-namespaces or --exclude-namespaces-regex."
181
185
excludeNamespacesFlag="[optional] The comma separated list of namespaces names to exclude from reporting artifacts info from. Requires cluster-wide read permissions for pods and namespaces. Can't be used together with --namespaces or --namespaces-regex."
goldenRegex: `(?s)THIS IS A DRY-RUN.*report/cloud-run.*"revisionName": "hello-world-rev1".*"service_name": "hello-world".*"project": "proj-x".*"region": "europe-west1".*"gcr.io/x/hello@sha256:abc": "abc"`,
107
+
goldenRegex: `(?s)THIS IS A DRY-RUN.*report/cloud-run.*"service_name": "alpha".*"service_name": "beta"`,
108
+
},
109
+
{
110
+
wantError: true,
111
+
name: "snapshot cloud-run fails if --services and --exclude are set",
112
+
cmd: fmt.Sprintf(`snapshot cloud-run %s --project p --region r --services alpha --exclude beta %s`, suite.envName, suite.defaultKosliArguments),
113
+
golden: "Error: only one of --services, --exclude is allowed\n",
114
+
},
115
+
{
116
+
wantError: true,
117
+
name: "snapshot cloud-run fails if --services and --exclude-regex are set",
118
+
cmd: fmt.Sprintf(`snapshot cloud-run %s --project p --region r --services alpha --exclude-regex "^b" %s`, suite.envName, suite.defaultKosliArguments),
119
+
golden: "Error: only one of --services, --exclude-regex is allowed\n",
120
+
},
121
+
{
122
+
wantError: true,
123
+
name: "snapshot cloud-run fails if --services-regex and --exclude are set",
124
+
cmd: fmt.Sprintf(`snapshot cloud-run %s --project p --region r --services-regex "^a" --exclude beta %s`, suite.envName, suite.defaultKosliArguments),
125
+
golden: "Error: only one of --services-regex, --exclude is allowed\n",
126
+
},
127
+
{
128
+
wantError: true,
129
+
name: "snapshot cloud-run fails if --services-regex and --exclude-regex are set",
130
+
cmd: fmt.Sprintf(`snapshot cloud-run %s --project p --region r --services-regex "^a" --exclude-regex "^b" %s`, suite.envName, suite.defaultKosliArguments),
131
+
golden: "Error: only one of --services-regex, --exclude-regex is allowed\n",
92
132
},
93
133
}
94
134
95
135
runTestCmd(suite.T(), tests)
96
136
}
97
137
138
+
// runFilteredCmd executes the command and returns the combined output for
139
+
// substring assertions. Filter tests need to assert both presence (kept
140
+
// service appears) and absence (excluded service does not appear), so they
141
+
// cannot use the single-assertion cmdTestCase table.
-[x]**Slice 2:** Internal `internal/cloudrun` package — wraps `cloud.google.com/go/run/apiv2` to list services in project+region; unit-tested with a fake. Done 2026-04-28: `Client.ListServices` returns `Service{Name, URI, Revisions}` with one `Revision{Name, Digests, CreatedAt}` per traffic-configured revision (any percent including 0%, with `LATEST` resolved via `LatestReadyRevision` and dupes removed). Digest extraction mirrors the ECS fallback (`@sha256:` parse, else empty string). 9 unit tests passing.
48
48
-[x]**Slice 3:** End-to-end happy path — wire the package into `RunE`, build the snapshot payload, POST to the server `cloud-run` endpoint (still dry-run only). Done 2026-04-28: command now calls `cloudrun.New` + `ListServices`, builds an `EnvRequest` via `ToEnvRequest(services, project, region)`, and submits PUT `report/cloud-run` via `kosliClient.Do` (dry-run forced, so no network call leaves the client). Tested against the real `hello-world-cli-demo` GCP project — emits a digest-pinned artifact for the running `hello-world` service.
-[x]**Slice 4:** Filtering flags — `--services`, `--services-regex`, `--exclude`, `--exclude-regex`. Done 2026-04-28: backed by `filters.ResourceFilterOptions` (same struct ECS uses); 4 mutex pairs validated in `PreRunE`. Filter is applied in the command after `cloudrun.ListServices` returns — services excluded by name still cost their revision-fetch round-trips. If that becomes a bottleneck, push the filter into `cloudrun.ListServices` so excluded services skip the per-revision API calls.
50
50
-[ ]**Slice 5:** Multi-revision / traffic splitting — handle services with multiple active revisions and services with no active revisions.
51
51
-[ ]**Slice 6:** Auth error UX — clear messages for ADC / `GOOGLE_APPLICATION_CREDENTIALS` failures and for missing project/region.
52
52
-[ ]**Slice 7:** Unhide the command, lift the forced dry-run, update CLI reference docs and examples.
0 commit comments