Skip to content

Commit

Permalink
internal/v2: add GetControllerLocations endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
rogpeppe committed Apr 26, 2016
1 parent c6796c6 commit 1c88dc1
Show file tree
Hide file tree
Showing 6 changed files with 314 additions and 80 deletions.
3 changes: 2 additions & 1 deletion internal/jem/jem.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,10 @@ func (j *JEM) DeleteTemplate(path params.EntityPath) error {

// ControllerLocationQuery returns a mongo query that iterates through
// all the controllers matching the given location attributes.
// It returns an error if the location attribute keys aren't valid.
func (j *JEM) ControllerLocationQuery(location map[string]string) (*mgo.Query, error) {
if err := validateLocationAttrs(location); err != nil {
return nil, errgo.WithCausef(err, params.ErrBadRequest, "bad controller location query")
return nil, errgo.Notef(err, "bad controller location query")
}
q := make(bson.D, 0, len(location))
for attr, val := range location {
Expand Down
46 changes: 46 additions & 0 deletions internal/v2/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package v2

import (
"reflect"
"sort"
"strings"

"github.com/juju/httprequest"
Expand Down Expand Up @@ -333,6 +334,51 @@ func (h *Handler) ListController(arg *params.ListController) (*params.ListContro
}, nil
}

// GetControllerLocations returns all the available values for a given controller
// location attribute. The set of controllers is constrained by the URL query
// parameters.
func (h *Handler) GetControllerLocations(p httprequest.Params, arg *params.GetControllerLocations) (*params.ControllerLocationsResponse, error) {
attr := arg.Attr
if !params.IsValidLocationAttr(attr) {
return nil, badRequestf(nil, "invalid location %q", attr)
}
// Make the required attributes from the HTTP URL query parameters.
attrs := make(map[string]string)
for attr, vals := range p.Request.Form {
if len(vals) > 0 {
attrs[attr] = vals[0]
}
}
found := make(map[string]bool)

// Query all the controllers that match the attributes, building
// up all the possible values.
q, err := h.jem.ControllerLocationQuery(attrs)
if err != nil {
return nil, errgo.WithCausef(err, params.ErrBadRequest, "%s", "")
}
iter := h.jem.CanReadIter(q.Iter())
var ctl mongodoc.Controller
for iter.Next(&ctl) {
if val, ok := ctl.Location[attr]; ok {
found[val] = true
}
}
if err := iter.Err(); err != nil {
return nil, errgo.Notef(err, "cannot query")
}

// Build the result slice and sort it so we get deterministic results.
results := make([]string, 0, len(found))
for val := range found {
results = append(results, val)
}
sort.Strings(results)
return &params.ControllerLocationsResponse{
Values: results,
}, nil
}

// configWithTemplates returns the given configuration applied
// along with the given templates.
// Each template is applied in turn, then the configuration
Expand Down
Loading

0 comments on commit 1c88dc1

Please sign in to comment.