wip: hepc db store

This commit is contained in:
Michael Hohn
2025-01-21 21:48:25 -08:00
committed by =Michael Hohn
parent 3e47bd4adb
commit 4140eaafc4

View File

@@ -0,0 +1,121 @@
package qldbstore
import (
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/hohn/mrvacommander/pkg/common"
)
type HepcStore struct {
Endpoint string
}
type HepcResult struct {
GitBranch string `json:"git_branch"`
GitCommitID string `json:"git_commit_id"`
GitRepo string `json:"git_repo"`
IngestionDatetime string `json:"ingestion_datetime_utc"`
ResultURL string `json:"result_url"`
ToolID string `json:"tool_id"`
ToolName string `json:"tool_name"`
ToolVersion string `json:"tool_version"`
Projname string `json:"projname"`
}
func NewHepcStore(endpoint string) *HepcStore {
return &HepcStore{Endpoint: endpoint}
}
func (h *HepcStore) FindAvailableDBs(analysisReposRequested []common.NameWithOwner) (
notFoundRepos []common.NameWithOwner,
foundRepos []common.NameWithOwner) {
// Fetch the metadata.json from the Hepc server
url := fmt.Sprintf("%s/index", h.Endpoint)
resp, err := http.Get(url)
if err != nil {
fmt.Printf("Error fetching metadata: %v\n", err)
return analysisReposRequested, nil
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Printf("Non-OK HTTP status: %s\n", resp.Status)
return analysisReposRequested, nil
}
// Decode the response
var results []HepcResult
decoder := json.NewDecoder(resp.Body)
for {
var result HepcResult
if err := decoder.Decode(&result); err == io.EOF {
break
} else if err != nil {
fmt.Printf("Error decoding JSON: %v\n", err)
return analysisReposRequested, nil
}
results = append(results, result)
}
// Compare against requested repos
repoSet := make(map[string]struct{})
for _, result := range results {
repoSet[result.Projname] = struct{}{}
}
for _, reqRepo := range analysisReposRequested {
repoKey := fmt.Sprintf("%s/%s", reqRepo.Owner, reqRepo.Repo)
if _, exists := repoSet[repoKey]; exists {
foundRepos = append(foundRepos, reqRepo)
} else {
notFoundRepos = append(notFoundRepos, reqRepo)
}
}
return notFoundRepos, foundRepos
}
func (h *HepcStore) GetDatabase(location common.NameWithOwner) ([]byte, error) {
// Fetch the latest results for the specified repository
url := fmt.Sprintf("%s/api/v1/latest_results/codeql-all", h.Endpoint)
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("error fetching database metadata: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("non-OK HTTP status: %s", resp.Status)
}
var latestResults []HepcResult
decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(&latestResults); err != nil {
return nil, fmt.Errorf("error decoding JSON: %w", err)
}
// Find the correct result for the requested repo
repoKey := fmt.Sprintf("%s/%s", location.Owner, location.Repo)
for _, result := range latestResults {
if result.Projname == repoKey {
// Fetch the database as a byte slice
dbResp, err := http.Get(result.ResultURL)
if err != nil {
return nil, fmt.Errorf("error fetching database: %w", err)
}
defer dbResp.Body.Close()
if dbResp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("non-OK HTTP status for database fetch: %s", dbResp.Status)
}
return io.ReadAll(dbResp.Body)
}
}
return nil, fmt.Errorf("database not found for repository: %s", repoKey)
}