zrhoffman commented on code in PR #7708:
URL: https://github.com/apache/trafficcontrol/pull/7708#discussion_r1294756922


##########
traffic_ops/traffic_ops_golang/parameter/parameters.go:
##########
@@ -251,3 +256,376 @@ func deleteQuery() string {
 WHERE id=:id`
        return query
 }
+
+func GetParameters(w http.ResponseWriter, r *http.Request) {
+       var runSecond bool
+       var maxTime time.Time
+       inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
+       tx := inf.Tx
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, tx.Tx, errCode, userErr, sysErr)
+               return
+       }
+       defer inf.Close()
+
+       // Query Parameters to Database Query column mappings
+       queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
+               ConfigFileQueryParam: {Column: "p.config_file"},
+               IDQueryParam:         {Column: "p.id", Checker: api.IsInt},
+               NameQueryParam:       {Column: "p.name"},
+               SecureQueryParam:     {Column: "p.secure", Checker: api.IsBool},
+               ValueQueryParam:      {Column: "p.value"},
+       }
+       if _, ok := inf.Params["orderby"]; !ok {
+               inf.Params["orderby"] = "name"
+       }
+       where, orderBy, pagination, queryValues, errs := 
dbhelpers.BuildWhereAndOrderByAndPagination(inf.Params, queryParamsToQueryCols)
+       if len(errs) > 0 {
+               api.HandleErr(w, r, tx.Tx, http.StatusBadRequest, 
util.JoinErrs(errs), nil)
+               return
+       }
+
+       if inf.Config.UseIMS {
+               runSecond, maxTime = ims.TryIfModifiedSinceQuery(tx, r.Header, 
queryValues, selectMaxLastUpdatedQuery(where))
+               if !runSecond {
+                       log.Debugln("IMS HIT")
+                       api.AddLastModifiedHdr(w, maxTime)
+                       w.WriteHeader(http.StatusNotModified)
+                       return
+               }
+               log.Debugln("IMS MISS")
+       } else {
+               log.Debugln("Non IMS request")
+       }
+
+       query := selectQuery() + where + ParametersGroupBy() + orderBy + 
pagination
+       rows, err := tx.NamedQuery(query, queryValues)
+       if err != nil {
+               api.HandleErr(w, r, tx.Tx, http.StatusInternalServerError, nil, 
fmt.Errorf("Parameter read: error getting Parameter(s): %w", err))
+               return
+       }
+       defer log.Close(rows, "unable to close DB connection")
+
+       params := tc.ParameterNullableV5{}
+       paramsList := []tc.ParameterNullableV5{}
+       for rows.Next() {
+               if err = rows.Scan(&params.ConfigFile, &params.ID, 
&params.LastUpdated, &params.Name, &params.Value, &params.Secure, 
&params.Profiles); err != nil {
+                       api.HandleErr(w, r, tx.Tx, 
http.StatusInternalServerError, nil, fmt.Errorf("error getting parameter(s): 
%w", err))
+                       return
+               }
+               if params.Secure != nil && *params.Secure {
+                       if inf.Version.Major >= 4 &&
+                               inf.Config.RoleBasedPermissions &&
+                               !inf.User.Can("PARAMETER-SECURE:READ") {
+                               params.Value = &HiddenField
+                       } else if inf.User.PrivLevel < auth.PrivLevelAdmin {
+                               params.Value = &HiddenField
+                       }
+               }
+
+               paramsList = append(paramsList, params)
+       }
+
+       api.WriteResp(w, r, paramsList)
+       return
+}
+
+func CreateParameter(w http.ResponseWriter, r *http.Request) {
+       inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
+               return
+       }
+       defer inf.Close()
+       tx := inf.Tx.Tx
+
+       body, err := io.ReadAll(r.Body)
+       if err != nil {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, 
errors.New("error reading request body"), nil)
+               return
+       }
+       defer r.Body.Close()
+
+       // Initial Unmarshal to validate request body
+       var data interface{}
+       err = json.Unmarshal(body, &data)
+       if err != nil {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, 
errors.New("invalid request format"), nil)
+               return
+       }
+
+       // This code block decides if the request body is a slice of parameters 
or a single object.
+       var params []tc.ParameterV5
+       switch reflect.TypeOf(data).Kind() {
+       case reflect.Slice:
+               if err := json.Unmarshal(body, &params); err != nil {
+                       api.HandleErr(w, r, tx, http.StatusBadRequest, 
errors.New("error unmarshalling slice"), nil)
+                       return
+               }
+       case reflect.Map:
+               // If it is a single object it is still converted to a slice 
for code simplicity.
+               var param tc.ParameterV5
+               if err := json.Unmarshal(body, &param); err != nil {
+                       api.HandleErr(w, r, tx, http.StatusBadRequest, 
errors.New("error unmarshalling single object"), nil)
+                       return
+               }
+               params = append(params, param)
+       default:
+               api.HandleErr(w, r, tx, http.StatusBadRequest, 
errors.New("invalid request format"), nil)
+               return
+       }
+
+       // Validate all objects of the every parameter from the request slice
+       for _, parameter := range params {
+               readValErr := validateRequestParameter(parameter)
+               if readValErr != nil {
+                       api.HandleErr(w, r, tx, http.StatusBadRequest, 
readValErr, nil)
+                       return
+               }
+       }
+
+       // Check if any of the parameter from the request slice already exists
+       for _, parameter := range params {
+               var count int
+               err = tx.QueryRow("SELECT count(*) from parameter where name = 
$1", parameter.Name).Scan(&count)
+               if err != nil {
+                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
nil, fmt.Errorf("error: %w, when checking if parameter with name %s exists", 
err, parameter.Name))
+                       return
+               }
+               if count == 1 {
+                       api.HandleErr(w, r, tx, http.StatusBadRequest, 
fmt.Errorf("parameter name '%s' already exists", parameter.Name), nil)
+                       return
+               }
+       }
+       // Create all parameters from the request slice
+       var objParams []tc.ParameterV5
+       for _, parameter := range params {
+               query := `
+                       INSERT INTO parameter (
+                           name,
+                           config_file,
+                           value,
+                           secure
+                           ) VALUES (
+                               $1, $2, $3, $4
+                           ) RETURNING id, name, config_file, value, 
last_updated, secure 
+               `
+               var objParam tc.ParameterV5
+               err = tx.QueryRow(
+                       query,
+                       parameter.Name,
+                       parameter.ConfigFile,
+                       parameter.Value,
+                       parameter.Secure,
+               ).Scan(
+
+                       &objParam.ID,
+                       &objParam.Name,
+                       &objParam.ConfigFile,
+                       &objParam.Value,
+                       &objParam.LastUpdated,
+                       &objParam.Secure,
+               )
+
+               if err != nil {
+                       if errors.Is(err, sql.ErrNoRows) {
+                               api.HandleErr(w, r, tx, 
http.StatusInternalServerError, fmt.Errorf("error: %w in parameter  with name: 
%s", err, parameter.Name), nil)
+                               return
+                       }
+                       usrErr, sysErr, code := api.ParseDBError(err)
+                       api.HandleErr(w, r, tx, code, usrErr, sysErr)
+                       return
+               }
+
+               objParams = append(objParams, objParam)
+       }
+       alerts := tc.CreateAlerts(tc.SuccessLevel, "All Requested Parameters 
were created.")
+       api.WriteAlertsObj(w, r, http.StatusCreated, alerts, objParams)
+       return
+}
+
+func UpdateParameter(w http.ResponseWriter, r *http.Request) {
+       inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
+               return
+       }
+       defer inf.Close()
+
+       tx := inf.Tx.Tx
+       parameter, readValErr := readAndValidateJsonStruct(r)
+       if readValErr != nil {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, readValErr, nil)
+               return
+       }
+
+       requestedID := inf.Params["id"]
+
+       intRequestId, convErr := strconv.Atoi(requestedID)
+       if convErr != nil {
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, 
fmt.Errorf("parameter update error: %w, while converting from string to int", 
convErr), nil)
+       }
+       // check if the entity was already updated
+       userErr, sysErr, errCode = api.CheckIfUnModified(r.Header, inf.Tx, 
intRequestId, "parameter")
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
+               return
+       }
+
+       //update name and description of a phys_location
+       query := `
+       UPDATE parameter p
+       SET
+               config_file = $1,
+               name = $2,
+               value = $3,
+               secure = $4
+       WHERE
+               p.id = $5
+       RETURNING
+               p.id,
+               p.last_updated
+`
+
+       err := tx.QueryRow(
+               query,
+               parameter.ConfigFile,
+               parameter.Name,
+               parameter.Value,
+               parameter.Secure,
+               requestedID,
+       ).Scan(
+               &parameter.ID,
+               &parameter.LastUpdated,
+       )
+       if err != nil {
+               if errors.Is(err, sql.ErrNoRows) {
+                       api.HandleErr(w, r, tx, http.StatusBadRequest, 
fmt.Errorf("parameter with ID: %v not found", parameter.ID), nil)
+                       return
+               }
+               usrErr, sysErr, code := api.ParseDBError(err)
+               api.HandleErr(w, r, tx, code, usrErr, sysErr)
+               return
+       }
+       alerts := tc.CreateAlerts(tc.SuccessLevel, "parameter was updated")
+       api.WriteAlertsObj(w, r, http.StatusOK, alerts, parameter)
+       return
+}
+
+func DeleteParameter(w http.ResponseWriter, r *http.Request) {
+       inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
+       tx := inf.Tx.Tx
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
+               return
+       }
+       defer inf.Close()
+
+       id := inf.Params["id"]
+       if id == "" {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, 
fmt.Errorf("couldn't delete Parameter. Invalid ID. Id Cannot be empty for 
Delete Operation"), nil)
+               return
+       }
+       exists, err := dbhelpers.ParameterExists(tx, id)
+       if err != nil {
+               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
err)
+               return
+       }
+       if !exists {
+               api.HandleErr(w, r, tx, http.StatusNotFound, fmt.Errorf("no 
Parameter exists by id: %s", id), nil)
+               return
+       }
+
+       //assignedProfile := 0
+       //if err := inf.Tx.Get(&assignedProfile, "SELECT count(profile) FROM 
profile_parameter pp WHERE pp.parameter=$1", id); err != nil {
+       //      api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
fmt.Errorf("parameter delete error, could not count assigned profiles: %w", 
err))
+       //      return
+       //} else if assignedProfile != 0 {
+       //      api.HandleErr(w, r, tx, http.StatusBadRequest, fmt.Errorf("can 
not delete a parameter with %d assigned profile", assignedProfile), nil)
+       //      return
+       //}
+

Review Comment:
   Probably these commented lines can be removed?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to