187 lines
5.8 KiB
Go
187 lines
5.8 KiB
Go
package server
|
|
|
|
import (
|
|
"github.com/influxdata/influxdb/v2/chronograf"
|
|
"github.com/influxdata/influxdb/v2/chronograf/canned"
|
|
"github.com/influxdata/influxdb/v2/chronograf/filestore"
|
|
"github.com/influxdata/influxdb/v2/chronograf/memdb"
|
|
"github.com/influxdata/influxdb/v2/chronograf/multistore"
|
|
)
|
|
|
|
// LayoutBuilder is responsible for building Layouts
|
|
type LayoutBuilder interface {
|
|
Build(chronograf.LayoutsStore) (*multistore.Layouts, error)
|
|
}
|
|
|
|
// MultiLayoutBuilder implements LayoutBuilder and will return a Layouts
|
|
type MultiLayoutBuilder struct {
|
|
Logger chronograf.Logger
|
|
UUID chronograf.ID
|
|
CannedPath string
|
|
}
|
|
|
|
// Build will construct a Layouts of canned and db-backed personalized
|
|
// layouts
|
|
func (builder *MultiLayoutBuilder) Build(db chronograf.LayoutsStore) (*multistore.Layouts, error) {
|
|
// These apps are those handled from a directory
|
|
apps := filestore.NewApps(builder.CannedPath, builder.UUID, builder.Logger)
|
|
// These apps are statically compiled into chronograf
|
|
binApps := &canned.BinLayoutsStore{
|
|
Logger: builder.Logger,
|
|
}
|
|
// Acts as a front-end to both the bolt layouts, filesystem layouts and binary statically compiled layouts.
|
|
// The idea here is that these stores form a hierarchy in which each is tried sequentially until
|
|
// the operation has success. So, the database is preferred over filesystem over binary data.
|
|
layouts := &multistore.Layouts{
|
|
Stores: []chronograf.LayoutsStore{
|
|
db,
|
|
apps,
|
|
binApps,
|
|
},
|
|
}
|
|
|
|
return layouts, nil
|
|
}
|
|
|
|
// DashboardBuilder is responsible for building dashboards
|
|
type DashboardBuilder interface {
|
|
Build(chronograf.DashboardsStore) (*multistore.DashboardsStore, error)
|
|
}
|
|
|
|
// MultiDashboardBuilder builds a DashboardsStore backed by bolt and the filesystem
|
|
type MultiDashboardBuilder struct {
|
|
Logger chronograf.Logger
|
|
ID chronograf.ID
|
|
Path string
|
|
}
|
|
|
|
// Build will construct a Dashboard store of filesystem and db-backed dashboards
|
|
func (builder *MultiDashboardBuilder) Build(db chronograf.DashboardsStore) (*multistore.DashboardsStore, error) {
|
|
// These dashboards are those handled from a directory
|
|
files := filestore.NewDashboards(builder.Path, builder.ID, builder.Logger)
|
|
// Acts as a front-end to both the bolt dashboard and filesystem dashboards.
|
|
// The idea here is that these stores form a hierarchy in which each is tried sequentially until
|
|
// the operation has success. So, the database is preferred over filesystem
|
|
dashboards := &multistore.DashboardsStore{
|
|
Stores: []chronograf.DashboardsStore{
|
|
db,
|
|
files,
|
|
},
|
|
}
|
|
|
|
return dashboards, nil
|
|
}
|
|
|
|
// SourcesBuilder builds a MultiSourceStore
|
|
type SourcesBuilder interface {
|
|
Build(chronograf.SourcesStore) (*multistore.SourcesStore, error)
|
|
}
|
|
|
|
// MultiSourceBuilder implements SourcesBuilder
|
|
type MultiSourceBuilder struct {
|
|
InfluxDBURL string
|
|
InfluxDBUsername string
|
|
InfluxDBPassword string
|
|
|
|
Logger chronograf.Logger
|
|
ID chronograf.ID
|
|
Path string
|
|
}
|
|
|
|
// Build will return a MultiSourceStore
|
|
func (fs *MultiSourceBuilder) Build(db chronograf.SourcesStore) (*multistore.SourcesStore, error) {
|
|
// These dashboards are those handled from a directory
|
|
files := filestore.NewSources(fs.Path, fs.ID, fs.Logger)
|
|
|
|
stores := []chronograf.SourcesStore{db, files}
|
|
|
|
if fs.InfluxDBURL != "" {
|
|
influxStore := &memdb.SourcesStore{
|
|
Source: &chronograf.Source{
|
|
ID: 0,
|
|
Name: fs.InfluxDBURL,
|
|
Type: chronograf.InfluxDB,
|
|
Username: fs.InfluxDBUsername,
|
|
Password: fs.InfluxDBPassword,
|
|
URL: fs.InfluxDBURL,
|
|
Default: true,
|
|
}}
|
|
stores = append([]chronograf.SourcesStore{influxStore}, stores...)
|
|
}
|
|
sources := &multistore.SourcesStore{
|
|
Stores: stores,
|
|
}
|
|
|
|
return sources, nil
|
|
}
|
|
|
|
// KapacitorBuilder builds a KapacitorStore
|
|
type KapacitorBuilder interface {
|
|
Build(chronograf.ServersStore) (*multistore.KapacitorStore, error)
|
|
}
|
|
|
|
// MultiKapacitorBuilder implements KapacitorBuilder
|
|
type MultiKapacitorBuilder struct {
|
|
KapacitorURL string
|
|
KapacitorUsername string
|
|
KapacitorPassword string
|
|
|
|
Logger chronograf.Logger
|
|
ID chronograf.ID
|
|
Path string
|
|
}
|
|
|
|
// Build will return a multistore facade KapacitorStore over memdb and bolt
|
|
func (builder *MultiKapacitorBuilder) Build(db chronograf.ServersStore) (*multistore.KapacitorStore, error) {
|
|
// These dashboards are those handled from a directory
|
|
files := filestore.NewKapacitors(builder.Path, builder.ID, builder.Logger)
|
|
|
|
stores := []chronograf.ServersStore{db, files}
|
|
|
|
if builder.KapacitorURL != "" {
|
|
memStore := &memdb.KapacitorStore{
|
|
Kapacitor: &chronograf.Server{
|
|
ID: 0,
|
|
SrcID: 0,
|
|
Name: builder.KapacitorURL,
|
|
URL: builder.KapacitorURL,
|
|
Username: builder.KapacitorUsername,
|
|
Password: builder.KapacitorPassword,
|
|
},
|
|
}
|
|
stores = append([]chronograf.ServersStore{memStore}, stores...)
|
|
}
|
|
kapacitors := &multistore.KapacitorStore{
|
|
Stores: stores,
|
|
}
|
|
return kapacitors, nil
|
|
}
|
|
|
|
// OrganizationBuilder is responsible for building dashboards
|
|
type OrganizationBuilder interface {
|
|
Build(chronograf.OrganizationsStore) (*multistore.OrganizationsStore, error)
|
|
}
|
|
|
|
// MultiOrganizationBuilder builds a OrganizationsStore backed by bolt and the filesystem
|
|
type MultiOrganizationBuilder struct {
|
|
Logger chronograf.Logger
|
|
Path string
|
|
}
|
|
|
|
// Build will construct a Organization store of filesystem and db-backed dashboards
|
|
func (builder *MultiOrganizationBuilder) Build(db chronograf.OrganizationsStore) (*multistore.OrganizationsStore, error) {
|
|
// These organization are those handled from a directory
|
|
files := filestore.NewOrganizations(builder.Path, builder.Logger)
|
|
// Acts as a front-end to both the bolt org and filesystem orgs.
|
|
// The idea here is that these stores form a hierarchy in which each is tried sequentially until
|
|
// the operation has success. So, the database is preferred over filesystem
|
|
orgs := &multistore.OrganizationsStore{
|
|
Stores: []chronograf.OrganizationsStore{
|
|
db,
|
|
files,
|
|
},
|
|
}
|
|
|
|
return orgs, nil
|
|
}
|