package file // Contract: Be a service layer for data storage and retrieval // see validation.go for details on json. import ( "encoding/json" "fmt" "io/fs" "os" "path" "strings" rulesengine "edge-infra.dev/pkg/sds/emergencyaccess/rules" "github.com/go-logr/logr" ) const ( defaultRolesName = "default" ) type Dataset struct { rootDir string log logr.Logger bannerRoleMap map[string]map[string][]string rulesengine.Dataset } // New generates a new dataset struct by loading all json files under the input directory and stores it as a map in memory. func New(log logr.Logger, dir string) (Dataset, error) { ds := Dataset{ rootDir: dir, log: log, bannerRoleMap: map[string]map[string][]string{}, } // loadfiles checks if rootdir is correct and no duplicate bannerids exist return ds, ds.loadFiles() } func (ds *Dataset) loadFiles() error { dirEntries, err := os.ReadDir(ds.rootDir) if err != nil { return err } for _, dirEntry := range dirEntries { var vals jsonData if dirEntry.IsDir() { continue } if !strings.HasSuffix(dirEntry.Name(), ".json") { continue } err := ds.parseJSONFile(dirEntry, &vals) if err != nil { ds.log.Error(err, "error when parsing file", "file", dirEntry.Name()) continue } if _, exists := ds.bannerRoleMap[vals.BannerID]; exists { // continuing with load here would result in unpredictable behaviour depending on what order the file are loaded in return fmt.Errorf("cannot overwrite unique id %s", vals.BannerID) } ds.bannerRoleMap[vals.BannerID] = vals.Roles } return nil } func (ds Dataset) parseJSONFile(dirEntry fs.DirEntry, vals *jsonData) error { file, err := os.ReadFile(path.Join(ds.rootDir, dirEntry.Name())) if err != nil { return err } return json.Unmarshal(file, vals) }