influxdb/chronograf/filestore/organizations.go

118 lines
3.8 KiB
Go

package filestore
import (
"context"
"fmt"
"io/ioutil"
"os"
"path"
"github.com/influxdata/influxdb/chronograf"
)
// OrgExt is the the file extension searched for in the directory for org files
const OrgExt = ".org"
var _ chronograf.OrganizationsStore = (*Organizations)(nil)
// Organizations are JSON orgs stored in the filesystem
type Organizations struct {
Dir string // Dir is the directory containing the orgs.
Load func(string, interface{}) error // Load loads string name and org passed in as interface
ReadDir func(dirname string) ([]os.FileInfo, error) // ReadDir reads the directory named by dirname and returns a list of directory entries sorted by filename.
Logger chronograf.Logger
}
// NewOrganizations constructs a org store wrapping a file system directory
func NewOrganizations(dir string, logger chronograf.Logger) chronograf.OrganizationsStore {
return &Organizations{
Dir: dir,
Load: load,
ReadDir: ioutil.ReadDir,
Logger: logger,
}
}
// All returns all orgs from the directory
func (o *Organizations) All(ctx context.Context) ([]chronograf.Organization, error) {
files, err := o.ReadDir(o.Dir)
if err != nil {
return nil, err
}
orgs := []chronograf.Organization{}
for _, file := range files {
if path.Ext(file.Name()) != OrgExt {
continue
}
var org chronograf.Organization
if err := o.Load(path.Join(o.Dir, file.Name()), &org); err != nil {
continue // We want to load all files we can.
} else {
orgs = append(orgs, org)
}
}
return orgs, nil
}
// Get returns a org file from the org directory
func (o *Organizations) Get(ctx context.Context, query chronograf.OrganizationQuery) (*chronograf.Organization, error) {
org, _, err := o.findOrg(query)
return org, err
}
// Add is not allowed for the filesystem organization store
func (o *Organizations) Add(ctx context.Context, org *chronograf.Organization) (*chronograf.Organization, error) {
return nil, fmt.Errorf("unable to add organizations to the filesystem")
}
// Delete is not allowed for the filesystem organization store
func (o *Organizations) Delete(ctx context.Context, org *chronograf.Organization) error {
return fmt.Errorf("unable to delete an organization from the filesystem")
}
// Update is not allowed for the filesystem organization store
func (o *Organizations) Update(ctx context.Context, org *chronograf.Organization) error {
return fmt.Errorf("unable to update organizations on the filesystem")
}
// CreateDefault is not allowed for the filesystem organization store
func (o *Organizations) CreateDefault(ctx context.Context) error {
return fmt.Errorf("unable to create default organizations on the filesystem")
}
// DefaultOrganization is not allowed for the filesystem organization store
func (o *Organizations) DefaultOrganization(ctx context.Context) (*chronograf.Organization, error) {
return nil, fmt.Errorf("unable to get default organizations from the filestore")
}
// findOrg takes an OrganizationQuery and finds the associated filename
func (o *Organizations) findOrg(query chronograf.OrganizationQuery) (*chronograf.Organization, string, error) {
// Because the entire org information is not known at this point, we need
// to try to find the name of the file through matching the ID or name in the org
// content with the ID passed.
files, err := o.ReadDir(o.Dir)
if err != nil {
return nil, "", err
}
for _, f := range files {
if path.Ext(f.Name()) != OrgExt {
continue
}
file := path.Join(o.Dir, f.Name())
var org chronograf.Organization
if err := o.Load(file, &org); err != nil {
return nil, "", err
}
if query.ID != nil && org.ID == *query.ID {
return &org, file, nil
}
if query.Name != nil && org.Name == *query.Name {
return &org, file, nil
}
}
return nil, "", chronograf.ErrOrganizationNotFound
}