func (ur *unitsResource) set(rw http.ResponseWriter, req *http.Request, item string) { if err := validateContentType(req); err != nil { sendError(rw, http.StatusUnsupportedMediaType, err) return } var su schema.Unit dec := json.NewDecoder(req.Body) err := dec.Decode(&su) if err != nil { sendError(rw, http.StatusBadRequest, fmt.Errorf("unable to decode body: %v", err)) return } if su.Name == "" { su.Name = item } if item != su.Name { sendError(rw, http.StatusBadRequest, fmt.Errorf("name in URL %q differs from unit name in request body %q", item, su.Name)) return } if err := ValidateName(su.Name); err != nil { sendError(rw, http.StatusBadRequest, err) return } eu, err := ur.cAPI.Unit(su.Name) if err != nil { log.Errorf("Failed fetching Unit(%s) from Registry: %v", su.Name, err) sendError(rw, http.StatusInternalServerError, nil) return } if eu == nil { if len(su.Options) == 0 { err := errors.New("unit does not exist and options field empty") sendError(rw, http.StatusConflict, err) } else if err := ValidateOptions(su.Options); err != nil { sendError(rw, http.StatusBadRequest, err) } else { ur.create(rw, su.Name, &su) } return } if len(su.DesiredState) == 0 { err := errors.New("must provide DesiredState to update existing unit") sendError(rw, http.StatusConflict, err) return } un := unit.NewUnitNameInfo(su.Name) if un.IsTemplate() && job.JobState(su.DesiredState) != job.JobStateInactive { err := fmt.Errorf("cannot activate template %q", su.Name) sendError(rw, http.StatusBadRequest, err) return } ur.update(rw, su.Name, su.DesiredState) }
func (ur *unitsResource) set(rw http.ResponseWriter, req *http.Request, item string) { if err := validateContentType(req); err != nil { sendError(rw, http.StatusUnsupportedMediaType, err) return } var su schema.Unit dec := json.NewDecoder(req.Body) err := dec.Decode(&su) if err != nil { sendError(rw, http.StatusBadRequest, fmt.Errorf("unable to decode body: %v", err)) return } if su.Name == "" { su.Name = item } if item != su.Name { sendError(rw, http.StatusBadRequest, fmt.Errorf("name in URL %q differs from unit name in request body %q", item, su.Name)) return } if err := ValidateName(su.Name); err != nil { sendError(rw, http.StatusBadRequest, err) return } eu, err := ur.cAPI.Unit(su.Name) if err != nil { log.Errorf("Failed fetching Unit(%s) from Registry: %v", su.Name, err) sendError(rw, http.StatusInternalServerError, nil) return } newUnit := false if eu == nil { if len(su.Options) == 0 { err := errors.New("unit does not exist and options field empty") sendError(rw, http.StatusConflict, err) return } else if err := ValidateOptions(su.Options); err != nil { sendError(rw, http.StatusBadRequest, err) return } else { // New valid unit newUnit = true } } else if eu.Name == su.Name && len(su.Options) > 0 { // There is already a unit with the same name that // was submitted before. Check their hashes, if they do // not match then this is probably a new version which // needs its own new unit entry. // In the other case if su.Options == 0 then probably we // don't want to update the Unit options nor its content // but only set the target job state of the // corresponding unit, in this case just ignore. a := schema.MapSchemaUnitOptionsToUnitFile(su.Options) b := schema.MapSchemaUnitOptionsToUnitFile(eu.Options) newUnit = !unit.MatchUnitFiles(a, b) } if newUnit { ur.create(rw, su.Name, &su) return } if len(su.DesiredState) == 0 { err := errors.New("must provide DesiredState to update existing unit") sendError(rw, http.StatusConflict, err) return } un := unit.NewUnitNameInfo(su.Name) if un.IsTemplate() && job.JobState(su.DesiredState) != job.JobStateInactive { err := fmt.Errorf("cannot activate template %q", su.Name) sendError(rw, http.StatusBadRequest, err) return } ur.update(rw, su.Name, su.DesiredState) }