Skip to content

Commit 2ba51bf

Browse files
committed
remove imageRef param from Upload funcs
* This commit removes the imageRef param from the Upload functions used by our backends (Rekor and Local). * This is because we were using imageRef only to differentiate between Component and Snapshot VSA types, specifically for Local backend, so users can differentiate between the local files for these VSAs. * Now, we won't need to differentiate since we're already writing the correctly-named VSA files to the disk for any backend. resolves: EC-1309
1 parent 13dd511 commit 2ba51bf

6 files changed

Lines changed: 57 additions & 136 deletions

File tree

cmd/validate/image.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,17 +503,21 @@ func validateImageCmd(validate imageValidationFunc) *cobra.Command {
503503

504504
// Upload component VSA envelopes
505505
for imageRef, envelopePath := range vsaResult.ComponentEnvelopes {
506-
uploadErr := vsa.UploadVSAEnvelope(cmd.Context(), envelopePath, imageRef, data.vsaUpload, signer)
506+
uploadErr := vsa.UploadVSAEnvelope(cmd.Context(), envelopePath, data.vsaUpload, signer)
507507
if uploadErr != nil {
508508
log.Errorf("[VSA] Upload failed for component %s: %v", imageRef, uploadErr)
509+
} else {
510+
log.Infof("[VSA] Uploaded Component VSA")
509511
}
510512
}
511513

512514
// Upload snapshot VSA envelope if it exists
513515
if vsaResult.SnapshotEnvelope != "" {
514-
uploadErr := vsa.UploadVSAEnvelope(cmd.Context(), vsaResult.SnapshotEnvelope, "", data.vsaUpload, signer)
516+
uploadErr := vsa.UploadVSAEnvelope(cmd.Context(), vsaResult.SnapshotEnvelope, data.vsaUpload, signer)
515517
if uploadErr != nil {
516518
log.Errorf("[VSA] Upload failed for snapshot: %v", uploadErr)
519+
} else {
520+
log.Infof("[VSA] Uploaded Snapshot VSA")
517521
}
518522
}
519523
} else {

internal/validate/vsa/storage.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ import (
2929
// StorageBackend defines the interface for VSA storage implementations
3030
type StorageBackend interface {
3131
Name() string
32-
Upload(ctx context.Context, envelopeContent []byte, imageRef string) error
32+
Upload(ctx context.Context, envelopeContent []byte) error
3333
}
3434

3535
// SignerAwareUploader extends StorageBackend for backends that need access to the signer
3636
// (e.g., Rekor backend needs the public key for transparency log upload)
3737
type SignerAwareUploader interface {
3838
StorageBackend
39-
UploadWithSigner(ctx context.Context, envelopeContent []byte, imageRef string, signer *Signer) error
39+
UploadWithSigner(ctx context.Context, envelopeContent []byte, signer *Signer) error
4040
}
4141

4242
// StorageConfig represents parsed storage configuration
@@ -141,8 +141,7 @@ func CreateStorageBackend(config *StorageConfig) (StorageBackend, error) {
141141
}
142142

143143
// UploadVSAEnvelope uploads a VSA envelope to the configured storage backends
144-
// imageRef should be the full container image reference for component VSAs, or empty string for snapshot VSAs
145-
func UploadVSAEnvelope(ctx context.Context, envelopePath string, imageRef string, storageConfigs []string, signer *Signer) error {
144+
func UploadVSAEnvelope(ctx context.Context, envelopePath string, storageConfigs []string, signer *Signer) error {
146145
if len(storageConfigs) == 0 {
147146
log.Infof("[VSA] No storage backends configured, skipping upload")
148147
return nil
@@ -171,9 +170,9 @@ func UploadVSAEnvelope(ctx context.Context, envelopePath string, imageRef string
171170
// Upload using the appropriate method
172171
var uploadErr error
173172
if signerAwareUploader, ok := backend.(SignerAwareUploader); ok && signer != nil {
174-
uploadErr = signerAwareUploader.UploadWithSigner(ctx, envelopeContent, imageRef, signer)
173+
uploadErr = signerAwareUploader.UploadWithSigner(ctx, envelopeContent, signer)
175174
} else {
176-
uploadErr = backend.Upload(ctx, envelopeContent, imageRef)
175+
uploadErr = backend.Upload(ctx, envelopeContent)
177176
}
178177

179178
if uploadErr != nil {

internal/validate/vsa/storage_local.go

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,16 @@ func (l *LocalBackend) Name() string {
6565
}
6666

6767
// Upload saves the VSA envelope to a local file
68-
func (l *LocalBackend) Upload(ctx context.Context, envelopeContent []byte, imageRef string) error {
68+
func (l *LocalBackend) Upload(ctx context.Context, envelopeContent []byte) error {
6969
// Create directory if it doesn't exist
7070
if err := os.MkdirAll(l.basePath, 0755); err != nil {
7171
return fmt.Errorf("failed to create directory %s: %w", l.basePath, err)
7272
}
7373

74-
// Generate filename based on imageRef type
74+
// Generate filename with timestamp and content hash for uniqueness
7575
timestamp := time.Now().Format("2006-01-02T15-04-05.000000000")
76-
var filename string
77-
if imageRef == "" {
78-
// Snapshot VSA - include content hash for uniqueness
79-
contentHash := sha256.Sum256(envelopeContent)
80-
filename = fmt.Sprintf("vsa-snapshot-%s-%x.json", timestamp, contentHash[:4])
81-
} else {
82-
// Component VSA
83-
hash := sha256.Sum256([]byte(imageRef))
84-
filename = fmt.Sprintf("vsa-%s-%x.json", timestamp, hash[:8])
85-
}
76+
contentHash := sha256.Sum256(envelopeContent)
77+
filename := fmt.Sprintf("vsa-%s-%x.json", timestamp, contentHash[:8])
8678

8779
// Write to file
8880
filePath := filepath.Join(l.basePath, filename)
@@ -96,18 +88,10 @@ func (l *LocalBackend) Upload(ctx context.Context, envelopeContent []byte, image
9688
absPath = filePath // fallback to relative path
9789
}
9890

99-
// Log success with different messages for component vs snapshot VSAs
100-
var logMessage string
101-
if imageRef == "" {
102-
logMessage = "[VSA] Successfully saved Snapshot VSA to local file"
103-
} else {
104-
logMessage = "[VSA] Successfully saved Component VSA to local file"
105-
}
106-
10791
log.WithFields(log.Fields{
10892
"path": absPath,
10993
"size": len(envelopeContent),
110-
}).Info(logMessage)
94+
}).Info("[VSA] Successfully saved VSA to local file")
11195

11296
return nil
11397
}

internal/validate/vsa/storage_local_test.go

Lines changed: 35 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,18 @@ func TestLocalBackend_Name(t *testing.T) {
7979
assert.Equal(t, "Local (/tmp/test)", backend.Name())
8080
}
8181

82-
func TestLocalBackend_Upload_ComponentVSA(t *testing.T) {
82+
func TestLocalBackend_Upload(t *testing.T) {
8383
// Create temporary directory
8484
tempDir := t.TempDir()
8585
backend := &LocalBackend{basePath: tempDir}
8686

8787
ctx := context.Background()
88-
testEnvelope := `{"payload":"test-component","signatures":[{"sig":"test-sig"}]}`
89-
imageRef := "quay.io/test/image@sha256:abc123def456"
88+
testEnvelope := `{"payload":"test-vsa","signatures":[{"sig":"test-sig"}]}`
9089

91-
err := backend.Upload(ctx, []byte(testEnvelope), imageRef)
90+
err := backend.Upload(ctx, []byte(testEnvelope))
9291
require.NoError(t, err)
9392

94-
// Verify file was created (should contain hash of imageRef)
93+
// Verify file was created
9594
files, err := os.ReadDir(tempDir)
9695
require.NoError(t, err)
9796
require.Len(t, files, 1)
@@ -108,126 +107,69 @@ func TestLocalBackend_Upload_ComponentVSA(t *testing.T) {
108107
assert.Equal(t, testEnvelope, string(content))
109108
}
110109

111-
func TestLocalBackend_Upload_SnapshotVSA(t *testing.T) {
112-
// Create temporary directory
113-
tempDir := t.TempDir()
114-
backend := &LocalBackend{basePath: tempDir}
115-
116-
ctx := context.Background()
117-
testEnvelope := `{"payload":"test-snapshot","signatures":[{"sig":"test-sig"}]}`
118-
imageRef := "" // Empty for snapshot VSAs
119-
120-
err := backend.Upload(ctx, []byte(testEnvelope), imageRef)
121-
require.NoError(t, err)
122-
123-
// Verify file was created with snapshot naming
124-
files, err := os.ReadDir(tempDir)
125-
require.NoError(t, err)
126-
require.Len(t, files, 1)
127-
128-
filename := files[0].Name()
129-
assert.True(t, strings.HasPrefix(filename, "vsa-snapshot-"))
130-
assert.True(t, strings.HasSuffix(filename, ".json"))
131-
132-
// Verify file content
133-
filePath := filepath.Join(tempDir, filename)
134-
content, err := os.ReadFile(filePath)
135-
require.NoError(t, err)
136-
assert.Equal(t, testEnvelope, string(content))
137-
}
138-
139110
func TestLocalBackend_Upload_FilenameUniqueness(t *testing.T) {
140111
// Create temporary directory
141112
tempDir := t.TempDir()
142113
backend := &LocalBackend{basePath: tempDir}
143114

144115
ctx := context.Background()
145116
testEnvelope := `{"payload":"test","signatures":[{"sig":"test"}]}`
146-
imageRef := "quay.io/test/image@sha256:same"
147117

148118
// Upload same content multiple times
149-
err1 := backend.Upload(ctx, []byte(testEnvelope), imageRef)
119+
err1 := backend.Upload(ctx, []byte(testEnvelope))
150120
require.NoError(t, err1)
151121

152-
err2 := backend.Upload(ctx, []byte(testEnvelope), imageRef)
122+
err2 := backend.Upload(ctx, []byte(testEnvelope))
153123
require.NoError(t, err2)
154124

155125
// Should have created two different files due to timestamps
156126
files, err := os.ReadDir(tempDir)
157127
require.NoError(t, err)
158128
assert.Len(t, files, 2)
159129

160-
// Both should be valid component VSA files
130+
// Both should be valid VSA files with proper naming
161131
for _, file := range files {
162132
assert.True(t, strings.HasPrefix(file.Name(), "vsa-"))
163133
assert.True(t, strings.HasSuffix(file.Name(), ".json"))
164-
assert.False(t, strings.HasPrefix(file.Name(), "vsa-snapshot-"))
134+
assert.Contains(t, file.Name(), "-") // Should have timestamp and hash parts
165135
}
166-
}
167136

168-
func TestLocalBackend_Upload_SnapshotFilenameUniqueness(t *testing.T) {
169-
// Create temporary directory
170-
tempDir := t.TempDir()
171-
backend := &LocalBackend{basePath: tempDir}
172-
173-
ctx := context.Background()
174-
testEnvelope := `{"payload":"test-snapshot","signatures":[{"sig":"test"}]}`
175-
imageRef := "" // Empty for snapshots
176-
177-
// Upload multiple snapshot VSAs
178-
err1 := backend.Upload(ctx, []byte(testEnvelope), imageRef)
179-
require.NoError(t, err1)
180-
181-
err2 := backend.Upload(ctx, []byte(testEnvelope), imageRef)
182-
require.NoError(t, err2)
183-
184-
// Should have created two different files due to timestamps
185-
files, err := os.ReadDir(tempDir)
186-
require.NoError(t, err)
187-
assert.Len(t, files, 2)
188-
189-
// Both should be snapshot VSA files
190-
for _, file := range files {
191-
assert.True(t, strings.HasPrefix(file.Name(), "vsa-snapshot-"))
192-
assert.True(t, strings.HasSuffix(file.Name(), ".json"))
193-
}
137+
// Verify filenames are different (uniqueness)
138+
assert.NotEqual(t, files[0].Name(), files[1].Name())
194139
}
195140

196-
func TestLocalBackend_Upload_WriteError(t *testing.T) {
197-
// Use non-existent directory to trigger write error (without creating it first)
198-
backend := &LocalBackend{basePath: "/non/existent/path"}
199-
141+
func TestLocalBackend_Upload_DirectoryHandling(t *testing.T) {
200142
ctx := context.Background()
201143
testEnvelope := `{"payload":"test","signatures":[{"sig":"test"}]}`
202-
imageRef := "test-image@sha256:abc123"
203144

204-
err := backend.Upload(ctx, []byte(testEnvelope), imageRef)
205-
assert.Error(t, err)
206-
assert.Contains(t, err.Error(), "failed to create directory")
207-
}
145+
t.Run("successful directory creation", func(t *testing.T) {
146+
// Create base temp directory
147+
baseDir := t.TempDir()
208148

209-
func TestLocalBackend_Upload_DirectoryCreation(t *testing.T) {
210-
// Create base temp directory
211-
baseDir := t.TempDir()
149+
// Use a subdirectory that doesn't exist yet
150+
subDir := filepath.Join(baseDir, "subdir", "nested")
151+
backend := &LocalBackend{basePath: subDir}
212152

213-
// Use a subdirectory that doesn't exist yet
214-
subDir := filepath.Join(baseDir, "subdir", "nested")
215-
backend := &LocalBackend{basePath: subDir}
153+
// This should create the directory structure
154+
err := backend.Upload(ctx, []byte(testEnvelope))
155+
require.NoError(t, err)
216156

217-
ctx := context.Background()
218-
testEnvelope := `{"payload":"test","signatures":[{"sig":"test"}]}`
219-
imageRef := "test-image@sha256:abc123"
157+
// Verify directory was created
158+
_, err = os.Stat(subDir)
159+
assert.NoError(t, err)
220160

221-
// This should create the directory structure
222-
err := backend.Upload(ctx, []byte(testEnvelope), imageRef)
223-
require.NoError(t, err)
161+
// Verify file was created
162+
files, err := os.ReadDir(subDir)
163+
require.NoError(t, err)
164+
assert.Len(t, files, 1)
165+
})
224166

225-
// Verify directory was created
226-
_, err = os.Stat(subDir)
227-
assert.NoError(t, err)
167+
t.Run("directory creation error", func(t *testing.T) {
168+
// Use non-existent directory to trigger write error (without creating it first)
169+
backend := &LocalBackend{basePath: "/non/existent/path"}
228170

229-
// Verify file was created
230-
files, err := os.ReadDir(subDir)
231-
require.NoError(t, err)
232-
assert.Len(t, files, 1)
171+
err := backend.Upload(ctx, []byte(testEnvelope))
172+
assert.Error(t, err)
173+
assert.Contains(t, err.Error(), "failed to create directory")
174+
})
233175
}

internal/validate/vsa/storage_rekor.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ func (r *RekorBackend) Name() string {
8080
}
8181

8282
// Upload is not supported for Rekor backend - use UploadWithSigner instead
83-
func (r *RekorBackend) Upload(ctx context.Context, envelopeContent []byte, imageRef string) error {
83+
func (r *RekorBackend) Upload(ctx context.Context, envelopeContent []byte) error {
8484
return fmt.Errorf("Rekor backend requires signer access for public key. Use UploadWithSigner instead")
8585
}
8686

8787
// UploadWithSigner uploads a VSA envelope to the Rekor transparency log with access to the signer for public key extraction
88-
func (r *RekorBackend) UploadWithSigner(ctx context.Context, envelopeContent []byte, imageRef string, signer *Signer) error {
88+
func (r *RekorBackend) UploadWithSigner(ctx context.Context, envelopeContent []byte, signer *Signer) error {
8989
// Safely convert retries to uint
9090
var retryCount uint
9191
if r.retries < 0 {
@@ -132,19 +132,11 @@ func (r *RekorBackend) UploadWithSigner(ctx context.Context, envelopeContent []b
132132
logIndex = "unknown"
133133
}
134134

135-
// Log success with different messages for component vs snapshot VSAs
136-
var logMessage string
137-
if imageRef == "" {
138-
logMessage = "[VSA] Successfully uploaded Snapshot VSA to Rekor"
139-
} else {
140-
logMessage = "[VSA] Successfully uploaded Component VSA to Rekor"
141-
}
142-
143135
log.WithFields(log.Fields{
144136
"rekor_uuid": entryUUID,
145137
"rekor_url": fmt.Sprintf("%s/api/v1/log/entries/%s", r.serverURL, entryUUID),
146138
"rekor_index": logIndex,
147-
}).Info(logMessage)
139+
}).Info("[VSA] Successfully uploaded VSA to Rekor")
148140

149141
return nil
150142
}

internal/validate/vsa/storage_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,14 @@ func TestUploadVSAEnvelope_EmptyConfigs(t *testing.T) {
173173
envelopePath := tempFile.Name()
174174

175175
ctx := context.Background()
176-
err = UploadVSAEnvelope(ctx, envelopePath, "test-image@sha256:abc123", []string{}, nil)
176+
err = UploadVSAEnvelope(ctx, envelopePath, []string{}, nil)
177177
assert.NoError(t, err)
178178
}
179179

180180
func TestUploadVSAEnvelope_InvalidEnvelopePath(t *testing.T) {
181181
ctx := context.Background()
182182

183-
err := UploadVSAEnvelope(ctx, "/non/existent/path", "test-image@sha256:abc123", []string{"local@/tmp"}, nil)
183+
err := UploadVSAEnvelope(ctx, "/non/existent/path", []string{"local@/tmp"}, nil)
184184
assert.Error(t, err)
185185
assert.Contains(t, err.Error(), "failed to read VSA envelope")
186186
}
@@ -200,6 +200,6 @@ func TestUploadVSAEnvelope_InvalidStorageConfig(t *testing.T) {
200200
envelopePath := tempFile.Name()
201201

202202
ctx := context.Background()
203-
err = UploadVSAEnvelope(ctx, envelopePath, "test-image@sha256:abc123", []string{"invalid-format"}, nil)
203+
err = UploadVSAEnvelope(ctx, envelopePath, []string{"invalid-format"}, nil)
204204
assert.NoError(t, err) // Should not error, just warn and continue
205205
}

0 commit comments

Comments
 (0)