예제 #1
0
// title: service instance info
// path: /services/{service}/instances/{instance}
// method: GET
// produce: application/json
// responses:
//   200: OK
//   401: Unauthorized
//   404: Service instance not found
func serviceInstance(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	instanceName := r.URL.Query().Get(":instance")
	serviceName := r.URL.Query().Get(":service")
	serviceInstance, err := getServiceInstanceOrError(serviceName, instanceName)
	if err != nil {
		return err
	}
	allowed := permission.Check(t, permission.PermServiceInstanceRead,
		contextsForServiceInstance(serviceInstance, serviceName)...,
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	requestIDHeader, _ := config.GetString("request-id-header")
	requestID := context.GetRequestID(r, requestIDHeader)
	info, err := serviceInstance.Info(requestID)
	if err != nil {
		return err
	}
	plan, err := service.GetPlanByServiceNameAndPlanName(serviceName, serviceInstance.PlanName, requestID)
	if err != nil {
		return err
	}
	sInfo := serviceInstanceInfo{
		Apps:            serviceInstance.Apps,
		Teams:           serviceInstance.Teams,
		TeamOwner:       serviceInstance.TeamOwner,
		Description:     serviceInstance.Description,
		PlanName:        plan.Name,
		PlanDescription: plan.Description,
		CustomInfo:      info,
	}
	w.Header().Set("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(sInfo)
}
예제 #2
0
func (s *S) TestSetRequestIDHeaderMiddlewareNoConfig(c *check.C) {
	config.Unset("request-id-header")
	rec := httptest.NewRecorder()
	req, err := http.NewRequest("GET", "/", nil)
	c.Assert(err, check.IsNil)
	h, log := doHandler()
	setRequestIDHeaderMiddleware(rec, req, h)
	c.Assert(log.called, check.Equals, true)
	reqID := context.GetRequestID(req, "")
	c.Assert(reqID, check.Equals, "")
}
예제 #3
0
파일: middleware.go 프로젝트: tsuru/tsuru
func (l *loggerMiddleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	start := time.Now()
	next(rw, r)
	duration := time.Since(start)
	statusCode := rw.(negroni.ResponseWriter).Status()
	if statusCode == 0 {
		statusCode = 200
	}
	nowFormatted := time.Now().Format(time.RFC3339Nano)
	requestIDHeader, _ := config.GetString("request-id-header")
	var requestID string
	if requestIDHeader != "" {
		requestID = context.GetRequestID(r, requestIDHeader)
		if requestID != "" {
			requestID = fmt.Sprintf(" [%s: %s]", requestIDHeader, requestID)
		}
	}
	l.logger.Printf("%s %s %s %d in %0.6fms%s", nowFormatted, r.Method, r.URL.Path, statusCode, float64(duration)/float64(time.Millisecond), requestID)
}
예제 #4
0
// title: service instance status
// path: /services/{service}/instances/{instance}/status
// method: GET
// responses:
//   200: List services instances
//   401: Unauthorized
//   404: Service instance not found
func serviceInstanceStatus(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	instanceName := r.URL.Query().Get(":instance")
	serviceName := r.URL.Query().Get(":service")
	serviceInstance, err := getServiceInstanceOrError(serviceName, instanceName)
	if err != nil {
		return err
	}
	allowed := permission.Check(t, permission.PermServiceInstanceReadStatus,
		contextsForServiceInstance(serviceInstance, serviceName)...,
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	var b string
	requestIDHeader, _ := config.GetString("request-id-header")
	requestID := context.GetRequestID(r, requestIDHeader)
	if b, err = serviceInstance.Status(requestID); err != nil {
		return errors.Wrap(err, "Could not retrieve status of service instance, error")
	}
	_, err = fmt.Fprintf(w, `Service instance "%s" is %s`, instanceName, b)
	return err
}
예제 #5
0
// title: service plans
// path: /services/{name}/plans
// method: GET
// produce: application/json
// responses:
//   200: OK
//   401: Unauthorized
//   404: Service not found
func servicePlans(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	serviceName := r.URL.Query().Get(":name")
	s, err := getService(serviceName)
	if err != nil {
		return err
	}
	if s.IsRestricted {
		allowed := permission.Check(t, permission.PermServiceReadPlans,
			contextsForService(&s)...,
		)
		if !allowed {
			return permission.ErrUnauthorized
		}
	}
	requestIDHeader, _ := config.GetString("request-id-header")
	requestID := context.GetRequestID(r, requestIDHeader)
	plans, err := service.GetPlansByServiceName(serviceName, requestID)
	if err != nil {
		return err
	}
	w.Header().Set("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(plans)
}
예제 #6
0
// title: service instance create
// path: /services/{service}/instances
// method: POST
// consume: application/x-www-form-urlencoded
// responses:
//   201: Service created
//   400: Invalid data
//   401: Unauthorized
//   409: Service already exists
func createServiceInstance(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	serviceName := r.URL.Query().Get(":service")
	user, err := t.User()
	if err != nil {
		return err
	}
	srv, err := getService(serviceName)
	if err != nil {
		return err
	}
	instance := service.ServiceInstance{
		Name:        r.FormValue("name"),
		PlanName:    r.FormValue("plan"),
		TeamOwner:   r.FormValue("owner"),
		Description: r.FormValue("description"),
	}
	var teamOwner string
	if instance.TeamOwner == "" {
		teamOwner, err = permission.TeamForPermission(t, permission.PermServiceInstanceCreate)
		if err != nil {
			return err
		}
		instance.TeamOwner = teamOwner
	}
	allowed := permission.Check(t, permission.PermServiceInstanceCreate,
		permission.Context(permission.CtxTeam, instance.TeamOwner),
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	if srv.IsRestricted {
		allowed := permission.Check(t, permission.PermServiceRead,
			contextsForService(&srv)...,
		)
		if !allowed {
			return permission.ErrUnauthorized
		}
	}
	evt, err := event.New(&event.Opts{
		Target:     serviceInstanceTarget(serviceName, instance.Name),
		Kind:       permission.PermServiceInstanceCreate,
		Owner:      t,
		CustomData: event.FormToCustomData(r.Form),
		Allowed: event.Allowed(permission.PermServiceInstanceReadEvents,
			contextsForServiceInstance(&instance, srv.Name)...),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	requestIDHeader, _ := config.GetString("request-id-header")
	requestID := context.GetRequestID(r, requestIDHeader)
	err = service.CreateServiceInstance(instance, &srv, user, requestID)
	if err == service.ErrInstanceNameAlreadyExists {
		return &tsuruErrors.HTTP{
			Code:    http.StatusConflict,
			Message: err.Error(),
		}
	}
	if err == service.ErrInvalidInstanceName {
		return &tsuruErrors.HTTP{
			Code:    http.StatusBadRequest,
			Message: err.Error(),
		}
	}
	if err == nil {
		w.WriteHeader(http.StatusCreated)
	}
	return err
}
예제 #7
0
// title: remove service instance
// path: /services/{name}/instances/{instance}
// method: DELETE
// produce: application/x-json-stream
// responses:
//   200: Service removed
//   401: Unauthorized
//   404: Service instance not found
func removeServiceInstance(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	r.ParseForm()
	unbindAll := r.URL.Query().Get("unbindall")
	serviceName := r.URL.Query().Get(":service")
	instanceName := r.URL.Query().Get(":instance")
	serviceInstance, err := getServiceInstanceOrError(serviceName, instanceName)
	if err != nil {
		return err
	}
	keepAliveWriter := tsuruIo.NewKeepAliveWriter(w, 30*time.Second, "")
	defer keepAliveWriter.Stop()
	writer := &tsuruIo.SimpleJsonMessageEncoderWriter{Encoder: json.NewEncoder(keepAliveWriter)}
	w.Header().Set("Content-Type", "application/x-json-stream")
	allowed := permission.Check(t, permission.PermServiceInstanceDelete,
		contextsForServiceInstance(serviceInstance, serviceName)...,
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     serviceInstanceTarget(serviceName, instanceName),
		Kind:       permission.PermServiceInstanceDelete,
		Owner:      t,
		CustomData: event.FormToCustomData(r.Form),
		Allowed: event.Allowed(permission.PermServiceInstanceReadEvents,
			contextsForServiceInstance(serviceInstance, serviceName)...),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	unbindAllBool, _ := strconv.ParseBool(unbindAll)
	if unbindAllBool {
		if len(serviceInstance.Apps) > 0 {
			for _, appName := range serviceInstance.Apps {
				_, app, instErr := getServiceInstance(serviceInstance.ServiceName, serviceInstance.Name, appName)
				if instErr != nil {
					return instErr
				}
				fmt.Fprintf(writer, "Unbind app %q ...\n", app.GetName())
				instErr = serviceInstance.UnbindApp(app, true, writer)
				if instErr != nil {
					return instErr
				}
				fmt.Fprintf(writer, "\nInstance %q is not bound to the app %q anymore.\n", serviceInstance.Name, app.GetName())
			}
			serviceInstance, err = getServiceInstanceOrError(serviceName, instanceName)
			if err != nil {
				return err
			}
		}
	}
	requestIDHeader, _ := config.GetString("request-id-header")
	requestID := context.GetRequestID(r, requestIDHeader)
	err = service.DeleteInstance(serviceInstance, requestID)
	if err != nil {
		if err == service.ErrServiceInstanceBound {
			writer.Write([]byte(strings.Join(serviceInstance.Apps, ",")))
		}
		return err
	}
	writer.Write([]byte("service instance successfully removed"))
	return nil
}