github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/providers/data/ddl/data.go (about) 1 // Copyright (c) 2021, R.I. Pienaar and the Choria Project contributors 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package ddl 6 7 import ( 8 "encoding/json" 9 "fmt" 10 "os" 11 "sync" 12 "time" 13 14 "github.com/choria-io/go-choria/providers/agent/mcorpc/ddl/common" 15 ) 16 17 // Metadata describes an agent at a high level and is required for any agent 18 type Metadata struct { 19 License string `json:"license"` 20 Author string `json:"author"` 21 Timeout int `json:"timeout"` 22 Name string `json:"name"` 23 Version string `json:"version"` 24 URL string `json:"url"` 25 Description string `json:"description"` 26 Provider string `json:"provider,omitempty"` 27 } 28 29 type DDL struct { 30 Schema string `json:"$schema"` 31 Metadata Metadata `json:"metadata"` 32 Query *common.InputItem `json:"query"` 33 Output map[string]*common.OutputItem `json:"output"` 34 35 SourceLocation string `json:"-"` 36 37 sync.Mutex 38 } 39 40 // New creates a new DDL from a JSON file 41 func New(file string) (*DDL, error) { 42 ddl := &DDL{ 43 SourceLocation: file, 44 } 45 46 dat, err := os.ReadFile(file) 47 if err != nil { 48 return nil, fmt.Errorf("could not load DDL data: %s", err) 49 } 50 51 err = json.Unmarshal(dat, ddl) 52 if err != nil { 53 return nil, fmt.Errorf("could not parse JSON data in %s: %s", file, err) 54 } 55 56 return ddl, nil 57 } 58 59 func Find(plugin string, libdirs []string) (ddl *DDL, err error) { 60 EachFile(libdirs, func(n string, f string) bool { 61 if n == plugin { 62 ddl, err = New(f) 63 return true 64 } 65 66 return false 67 }) 68 69 if err != nil { 70 return nil, fmt.Errorf("could not load data plugin %s: %s", plugin, err) 71 } 72 73 if ddl == nil { 74 return nil, fmt.Errorf("could not find DDL file for %s", plugin) 75 } 76 77 return ddl, nil 78 } 79 80 // EachFile calls cb with a path to every found data DDL, stops looking when br is true 81 func EachFile(libdirs []string, cb func(name string, path string) (br bool)) { 82 common.EachFile("data", libdirs, cb) 83 } 84 85 // Timeout is the timeout for this data plugin 86 func (d *DDL) Timeout() time.Duration { 87 if d.Metadata.Timeout == 0 { 88 return 10 * time.Second 89 } 90 91 return time.Second * time.Duration(d.Metadata.Timeout) 92 }