// Copyright 2024 Matthew Rich . All rights reserved. package fan import ( _ "context" _ "encoding/json" "fmt" _ "gopkg.in/yaml.v3" "net/url" _ "path/filepath" "decl/internal/data" "decl/internal/resource" "decl/internal/folio" _ "os" _ "io" "strings" "log/slog" ) type Iptable struct { Table string `yaml:"table" json:"table"` Chain string `yaml:"chain" json:"chain"` } func NewIptable() *Iptable { return &Iptable{} } func init() { folio.DocumentRegistry.ConverterTypes.Register([]string{"iptable"}, func(u *url.URL) data.Converter { t := NewIptable() t.Table = u.Hostname() elements := strings.FieldsFunc(u.Path, func(c rune) bool { return c == '/' }) if len(elements) >= 1 { t.Chain = elements[0] } slog.Info("iptable chain source factory", "table", t, "uri", u, "table", u.Hostname()) return t }) } func (i *Iptable) Type() data.TypeName { return "iptable" } func (i *Iptable) Extract(sourceResource data.Resource, filter data.ElementSelector) (document data.Document, err error) { slog.Info("fan.Iptable.Extract()", "table", i) iptRules := make([]*resource.Iptable, 0, 100) cmd := resource.NewIptableReadChainCommand() if cmd == nil { return document, fmt.Errorf("Iptable read chain: invalid command") } var out []byte if out, err = cmd.Execute(i); err == nil { if err = cmd.Extractor(out, &iptRules); err == nil { document = folio.DocumentRegistry.NewDocument(folio.URI(sourceResource.URI())) for _, rule := range iptRules { if rule == nil { rule = resource.NewIptable() } rule.Table = resource.IptableName(i.Table) rule.Chain = resource.IptableChain(i.Chain) slog.Info("iptable chain source Extract()", "rule", rule) document.(*folio.Document).AddResourceDeclaration("iptable", rule) } } } slog.Info("fan.Iptable.Extract()", "output", out, "error", err) return document, err } func (i *Iptable) Emit(document data.Document, filter data.ElementSelector) (resourceTarget data.Resource, err error) { return nil, nil } func (i *Iptable) Close() error { return nil }