func (c *Client) Bind(instance *ServiceInstance, app bind.App, unit bind.Unit) (map[string]string, error) { log.Print("Attempting to call bind of service instance " + instance.Name + " and unit " + unit.GetIp() + " at " + instance.ServiceName + " api") var resp *http.Response params := map[string][]string{ "unit-host": {unit.GetIp()}, "app-host": {app.GetIp()}, } resp, err := c.issueRequest("/resources/"+instance.Name, "POST", params) if err != nil { if m, _ := regexp.MatchString("", err.Error()); m { return nil, fmt.Errorf("%s api is down.", instance.Name) } return nil, err } if err == nil && resp.StatusCode < 300 { var result map[string]string err = c.jsonFromResponse(resp, &result) if err != nil { return nil, err } return result, nil } if resp.StatusCode == http.StatusPreconditionFailed { return nil, &errors.HTTP{Code: resp.StatusCode, Message: "You cannot bind any app to this service instance because it is not ready yet."} } msg := "Failed to bind instance " + instance.Name + " to the unit " + unit.GetIp() + ": " + c.buildErrorMessage(err, resp) log.Print(msg) return nil, &errors.HTTP{Code: http.StatusInternalServerError, Message: msg} }
// BindApp makes the bind between the service instance and an app. func (si *ServiceInstance) BindApp(app bind.App) error { err := si.AddApp(app.GetName()) if err != nil { return &errors.Http{Code: http.StatusConflict, Message: "This app is already bound to this service instance."} } err = si.update() if err != nil { return err } if len(app.GetUnits()) == 0 { return &errors.Http{Code: http.StatusPreconditionFailed, Message: "This app does not have an IP yet."} } envs := make(chan map[string]string, len(app.GetUnits())+1) for _, unit := range app.GetUnits() { go func(unit bind.Unit) { vars, _ := si.BindUnit(app, unit) envs <- vars }(unit) } var envVars []bind.EnvVar for k, v := range <-envs { envVars = append(envVars, bind.EnvVar{ Name: k, Value: v, Public: false, InstanceName: si.Name, }) } return app.SetEnvs(envVars, false) }
func (c *Client) Unbind(instance *ServiceInstance, app bind.App) (err error) { log.Print("Attempting to call unbind of service instance " + instance.Name + " and app " + app.GetName() + " at " + instance.ServiceName + " api") var resp *http.Response url := "/resources/" + instance.Name + "/hostname/" + app.GetUnits()[0].GetIp() if resp, err = c.issueRequest(url, "DELETE", nil); err == nil && resp.StatusCode > 299 { msg := "Failed to unbind instance " + instance.Name + " from the app " + app.GetName() + ": " + c.buildErrorMessage(err, resp) log.Print(msg) err = &errors.Http{Code: http.StatusInternalServerError, Message: msg} } return }
func (c *Client) Bind(instance *ServiceInstance, app bind.App) (envVars map[string]string, err error) { log.Print("Attempting to call bind of service instance " + instance.Name + " and app " + app.GetName() + " at " + instance.ServiceName + " api") var resp *http.Response params := map[string][]string{ "hostname": {app.GetUnits()[0].GetIp()}, } if resp, err = c.issueRequest("/resources/"+instance.Name, "POST", params); err == nil && resp.StatusCode < 300 { return c.jsonFromResponse(resp) } else if resp.StatusCode == http.StatusPreconditionFailed { err = &errors.Http{Code: resp.StatusCode, Message: "You cannot bind any app to this service instance because it is not ready yet."} } else { msg := "Failed to bind instance " + instance.Name + " to the app " + app.GetName() + ": " + c.buildErrorMessage(err, resp) log.Print(msg) err = &errors.Http{Code: http.StatusInternalServerError, Message: msg} } return }
func (si *ServiceInstance) Bind(app bind.App) error { err := si.AddApp(app.GetName()) if err != nil { return &errors.Http{Code: http.StatusConflict, Message: "This app is already binded to this service instance."} } var envVars []bind.EnvVar var setEnv = func(env map[string]string) { for k, v := range env { envVars = append(envVars, bind.EnvVar{ Name: k, Value: v, Public: false, InstanceName: si.Name, }) } } cli := si.Service().ProductionEndpoint() if len(app.GetUnits()) == 0 { return &errors.Http{Code: http.StatusPreconditionFailed, Message: "This app does not have an IP yet."} } env, err := cli.Bind(si, app) if err != nil { return err } setEnv(env) err = si.update() if err != nil { cli.Unbind(si, app) return err } return app.SetEnvs(envVars, false) }
// UnbindApp makes the unbind between the service instance and an app. func (si *ServiceInstance) UnbindApp(app bind.App) error { err := si.RemoveApp(app.GetName()) if err != nil { return &errors.Http{Code: http.StatusPreconditionFailed, Message: "This app is not bound to this service instance."} } err = si.update() if err != nil { return err } for _, unit := range app.GetUnits() { go func(unit bind.Unit) { si.UnbindUnit(unit) }(unit) } var envVars []string for k := range app.InstanceEnv(si.Name) { envVars = append(envVars, k) } return app.UnsetEnvs(envVars, false) }
func (si *ServiceInstance) Unbind(app bind.App) error { err := si.RemoveApp(app.GetName()) if err != nil { return &errors.Http{Code: http.StatusPreconditionFailed, Message: "This app is not binded to this service instance."} } err = si.update() if err != nil { return err } go func() { si.Service().ProductionEndpoint().Unbind(si, app) }() var envVars []string for k := range app.InstanceEnv(si.Name) { envVars = append(envVars, k) } return app.UnsetEnvs(envVars, false) }