Files
o11y-foundry/internal/domain/yaml_material.go
NageshbansalandGitHub e8b1b4f653 feat: introduce casting kind (#116)
### Summary                            

- Introduce a `kind` discriminator for Casting. Existing Casting without
a kind field keep working, empty kind defaults to `Installation`
- New `api/v1alpha1/installation/` subpackage with the Installation
Casting, Spec types and holds its own JSON schema from its Go type:
`installation/casting.schema.json`
- New Machinery interface in `api/v1alpha1/machinery.go` exposes
`Kind()` and `TrackableProperties()` so Dispatcher(Getv1alpha1 and
Forge/Cast/Gauge) work across any kind without knowing its concrete
type.
- A root casting.schema.json lists every per-Kind schema to supports
IDEs completion from one schema URL
- cmd/foundryctl gen schemas reads a list of types from schemaTargets.
Adding a kind means adding one entry.
  
Related: https://github.com/SigNoz/platform-pod/issues/1970
2026-05-16 17:40:03 +05:30

136 lines
3.1 KiB
Go

package domain
import (
"bytes"
"encoding/json"
"github.com/signoz/foundry/internal/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
kyaml "sigs.k8s.io/yaml"
)
var _ StructuredMaterial = YAMLMaterial{}
type YAMLMaterial struct {
path string
contents []byte
hasMultipleDocuments bool
}
func NewYAMLMaterial(contents []byte, path string) (YAMLMaterial, error) {
reader := kio.ByteReader{Reader: bytes.NewReader(contents), OmitReaderAnnotations: true}
nodes, err := reader.Read()
if err != nil {
return YAMLMaterial{}, errors.Wrapf(err, errors.TypeInvalidInput, "failed to create YAML material for path %q: contents are not valid YAML", path)
}
var jsonContents []byte
if len(nodes) == 1 {
jsonContents, err = nodes[0].MarshalJSON()
if err != nil {
return YAMLMaterial{}, errors.Wrapf(err, errors.TypeInternal, "failed to convert YAML material to canonical JSON for path %q", path)
}
return YAMLMaterial{
contents: jsonContents,
path: path,
hasMultipleDocuments: false,
}, nil
}
var docs []json.RawMessage
for _, node := range nodes {
jsonContents, err := node.MarshalJSON()
if err != nil {
return YAMLMaterial{}, errors.Wrapf(err, errors.TypeInternal, "failed to convert YAML material to canonical JSON for path %q", path)
}
docs = append(docs, jsonContents)
}
jsonContents, err = json.Marshal(docs)
if err != nil {
return YAMLMaterial{}, errors.Wrapf(err, errors.TypeInternal, "failed to convert multi-document YAML material to canonical JSON for path %q", path)
}
return YAMLMaterial{
contents: jsonContents,
path: path,
hasMultipleDocuments: len(nodes) > 1,
}, nil
}
func MustNewYAMLMaterial(contents []byte, path string) YAMLMaterial {
material, err := NewYAMLMaterial(contents, path)
if err != nil {
panic(err)
}
return material
}
func (m YAMLMaterial) Path() string {
return m.path
}
func (m YAMLMaterial) JSONContents() []byte {
return m.contents
}
func (m YAMLMaterial) HasMultipleDocuments() bool {
return m.hasMultipleDocuments
}
func (m YAMLMaterial) FmtContents() []byte {
if !m.HasMultipleDocuments() {
node, err := kyaml.JSONToYAML(m.contents)
if err != nil {
return nil
}
return node
}
var docs []json.RawMessage
if err := json.Unmarshal(m.contents, &docs); err != nil {
return nil
}
var nodes []*yaml.RNode
for _, doc := range docs {
node, err := yaml.ConvertJSONToYamlNode(string(doc))
if err != nil {
return nil
}
nodes = append(nodes, node)
}
var buf bytes.Buffer
writer := kio.ByteWriter{Writer: &buf, KeepReaderAnnotations: true}
if err := writer.Write(nodes); err != nil {
return nil
}
return buf.Bytes()
}
func (m YAMLMaterial) CloneWithJSONContents(contents []byte) StructuredMaterial {
return YAMLMaterial{
contents: contents,
path: m.path,
hasMultipleDocuments: m.hasMultipleDocuments,
}
}
func (m YAMLMaterial) GetBytes(path string) ([]byte, error) {
return getBytes(m.contents, path)
}
func (m YAMLMaterial) GetStringSlice(path string) ([]string, error) {
return getStringSlice(m.contents, path)
}