// 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" "regexp" "os" "io" "compress/gzip" "errors" "log/slog" ) type DeclFile struct { Path string `yaml:"path" json:"path"` } 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())) 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) } return t }) } func (d *DeclFile) Type() string { return "decl" } func (d *DeclFile) ExtractResources(filter ResourceSelector) ([]*resource.Document, error) { documents := make([]*resource.Document, 0, 100) documents = append(documents, resource.NewDocument()) GzipFileName := regexp.MustCompile(`^.*\.gz$`) file, fileErr := os.Open(d.Path) if fileErr != nil { return documents, fileErr } var fileReader io.Reader if GzipFileName.FindString(d.Path) == d.Path { slog.Info("decompressing gzip", "path", d.Path) zr, err := gzip.NewReader(file) if err != nil { return documents, err } fileReader = zr } else { fileReader = file } decoder := resource.NewYAMLDecoder(fileReader) index := 0 for { doc := documents[index] e := decoder.Decode(doc) if errors.Is(e, io.EOF) { if len(documents) > 1 { documents[index] = nil } break } if e != nil { return documents, e } if validationErr := doc.Validate(); validationErr != nil { return documents, validationErr } /* if applyErr := doc.Apply(); applyErr != nil { return documents, applyErr } */ documents = append(documents, resource.NewDocument()) index++ } return documents, nil }