api/service_instance.go
func removeServiceInstance(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	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(InputFields(r)),
		Allowed: event.Allowed(permission.PermServiceInstanceReadEvents,
			contextsForServiceInstance(serviceInstance, serviceName)...),
	})
	if err != nil {
		return err
	}
	evt.SetLogWriter(writer)
	defer func() { evt.Done(err) }()
	requestID := requestIDHeader(r)
	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(evt, "Unbind app %q ...\n", app.GetName())
				instErr = serviceInstance.UnbindApp(service.UnbindAppArgs{
					App:         app,
					Restart:     true,
					ForceRemove: false,
					Event:       evt,
					RequestID:   requestID,
				})
				if instErr != nil {
					return instErr
				}
				fmt.Fprintf(evt, "\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
			}
		}
	}
	err = service.DeleteInstance(serviceInstance, evt, requestID)
	if err != nil {
		if err == service.ErrServiceInstanceBound {
			return &tsuruErrors.HTTP{
				Message: errors.Wrapf(err, `Applications bound to the service "%s": "%s"`+"\n", instanceName, strings.Join(serviceInstance.Apps, ",")).Error(),
				Code:    http.StatusBadRequest,
			}
		}
		return err
	}
	evt.Write([]byte("service instance successfully removed\n"))
	return nil
}
func removeServiceInstance(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	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(InputFields(r)),
		Allowed: event.Allowed(permission.PermServiceInstanceReadEvents,
			contextsForServiceInstance(serviceInstance, serviceName)...),
	})
	if err != nil {
		return err
	}
	evt.SetLogWriter(writer)
	defer func() { evt.Done(err) }()
	requestID := requestIDHeader(r)
	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(evt, "Unbind app %q ...\n", app.GetName())
				instErr = serviceInstance.UnbindApp(service.UnbindAppArgs{
					App:         app,
					Restart:     true,
					ForceRemove: false,
					Event:       evt,
					RequestID:   requestID,
				})
				if instErr != nil {
					return instErr
				}
				fmt.Fprintf(evt, "\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
			}
		}
	}
	err = service.DeleteInstance(serviceInstance, evt, requestID)
	if err != nil {
		if err == service.ErrServiceInstanceBound {
			return &tsuruErrors.HTTP{
				Message: errors.Wrapf(err, `Applications bound to the service "%s": "%s"`+"\n", instanceName, strings.Join(serviceInstance.Apps, ",")).Error(),
				Code:    http.StatusBadRequest,
			}
		}
		return err
	}
	evt.Write([]byte("service instance successfully removed\n"))
	return nil
}
// title: remove service instance
// path: /services/{name}/instances/{instance}
// method: DELETE
// produce: application/x-json-stream
// responses:
//   200: Service removed
//   400: Bad request
//   401: Unauthorized
//   404: Service instance not found