wip: hepc db store
This commit is contained in:
committed by
=Michael Hohn
parent
3e47bd4adb
commit
4140eaafc4
121
pkg/qldbstore/qldbstore_hepc.go
Normal file
121
pkg/qldbstore/qldbstore_hepc.go
Normal 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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user