mirror of
https://github.com/hanzoai/o11y-foundry.git
synced 2026-10-30 18:26:45 +00:00
108 lines
3.6 KiB
Go
108 lines
3.6 KiB
Go
package foundry
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"path/filepath"
|
|
|
|
"github.com/hanzoai/o11y-foundry/api/v1alpha1"
|
|
"github.com/hanzoai/o11y-foundry/api/v1alpha1/installation"
|
|
"github.com/hanzoai/o11y-foundry/internal/domain"
|
|
foundryerrors "github.com/hanzoai/o11y-foundry/internal/errors"
|
|
"github.com/hanzoai/o11y-foundry/internal/writer"
|
|
)
|
|
|
|
func (foundry *Foundry) Forge(ctx context.Context, machinery v1alpha1.Machinery, path string, poursWriterOpts *writer.Options) error {
|
|
p, err := foundry.newPlanner(ctx, machinery)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, kind := range p.MoldingKinds() {
|
|
if err := p.EnrichStatus(ctx, kind); err != nil {
|
|
return foundryerrors.Wrapf(err, foundryerrors.TypeInternal, "failed to enrich molding %s", kind)
|
|
}
|
|
}
|
|
|
|
for _, kind := range p.MoldingKinds() {
|
|
foundry.Logger.InfoContext(ctx, "molding configuration for kind", slog.String("molding.kind", kind.String()))
|
|
if err := p.Mold(ctx, kind); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err := p.MergeStatusIntoSpec(); err != nil {
|
|
return err
|
|
}
|
|
|
|
materials, err := p.Forge(ctx, poursWriterOpts.TargetDirectory)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, pe := range p.Patches() {
|
|
patcher, ok := foundry.Patchers[pe.PatchType()]
|
|
if !ok {
|
|
return foundryerrors.Newf(foundryerrors.TypeUnsupported, "unknown patch type %q", pe.PatchType())
|
|
}
|
|
foundry.Logger.InfoContext(ctx, "applying patch", slog.String("patch.type", pe.PatchType()), slog.String("patch.target", pe.Target))
|
|
materials, err = patcher.Apply(ctx, materials, pe)
|
|
if err != nil {
|
|
return foundryerrors.Wrapf(err, foundryerrors.TypeInternal, "failed to apply patch for target %q", pe.Target)
|
|
}
|
|
}
|
|
|
|
// Generate infrastructure-as-code manifests if enabled, before writing the lock file
|
|
// so that the generated file contents are captured in the lock's infrastructure.status.
|
|
// Gated to installation.Casting
|
|
var infraMaterials []domain.Material
|
|
if config, ok := machinery.(*installation.Casting); ok && config.Spec.Infrastructure.Enabled {
|
|
spec := &config.Spec
|
|
foundry.Logger.InfoContext(ctx, "generating infrastructure manifests",
|
|
slog.String("casting.metadata.name", config.Metadata.Name),
|
|
slog.String("deployment.platform", spec.Deployment.Platform.String()))
|
|
|
|
infraMaterials, err = foundry.InfrastructureGenerator.Generate(ctx, *config)
|
|
if err != nil {
|
|
return foundryerrors.Wrapf(err, foundryerrors.TypeInternal, "failed to generate infrastructure manifests")
|
|
}
|
|
|
|
// Populate infrastructure status with generated file contents keyed by filename.
|
|
if len(infraMaterials) > 0 {
|
|
spec.Infrastructure.Status = make(map[string]string, len(infraMaterials))
|
|
for _, m := range infraMaterials {
|
|
spec.Infrastructure.Status[filepath.Base(m.Path())] = string(m.FmtContents())
|
|
}
|
|
}
|
|
}
|
|
|
|
// writing the merged config (including infrastructure status) to the lock file
|
|
foundry.Logger.InfoContext(ctx, "writing lock file")
|
|
if err := foundry.Config.CreateV1Alpha1Lock(ctx, p.Machinery(), path); err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(materials) == 0 && len(infraMaterials) == 0 {
|
|
foundry.Logger.WarnContext(ctx, "casting did not generate any materials for writing")
|
|
return nil
|
|
}
|
|
|
|
poursWriter, err := writer.New(foundry.Logger, poursWriterOpts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(infraMaterials) > 0 {
|
|
foundry.Logger.InfoContext(ctx, "writing infrastructure materials", slog.Int("count", len(infraMaterials)))
|
|
if err := poursWriter.WriteMany(ctx, infraMaterials...); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
foundry.Logger.InfoContext(ctx, "writing materials")
|
|
if err := poursWriter.WriteMany(ctx, materials...); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|