pull/1022/merge^2
Jade McGough 2017-03-22 01:40:30 -07:00
parent 36ffe0c436
commit 056abde56d
7 changed files with 116 additions and 62 deletions

View File

@ -59,6 +59,8 @@ type TimeSeries interface {
Permissions(context.Context) Permissions
// Roles represents the roles associated with this TimesSeriesDatabase
Roles(context.Context) (RolesStore, error)
// Databases represents the named databases within an InfluxDB instance
Databases(context.Context) Databases
}
// Role is a restricted set of permissions assigned to a set of users.
@ -294,6 +296,18 @@ type UsersStore interface {
Update(context.Context, *User) error
}
// type Database struct {
// Name string `json:"name"` // a unique string identifier for the database
// Duration string `json:"duration,omitempty"` // the duration (when creating a default retention policy)
// Replication int32 `json:"replication,omitempty"` // the replication factor (when creating a default retention policy)
// ShardDuration string `json:shardDuration,omitempty` // the shard duration (when creating a default retention policy)
// }
//
// type Databases interface {
// // All lists all databases
// AllDB(context.Context) ([]Database, error)
// }
// DashboardID is the dashboard ID
type DashboardID int

View File

@ -34,6 +34,8 @@ type Ctrl interface {
SetRoleUsers(ctx context.Context, name string, users []string) error
AddRoleUsers(ctx context.Context, name string, users []string) error
RemoveRoleUsers(ctx context.Context, name string, users []string) error
Databases(ctx context.Context) (*Databases, error)
}
// Client is a device for retrieving time series data from an Influx Enterprise

View File

