Beispiel #1
0
func (api *HTTPAPI) Send(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	volumeID := ps.ByName("volume_id")

	if !strings.Contains(r.Header.Get("Accept"), snapshotContentType) {
		httphelper.ValidationError(w, "", fmt.Sprintf("must be prepared to accept a content type of %q", snapshotContentType))
		return
	}
	w.Header().Set("Content-Type", snapshotContentType)

	var haves []json.RawMessage
	if err := httphelper.DecodeJSON(r, &haves); err != nil {
		httphelper.Error(w, err)
		return
	}

	err := api.vman.SendSnapshot(volumeID, haves, w)
	if err != nil {
		switch err {
		case volume.ErrNoSuchVolume:
			httphelper.ObjectNotFoundError(w, fmt.Sprintf("no volume with id %q", volumeID))
			return
		default:
			httphelper.Error(w, err)
			return
		}
	}
}
Beispiel #2
0
// serveGetLeader returns the current leader for a service.
func (h *Handler) serveGetLeader(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	// Process as a stream if that's what the client wants.
	if strings.Contains(r.Header.Get("Accept"), "text/event-stream") {
		if !h.Store.IsLeader() {
			h.redirectToLeader(w, r)
			return
		}
		h.serveStream(w, params, discoverd.EventKindLeader)
		return
	}

	// Otherwise retrieve the current leader.
	service := params.ByName("service")
	leader, err := h.Store.ServiceLeader(service)
	if err != nil {
		hh.Error(w, err)
		return
	} else if leader == nil {
		hh.ObjectNotFoundError(w, "no leader found")
		return
	}

	// Write leader to the response.
	hh.JSON(w, 200, leader)
}
Beispiel #3
0
func (api *httpAPI) EventsHandler(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	api.InstallerStackMtx.Lock()
	s := api.InstallerStacks[params.ByName("id")]
	api.InstallerStackMtx.Unlock()
	if s == nil {
		httphelper.ObjectNotFoundError(w, "install instance not found")
		return
	}

	eventChan := make(chan *httpEvent)
	doneChan, errChan := s.Subscribe(eventChan)

	stream := sse.NewStream(w, eventChan, s.logger)
	stream.Serve()

	s.logger.Info(fmt.Sprintf("streaming events for %s", s.ID))

	go func() {
		for {
			select {
			case err := <-errChan:
				s.logger.Info(err.Error())
				stream.Error(err)
			case <-doneChan:
				stream.Close()
				return
			}
		}
	}()

	stream.Wait()
}
Beispiel #4
0
func (api *httpAPI) GetCloudRegions(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	params := req.URL.Query()
	cloud := params.Get("cloud")
	if cloud != "digital_ocean" && cloud != "azure" {
		httphelper.ObjectNotFoundError(w, "")
		return
	}
	credentialID := params.Get("credential_id")
	creds, err := api.Installer.FindCredentials(credentialID)
	if err != nil {
		httphelper.ValidationError(w, "credential_id", "Invalid credential id")
		return
	}
	var res interface{}
	switch cloud {
	case "digital_ocean":
		res, err = api.Installer.ListDigitalOceanRegions(creds)
	case "azure":
		res, err = api.Installer.ListAzureRegions(creds)
	}
	if err != nil {
		httphelper.Error(w, err)
		return
	}
	httphelper.JSON(w, 200, res)
}
Beispiel #5
0
// servePutInstance adds an instance to a service.
func (h *Handler) servePutInstance(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	// Read path parameter.
	service := params.ByName("service")

	// Read instance from request.
	inst := &discoverd.Instance{}
	if err := json.NewDecoder(r.Body).Decode(inst); err != nil {
		hh.Error(w, err)
		return
	}

	// Ensure instance is valid.
	if err := inst.Valid(); err != nil {
		hh.ValidationError(w, "", err.Error())
		return
	}

	// Add instance to service in the store.
	if err := h.Store.AddInstance(service, inst); err == ErrNotLeader {
		h.redirectToLeader(w, r)
		return
	} else if IsNotFound(err) {
		hh.ObjectNotFoundError(w, err.Error())
		return
	} else if err != nil {
		hh.Error(w, err)
		return
	}
}
Beispiel #6
0
func (api *httpAPI) ServeTemplate(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	if req.Header.Get("Accept") == "application/json" {
		s, err := api.Installer.FindBaseCluster(params.ByName("id"))
		if err != nil {
			httphelper.ObjectNotFoundError(w, err.Error())
			return
		}
		httphelper.JSON(w, 200, s)
		return
	}

	manifest, err := api.AssetManifest()
	if err != nil {
		httphelper.Error(w, err)
		api.logger.Debug(err.Error())
		return
	}

	w.Header().Add("Content-Type", "text/html; charset=utf-8")
	w.Header().Add("Cache-Control", "max-age=0")

	err = htmlTemplate.Execute(w, &htmlTemplateData{
		ApplicationJSPath:  manifest.Assets["application.js"],
		ApplicationCSSPath: manifest.Assets["application.css"],
		ReactJSPath:        manifest.Assets["react.js"],
	})
	if err != nil {
		httphelper.Error(w, err)
		api.logger.Debug(err.Error())
		return
	}
}
Beispiel #7
0
func (h *httpAPI) GetServiceMeta(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	meta := h.Store.GetServiceMeta(params.ByName("service"))
	if meta == nil {
		hh.ObjectNotFoundError(w, "service meta not found")
		return
	}
	hh.JSON(w, 200, meta)
}
Beispiel #8
0
func (api *httpAPI) GetCert(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	cluster, err := api.Installer.FindBaseCluster(params.ByName("id"))
	if err != nil {
		httphelper.ObjectNotFoundError(w, err.Error())
		return
	}
	w.Header().Set("Content-Type", "application/x-x509-ca-cert")
	w.Header().Set("Content-Disposition", `attachment; filename="flynn-ca.cer"`)
	w.Write([]byte(cluster.CACert))
}
Beispiel #9
0
func (h *httpAPI) RemoveInstance(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	if err := h.Store.RemoveInstance(params.ByName("service"), params.ByName("instance_id")); err != nil {
		if IsNotFound(err) {
			hh.ObjectNotFoundError(w, err.Error())
		} else {
			hh.Error(w, err)
		}
		return
	}
}
Beispiel #10
0
func (api *HTTPAPI) Inspect(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	volumeID := ps.ByName("volume_id")
	vol := api.vman.GetVolume(volumeID)
	if vol == nil {
		httphelper.ObjectNotFoundError(w, fmt.Sprintf("no volume with id %q", volumeID))
		return
	}

	httphelper.JSON(w, 200, vol.Info())
}
Beispiel #11
0
func (api *HTTPAPI) Create(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	providerID := ps.ByName("provider_id")

	vol, err := api.vman.NewVolumeFromProvider(providerID)
	if err == volumemanager.NoSuchProvider {
		httphelper.ObjectNotFoundError(w, fmt.Sprintf("no volume provider with id %q", providerID))
		return
	}

	httphelper.JSON(w, 200, vol.Info())
}
Beispiel #12
0
func (api *httpAPI) Prompt(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	s, err := api.Installer.FindBaseCluster(params.ByName("id"))
	if err != nil {
		httphelper.ObjectNotFoundError(w, "cluster not found")
		return
	}
	prompt, err := s.findPrompt(params.ByName("prompt_id"))
	if err != nil {
		httphelper.ObjectNotFoundError(w, "prompt not found")
		return
	}

	var input *Prompt
	if err := httphelper.DecodeJSON(req, &input); err != nil {
		httphelper.Error(w, err)
		return
	}
	prompt.Resolve(input)
	w.WriteHeader(200)
}
Beispiel #13
0
func (api *httpAPI) DeleteCluster(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	if err := api.Installer.DeleteCluster(params.ByName("id")); err != nil {
		if err == ClusterNotFoundError {
			httphelper.ObjectNotFoundError(w, err.Error())
			return
		}
		httphelper.Error(w, err)
		return
	}
	w.WriteHeader(200)
}
Beispiel #14
0
func (h *httpAPI) GetLeader(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	if strings.Contains(r.Header.Get("Accept"), "text/event-stream") {
		h.handleStream(w, params, discoverd.EventKindLeader)
		return
	}

	leader := h.Store.GetLeader(params.ByName("service"))
	if leader == nil {
		hh.ObjectNotFoundError(w, "no leader found")
		return
	}
	hh.JSON(w, 200, leader)
}
Beispiel #15
0
func (h *httpAPI) GetInstances(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	if strings.Contains(r.Header.Get("Accept"), "text/event-stream") {
		h.handleStream(w, params, discoverd.EventKindUp|discoverd.EventKindUpdate|discoverd.EventKindDown)
		return
	}

	instances := h.Store.Get(params.ByName("service"))
	if instances == nil {
		hh.ObjectNotFoundError(w, "service not found")
		return
	}
	hh.JSON(w, 200, instances)
}
Beispiel #16
0
// serveGetServiceMeta returns the metadata for a service.
func (h *Handler) serveGetServiceMeta(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	// Read path parameter.
	service := params.ByName("service")

	// Read meta from the store.
	meta := h.Store.ServiceMeta(service)
	if meta == nil {
		hh.ObjectNotFoundError(w, "service meta not found")
		return
	}

	// Write meta to the response.
	hh.JSON(w, 200, meta)
}
Beispiel #17
0
func (h *httpAPI) RemoveService(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	service := params.ByName("service")
	if err := ValidServiceName(service); err != nil {
		hh.ValidationError(w, "", err.Error())
		return
	}
	if err := h.Store.RemoveService(params.ByName("service")); err != nil {
		if IsNotFound(err) {
			hh.ObjectNotFoundError(w, err.Error())
		} else {
			hh.Error(w, err)
		}
		return
	}
}
Beispiel #18
0
func (api *httpAPI) Prompt(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	cluster, err := api.Installer.FindCluster(params.ByName("id"))
	if err != nil {
		httphelper.ObjectNotFoundError(w, "cluster not found")
		return
	}
	prompt, err := cluster.Base().findPrompt(params.ByName("prompt_id"))
	if err != nil {
		httphelper.ObjectNotFoundError(w, "prompt not found")
		return
	}

	defer req.Body.Close()
	var input *Prompt
	if prompt.Type == PromptTypeFile {
		size, err := strconv.Atoi(req.Header.Get("Content-Length"))
		if err != nil {
			httphelper.Error(w, err)
			return
		}
		input = &Prompt{
			File:     req.Body,
			FileSize: size,
		}
	} else {
		if err := httphelper.DecodeJSON(req, &input); err != nil {
			httphelper.Error(w, err)
			return
		}
	}
	if err := prompt.Resolve(input); err != nil {
		httphelper.Error(w, err)
		return
	}
	w.WriteHeader(200)
}
Beispiel #19
0
func (api *HTTPAPI) Destroy(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	volumeID := ps.ByName("volume_id")
	err := api.vman.DestroyVolume(volumeID)
	if err != nil {
		switch err {
		case volume.ErrNoSuchVolume:
			httphelper.ObjectNotFoundError(w, fmt.Sprintf("no volume with id %q", volumeID))
			return
		default:
			httphelper.Error(w, err)
			return
		}
	}

	w.WriteHeader(200)
}
Beispiel #20
0
func (api *HTTPAPI) Snapshot(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	volumeID := ps.ByName("volume_id")
	snap, err := api.vman.CreateSnapshot(volumeID)
	if err != nil {
		switch err {
		case volume.ErrNoSuchVolume:
			httphelper.ObjectNotFoundError(w, fmt.Sprintf("no volume with id %q", volumeID))
			return
		default:
			httphelper.Error(w, err)
			return
		}
	}

	httphelper.JSON(w, 200, snap.Info())
}
Beispiel #21
0
func (h *jobAPI) GetJob(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	id := ps.ByName("id")

	if strings.Contains(r.Header.Get("Accept"), "text/event-stream") {
		if err := h.host.streamEvents(id, w); err != nil {
			httphelper.Error(w, err)
		}
		return
	}
	job := h.host.state.GetJob(id)
	if job == nil {
		httphelper.ObjectNotFoundError(w, ErrNotFound.Error())
		return
	}
	httphelper.JSON(w, 200, job)
}
Beispiel #22
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)
}
Beispiel #23
0
func (api *httpAPI) PromptHandler(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	api.InstallerPromptsMtx.Lock()
	prompt := api.InstallerPrompts[params.ByName("id")]
	api.InstallerPromptsMtx.Unlock()
	if prompt == nil {
		httphelper.ObjectNotFoundError(w, "prompt not found")
		return
	}

	var input *httpPrompt
	if err := httphelper.DecodeJSON(req, &input); err != nil {
		httphelper.Error(w, err)
		return
	}
	prompt.Resolve(input)
	w.WriteHeader(200)
}
Beispiel #24
0
// serveDeleteInstance removes an instance from the store by name.
func (h *Handler) serveDeleteInstance(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	// Retrieve path parameters.
	service := params.ByName("service")
	instanceID := params.ByName("instance_id")

	// Remove instance from the store.
	if err := h.Store.RemoveInstance(service, instanceID); err == ErrNotLeader {
		h.redirectToLeader(w, r)
		return
	} else if IsNotFound(err) {
		hh.ObjectNotFoundError(w, err.Error())
		return
	} else if err != nil {
		hh.Error(w, err)
		return
	}
}
Beispiel #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)
}
Beispiel #26
0
func (h *httpAPI) SetServiceMeta(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	meta := &discoverd.ServiceMeta{}
	if err := hh.DecodeJSON(r, meta); err != nil {
		hh.Error(w, err)
		return
	}

	if err := h.Store.SetServiceMeta(params.ByName("service"), meta); err != nil {
		if IsNotFound(err) {
			hh.ObjectNotFoundError(w, err.Error())
		} else {
			hh.Error(w, err)
		}
		return
	}

	hh.JSON(w, 200, meta)
}
Beispiel #27
0
func (api *httpAPI) ReceiveBackup(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	cluster, err := api.Installer.FindBaseCluster(params.ByName("id"))
	if err != nil {
		httphelper.ObjectNotFoundError(w, err.Error())
		return
	}
	defer req.Body.Close()
	size, err := strconv.Atoi(req.Header.Get("Content-Length"))
	if err != nil {
		httphelper.Error(w, err)
		return
	}
	if err := cluster.ReceiveBackup(req.Body, size); err != nil {
		httphelper.Error(w, err)
		return
	}
	w.WriteHeader(200)
}
Beispiel #28
0
func (h *httpAPI) AddInstance(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	inst := &discoverd.Instance{}
	if err := json.NewDecoder(r.Body).Decode(inst); err != nil {
		hh.Error(w, err)
		return
	}
	if err := inst.Valid(); err != nil {
		hh.ValidationError(w, "", err.Error())
		return
	}
	if err := h.Store.AddInstance(params.ByName("service"), inst); err != nil {
		if IsNotFound(err) {
			hh.ObjectNotFoundError(w, err.Error())
		} else {
			hh.Error(w, err)
		}
		return
	}
}
Beispiel #29
0
// serveGetInstances returns a list of all instances for a service.
func (h *Handler) serveGetInstances(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	// If the client is requesting a stream, then handle as a stream.
	if strings.Contains(r.Header.Get("Accept"), "text/event-stream") {
		h.serveStream(w, params, discoverd.EventKindUp|discoverd.EventKindUpdate|discoverd.EventKindDown)
		return
	}

	// Otherwise read instances from the store.
	instances, err := h.Store.Instances(params.ByName("service"))
	if err != nil {
		hh.Error(w, err)
		return
	} else if instances == nil {
		hh.ObjectNotFoundError(w, "service not found")
		return
	}

	// Write instances to the response.
	hh.JSON(w, 200, instances)
}
Beispiel #30
0
// serveDeleteService removes a service from the store by name.
func (h *Handler) serveDeleteService(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	// Retrieve the path parameter.
	service := params.ByName("service")
	if err := ValidServiceName(service); err != nil {
		hh.ValidationError(w, "", err.Error())
		return
	}

	// Delete from the store.
	if err := h.Store.RemoveService(params.ByName("service")); err == ErrNotLeader {
		h.redirectToLeader(w, r)
		return
	} else if IsNotFound(err) {
		hh.ObjectNotFoundError(w, err.Error())
		return
	} else if err != nil {
		hh.Error(w, err)
		return
	}
}