func bindServiceInstance(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	instanceName := r.URL.Query().Get(":instance")
	appName := r.URL.Query().Get(":app")
	serviceName := r.URL.Query().Get(":service")
	req := struct {
		NoRestart  bool
		Parameters service.BindAppParameters
	}{}
	err = ParseInput(r, &req)
	if err != nil {
		return err
	}
	instance, a, err := getServiceInstance(serviceName, instanceName, appName)
	if err != nil {
		return err
	}
	allowed := permission.Check(t, permission.PermServiceInstanceUpdateBind,
		append(permission.Contexts(permTypes.CtxTeam, instance.Teams),
			permission.Context(permTypes.CtxServiceInstance, instance.Name),
		)...,
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	allowed = permission.Check(t, permission.PermAppUpdateBind,
		contextsForApp(a)...,
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	err = a.ValidateService(serviceName)
	if err != nil {
		if err == pool.ErrPoolHasNoService {
			return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
		}
		return err
	}
	evt, err := event.New(&event.Opts{
		Target:     appTarget(appName),
		Kind:       permission.PermAppUpdateBind,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermAppReadEvents, contextsForApp(a)...),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	w.Header().Set("Content-Type", "application/x-json-stream")
	keepAliveWriter := tsuruIo.NewKeepAliveWriter(w, 30*time.Second, "")
	defer keepAliveWriter.Stop()
	writer := &tsuruIo.SimpleJsonMessageEncoderWriter{Encoder: json.NewEncoder(keepAliveWriter)}
	evt.SetLogWriter(writer)
	err = instance.BindApp(a, req.Parameters, !req.NoRestart, evt, evt, requestIDHeader(r))
	if err != nil {
		status, errStatus := instance.Status(requestIDHeader(r))
		if errStatus != nil {
			return fmt.Errorf("%v (failed to retrieve instance status: %v)", err, errStatus)
		}
		return fmt.Errorf("%v (%q is %v)", err, instanceName, status)
	}
	fmt.Fprintf(writer, "\nInstance %q is now bound to the app %q.\n", instanceName, appName)
	envs := a.InstanceEnvs(serviceName, instanceName)
	if len(envs) > 0 {
		fmt.Fprintf(writer, "The following environment variables are available for use in your app:\n\n")
		for k := range envs {
			fmt.Fprintf(writer, "- %s\n", k)
		}
		fmt.Fprintf(writer, "- %s\n", app.TsuruServicesEnvVar)
	}
	return nil
}
func bindServiceInstance(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	instanceName := r.URL.Query().Get(":instance")
	appName := r.URL.Query().Get(":app")
	serviceName := r.URL.Query().Get(":service")
	req := struct {
		NoRestart  bool
		Parameters service.BindAppParameters
	}{}
	err = ParseInput(r, &req)
	if err != nil {
		return err
	}
	instance, a, err := getServiceInstance(serviceName, instanceName, appName)
	if err != nil {
		return err
	}
	allowed := permission.Check(t, permission.PermServiceInstanceUpdateBind,
		append(permission.Contexts(permTypes.CtxTeam, instance.Teams),
			permission.Context(permTypes.CtxServiceInstance, instance.Name),
		)...,
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	allowed = permission.Check(t, permission.PermAppUpdateBind,
		contextsForApp(a)...,
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	err = a.ValidateService(serviceName)
	if err != nil {
		if err == pool.ErrPoolHasNoService {
			return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
		}
		return err
	}
	evt, err := event.New(&event.Opts{
		Target:     appTarget(appName),
		Kind:       permission.PermAppUpdateBind,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermAppReadEvents, contextsForApp(a)...),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	w.Header().Set("Content-Type", "application/x-json-stream")
	keepAliveWriter := tsuruIo.NewKeepAliveWriter(w, 30*time.Second, "")
	defer keepAliveWriter.Stop()
	writer := &tsuruIo.SimpleJsonMessageEncoderWriter{Encoder: json.NewEncoder(keepAliveWriter)}
	evt.SetLogWriter(writer)
	err = instance.BindApp(a, req.Parameters, !req.NoRestart, evt, evt, requestIDHeader(r))
	if err != nil {
		status, errStatus := instance.Status(requestIDHeader(r))
		if errStatus != nil {
			return fmt.Errorf("%v (failed to retrieve instance status: %v)", err, errStatus)
		}
		return fmt.Errorf("%v (%q is %v)", err, instanceName, status)
	}
	fmt.Fprintf(writer, "\nInstance %q is now bound to the app %q.\n", instanceName, appName)
	envs := a.InstanceEnvs(serviceName, instanceName)
	if len(envs) > 0 {
		fmt.Fprintf(writer, "The following environment variables are available for use in your app:\n\n")
		for k := range envs {
			fmt.Fprintf(writer, "- %s\n", k)
		}
		fmt.Fprintf(writer, "- %s\n", app.TsuruServicesEnvVar)
	}
	return nil
}
func bindServiceInstance ( w http . ResponseWriter , r * http . Request , t auth . Token ) ( err error ) { instanceName := r . URL . Query ( ) . Get ( " " ) appName := r . URL . Query ( ) . Get ( " " ) serviceName := r . URL . Query ( ) . Get ( " " ) req := struct { NoRestart bool Parameters service . BindAppParameters } { } err = ParseInput ( r , & req ) if err != nil { return err } instance , a , err := getServiceInstance ( serviceName , instanceName , appName ) if err != nil { return err } allowed := permission . Check ( t , permission . PermServiceInstanceUpdateBind , append ( permission . Contexts ( permTypes . CtxTeam , instance . Teams ) , permission . Context ( permTypes . CtxServiceInstance , instance . Name ) , ) ... , ) if ! allowed { return permission . ErrUnauthorized } allowed = permission . Check ( t , permission . PermAppUpdateBind , contextsForApp ( a ) ... , ) if ! allowed { return permission . ErrUnauthorized } err = a . ValidateService ( serviceName ) if err != nil { if err == pool . ErrPoolHasNoService { return & errors . HTTP { Code : http . StatusBadRequest , Message : err . Error ( ) } } return err } evt , err := event . New ( & event . Opts { Target : appTarget ( appName ) , Kind : permission . PermAppUpdateBind , Owner : t , CustomData : event . FormToCustomData ( InputFields ( r ) ) , Allowed : event . Allowed ( permission . PermAppReadEvents , contextsForApp ( a ) ... ) , } ) if err != nil { return err } defer func ( ) { evt . Done ( err ) } ( ) w . Header ( ) . Set ( " " , " " ) keepAliveWriter := tsuruIo . NewKeepAliveWriter ( w , 30 * time . Second , " " ) defer keepAliveWriter . Stop ( ) writer := & tsuruIo . SimpleJsonMessageEncoderWriter { Encoder : json . NewEncoder ( keepAliveWriter ) } evt . SetLogWriter ( writer ) err = instance . BindApp ( a , req . Parameters , ! req . NoRestart , evt , evt , requestIDHeader ( r ) ) if err != nil { status , errStatus := instance . Status ( requestIDHeader ( r ) ) if errStatus != nil { return fmt . Errorf ( " " , err , errStatus ) } return fmt . Errorf ( " " , err , instanceName , status ) } fmt . Fprintf ( writer , " \n \n " , instanceName , appName ) envs := a . InstanceEnvs ( serviceName , instanceName ) if len ( envs ) > 0 { fmt . Fprintf ( writer , " \n \n " ) for k := range envs { fmt . Fprintf ( writer , " \n " , k ) } fmt . Fprintf ( writer , " \n " , app . TsuruServicesEnvVar ) } return nil }
// title: bind service instance
// path: /services/{service}/instances/{instance}/{app}
// method: PUT
// consume: application/x-www-form-urlencoded
// produce: application/x-json-stream
// responses:
//   200: Ok
//   400: Invalid data
//   401: Unauthorized
//   404: App not found
title : bind service instance path : / services / { service } / instances / { instance } / { app } method : PUT consume : application / x - www - form - urlencoded produce : application / x - json - stream responses : 200 : Ok 400 : Invalid data 401 : Unauthorized 404 : App not found