github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/providers/ddlresolver/filesystem_resolver.go (about) 1 // Copyright (c) 2021-2022, R.I. Pienaar and the Choria Project contributors 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package ddlresolver 6 7 import ( 8 "context" 9 "encoding/json" 10 "fmt" 11 "os" 12 "path/filepath" 13 "sort" 14 "strings" 15 16 "github.com/choria-io/go-choria/inter" 17 ) 18 19 // FileSystemDDLResolver resolves DDL in the lib directories configured in the framework 20 type FileSystemDDLResolver struct{} 21 22 func (f *FileSystemDDLResolver) String() string { 23 return "File System DDL Resolver" 24 } 25 26 func (f *FileSystemDDLResolver) DDL(ctx context.Context, kind string, name string, target any, fw inter.Framework) error { 27 b, err := f.DDLBytes(ctx, kind, name, fw) 28 if err != nil { 29 return err 30 } 31 32 return json.Unmarshal(b, target) 33 } 34 35 func (f *FileSystemDDLResolver) DDLBytes(_ context.Context, kind string, name string, fw inter.Framework) ([]byte, error) { 36 if kind != "agent" && kind != "data" { 37 return nil, fmt.Errorf("unsupported ddl type %q", kind) 38 } 39 40 var ( 41 b []byte 42 err error 43 ) 44 45 f.EachFile(kind, f.libDirs(fw), func(n, p string) bool { 46 if n == name { 47 b, err = os.ReadFile(p) 48 return true 49 } 50 return false 51 }) 52 if err != nil { 53 return nil, fmt.Errorf("could not find DDL %s/%s: %s", kind, name, err) 54 } 55 if len(b) == 0 { 56 return nil, fmt.Errorf("could not find DDL %s/%s", kind, name) 57 } 58 59 return b, nil 60 } 61 62 func (f *FileSystemDDLResolver) DDLNames(_ context.Context, kind string, fw inter.Framework) ([]string, error) { 63 if kind != "agent" && kind != "data" { 64 return nil, fmt.Errorf("unsupported ddl type %q", kind) 65 } 66 67 names := []string{} 68 f.EachFile(kind, f.libDirs(fw), func(n, _ string) bool { 69 names = append(names, n) 70 return false 71 }) 72 73 sort.Strings(names) 74 75 return names, nil 76 } 77 78 func (f *FileSystemDDLResolver) libDirs(fw inter.Framework) []string { 79 return append(fw.Configuration().LibDir, fw.Configuration().Choria.RubyLibdir...) 80 } 81 82 func (f *FileSystemDDLResolver) EachFile(kind string, libdirs []string, cb func(name string, path string) (br bool)) { 83 for _, dir := range libdirs { 84 for _, n := range []string{"choria", "mcollective"} { 85 filepath.Walk(filepath.Join(dir, n, kind), func(path string, info os.FileInfo, err error) error { 86 if err != nil { 87 return err 88 } 89 90 if info.IsDir() { 91 return nil 92 } 93 94 _, name := filepath.Split(path) 95 extension := filepath.Ext(name) 96 97 if extension != ".json" { 98 return nil 99 } 100 101 cb(strings.TrimSuffix(name, extension), path) 102 103 return nil 104 }) 105 } 106 } 107 }