// Copyright 2024 Matthew Rich . All rights reserved. package source import ( _ "context" _ "encoding/json" _ "fmt" _ "gopkg.in/yaml.v3" "net/url" "path/filepath" "decl/internal/resource" "decl/internal/transport" "decl/internal/codec" "regexp" _ "os" "io" "compress/gzip" "errors" "log/slog" ) type DeclFile struct { Path string `yaml:"path" json:"path"` transport *transport.Reader `yaml:"-" json:"-"` } func NewDeclFile() *DeclFile { return &DeclFile{} } func init() { SourceTypes.Register([]string{"decl"}, func(u *url.URL) DocSource { t := NewDeclFile() t.Path,_ = filepath.Abs(filepath.Join(u.Hostname(), u.RequestURI())) t.transport,_ = transport.NewReader(u) return t }) SourceTypes.Register([]string{"yaml","yml","yaml.gz","yml.gz"}, func(u *url.URL) DocSource { t := NewDeclFile() if u.Scheme == "file" { fileAbsolutePath, _ := filepath.Abs(filepath.Join(u.Hostname(), u.RequestURI())) t.Path = fileAbsolutePath } else { t.Path = filepath.Join(u.Hostname(), u.Path) } t.transport,_ = transport.NewReader(u) return t }) } func (d *DeclFile) Type() string { return "decl" } func (d *DeclFile) ExtractResources(filter ResourceSelector) ([]*resource.Document, error) { documents := make([]*resource.Document, 0, 100) GzipFileName := regexp.MustCompile(`^.*\.gz$`) defer d.transport.Close() var fileReader io.Reader if GzipFileName.FindString(d.Path) == d.Path { slog.Info("decompressing gzip", "path", d.Path) zr, err := gzip.NewReader(d.transport) if err != nil { return documents, err } fileReader = zr } else { fileReader = d.transport } decoder := codec.NewYAMLDecoder(fileReader) slog.Info("ExtractResources()", "documents", documents) index := 0 for { doc := resource.NewDocument() e := decoder.Decode(doc) if errors.Is(e, io.EOF) { break } if e != nil { return documents, e } slog.Info("ExtractResources()", "res", doc.ResourceDecls[0].Attributes) if validationErr := doc.Validate(); validationErr != nil { return documents, validationErr } documents = append(documents, doc) index++ } return documents, nil }