Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions pkg/compose/publish.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -325,7 +325,7 @@ func (s *composeService) preChecks(ctx context.Context, project *types.Project,
return false, err
}
}
detectedSecrets, err := s.checkForSensitiveData(ctx, project)
detectedSecrets, err := s.checkForSensitiveData(project)
if err != nil {
return false, err
}
Expand DownExpand Up@@ -602,7 +602,7 @@ func buildConfigContentPromptMessage(configs []string) string {

// loadUnresolvedFile loads a single compose file with interpolation and
// environment resolution skipped, so callers can inspect raw user-provided
// values. Used by both checkEnvironmentVariables and composeFileAsByteReader.
// values. Used by checkEnvironmentVariables.
func loadUnresolvedFile(ctx context.Context, project *types.Project, filePath string) (*types.Project, error) {
return loader.LoadWithContext(ctx, types.ConfigDetails{
WorkingDir: project.WorkingDir,
Expand DownExpand Up@@ -671,12 +671,12 @@ func (s *composeService) checkForBindMount(project *types.Project) map[string][]
return allFindings
}

func (s *composeService) checkForSensitiveData(ctx context.Context, project *types.Project) ([]secrets.DetectedSecret, error) {
func (s *composeService) checkForSensitiveData(project *types.Project) ([]secrets.DetectedSecret, error) {
var allFindings []secrets.DetectedSecret
scan := scanner.NewDefaultScanner()
// Check all compose files
for _, file := range project.ComposeFiles {
in, err := composeFileAsByteReader(ctx, file, project)
in, err := composeFileAsByteReader(file)
if err != nil {
return nil, err
}
Expand DownExpand Up@@ -723,14 +723,10 @@ func (s *composeService) checkForSensitiveData(ctx context.Context, project *typ
return allFindings, nil
}

func composeFileAsByteReader(ctx context.Context, filePath string, project *types.Project) (io.Reader, error) {
base, err := loadUnresolvedFile(ctx, project, filePath)
func composeFileAsByteReader(filePath string) (io.Reader, error) {
in, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("failed to load compose file %s: %w", filePath, err)
return nil, fmt.Errorf("failed to open compose file %s: %w", filePath, err)
}
in, err := base.MarshalYAML()
if err != nil {
return nil, err
}
return bytes.NewBuffer(in), nil
return bytes.NewReader(in), nil
}
24 changes: 24 additions & 0 deletions pkg/compose/publish_test.go
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ package compose

import (
"errors"
"io"
"os"
"path/filepath"
"slices"
Expand DownExpand Up@@ -593,3 +594,26 @@ func Test_publish_decline_returns_ErrCanceled(t *testing.T) {
assert.Assert(t, errors.Is(err, api.ErrCanceled),
"expected api.ErrCanceled when user declines, got: %v", err)
}

func Test_composeFileAsByteReader(t *testing.T) {
composeFile := []byte(`name: test
services:
whoami:
image: docker.io/traefik/whoami:v1.11
ports:
- ${DASHBOARD_PORT:-3000}:3000
`)
composePath := filepath.Join(t.TempDir(), "compose.yaml")
assert.NilError(t, os.WriteFile(composePath, composeFile, 0o600))

reader, err := composeFileAsByteReader(composePath)
assert.NilError(t, err)
actual, err := io.ReadAll(reader)
assert.NilError(t, err)
assert.DeepEqual(t, actual, composeFile)
}

func Test_composeFileAsByteReader_missingFile(t *testing.T) {
_, err := composeFileAsByteReader(filepath.Join(t.TempDir(), "missing.yaml"))
assert.Assert(t, errors.Is(err, os.ErrNotExist))
}