Skip to content

Commit 31cf076

Browse files
committed
fix(gcp): add missing SQLAdmin and logging replay endpoints
1 parent d00ec4c commit 31cf076

1 file changed

Lines changed: 44 additions & 6 deletions

File tree

pkg/providers/gcp/replay/transport.go

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -702,19 +702,57 @@ func (t *transport) handleDNS(req *http.Request) (*http.Response, error) {
702702
fmt.Sprintf("unsupported dns path: %s", path)), nil
703703
}
704704

705+
// handleLogging routes Cloud Logging requests. Cloudlist `log` asset uses
706+
// `GET /v2/projects/{p}/logs` to enumerate log names; `event-check` uses
707+
// `POST /v2/entries:list` to read recent audit entries.
705708
func (t *transport) handleLogging(req *http.Request, _ []byte) (*http.Response, error) {
706-
if req.Method != http.MethodPost || !strings.HasSuffix(req.URL.Path, "/v2/entries:list") {
707-
return apiErrorResponse(req, http.StatusNotFound, "NOT_FOUND",
708-
fmt.Sprintf("unsupported logging path: %s %s", req.Method, req.URL.Path)), nil
709+
path := req.URL.Path
710+
switch {
711+
case req.Method == http.MethodPost && strings.HasSuffix(path, "/v2/entries:list"):
712+
resp := api.ListLogEntriesResponse{Entries: demoCloudAuditLogEntries()}
713+
return demoreplay.JSONResponse(req, http.StatusOK, resp), nil
714+
case req.Method == http.MethodGet && strings.HasSuffix(path, "/logs") && strings.Contains(path, "/v2/projects/"):
715+
project := extractLoggingProject(path)
716+
if project != "" && project != demoProjectID {
717+
return apiErrorResponse(req, http.StatusNotFound, "NOT_FOUND",
718+
fmt.Sprintf("project %s not visible to current credentials", project)), nil
719+
}
720+
resp := api.ListLogsResponse{LogNames: demoLogNames(demoProjectID)}
721+
return demoreplay.JSONResponse(req, http.StatusOK, resp), nil
722+
}
723+
return apiErrorResponse(req, http.StatusNotFound, "NOT_FOUND",
724+
fmt.Sprintf("unsupported logging path: %s %s", req.Method, req.URL.Path)), nil
725+
}
726+
727+
// extractLoggingProject parses `/v2/projects/{project}/logs`.
728+
func extractLoggingProject(path string) string {
729+
const prefix = "/v2/projects/"
730+
idx := strings.Index(path, prefix)
731+
if idx < 0 {
732+
return ""
733+
}
734+
rest := path[idx+len(prefix):]
735+
end := strings.Index(rest, "/")
736+
if end < 0 {
737+
return rest
738+
}
739+
return rest[:end]
740+
}
741+
742+
func demoLogNames(project string) []string {
743+
return []string{
744+
fmt.Sprintf("projects/%s/logs/cloudaudit.googleapis.com%%2Factivity", project),
745+
fmt.Sprintf("projects/%s/logs/cloudaudit.googleapis.com%%2Fdata_access", project),
746+
fmt.Sprintf("projects/%s/logs/run.googleapis.com%%2Fstdout", project),
709747
}
710-
resp := api.ListLogEntriesResponse{Entries: demoCloudAuditLogEntries()}
711-
return demoreplay.JSONResponse(req, http.StatusOK, resp), nil
712748
}
713749

714750
func (t *transport) handleSQLAdmin(req *http.Request, _ []byte) (*http.Response, error) {
715751
path := strings.TrimSuffix(req.URL.Path, "/")
716752
parts := strings.Split(strings.TrimPrefix(path, "/sql/v1beta4/"), "/")
717-
if len(parts) < 4 || parts[0] != "projects" || parts[2] != "instances" {
753+
// Minimum well-formed sqladmin path is `projects/{p}/instances` (3 parts).
754+
// Deeper paths (`.../instances/{id}/users[...]`) are validated below.
755+
if len(parts) < 3 || parts[0] != "projects" || parts[2] != "instances" {
718756
return apiErrorResponse(req, http.StatusBadRequest, "INVALID_ARGUMENT",
719757
"malformed sqladmin path"), nil
720758
}

0 commit comments

Comments
 (0)