// 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) 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, append(permission.Contexts(permission.CtxTeam, srv.Teams), permission.Context(permission.CtxService, srv.Name))..., ) if !allowed { return permission.ErrUnauthorized } } rec.Log(user.Email, "create-service-instance", fmt.Sprintf("%#v", instance)) err = service.CreateServiceInstance(instance, &srv, user) if err == service.ErrInstanceNameAlreadyExists { return &errors.HTTP{ Code: http.StatusConflict, Message: err.Error(), } } if err == service.ErrInvalidInstanceName { return &errors.HTTP{ Code: http.StatusBadRequest, Message: err.Error(), } } if err == nil { w.WriteHeader(http.StatusCreated) } return err }
// title: service create // path: /services // method: POST // consume: application/x-www-form-urlencoded // responses: // 201: Service created // 400: Invalid data // 401: Unauthorized // 409: Service already exists func serviceCreate(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) { s := service.Service{ Name: r.FormValue("id"), Username: r.FormValue("username"), Endpoint: map[string]string{"production": r.FormValue("endpoint")}, Password: r.FormValue("password"), } team := r.FormValue("team") if team == "" { team, err = permission.TeamForPermission(t, permission.PermServiceCreate) if err == permission.ErrTooManyTeams { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "You must provide a team responsible for this service in the manifest file.", } } if err != nil { return err } } s.OwnerTeams = []string{team} err = serviceValidate(s) if err != nil { return err } allowed := permission.Check(t, permission.PermServiceCreate, permission.Context(permission.CtxTeam, s.OwnerTeams[0]), ) if !allowed { return permission.ErrUnauthorized } delete(r.Form, "password") evt, err := event.New(&event.Opts{ Target: serviceTarget(s.Name), Kind: permission.PermServiceCreate, Owner: t, CustomData: event.FormToCustomData(r.Form), Allowed: event.Allowed(permission.PermServiceReadEvents, contextsForServiceProvision(&s)...), }) if err != nil { return err } defer func() { evt.Done(err) }() err = s.Create() if err != nil { httpError := http.StatusInternalServerError if err == service.ErrServiceAlreadyExists { httpError = http.StatusConflict } return &errors.HTTP{Code: httpError, Message: err.Error()} } w.WriteHeader(http.StatusCreated) fmt.Fprint(w, "success") return nil }
func serviceCreate(w http.ResponseWriter, r *http.Request, t auth.Token) error { defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { return err } var input serviceYaml err = yaml.Unmarshal(body, &input) if err != nil { return err } if input.Team == "" { input.Team, err = permission.TeamForPermission(t, permission.PermServiceCreate) if err == permission.ErrTooManyTeams { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "You must provide a team responsible for this service in the manifest file.", } } if err != nil { return err } } err = input.validate() if err != nil { return err } allowed := permission.Check(t, permission.PermServiceCreate, permission.Context(permission.CtxTeam, input.Team), ) if !allowed { return permission.ErrUnauthorized } rec.Log(t.GetUserName(), "create-service", input.Id, input.Endpoint) s := service.Service{ Name: input.Id, Username: input.Username, Endpoint: input.Endpoint, Password: input.Password, OwnerTeams: []string{input.Team}, } err = s.Create() if err != nil { httpError := http.StatusInternalServerError if err == service.ErrServiceAlreadyExists { httpError = http.StatusConflict } return &errors.HTTP{Code: httpError, Message: err.Error()} } fmt.Fprint(w, "success") return nil }
func createServiceInstance(w http.ResponseWriter, r *http.Request, t auth.Token) error { b, err := ioutil.ReadAll(r.Body) if err != nil { return err } var body map[string]string err = json.Unmarshal(b, &body) if err != nil { return err } serviceName := body["service_name"] user, err := t.User() if err != nil { return err } srv, err := getService(serviceName) if err != nil { return err } instance := service.ServiceInstance{ Name: body["name"], PlanName: body["plan"], TeamOwner: body["owner"], Description: body["description"], } 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, append(permission.Contexts(permission.CtxTeam, srv.Teams), permission.Context(permission.CtxService, srv.Name))..., ) if !allowed { return permission.ErrUnauthorized } } rec.Log(user.Email, "create-service-instance", string(b)) return service.CreateServiceInstance(instance, &srv, user) }
// title: service create // path: /services // method: POST // consume: application/x-www-form-urlencoded // responses: // 201: Service created // 400: Invalid data // 401: Unauthorized // 409: Service already exists func serviceCreate(w http.ResponseWriter, r *http.Request, t auth.Token) error { s := service.Service{ Name: r.FormValue("id"), Username: r.FormValue("username"), Endpoint: map[string]string{"production": r.FormValue("endpoint")}, Password: r.FormValue("password"), } team := r.FormValue("team") if team == "" { var err error team, err = permission.TeamForPermission(t, permission.PermServiceCreate) if err == permission.ErrTooManyTeams { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "You must provide a team responsible for this service in the manifest file.", } } if err != nil { return err } } s.OwnerTeams = []string{team} err := serviceValidate(s) if err != nil { return err } allowed := permission.Check(t, permission.PermServiceCreate, permission.Context(permission.CtxTeam, s.OwnerTeams[0]), ) if !allowed { return permission.ErrUnauthorized } rec.Log(t.GetUserName(), "create-service", s.Name, s.Endpoint["production"]) err = s.Create() if err != nil { httpError := http.StatusInternalServerError if err == service.ErrServiceAlreadyExists { httpError = http.StatusConflict } return &errors.HTTP{Code: httpError, Message: err.Error()} } w.WriteHeader(http.StatusCreated) fmt.Fprint(w, "success") return nil }
// title: app create // path: /apps // method: POST // consume: application/x-www-form-urlencoded // produce: application/json // responses: // 201: App created // 400: Invalid data // 401: Unauthorized // 403: Quota exceeded // 409: App already exists func createApp(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) { err = r.ParseForm() if err != nil { return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()} } var ia inputApp dec := form.NewDecoder(nil) dec.IgnoreCase(true) dec.IgnoreUnknownKeys(true) dec.DecodeValues(&ia, r.Form) a := app.App{ TeamOwner: ia.TeamOwner, Platform: ia.Platform, Plan: app.Plan{Name: ia.Plan}, Name: ia.Name, Description: ia.Description, Pool: ia.Pool, RouterOpts: ia.RouterOpts, } if a.TeamOwner == "" { a.TeamOwner, err = permission.TeamForPermission(t, permission.PermAppCreate) if err != nil { if err != permission.ErrTooManyTeams { return err } teams, listErr := auth.ListTeams() if listErr != nil { return listErr } if len(teams) != 1 { return err } a.TeamOwner = teams[0].Name } } canCreate := permission.Check(t, permission.PermAppCreate, permission.Context(permission.CtxTeam, a.TeamOwner), ) if !canCreate { return permission.ErrUnauthorized } u, err := t.User() if err != nil { return err } platform, err := app.GetPlatform(a.Platform) if err != nil { return err } if platform.Disabled { canUsePlat := permission.Check(t, permission.PermPlatformUpdate) || permission.Check(t, permission.PermPlatformCreate) if !canUsePlat { return &errors.HTTP{Code: http.StatusBadRequest, Message: app.InvalidPlatformError.Error()} } } evt, err := event.New(&event.Opts{ Target: appTarget(a.Name), Kind: permission.PermAppCreate, Owner: t, CustomData: event.FormToCustomData(r.Form), Allowed: event.Allowed(permission.PermAppReadEvents, contextsForApp(&a)...), }) if err != nil { return err } defer func() { evt.Done(err) }() err = app.CreateApp(&a, u) if err != nil { log.Errorf("Got error while creating app: %s", err) if e, ok := err.(*errors.ValidationError); ok { return &errors.HTTP{Code: http.StatusBadRequest, Message: e.Message} } if _, ok := err.(app.NoTeamsError); ok { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "In order to create an app, you should be member of at least one team", } } if e, ok := err.(*app.AppCreationError); ok { if e.Err == app.ErrAppAlreadyExists { return &errors.HTTP{Code: http.StatusConflict, Message: e.Error()} } if _, ok := e.Err.(*quota.QuotaExceededError); ok { return &errors.HTTP{ Code: http.StatusForbidden, Message: "Quota exceeded", } } } if err == app.InvalidPlatformError { return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()} } return err } repo, err := repository.Manager().GetRepository(a.Name) if err != nil { return err } msg := map[string]string{ "status": "success", "repository_url": repo.ReadWriteURL, "ip": a.Ip, } jsonMsg, err := json.Marshal(msg) if err != nil { return err } w.WriteHeader(http.StatusCreated) w.Header().Set("Content-Type", "application/json") w.Write(jsonMsg) return nil }
func createApp(w http.ResponseWriter, r *http.Request, t auth.Token) error { var a app.App defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { return err } if err = json.Unmarshal(body, &a); err != nil { return err } if a.TeamOwner == "" { a.TeamOwner, err = permission.TeamForPermission(t, permission.PermAppCreate) if err != nil { return err } } canCreate := permission.Check(t, permission.PermAppCreate, permission.Context(permission.CtxTeam, a.TeamOwner), ) if !canCreate { return permission.ErrUnauthorized } u, err := t.User() if err != nil { return err } platform, err := app.GetPlatform(a.Platform) if err != nil { return err } if platform.Disabled { canUsePlat := permission.Check(t, permission.PermPlatformUpdate) || permission.Check(t, permission.PermPlatformCreate) if !canUsePlat { return app.InvalidPlatformError{} } } rec.Log(u.Email, "create-app", "app="+a.Name, "platform="+a.Platform, "plan="+a.Plan.Name, "description="+a.Description) err = app.CreateApp(&a, u) if err != nil { log.Errorf("Got error while creating app: %s", err) if e, ok := err.(*errors.ValidationError); ok { return &errors.HTTP{Code: http.StatusBadRequest, Message: e.Message} } if _, ok := err.(app.NoTeamsError); ok { return &errors.HTTP{ Code: http.StatusBadRequest, Message: "In order to create an app, you should be member of at least one team", } } if e, ok := err.(*app.AppCreationError); ok { if e.Err == app.ErrAppAlreadyExists { return &errors.HTTP{Code: http.StatusConflict, Message: e.Error()} } if _, ok := e.Err.(*quota.QuotaExceededError); ok { return &errors.HTTP{ Code: http.StatusForbidden, Message: "Quota exceeded", } } } if e, ok := err.(app.InvalidPlatformError); ok { return &errors.HTTP{Code: http.StatusNotFound, Message: e.Error()} } return err } repo, _ := repository.Manager().GetRepository(a.Name) msg := map[string]string{ "status": "success", "repository_url": repo.ReadWriteURL, "ip": a.Ip, } jsonMsg, err := json.Marshal(msg) if err != nil { return err } fmt.Fprintf(w, "%s", jsonMsg) return nil }
// 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 }