Skip to content
Merged
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
15 changes: 14 additions & 1 deletion pkg/blueprint/blueprint_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type BaseBlueprintHandler struct {
projectRoot string
shims *Shims
kustomizeData map[string]any
configLoaded bool
}

// NewBlueprintHandler creates a new instance of BaseBlueprintHandler.
Expand Down Expand Up @@ -138,13 +139,25 @@ func (b *BaseBlueprintHandler) LoadConfig() error {
if err != nil {
return err
}
return b.processBlueprintData(yamlData, &b.blueprint)

if err := b.processBlueprintData(yamlData, &b.blueprint); err != nil {
return err
}

b.configLoaded = true
return nil
}

// LoadData loads blueprint configuration from a map containing blueprint data.
// It marshals the input map to YAML, processes it as a Blueprint object, and updates the handler's blueprint state.
// The ociInfo parameter optionally provides OCI artifact source information for source resolution and tracking.
// If config is already loaded from YAML, this is a no-op to preserve resolved state.
func (b *BaseBlueprintHandler) LoadData(data map[string]any, ociInfo ...*artifact.OCIArtifactInfo) error {
// If config is already loaded from YAML, don't overwrite with template data
if b.configLoaded {
return nil
}

yamlData, err := b.shims.YamlMarshal(data)
if err != nil {
return fmt.Errorf("error marshalling blueprint data to yaml: %w", err)
Expand Down
41 changes: 41 additions & 0 deletions pkg/blueprint/blueprint_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3589,6 +3589,47 @@ func TestBlueprintHandler_LoadData(t *testing.T) {
t.Errorf("Expected description to be 'A blueprint from OCI artifact', got %s", metadata.Description)
}
})

t.Run("LoadDataIgnoredWhenConfigAlreadyLoaded", func(t *testing.T) {
// Given a blueprint handler that has already loaded config
handler, _ := setup(t)

// Load config first (simulates loading from YAML)
err := handler.LoadConfig()
if err != nil {
t.Fatalf("Failed to load config: %v", err)
}

// Get the original metadata
originalMetadata := handler.GetMetadata()

// And different blueprint data that would overwrite the config
differentData := map[string]any{
"kind": "Blueprint",
"apiVersion": "v1alpha1",
"metadata": map[string]any{
"name": "different-blueprint",
"description": "This should not overwrite the loaded config",
},
}

// When loading the different data
err = handler.LoadData(differentData)

// Then no error should be returned
if err != nil {
t.Errorf("Expected no error, got %v", err)
}

// But the metadata should remain unchanged (LoadData should be ignored)
currentMetadata := handler.GetMetadata()
if currentMetadata.Name != originalMetadata.Name {
t.Errorf("Expected metadata to remain unchanged, but name changed from %s to %s", originalMetadata.Name, currentMetadata.Name)
}
if currentMetadata.Description != originalMetadata.Description {
t.Errorf("Expected metadata to remain unchanged, but description changed from %s to %s", originalMetadata.Description, currentMetadata.Description)
}
})
}

func TestBlueprintHandler_Write(t *testing.T) {
Expand Down
16 changes: 9 additions & 7 deletions pkg/pipelines/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,12 @@ func (p *InstallPipeline) Execute(ctx context.Context) error {
return fmt.Errorf("No blueprint handler found")
}

// Phase 1: Process templates for kustomize data
// Phase 1: Load blueprint config (cached if already loaded)
if err := p.blueprintHandler.LoadConfig(); err != nil {
return fmt.Errorf("Error loading blueprint config: %w", err)
}

// Phase 2: Process templates for kustomize data
templateData, err := p.prepareTemplateData(ctx)
if err != nil {
return fmt.Errorf("failed to prepare template data: %w", err)
Expand All @@ -110,7 +115,7 @@ func (p *InstallPipeline) Execute(ctx context.Context) error {
return fmt.Errorf("failed to process template data: %w", err)
}

// Phase 2: Generate kustomize data using generators
// Phase 3: Generate kustomize data using generators
if len(renderedData) > 0 {
for _, generator := range p.generators {
if err := generator.Generate(renderedData, false); err != nil {
Expand All @@ -119,15 +124,12 @@ func (p *InstallPipeline) Execute(ctx context.Context) error {
}
}

// Phase 3: Load blueprint config and install
if err := p.blueprintHandler.LoadConfig(); err != nil {
return fmt.Errorf("Error loading blueprint config: %w", err)
}
// Phase 4: Install blueprint
if err := p.blueprintHandler.Install(); err != nil {
return fmt.Errorf("Error installing blueprint: %w", err)
}

// Phase 4: Wait for kustomizations if requested
// Phase 5: Wait for kustomizations if requested
waitFlag := ctx.Value("wait")
if waitFlag != nil {
if wait, ok := waitFlag.(bool); ok && wait {
Expand Down
Loading