Integrate extraction artifacts into analysis catalog
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
const (
|
||||
ArtifactProvenanceGeneratedCurrentAnalyzeRun = "generated.current_analyze_run"
|
||||
ArtifactProvenanceDisabledFromDisk = "filesystem.disabled_artifact_output"
|
||||
ArtifactProvenanceCurrentExtractManifest = "manifest.current_extract_run"
|
||||
)
|
||||
|
||||
// ConfiguredArtifactDefinition describes one configured analyze artifact.
|
||||
@@ -19,10 +20,21 @@ type ConfiguredArtifactDefinition struct {
|
||||
OutputPath string
|
||||
}
|
||||
|
||||
// ExtractionArtifactDefinition describes one configured Notarius output lane.
|
||||
type ExtractionArtifactDefinition struct {
|
||||
LaneID string
|
||||
PipelineID string
|
||||
MediaType string
|
||||
SchemaID string
|
||||
SchemaVersion string
|
||||
ModuleKey string
|
||||
}
|
||||
|
||||
// CatalogEntry is one runtime catalog entry resolved by source ID.
|
||||
type CatalogEntry struct {
|
||||
SourceID string
|
||||
ConfiguredKey string
|
||||
ExtractionKey string
|
||||
CanonicalRelPath string
|
||||
ProducerStage string
|
||||
OutputKind string
|
||||
@@ -31,12 +43,14 @@ type CatalogEntry struct {
|
||||
Available bool
|
||||
Path string
|
||||
Provenance string
|
||||
ProducerRunID string
|
||||
}
|
||||
|
||||
// ArtifactCatalog tracks built-in and configured artifact definitions and runtime state.
|
||||
// ArtifactCatalog tracks built-in, configured, and extraction artifact definitions and runtime state.
|
||||
type ArtifactCatalog struct {
|
||||
entries map[string]CatalogEntry
|
||||
configuredIndex map[string]string
|
||||
extractionIndex map[string]string
|
||||
}
|
||||
|
||||
// NewArtifactCatalog returns an empty runtime artifact catalog.
|
||||
@@ -44,9 +58,41 @@ func NewArtifactCatalog() *ArtifactCatalog {
|
||||
return &ArtifactCatalog{
|
||||
entries: map[string]CatalogEntry{},
|
||||
configuredIndex: map[string]string{},
|
||||
extractionIndex: map[string]string{},
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterExtractionArtifacts registers the configured Notarius output lanes.
|
||||
func (c *ArtifactCatalog) RegisterExtractionArtifacts(configured map[string]ExtractionArtifactDefinition) error {
|
||||
keys := make([]string, 0, len(configured))
|
||||
for key := range configured {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, key := range keys {
|
||||
trimmed := strings.TrimSpace(key)
|
||||
if trimmed == "" {
|
||||
return fmt.Errorf("extraction artifact keys must be non-empty")
|
||||
}
|
||||
if _, exists := c.extractionIndex[trimmed]; exists {
|
||||
return fmt.Errorf("duplicate extraction artifact key %q", trimmed)
|
||||
}
|
||||
sourceID := ExtractionArtifactSourceID(trimmed)
|
||||
if err := c.addEntry(CatalogEntry{
|
||||
SourceID: sourceID,
|
||||
ExtractionKey: trimmed,
|
||||
ProducerStage: "extract",
|
||||
OutputKind: "notarius_lane",
|
||||
Planned: true,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("register extraction artifact %q: %w", trimmed, err)
|
||||
}
|
||||
c.extractionIndex[trimmed] = sourceID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ConfiguredArtifactSourceID converts a configured artifact key into canonical source ID.
|
||||
func ConfiguredArtifactSourceID(key string) string {
|
||||
return artifactpolicy.ConfiguredSourceID(key)
|
||||
@@ -151,6 +197,15 @@ func (c *ArtifactCatalog) SourceIDForConfiguredKey(key string) (string, bool) {
|
||||
return sourceID, ok
|
||||
}
|
||||
|
||||
// SourceIDForExtractionKey returns the canonical source ID for one Notarius output key.
|
||||
func (c *ArtifactCatalog) SourceIDForExtractionKey(key string) (string, bool) {
|
||||
if c == nil {
|
||||
return "", false
|
||||
}
|
||||
sourceID, ok := c.extractionIndex[strings.TrimSpace(key)]
|
||||
return sourceID, ok
|
||||
}
|
||||
|
||||
// ListConfigured returns configured entries sorted by configured key.
|
||||
func (c *ArtifactCatalog) ListConfigured() []CatalogEntry {
|
||||
if c == nil || len(c.configuredIndex) == 0 {
|
||||
@@ -169,6 +224,23 @@ func (c *ArtifactCatalog) ListConfigured() []CatalogEntry {
|
||||
return out
|
||||
}
|
||||
|
||||
// ListExtraction returns extraction entries sorted by configured output key.
|
||||
func (c *ArtifactCatalog) ListExtraction() []CatalogEntry {
|
||||
if c == nil || len(c.extractionIndex) == 0 {
|
||||
return nil
|
||||
}
|
||||
keys := make([]string, 0, len(c.extractionIndex))
|
||||
for key := range c.extractionIndex {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
out := make([]CatalogEntry, 0, len(keys))
|
||||
for _, key := range keys {
|
||||
out = append(out, c.entries[c.extractionIndex[key]])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// MarkAvailableGenerated marks one source as available in current analyze execution.
|
||||
func (c *ArtifactCatalog) MarkAvailableGenerated(sourceID, path string) error {
|
||||
return c.markAvailable(sourceID, path, ArtifactProvenanceGeneratedCurrentAnalyzeRun)
|
||||
@@ -179,6 +251,16 @@ func (c *ArtifactCatalog) MarkAvailableFromDisk(sourceID, path string) error {
|
||||
return c.markAvailable(sourceID, path, ArtifactProvenanceDisabledFromDisk)
|
||||
}
|
||||
|
||||
func (c *ArtifactCatalog) markAvailableFromExtractManifest(sourceID, path, producerRunID string) error {
|
||||
if err := c.markAvailable(sourceID, path, ArtifactProvenanceCurrentExtractManifest); err != nil {
|
||||
return err
|
||||
}
|
||||
entry := c.entries[strings.TrimSpace(sourceID)]
|
||||
entry.ProducerRunID = strings.TrimSpace(producerRunID)
|
||||
c.entries[entry.SourceID] = entry
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ArtifactCatalog) markAvailable(sourceID, path, provenance string) error {
|
||||
if c == nil {
|
||||
return fmt.Errorf("artifact catalog is nil")
|
||||
|
||||
Reference in New Issue
Block a user