@ -65,6 +65,17 @@ type RoleAction struct {
Role *Role `json:"role"`
}
type Database struct {
Name string `json:"name"` // a unique string identifier for the database
Duration string `json:"duration,omitempty"` // the duration (when creating a default retention policy)
Replication int32 `json:"replication,omitempty"` // the replication factor (when creating a default retention policy)
ShardDuration string `json:shardDuration,omitempty` // the shard duration (when creating a default retention policy)
}
type Databases struct {
Databases []Database `json:"databases,omitempty"`
}
// Error is JSON error message return by Influx Enterprise's meta API.
type Error struct {
Error string `json:"error"`

View File

@ -180,6 +180,10 @@ func (c *Client) Users(ctx context.Context) chronograf.UsersStore {
return c
}
func (c *Client) Databases(ctx context.Context) chronograf.Databases {
return c
}
// Roles aren't support in OSS
func (c *Client) Roles(ctx context.Context) (chronograf.RolesStore, error) {
return nil, fmt.Errorf("Roles not support in open-source InfluxDB. Roles are support in Influx Enterprise")

View File

@ -75,6 +75,24 @@ func (r *showResults) Users() []chronograf.User {
return res
}
// Databases converts SHOW DATABASES to chronograf Databases
func (r *showResults) Databases() []chronograf.Database {
res := []chronograf.Database{}
for _, u := range *r {
for _, s := range u.Series {
for _, v := range s.Values {
if name, ok := v[0].(string); !ok {
continue
} else {
d := chronograf.Database{Name: name}
res = append(res, d)
}
}
}
}
return res
}
// Permissions converts SHOW GRANTS to chronograf.Permissions
func (r *showResults) Permissions() chronograf.Permissions {
res := []chronograf.Permission{}

View File

@ -12,7 +12,7 @@ type dbLinks struct {
RPs string `json:"rps"` // URL for retention policies for this database
}
type database struct {
type dbResponse struct {
Name string `json:"name"` // a unique string identifier for the database
Duration string `json:"duration,omitempty"` // the duration (when creating a default retention policy)
Replication int32 `json:"replication,omitempty"` // the replication factor (when creating a default retention policy)
@ -20,62 +20,67 @@ type database struct {
Links dbLinks `json:links` // Links are URI locations related to the database
}
type postInfluxResponze struct {
Results interface{} `json:"results"` // results from influx
type dbsResponse struct {
Databases []dbResponse `json:"databases"`
}
// type influxResponse struct {
// Results interface{} `json:"results"` // results from influx
// }
// func (h *Service) sourcesSeries(ctx context.Context, w http.ResponseWriter, r *http.Request) (int, chronograf.TimeSeries, error) {
// srcID, err := paramID("id", r)
// if err != nil {
// Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
// return 0, nil, err
// }
//
// src, err := h.SourcesStore.Get(ctx, srcID)
// if err != nil {
// notFound(w, srcID, h.Logger)
// return 0, nil, err
// }
//
// ts, err := h.TimeSeries(src)
// if err != nil {
// msg := fmt.Sprintf("Unable to connect to source %d: %v", srcID, err)
// Error(w, http.StatusBadRequest, msg, h.Logger)
// return 0, nil, err
// }
//
// if err = ts.Connect(ctx, &src); err != nil {
// msg := fmt.Sprintf("Unable to connect to source %d: %v", srcID, err)
// Error(w, http.StatusBadRequest, msg, h.Logger)
// return 0, nil, err
// }
// return srcID, ts, nil
// }
// Databases queries the list of all databases for a source
func (h *Service) Databases(w http.ResponseWriter, r *http.Request) {
id, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
ctx := r.Context()
srcID, ts, err := h.sourcesSeries(ctx, w, r)
if err != nil {
return
}
store := ts.Databases(ctx)
databases, err := store.All(ctx)
if err != nil {
Error(w, http.StatusBadRequest, err.Error(), h.Logger)
return
}
dbs := make([]dbResponse, len(databases))
for i, d := range databases {
}
// res = append(res, database{Name: response})
res := dbsResponse{
Databases: dbs,
}
// res := []database{}
// move this influxdb communication code somewhere else after it's working
// START
ctx := r.Context()
src, err := h.SourcesStore.Get(ctx, id)
if err != nil {
notFound(w, id, h.Logger)
return
}
ts, err := h.TimeSeries(src)
if err != nil {
msg := fmt.Sprintf("Unable to connect to source %d: %v", id, err)
Error(w, http.StatusBadRequest, msg, h.Logger)
return
}
if err = ts.Connect(ctx, &src); err != nil {
msg := fmt.Sprintf("Unable to connect to source %d: %v", id, err)
Error(w, http.StatusBadRequest, msg, h.Logger)
return
}
req := chronograf.Query{Command: "SHOW DATABASES"}
response, err := ts.Query(ctx, req)
if err != nil {
if err == chronograf.ErrUpstreamTimeout {
msg := "Timeout waiting for Influx response"
Error(w, http.StatusRequestTimeout, msg, h.Logger)
return
}
// TODO: Here I want to return the error code from influx.
Error(w, http.StatusBadRequest, err.Error(), h.Logger)
return
}
res := postInfluxResponze{
Results: response,
}
//fmt.Printf("%+v\n", foo)
// END
encodeJSON(w, http.StatusOK, res, h.Logger)
}

View File

@ -133,16 +133,16 @@ func NewMux(opts MuxOpts, service Service) http.Handler {
// Databases
router.GET("/chronograf/v1/sources/:id/dbs", service.Databases)
router.POST("/chronograf/v1/sources/:id/dbs", service.NewDatabase)
router.DELETE("/chronograf/v1/sources/:id/dbs/:did", service.DropDatabase)
// Retention Policies
router.GET("/chronograf/v1/sources/:id/dbs/:did/rps", service.RetentionPolicies)
router.POST("/chronograf/v1/sources/:id/dbs/:did/rps", service.NewRetentionPolicy)
router.PATCH("/chronograf/v1/sources/:id/dbs/:did/rps/:rpid", service.UpdateRetentionPolicy)
router.DELETE("/chronograf/v1/sources/:id/dbs/:did/rps/:rpid", service.DropRetentionPolicy)
// router.POST("/chronograf/v1/sources/:id/dbs", service.NewDatabase)
//
// router.DELETE("/chronograf/v1/sources/:id/dbs/:did", service.DropDatabase)
//
// // Retention Policies
// router.GET("/chronograf/v1/sources/:id/dbs/:did/rps", service.RetentionPolicies)
// router.POST("/chronograf/v1/sources/:id/dbs/:did/rps", service.NewRetentionPolicy)
//
// router.PATCH("/chronograf/v1/sources/:id/dbs/:did/rps/:rpid", service.UpdateRetentionPolicy)
// router.DELETE("/chronograf/v1/sources/:id/dbs/:did/rps/:rpid", service.DropRetentionPolicy)
var authRoutes AuthRoutes