Example #1
0
func (api *API) UpdateRoute(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	log, _ := ctxhelper.LoggerFromContext(ctx)
	params, _ := ctxhelper.ParamsFromContext(ctx)

	var route *router.Route
	if err := json.NewDecoder(req.Body).Decode(&route); err != nil {
		log.Error(err.Error())
		httphelper.Error(w, err)
		return
	}

	route.Type = params.ByName("route_type")
	route.ID = params.ByName("id")

	l := api.router.ListenerFor(route.Type)
	if l == nil {
		httphelper.ValidationError(w, "type", "Invalid route type")
		return
	}

	if err := l.UpdateRoute(route); err != nil {
		if err == ErrNotFound {
			w.WriteHeader(404)
			return
		}
		log.Error(err.Error())
		httphelper.Error(w, err)
		return
	}
	httphelper.JSON(w, 200, route)
}
Example #2
0
func (c *controllerAPI) KillJob(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	job, err := c.jobRepo.Get(params.ByName("jobs_id"))
	if err != nil {
		respondWithError(w, err)
		return
	} else if job.HostID == "" {
		httphelper.ValidationError(w, "", "cannot kill a job which has not been placed on a host")
		return
	}

	client, err := c.clusterClient.Host(job.HostID)
	if err != nil {
		respondWithError(w, err)
		return
	}

	if err = client.StopJob(job.ID); err != nil {
		if _, ok := err.(ct.NotFoundError); ok {
			err = ErrNotFound
		}
		respondWithError(w, err)
		return
	}
}
Example #3
0
func (api *API) DeleteRoute(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	log, _ := ctxhelper.LoggerFromContext(ctx)
	params, _ := ctxhelper.ParamsFromContext(ctx)

	l := api.router.ListenerFor(params.ByName("route_type"))
	if l == nil {
		w.WriteHeader(404)
		return
	}

	err := l.RemoveRoute(params.ByName("id"))
	if err != nil {
		switch err {
		case ErrNotFound:
			w.WriteHeader(404)
			return
		case ErrInvalid:
			httphelper.Error(w, httphelper.JSONError{
				Code:    httphelper.ValidationErrorCode,
				Message: "Route has dependent routes",
			})
			return
		default:
			log.Error(err.Error())
			httphelper.Error(w, err)
			return
		}
	}
	w.WriteHeader(200)
}
Example #4
0
File: app.go Project: imjorge/flynn
func (c *controllerAPI) UpdateApp(ctx context.Context, rw http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	var data appUpdate
	if err := httphelper.DecodeJSON(req, &data); err != nil {
		respondWithError(rw, err)
		return
	}

	if v, ok := data["meta"]; ok && v == nil {
		// handle {"meta": null}
		delete(data, "meta")
	}

	if err := schema.Validate(data); err != nil {
		respondWithError(rw, err)
		return
	}

	app, err := c.appRepo.Update(params.ByName("apps_id"), data)
	if err != nil {
		respondWithError(rw, err)
		return
	}
	httphelper.JSON(rw, 200, app)
}
Example #5
0
func (c *controllerAPI) DeleteResource(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	id := params.ByName("resources_id")

	p, err := c.getProvider(ctx)
	if err != nil {
		respondWithError(w, err)
		return
	}

	res, err := c.resourceRepo.Get(id)
	if err != nil {
		respondWithError(w, err)
		return
	}

	if err := resource.Deprovision(p.URL, res.ExternalID); err != nil {
		respondWithError(w, err)
		return
	}

	if err := c.resourceRepo.Remove(res); err != nil {
		respondWithError(w, err)
		return
	}

	httphelper.JSON(w, 200, res)
}
Example #6
0
func (c *controllerAPI) PutResource(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	p, err := c.getProvider(ctx)
	if err != nil {
		respondWithError(w, err)
		return
	}

	var resource ct.Resource
	if err = httphelper.DecodeJSON(req, &resource); err != nil {
		respondWithError(w, err)
		return
	}

	resource.ID = params.ByName("resources_id")
	resource.ProviderID = p.ID

	if err := schema.Validate(resource); err != nil {
		respondWithError(w, err)
		return
	}

	if err := c.resourceRepo.Add(&resource); err != nil {
		respondWithError(w, err)
		return
	}
	httphelper.JSON(w, 200, &resource)
}
Example #7
0
func (c *controllerAPI) UpdateAppMeta(ctx context.Context, rw http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	var data appUpdate
	if err := httphelper.DecodeJSON(req, &data); err != nil {
		respondWithError(rw, err)
		return
	}

	if err := schema.Validate(data); err != nil {
		respondWithError(rw, err)
		return
	}

	if data["meta"] == nil {
		data["meta"] = make(map[string]interface{})
	}

	app, err := c.appRepo.Update(params.ByName("apps_id"), data)
	if err != nil {
		respondWithError(rw, err)
		return
	}
	httphelper.JSON(rw, 200, app)
}
Example #8
0
func (c *controllerAPI) getRelease(ctx context.Context) (*ct.Release, error) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	data, err := c.releaseRepo.Get(params.ByName("releases_id"))
	if err != nil {
		return nil, err
	}
	return data.(*ct.Release), nil
}
Example #9
0
func (c *controllerAPI) getProvider(ctx context.Context) (*ct.Provider, error) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	data, err := c.providerRepo.Get(params.ByName("providers_id"))
	if err != nil {
		return nil, err
	}
	return data.(*ct.Provider), nil
}
Example #10
0
func (a *aggregatorAPI) GetLog(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	ctx, cancel := context.WithCancel(ctx)
	if cn, ok := w.(http.CloseNotifier); ok {
		ch := cn.CloseNotify()
		go func() {
			select {
			case <-ch:
				cancel()
			case <-ctx.Done():
			}
		}()
	}
	defer cancel()

	params, _ := ctxhelper.ParamsFromContext(ctx)

	follow := false
	if strFollow := req.FormValue("follow"); strFollow == "true" {
		follow = true
	}

	var (
		backlog bool
		lines   int
		err     error
	)
	if strLines := req.FormValue("lines"); strLines != "" {
		if lines, err = strconv.Atoi(strLines); err != nil {
			httphelper.ValidationError(w, "lines", err.Error())
			return
		}
		if lines < 0 || lines > 10000 {
			httphelper.ValidationError(w, "lines", "lines must be an integer between 0 and 10000")
			return
		}
		backlog = lines > 0
	}

	filters := make(filterSlice, 0)
	if jobID := req.FormValue("job_id"); jobID != "" {
		filters = append(filters, filterJobID(jobID))
	}
	if processTypeVals, ok := req.Form["process_type"]; ok && len(processTypeVals) > 0 {
		val := processTypeVals[len(processTypeVals)-1]
		filters = append(filters, filterProcessType(val))
	}

	iter := &Iterator{
		id:      params.ByName("channel_id"),
		follow:  follow,
		backlog: backlog,
		lines:   lines,
		filter:  filters,
		donec:   ctx.Done(),
	}

	writeMessages(ctx, w, iter.Scan(a.agg))
}
Example #11
0
func (c *controllerAPI) GetJob(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	job, err := c.jobRepo.Get(params.ByName("jobs_id"))
	if err != nil {
		respondWithError(w, err)
		return
	}
	httphelper.JSON(w, 200, job)
}
Example #12
0
func (c *controllerAPI) GetDeployment(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	deployment, err := c.deploymentRepo.Get(params.ByName("deployment_id"))
	if err != nil {
		respondWithError(w, err)
		return
	}
	httphelper.JSON(w, 200, deployment)
}
Example #13
0
func (c *controllerAPI) connectHost(ctx context.Context) (utils.HostClient, string, error) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	hostID, jobID, err := cluster.ParseJobID(params.ByName("jobs_id"))
	if err != nil {
		log.Printf("Unable to parse hostID from %q", params.ByName("jobs_id"))
		return nil, jobID, err
	}

	host, err := c.clusterClient.Host(hostID)
	return host, jobID, err
}
Example #14
0
func (c *controllerAPI) getRoute(ctx context.Context) (*router.Route, error) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	route, err := c.routerc.GetRoute(params.ByName("routes_type"), params.ByName("routes_id"))
	if err == routerc.ErrNotFound || err == nil && route.ParentRef != routeParentRef(c.getApp(ctx).ID) {
		err = ErrNotFound
	}
	if err != nil {
		return nil, err
	}
	return route, err
}
Example #15
0
func (api *API) GetCertRoutes(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	l := api.router.HTTP.(*HTTPListener)
	routes, err := l.GetCertRoutes(params.ByName("id"))
	if err != nil {
		httphelper.Error(w, err)
		return
	}
	httphelper.JSON(w, 200, routes)
}
Example #16
0
func (c *controllerAPI) connectHost(ctx context.Context) (utils.HostClient, *ct.Job, error) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	job, err := c.jobRepo.Get(params.ByName("jobs_id"))
	if err != nil {
		return nil, nil, err
	} else if job.HostID == "" {
		return nil, nil, errors.New("controller: cannot connect host, job has not been placed in the cluster")
	}
	host, err := c.clusterClient.Host(job.HostID)
	return host, job, err
}
Example #17
0
func (c *controllerAPI) GetFormation(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	app := c.getApp(ctx)
	formation, err := c.formationRepo.Get(app.ID, params.ByName("releases_id"))
	if err != nil {
		respondWithError(w, err)
		return
	}
	httphelper.JSON(w, 200, formation)
}
Example #18
0
func (c *controllerAPI) appLookup(handler httphelper.HandlerFunc) httphelper.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		params, _ := ctxhelper.ParamsFromContext(ctx)
		data, err := c.appRepo.Get(params.ByName("apps_id"))
		if err != nil {
			respondWithError(w, err)
			return
		}
		ctx = context.WithValue(ctx, "app", data.(*ct.App))
		handler(ctx, w, req)
	}
}
Example #19
0
func (api *API) ServeAsset(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	path := params.ByName("path")
	if !strings.HasPrefix(path, "/assets/") {
		api.ServeTemplate(ctx, w, req)
		return
	}
	if strings.HasPrefix(path, "/assets/dashboard") && strings.HasSuffix(path, ".js") {
		api.ServeDashboardJs(ctx, w, req)
		return
	}
	api.ServeStatic(ctx, w, req, filepath.Join("app", "build", path))
}
Example #20
0
func (c *controllerAPI) GetEvent(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	id, err := strconv.ParseInt(params.ByName("id"), 10, 64)
	if err != nil {
		respondWithError(w, err)
		return
	}
	event, err := c.eventRepo.GetEvent(id)
	if err != nil {
		respondWithError(w, err)
		return
	}
	httphelper.JSON(w, 200, event)
}
Example #21
0
File: api.go Project: kuntenz/flynn
func (a *aggregatorAPI) GetLog(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	ctx, cancel := context.WithCancel(ctx)
	if cn, ok := w.(http.CloseNotifier); ok {
		go func() {
			select {
			case <-cn.CloseNotify():
				cancel()
			case <-ctx.Done():
			}
		}()
	}
	defer cancel()

	params, _ := ctxhelper.ParamsFromContext(ctx)
	channelID := params.ByName("channel_id")

	follow := false
	if strFollow := req.FormValue("follow"); strFollow == "true" {
		follow = true
	}

	lines := -1 // default to all lines
	if strLines := req.FormValue("lines"); strLines != "" {
		var err error
		lines, err = strconv.Atoi(strLines)
		if err != nil || lines < 0 || lines > 10000 {
			httphelper.ValidationError(w, "lines", "lines must be an integer between 0 and 10000")
			return
		}
	}

	filters := make(filterSlice, 0)
	if jobID := req.FormValue("job_id"); jobID != "" {
		filters = append(filters, filterJobID(jobID))
	}
	if processTypeVals, ok := req.Form["process_type"]; ok && len(processTypeVals) > 0 {
		val := processTypeVals[len(processTypeVals)-1]
		filters = append(filters, filterProcessType(val))
	}

	w.WriteHeader(200)

	var msgc <-chan *rfc5424.Message
	if follow {
		msgc = a.agg.ReadLastNAndSubscribe(channelID, lines, filters, ctx.Done())
	} else {
		msgc = a.agg.ReadLastN(channelID, lines, filters, ctx.Done())
	}
	writeMessages(ctx, w, msgc)
}
Example #22
0
func (c *controllerAPI) GetResource(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	_, err := c.getProvider(ctx)
	if err != nil {
		respondWithError(w, err)
		return
	}

	res, err := c.resourceRepo.Get(params.ByName("resources_id"))
	if err != nil {
		respondWithError(w, err)
		return
	}
	httphelper.JSON(w, 200, res)
}
Example #23
0
func (c *controllerAPI) DeleteFormation(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	app := c.getApp(ctx)
	formation, err := c.formationRepo.Get(app.ID, params.ByName("releases_id"))
	if err != nil {
		respondWithError(w, err)
		return
	}
	err = c.formationRepo.Remove(app.ID, formation.ReleaseID)
	if err != nil {
		respondWithError(w, err)
		return
	}
	w.WriteHeader(200)
}
Example #24
0
func (api *API) GetCert(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	l := api.router.HTTP.(*HTTPListener)
	cert, err := l.GetCert(params.ByName("id"))
	if err == ErrNotFound {
		httphelper.ObjectNotFoundError(w, "certificate not found")
		return
	}
	if err != nil {
		httphelper.Error(w, err)
		return
	}

	httphelper.JSON(w, 200, cert)
}
Example #25
0
func (api *API) DeleteCert(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	l := api.router.HTTP.(*HTTPListener)
	err := l.RemoveCert(params.ByName("id"))
	if err != nil {
		switch err {
		case ErrNotFound:
			httphelper.ObjectNotFoundError(w, "certificate not found")
			return
		default:
			httphelper.Error(w, err)
			return
		}
	}
	w.WriteHeader(200)
}
Example #26
0
func (c *controllerAPI) GetFormation(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)

	app := c.getApp(ctx)
	releaseID := params.ByName("releases_id")
	if req.URL.Query().Get("expand") == "true" {
		formation, err := c.formationRepo.GetExpanded(app.ID, releaseID)
		if err != nil {
			respondWithError(w, err)
			return
		}
		httphelper.JSON(w, 200, formation)
		return
	}

	formation, err := c.formationRepo.Get(app.ID, releaseID)
	if err != nil {
		respondWithError(w, err)
		return
	}
	httphelper.JSON(w, 200, formation)
}
Example #27
0
func (c *controllerAPI) DeleteResource(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	params, _ := ctxhelper.ParamsFromContext(ctx)
	id := params.ByName("resources_id")

	logger.Info("getting provider", "params", params)

	p, err := c.getProvider(ctx)
	if err != nil {
		logger.Error("getting provider error", "err", err)
		respondWithError(w, err)
		return
	}

	logger.Info("getting resource", "id", id)
	res, err := c.resourceRepo.Get(id)
	if err != nil {
		logger.Error("getting resource error", "err", err)
		respondWithError(w, err)
		return
	}

	logger.Info("deprovisioning", "url", p.URL, "external.id", res.ExternalID)
	if err := resource.Deprovision(p.URL, res.ExternalID); err != nil {
		logger.Error("error deprovisioning", "err", err)
		respondWithError(w, err)
		return
	}

	logger.Info("removing resource")
	if err := c.resourceRepo.Remove(res); err != nil {
		logger.Error("error removing resource", "err", err)
		respondWithError(w, err)
		return
	}
	logger.Info("completed resource removal")

	httphelper.JSON(w, 200, res)
}
Example #28
0
func (api *API) GetRoute(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	log, _ := ctxhelper.LoggerFromContext(ctx)
	params, _ := ctxhelper.ParamsFromContext(ctx)

	l := api.router.ListenerFor(params.ByName("route_type"))
	if l == nil {
		w.WriteHeader(404)
		return
	}

	route, err := l.Get(params.ByName("id"))
	if err == ErrNotFound {
		w.WriteHeader(404)
		return
	}
	if err != nil {
		log.Error(err.Error())
		httphelper.Error(w, err)
		return
	}

	httphelper.JSON(w, 200, route)
}
Example #29
0
func (a *aggregatorAPI) GetLog(ctx context.Context, w http.ResponseWriter, req *http.Request) {
	ctx, cancel := context.WithCancel(ctx)
	if cn, ok := w.(http.CloseNotifier); ok {
		go func() {
			select {
			case <-cn.CloseNotify():
				cancel()
			case <-ctx.Done():
			}
		}()
	}
	defer cancel()

	params, _ := ctxhelper.ParamsFromContext(ctx)
	channelID := params.ByName("channel_id")

	follow := false
	if strFollow := req.FormValue("follow"); strFollow == "true" {
		follow = true
	}

	lines := -1 // default to all lines
	if strLines := req.FormValue("lines"); strLines != "" {
		var err error
		lines, err = strconv.Atoi(strLines)
		if err != nil || lines < 0 || lines > 10000 {
			httphelper.ValidationError(w, "lines", "lines must be an integer between 0 and 10000")
			return
		}
	}

	filters := make([]filter, 0)
	if strJobID := req.FormValue("job_id"); strJobID != "" {
		filters = append(filters, filterJobID{[]byte(strJobID)})
	}
	if processTypeVals, ok := req.Form["process_type"]; ok && len(processTypeVals) > 0 {
		val := processTypeVals[len(processTypeVals)-1]
		filters = append(filters, filterProcessType{[]byte(val)})
	}

	w.WriteHeader(200)

	var msgc <-chan *rfc5424.Message
	if follow {
		msgc = a.agg.ReadLastNAndSubscribe(channelID, lines, filters, ctx.Done())
		go flushLoop(w.(http.Flusher), 50*time.Millisecond, ctx.Done())
	} else {
		msgc = a.agg.ReadLastN(channelID, lines, filters, ctx.Done())
	}

	enc := json.NewEncoder(w)
	for {
		select {
		case syslogMsg := <-msgc:
			if syslogMsg == nil { // channel is closed / done
				return
			}
			if err := enc.Encode(NewMessageFromSyslog(syslogMsg)); err != nil {
				log15.Error("error writing msg", "err", err)
				return
			}
		case <-ctx.Done():
			return
		}
	}
}
Example #30
0
func crud(r *httprouter.Router, resource string, example interface{}, repo Repository) {
	resourceType := reflect.TypeOf(example)
	prefix := "/" + resource

	r.POST(prefix, httphelper.WrapHandler(func(ctx context.Context, rw http.ResponseWriter, req *http.Request) {
		thing := reflect.New(resourceType).Interface()
		if err := httphelper.DecodeJSON(req, thing); err != nil {
			respondWithError(rw, err)
			return
		}

		if err := schema.Validate(thing); err != nil {
			respondWithError(rw, err)
			return
		}

		if err := repo.Add(thing); err != nil {
			respondWithError(rw, err)
			return
		}
		httphelper.JSON(rw, 200, thing)
	}))

	lookup := func(ctx context.Context) (interface{}, error) {
		params, _ := ctxhelper.ParamsFromContext(ctx)
		return repo.Get(params.ByName(resource + "_id"))
	}

	singletonPath := prefix + "/:" + resource + "_id"
	r.GET(singletonPath, httphelper.WrapHandler(func(ctx context.Context, rw http.ResponseWriter, _ *http.Request) {
		thing, err := lookup(ctx)
		if err != nil {
			respondWithError(rw, err)
			return
		}
		httphelper.JSON(rw, 200, thing)
	}))

	r.GET(prefix, httphelper.WrapHandler(func(ctx context.Context, rw http.ResponseWriter, _ *http.Request) {
		list, err := repo.List()
		if err != nil {
			respondWithError(rw, err)
			return
		}
		httphelper.JSON(rw, 200, list)
	}))

	if remover, ok := repo.(Remover); ok {
		r.DELETE(singletonPath, httphelper.WrapHandler(func(ctx context.Context, rw http.ResponseWriter, _ *http.Request) {
			_, err := lookup(ctx)
			if err != nil {
				respondWithError(rw, err)
				return
			}
			params, _ := ctxhelper.ParamsFromContext(ctx)
			if err = remover.Remove(params.ByName(resource + "_id")); err != nil {
				respondWithError(rw, err)
				return
			}
			rw.WriteHeader(200)
		}))
	}
}