Began work on refactoring reading config values

This commit is contained in:
Torkel Ödegaard
2015-04-08 20:31:42 +02:00
parent 9c2040aa9b
commit a991cda233
28 changed files with 83 additions and 3661 deletions
-31
View File
@@ -1,31 +0,0 @@
package cmd
import (
"time"
"github.com/codegangsta/cli"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
)
func initRuntime(c *cli.Context) {
var args = &setting.CommandLineArgs{
Config: c.GlobalString("config"),
DefaultDataPath: c.GlobalString("default-data-path"),
DefaultLogPath: c.GlobalString("default-log-path"),
}
setting.NewConfigContext(args)
log.Info("Starting Grafana")
log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
setting.LogLoadedConfigFiles()
log.Info("Working Path: %s", setting.WorkPath)
log.Info("Data Path: %s", setting.DataPath)
log.Info("Log Path: %s", setting.LogRootPath)
sqlstore.NewEngine()
sqlstore.EnsureAdminUser()
}
-207
View File
@@ -1,207 +0,0 @@
package cmd
import (
"encoding/json"
"io"
"os"
"path/filepath"
"strings"
"github.com/codegangsta/cli"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
m "github.com/grafana/grafana/pkg/models"
)
var (
ImportDashboard = cli.Command{
Name: "dashboards:import",
Usage: "imports dashboards in JSON from a directory",
Description: "Starts Grafana import process",
Action: runImport,
Flags: []cli.Flag{
cli.StringFlag{
Name: "dir",
Usage: "path to folder containing json dashboards",
},
},
}
ExportDashboard = cli.Command{
Name: "dashboards:export",
Usage: "exports dashboards in JSON from a directory",
Description: "Starts Grafana export process",
Action: runExport,
Flags: []cli.Flag{
cli.StringFlag{
Name: "dir",
Usage: "path to folder containing json dashboards",
},
},
}
)
func runImport(c *cli.Context) {
dir := c.String("dir")
if len(dir) == 0 {
log.ConsoleFatalf("Missing command flag --dir")
}
file, err := os.Stat(dir)
if os.IsNotExist(err) {
log.ConsoleFatalf("Directory does not exist: %v", dir)
}
if !file.IsDir() {
log.ConsoleFatalf("%v is not a directory", dir)
}
if !c.Args().Present() {
log.ConsoleFatal("Organization name arg is required")
}
orgName := c.Args().First()
initRuntime(c)
orgQuery := m.GetOrgByNameQuery{Name: orgName}
if err := bus.Dispatch(&orgQuery); err != nil {
log.ConsoleFatalf("Failed to find account", err)
}
orgId := orgQuery.Result.Id
visitor := func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if f.IsDir() {
return nil
}
if strings.HasSuffix(f.Name(), ".json") {
if err := importDashboard(path, orgId); err != nil {
log.ConsoleFatalf("Failed to import dashboard file: %v, err: %v", path, err)
}
}
return nil
}
if err := filepath.Walk(dir, visitor); err != nil {
log.ConsoleFatalf("Failed to scan dir for json files: %v", err)
}
}
func importDashboard(path string, orgId int64) error {
log.ConsoleInfof("Importing %v", path)
reader, err := os.Open(path)
if err != nil {
return err
}
defer reader.Close()
dash := m.NewDashboard("temp")
jsonParser := json.NewDecoder(reader)
if err := jsonParser.Decode(&dash.Data); err != nil {
return err
}
dash.Data["id"] = nil
cmd := m.SaveDashboardCommand{
OrgId: orgId,
Dashboard: dash.Data,
}
if err := bus.Dispatch(&cmd); err != nil {
return err
}
return nil
}
func runExport(c *cli.Context) {
initRuntime(c)
if !c.Args().Present() {
log.ConsoleFatal("Account name arg is required")
}
name := c.Args().First()
orgQuery := m.GetOrgByNameQuery{Name: name}
if err := bus.Dispatch(&orgQuery); err != nil {
log.ConsoleFatalf("Failed to find organization: %s", err)
}
orgId := orgQuery.Result.Id
dir := c.String("dir")
dash := c.Args().Get(1)
query := m.SearchDashboardsQuery{OrgId: orgId, Title: dash}
err := bus.Dispatch(&query)
if err != nil {
log.ConsoleFatalf("Failed to find dashboards: %s", err)
return
}
if dir == "" && len(query.Result) > 1 {
log.ConsoleFatalf("Dashboard title '%s' returned too many results. "+
"Use --dir <dir> or a more specific title", dash)
return
}
for _, v := range query.Result {
f := os.Stdout
if dir != "" {
dest := filepath.Join(dir, v.Slug+".json")
f, err = os.Create(dest)
if err != nil {
log.ConsoleFatalf("Unable to create file: %s", err)
}
log.ConsoleInfof("Exporting '%s' dashboard to %s", v.Title, dest)
}
exportDashboard(f, orgId, v.Slug)
if dir != "" {
if err := f.Sync(); err != nil {
log.ConsoleFatalf("Unable to sync file: %s", err)
}
if err := f.Close(); err != nil {
log.ConsoleFatalf("Unable to close file: %s", err)
}
}
}
if dir != "" {
log.ConsoleInfof("Exported %d dashboards to %s", len(query.Result), dir)
}
}
func exportDashboard(w io.Writer, orgId int64, slug string) {
query := m.GetDashboardQuery{Slug: slug, OrgId: orgId}
err := bus.Dispatch(&query)
if err != nil {
log.ConsoleFatalf("Failed to find dashboard: %s", err)
return
}
out, err := json.MarshalIndent(query.Result.Data, "", " ")
if err != nil {
log.ConsoleFatalf("Failed to marshal dashboard: %s", err)
return
}
n, err := w.Write(out)
if err != nil {
log.ConsoleFatalf("Failed to write dashboard: %s", err)
return
}
if n != len(out) {
log.ConsoleFatalf("Failed to write dashboard: wrote %d expected %d", n, len(out))
return
}
}
-230
View File
@@ -1,230 +0,0 @@
package cmd
import (
"fmt"
"os"
"text/tabwriter"
"github.com/codegangsta/cli"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
m "github.com/grafana/grafana/pkg/models"
)
var (
ListDataSources = cli.Command{
Name: "datasources",
Usage: "list datasources",
Description: "Lists the datasources in the system",
Action: listDatasources,
}
CreateDataSource = cli.Command{
Name: "datasources:create",
Usage: "creates a new datasource",
Description: "Creates a new datasource",
Action: createDataSource,
Flags: []cli.Flag{
cli.StringFlag{
Name: "type",
Value: "graphite",
Usage: fmt.Sprintf("Datasource type [%s,%s,%s,%s]",
m.DS_GRAPHITE, m.DS_INFLUXDB, m.DS_ES, m.DS_OPENTSDB),
},
cli.StringFlag{
Name: "access",
Value: "proxy",
Usage: "Datasource access [proxy,direct]",
},
cli.BoolFlag{
Name: "default",
Usage: "Make this the default datasource",
},
cli.StringFlag{
Name: "db",
Usage: "InfluxDB DB",
},
cli.StringFlag{
Name: "user",
Usage: "InfluxDB username",
},
cli.StringFlag{
Name: "password",
Usage: "InfluxDB password",
},
},
}
DescribeDataSource = cli.Command{
Name: "datasources:info",
Usage: "describe the details of a datasource",
Description: "Describes the details of a datasource",
Action: describeDataSource,
}
DeleteDataSource = cli.Command{
Name: "datasources:delete",
Usage: "Deletes a datasource",
Description: "Deletes a datasource",
Action: deleteDataSource,
}
)
func createDataSource(c *cli.Context) {
initRuntime(c)
if len(c.Args()) != 3 {
log.ConsoleFatal("Missing required arguments")
}
name := c.Args().First()
ds := c.Args()[1]
url := c.Args()[2]
dsType := c.String("type")
dsAccess := c.String("access")
dsDefault := c.Bool("default")
orgQuery := m.GetOrgByNameQuery{Name: name}
if err := bus.Dispatch(&orgQuery); err != nil {
log.ConsoleFatalf("Failed to find organization: %s", err)
}
orgId := orgQuery.Result.Id
query := m.GetDataSourceByNameQuery{OrgId: orgId, Name: ds}
if err := bus.Dispatch(&query); err != nil {
if err != m.ErrDataSourceNotFound {
log.ConsoleFatalf("Failed to query for existing datasource: %s", err)
}
}
if query.Result.Id > 0 {
log.ConsoleFatalf("DataSource %s already exists", ds)
}
cmd := m.AddDataSourceCommand{
OrgId: orgId,
Name: ds,
Url: url,
Type: dsType,
Access: m.DsAccess(dsAccess),
IsDefault: dsDefault,
}
switch dsType {
case m.DS_INFLUXDB:
db := c.String("db")
if db == "" {
log.ConsoleFatal("db name is required for influxdb datasources")
}
cmd.Database = db
cmd.User = c.String("user")
cmd.Password = c.String("password")
}
if err := bus.Dispatch(&cmd); err != nil {
log.ConsoleFatalf("Failed to create datasource: %s", err)
}
datasource := cmd.Result
log.ConsoleInfof("Datasource %s created", datasource.Name)
}
func listDatasources(c *cli.Context) {
initRuntime(c)
if !c.Args().Present() {
log.ConsoleFatal("Account name arg is required")
}
name := c.Args().First()
orgQuery := m.GetOrgByNameQuery{Name: name}
if err := bus.Dispatch(&orgQuery); err != nil {
log.ConsoleFatalf("Failed to find organization: %s", err)
}
orgId := orgQuery.Result.Id
query := m.GetDataSourcesQuery{OrgId: orgId}
if err := bus.Dispatch(&query); err != nil {
log.ConsoleFatalf("Failed to find datasources: %s", err)
}
w := tabwriter.NewWriter(os.Stdout, 8, 1, 4, ' ', 0)
fmt.Fprintf(w, "ID\tNAME\tURL\tTYPE\tACCESS\tDEFAULT\n")
for _, ds := range query.Result {
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\n", ds.Id, ds.Name, ds.Url, ds.Type,
ds.Access, ds.IsDefault)
}
w.Flush()
}
func describeDataSource(c *cli.Context) {
initRuntime(c)
if len(c.Args()) != 2 {
log.ConsoleFatal("Organization and datasource name args are required")
}
name := c.Args().First()
ds := c.Args()[1]
orgQuery := m.GetOrgByNameQuery{Name: name}
if err := bus.Dispatch(&orgQuery); err != nil {
log.ConsoleFatalf("Failed to find organization: %s", err)
}
orgId := orgQuery.Result.Id
query := m.GetDataSourceByNameQuery{OrgId: orgId, Name: ds}
if err := bus.Dispatch(&query); err != nil {
log.ConsoleFatalf("Failed to find datasource: %s", err)
}
datasource := query.Result
w := tabwriter.NewWriter(os.Stdout, 8, 1, 4, ' ', 0)
fmt.Fprintf(w, "NAME\t%s\n", datasource.Name)
fmt.Fprintf(w, "URL\t%s\n", datasource.Url)
fmt.Fprintf(w, "DEFAULT\t%t\n", datasource.IsDefault)
fmt.Fprintf(w, "ACCESS\t%s\n", datasource.Access)
fmt.Fprintf(w, "TYPE\t%s\n", datasource.Type)
switch datasource.Type {
case m.DS_INFLUXDB:
fmt.Fprintf(w, "DATABASE\t%s\n", datasource.Database)
fmt.Fprintf(w, "DB USER\t%s\n", datasource.User)
fmt.Fprintf(w, "DB PASSWORD\t%s\n", datasource.Password)
case m.DS_ES:
fmt.Fprintf(w, "INDEX\t%s\n", datasource.Database)
}
w.Flush()
}
func deleteDataSource(c *cli.Context) {
initRuntime(c)
if len(c.Args()) != 2 {
log.ConsoleFatal("Account and datasource name args are required")
}
name := c.Args().First()
ds := c.Args()[1]
orgQuery := m.GetOrgByNameQuery{Name: name}
if err := bus.Dispatch(&orgQuery); err != nil {
log.ConsoleFatalf("Failed to find organization: %s", err)
}
orgId := orgQuery.Result.Id
query := m.GetDataSourceByNameQuery{OrgId: orgId, Name: ds}
if err := bus.Dispatch(&query); err != nil {
log.ConsoleFatalf("Failed to find datasource: %s", err)
}
datasource := query.Result
cmd := m.DeleteDataSourceCommand{OrgId: orgId, Id: datasource.Id}
if err := bus.Dispatch(&cmd); err != nil {
log.ConsoleFatalf("Failed to delete datasource: %s", err)
}
log.ConsoleInfof("DataSource %s deleted", ds)
}
-99
View File
@@ -1,99 +0,0 @@
package cmd
import (
"fmt"
"os"
"text/tabwriter"
"github.com/codegangsta/cli"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
)
var ListOrgs = cli.Command{
Name: "orgs",
Usage: "list organizations",
Description: "Lists the organizations in the system",
Action: listOrgs,
}
var CreateOrg = cli.Command{
Name: "orgs:create",
Usage: "Creates a new organization",
Description: "Creates a new organization",
Action: createOrg,
}
var DeleteOrg = cli.Command{
Name: "orgs:delete",
Usage: "Delete an existing organization",
Description: "Deletes an existing organization",
Action: deleteOrg,
}
func listOrgs(c *cli.Context) {
initRuntime(c)
orgsQuery := m.GetOrgListQuery{}
if err := bus.Dispatch(&orgsQuery); err != nil {
log.ConsoleFatalf("Failed to find organizations: %s", err)
}
w := tabwriter.NewWriter(os.Stdout, 8, 1, 4, ' ', 0)
fmt.Fprintf(w, "ID\tNAME\n")
for _, org := range orgsQuery.Result {
fmt.Fprintf(w, "%d\t%s\n", org.Id, org.Name)
}
w.Flush()
}
func createOrg(c *cli.Context) {
initRuntime(c)
if !c.Args().Present() {
log.ConsoleFatal("Organization name arg is required")
}
name := c.Args().First()
adminQuery := m.GetUserByLoginQuery{LoginOrEmail: setting.AdminUser}
if err := bus.Dispatch(&adminQuery); err == m.ErrUserNotFound {
log.ConsoleFatalf("Failed to find default admin user: %s", err)
}
adminUser := adminQuery.Result
cmd := m.CreateOrgCommand{Name: name, UserId: adminUser.Id}
if err := bus.Dispatch(&cmd); err != nil {
log.ConsoleFatalf("Failed to create organization: %s", err)
}
log.ConsoleInfof("Organization %s created for admin user %s\n", name, adminUser.Email)
}
func deleteOrg(c *cli.Context) {
initRuntime(c)
if !c.Args().Present() {
log.ConsoleFatal("Organization name arg is required")
}
name := c.Args().First()
orgQuery := m.GetOrgByNameQuery{Name: name}
if err := bus.Dispatch(&orgQuery); err != nil {
log.ConsoleFatalf("Failed to find organization: %s", err)
}
orgId := orgQuery.Result.Id
cmd := m.DeleteOrgCommand{Id: orgId}
if err := bus.Dispatch(&cmd); err != nil {
log.ConsoleFatalf("Failed to delete organization: %s", err)
}
log.ConsoleInfof("Organization %s deleted", name)
}
+2 -47
View File
@@ -5,38 +5,22 @@ package cmd
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
"path/filepath"
"strconv"
"github.com/Unknwon/macaron"
"github.com/codegangsta/cli"
"github.com/grafana/grafana/pkg/api"
"github.com/grafana/grafana/pkg/api/static"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/eventpublisher"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/social"
)
var Web = cli.Command{
Name: "web",
Usage: "Starts Grafana backend & web server",
Description: "Starts Grafana backend & web server",
Action: runWeb,
}
func newMacaron() *macaron.Macaron {
macaron.Env = setting.Env
m := macaron.New()
m.Use(middleware.Logger())
m.Use(macaron.Recovery())
@@ -83,22 +67,12 @@ func mapStatic(m *macaron.Macaron, dir string, prefix string) {
))
}
func runWeb(c *cli.Context) {
initRuntime(c)
writePIDFile(c)
social.NewOAuthService()
eventpublisher.Init()
plugins.Init()
func StartServer() {
var err error
m := newMacaron()
api.Register(m)
if setting.ReportingEnabled {
go metrics.StartUsageReportLoop()
}
listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
switch setting.Protocol {
@@ -114,22 +88,3 @@ func runWeb(c *cli.Context) {
log.Fatal(4, "Fail to start server: %v", err)
}
}
func writePIDFile(c *cli.Context) {
path := c.GlobalString("pidfile")
if path == "" {
return
}
// Ensure the required directory structure exists.
err := os.MkdirAll(filepath.Dir(path), 0700)
if err != nil {
log.Fatal(3, "Failed to verify pid directory", err)
}
// Retrieve the PID and write it.
pid := strconv.Itoa(os.Getpid())
if err := ioutil.WriteFile(path, []byte(pid), 0644); err != nil {
log.Fatal(3, "Failed to write pidfile", err)
}
}