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


##########
traffic_ops/v5-client/server.go:
##########
@@ -36,90 +36,90 @@ func needAndCanFetch(id *int, name *string) bool {
 }
 
 // CreateServer creates the given Server.
-func (to *Session) CreateServer(server tc.ServerV4, opts RequestOptions) 
(tc.Alerts, toclientlib.ReqInf, error) {
+func (to *Session) CreateServer(server tc.ServerV5, opts RequestOptions) 
(tc.Alerts, toclientlib.ReqInf, error) {
        var alerts tc.Alerts
        var remoteAddr net.Addr
        reqInf := toclientlib.ReqInf{CacheHitStatus: 
toclientlib.CacheHitStatusMiss, RemoteAddr: remoteAddr}
 
-       if needAndCanFetch(server.CachegroupID, server.Cachegroup) {
+       if server.CacheGroupID <= 0 && server.CacheGroup != "" {
                innerOpts := NewRequestOptions()
-               innerOpts.QueryParameters.Set("name", *server.Cachegroup)
+               innerOpts.QueryParameters.Set("name", server.CacheGroup)
                cg, reqInf, err := to.GetCacheGroups(innerOpts)
                if err != nil {
-                       return cg.Alerts, reqInf, fmt.Errorf("no cachegroup 
named %s: %w", *server.Cachegroup, err)
+                       return cg.Alerts, reqInf, fmt.Errorf("no Cache Group 
named %s: %w", server.CacheGroup, err)
                }
                if len(cg.Response) == 0 {
-                       return cg.Alerts, reqInf, fmt.Errorf("no cachegroup 
named %s", *server.Cachegroup)
+                       return cg.Alerts, reqInf, fmt.Errorf("no Cache Group 
named %s", server.CacheGroup)
                }
                if cg.Response[0].ID == nil {
-                       return cg.Alerts, reqInf, fmt.Errorf("Cachegroup named 
%s has a nil ID", *server.Cachegroup)
+                       return cg.Alerts, reqInf, fmt.Errorf("Cache Group named 
%s has a nil ID", server.CacheGroup)
                }
-               server.CachegroupID = cg.Response[0].ID
+               server.CacheGroupID = *cg.Response[0].ID
        }
-       if needAndCanFetch(server.CDNID, server.CDNName) {
+       if server.CDNID <= 0 && server.CDN != "" {
                innerOpts := NewRequestOptions()
-               innerOpts.QueryParameters.Set("name", *server.CDNName)
+               innerOpts.QueryParameters.Set("name", server.CDN)
                c, reqInf, err := to.GetCDNs(innerOpts)
                if err != nil {
-                       return c.Alerts, reqInf, fmt.Errorf("no CDN named %s: 
%w", *server.CDNName, err)
+                       return c.Alerts, reqInf, fmt.Errorf("no CDN named %s: 
%w", server.CDN, err)
                }
                if len(c.Response) == 0 {
-                       return c.Alerts, reqInf, fmt.Errorf("no CDN named %s", 
*server.CDNName)
+                       return c.Alerts, reqInf, fmt.Errorf("no CDN named %s", 
server.CDN)
                }
-               server.CDNID = &c.Response[0].ID
+               server.CDNID = c.Response[0].ID
        }
-       if needAndCanFetch(server.PhysLocationID, server.PhysLocation) {
+       if server.PhysicalLocationID <= 0 && server.PhysicalLocation != "" {
                innerOpts := NewRequestOptions()
-               innerOpts.QueryParameters.Set("name", *server.PhysLocation)
+               innerOpts.QueryParameters.Set("name", server.PhysicalLocation)
                ph, reqInf, err := to.GetPhysLocations(innerOpts)
                if err != nil {
-                       return ph.Alerts, reqInf, fmt.Errorf("no physlocation 
named %s: %w", *server.PhysLocation, err)
+                       return ph.Alerts, reqInf, fmt.Errorf("no Physical 
Location named %s: %w", server.PhysicalLocation, err)
                }
                if len(ph.Response) == 0 {
-                       return ph.Alerts, reqInf, fmt.Errorf("no physlocation 
named %s", *server.PhysLocation)
+                       return ph.Alerts, reqInf, fmt.Errorf("no Physical 
Location named %s", server.PhysicalLocation)
                }
-               server.PhysLocationID = &ph.Response[0].ID
+               server.PhysicalLocationID = ph.Response[0].ID
        }
-       if needAndCanFetch(server.StatusID, server.Status) {
+       if server.StatusID <= 0 && server.Status != "" {

Review Comment:
   `needAndCanFetch` is unused and should be removed



##########
traffic_ops/traffic_ops_golang/server/servers.go:
##########
@@ -2150,120 +2215,90 @@ func 
getActiveDeliveryServicesThatOnlyHaveThisServerAssigned(id int, serverType
 }
 
 // Delete is the handler for DELETE requests to the /servers API endpoint.
-func Delete(w http.ResponseWriter, r *http.Request) {
-       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, 
[]string{"id"})
-       tx := inf.Tx.Tx
-       if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
-       }
-       defer inf.Close()
-
-       // Middleware should've already handled this, so idk why this is a 
pointer at all tbh
-       version := inf.Version
-       if version == nil {
-               middleware.NotImplementedHandler().ServeHTTP(w, r)
-               return
-       }
-
+func Delete(inf *api.APIInfo) (int, error, error) {
        id := inf.IntParams["id"]
+       tx := inf.Tx.Tx
        serverInfo, exists, err := dbhelpers.GetServerInfo(id, tx)
        if err != nil {
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
err)
-               return
+               return http.StatusInternalServerError, nil, err
        }
        if !exists {
-               api.HandleErr(w, r, tx, http.StatusNotFound, fmt.Errorf("no 
server exists by id #%d", id), nil)
-               return
+               return http.StatusNotFound, fmt.Errorf("no server exists by id 
#%d", id), nil
        }
 
        if dsIDs, err := 
getActiveDeliveryServicesThatOnlyHaveThisServerAssigned(id, serverInfo.Type, 
tx); err != nil {
-               sysErr = fmt.Errorf("checking if server #%d is the last server 
assigned to any Delivery Services: %v", id, err)
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
+               return http.StatusInternalServerError, nil, 
fmt.Errorf("checking if server #%d is the last server assigned to any Delivery 
Services: %w", id, err)
        } else if len(dsIDs) > 0 {
-               alertText := fmt.Sprintf("deleting server #%d would leave 
Active Delivery Service", id)
-               alertText = 
InvalidStatusForDeliveryServicesAlertText(alertText, serverInfo.Type, dsIDs)
-
-               api.WriteAlerts(w, r, http.StatusConflict, 
tc.CreateAlerts(tc.ErrorLevel, alertText))
-               return
+               return http.StatusConflict, fmt.Errorf("deleting server #%d 
would leave Active Delivery Service", id), nil
        }
 
-       var servers []tc.ServerV40
-       servers, _, userErr, sysErr, errCode, _ = getServers(r.Header, 
map[string]string{"id": inf.Params["id"]}, inf.Tx, inf.User, false, *version, 
inf.Config.RoleBasedPermissions)
+       servers, _, userErr, sysErr, errCode, _ := 
getServers(inf.RequestHeaders(), map[string]string{"id": inf.Params["id"]}, 
inf.Tx, inf.User, false, *inf.Version, inf.Config.RoleBasedPermissions)
        if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        }
 
        if len(servers) < 1 {
-               api.HandleErr(w, r, tx, http.StatusNotFound, fmt.Errorf("no 
server exists by id #%d", id), nil)
-               return
+               return http.StatusNotFound, fmt.Errorf("no server exists by id 
#%d", id), nil
        }
        if len(servers) > 1 {
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
fmt.Errorf("there are somehow two servers with id %d - cannot delete", id))
-               return
+               return http.StatusInternalServerError, nil, fmt.Errorf("there 
are somehow two servers with id %d - cannot delete", id)
        }
        server := servers[0]
-       if server.CDNName != nil {
-               userErr, sysErr, errCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDN(inf.Tx.Tx, *server.CDNName, 
inf.User.UserName)
+       if server.CDN != "" {
+               userErr, sysErr, errCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDN(tx, server.CDN, inf.User.UserName)
                if userErr != nil || sysErr != nil {
-                       api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
-                       return
+                       return errCode, userErr, sysErr
                }
-       } else if server.CDNID != nil {
-               userErr, sysErr, errCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDNWithID(inf.Tx.Tx, int64(*server.CDNID), 
inf.User.UserName)
+       } else {
+               // when would this happen?
+               userErr, sysErr, errCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDNWithID(tx, int64(server.CDNID), 
inf.User.UserName)
                if userErr != nil || sysErr != nil {
-                       api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
-                       return
+                       return errCode, userErr, sysErr
                }
        }
-       cacheGroupIds := []int{*server.CachegroupID}
-       serverIds := []int{*server.ID}
-       hasDSOnCDN, err := 
dbhelpers.CachegroupHasTopologyBasedDeliveryServicesOnCDN(inf.Tx.Tx, 
*server.CachegroupID, *server.CDNID)
+       cacheGroupIds := []int{server.CacheGroupID}
+       serverIds := []int{server.ID}
+       hasDSOnCDN, err := 
dbhelpers.CachegroupHasTopologyBasedDeliveryServicesOnCDN(tx, 
server.CacheGroupID, server.CDNID)
        if err != nil {
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
err)
-               return
+               return http.StatusInternalServerError, nil, err
        }
        CDNIDs := []int{}
        if hasDSOnCDN {
-               CDNIDs = append(CDNIDs, *server.CDNID)
+               CDNIDs = append(CDNIDs, server.CDNID)
        }
        if err := topology_validation.CheckForEmptyCacheGroups(inf.Tx, 
cacheGroupIds, CDNIDs, true, serverIds); err != nil {
-               api.HandleErr(w, r, tx, http.StatusBadRequest, 
errors.New("server is the last one in its cachegroup, which is used by a 
topology: "+err.Error()), nil)
-               return
+               return http.StatusBadRequest, fmt.Errorf("server is the last 
one in its cachegroup, which is used by a topology: %w", err), nil
        }
 
        if result, err := tx.Exec(deleteServerQuery, id); err != nil {
                log.Errorf("Raw error: %v", err)
                userErr, sysErr, errCode = api.ParseDBError(err)
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        } else if rowsAffected, err := result.RowsAffected(); err != nil {
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
fmt.Errorf("getting rows affected by server delete: %v", err))
-               return
+               return http.StatusInternalServerError, nil, fmt.Errorf("getting 
rows affected by server delete: %w", err)
        } else if rowsAffected != 1 {
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
fmt.Errorf("incorrect number of rows affected: %d", rowsAffected))
-               return
+               return http.StatusInternalServerError, nil, 
fmt.Errorf("incorrect number of rows affected: %d", rowsAffected)
+       }
+
+       inf.CreateChangeLog(fmt.Sprintf("SERVER: %s.%s, ID: %d, ACTION: 
deleted", server.HostName, server.DomainName, server.ID))
+       if inf.Version.Major >= 5 {

Review Comment:
   This should use `Version.GreaterThanOrEqualTo`



##########
traffic_ops/traffic_ops_golang/server/servers.go:
##########
@@ -1308,108 +1270,90 @@ func deleteInterfaces(id int, tx *sql.Tx) (error, 
error, int) {
 }
 
 // Update is the handler for PUT requests to /servers.
-func Update(w http.ResponseWriter, r *http.Request) {
-       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, 
[]string{"id"})
-       tx := inf.Tx.Tx
-       if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
-               return
-       }
-       defer inf.Close()
-
-       // Middleware should've already handled this, so idk why this is a 
pointer at all tbh
-       version := inf.Version
-       if version == nil {
-               middleware.NotImplementedHandler().ServeHTTP(w, r)
-               return
-       }
-
+func Update(inf *api.APIInfo) (int, error, error) {
        id := inf.IntParams["id"]
 
        // Get original server
-       originals, _, userErr, sysErr, errCode, _ := getServers(r.Header, 
inf.Params, inf.Tx, inf.User, false, *version, inf.Config.RoleBasedPermissions)
+       originals, _, userErr, sysErr, errCode, _ := 
getServers(inf.RequestHeaders(), inf.Params, inf.Tx, inf.User, false, 
*inf.Version, inf.Config.RoleBasedPermissions)
        if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        }
        if len(originals) < 1 {
-               api.HandleErr(w, r, tx, http.StatusNotFound, errors.New("the 
server doesn't exist, cannot update"), nil)
-               return
+               return http.StatusNotFound, errors.New("the server doesn't 
exist, cannot update"), nil
        }
        if len(originals) > 1 {
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
fmt.Errorf("too many servers by ID %d: %d", id, len(originals)))
-               return
+               return http.StatusInternalServerError, nil, fmt.Errorf("too 
many servers by ID %d: %d", id, len(originals))
        }
 
        original := originals[0]
        if original.XMPPID == nil || *original.XMPPID == "" {
-               log.Warnf("original server %s had no XMPPID\n", 
*original.HostName)
-       }
-       if original.StatusID == nil {
-               sysErr = errors.New("original server had no status ID")
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
-       }
-       if original.Status == nil {
-               sysErr = errors.New("original server had no status name")
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
-       }
-       if original.CachegroupID == nil {
-               sysErr = errors.New("original server had no Cache Group ID")
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
+               log.Warnf("original server %s (#%d) had no XMPPID", 
original.HostName, original.ID)
        }
        if original.StatusLastUpdated == nil {
                log.Warnln("original server had no Status Last Updated time")
-               if original.LastUpdated == nil {
-                       sysErr = errors.New("original server had no Last 
Updated time")
-                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
nil, sysErr)
-                       return
-               }
-               original.StatusLastUpdated = &original.LastUpdated.Time
+               original.StatusLastUpdated = util.Ptr(original.LastUpdated)
        }
 
        var originalXMPPID string
        if original.XMPPID != nil {
                originalXMPPID = *original.XMPPID
        }
-       originalStatusID := *original.StatusID
+       originalStatusID := original.StatusID
 
-       var server tc.ServerV40
+       var server tc.ServerV5
        var serverV3 tc.ServerV30
        var statusLastUpdatedTime time.Time
+       tx := inf.Tx.Tx
 
-       if inf.Version.Major >= 4 {
-               server.ID = new(int)
-               *server.ID = inf.IntParams["id"]
-               if err := json.NewDecoder(r.Body).Decode(&server); err != nil {
-                       api.HandleErr(w, r, tx, http.StatusBadRequest, err, nil)
-                       return
+       if inf.Version.Major >= 5 {

Review Comment:
   This should use `Version.GreaterThanOrEqualTo`



##########
.gitignore:
##########
@@ -61,7 +61,7 @@ local.tar.gz
 *.sublime-project
 *.sublime-workspace
 .vscode/
-__debug_bin
+__debug_bin*

Review Comment:
   All `__debug_bin*` binaries in a directory should be deleted each time `dlv` 
is started, but that would fit in a different PR



##########
traffic_ops/traffic_ops_golang/server/servers.go:
##########
@@ -1308,108 +1270,90 @@ func deleteInterfaces(id int, tx *sql.Tx) (error, 
error, int) {
 }
 
 // Update is the handler for PUT requests to /servers.
-func Update(w http.ResponseWriter, r *http.Request) {
-       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, 
[]string{"id"})
-       tx := inf.Tx.Tx
-       if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
-               return
-       }
-       defer inf.Close()
-
-       // Middleware should've already handled this, so idk why this is a 
pointer at all tbh
-       version := inf.Version
-       if version == nil {
-               middleware.NotImplementedHandler().ServeHTTP(w, r)
-               return
-       }
-
+func Update(inf *api.APIInfo) (int, error, error) {
        id := inf.IntParams["id"]
 
        // Get original server
-       originals, _, userErr, sysErr, errCode, _ := getServers(r.Header, 
inf.Params, inf.Tx, inf.User, false, *version, inf.Config.RoleBasedPermissions)
+       originals, _, userErr, sysErr, errCode, _ := 
getServers(inf.RequestHeaders(), inf.Params, inf.Tx, inf.User, false, 
*inf.Version, inf.Config.RoleBasedPermissions)
        if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        }
        if len(originals) < 1 {
-               api.HandleErr(w, r, tx, http.StatusNotFound, errors.New("the 
server doesn't exist, cannot update"), nil)
-               return
+               return http.StatusNotFound, errors.New("the server doesn't 
exist, cannot update"), nil
        }
        if len(originals) > 1 {
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
fmt.Errorf("too many servers by ID %d: %d", id, len(originals)))
-               return
+               return http.StatusInternalServerError, nil, fmt.Errorf("too 
many servers by ID %d: %d", id, len(originals))
        }
 
        original := originals[0]
        if original.XMPPID == nil || *original.XMPPID == "" {
-               log.Warnf("original server %s had no XMPPID\n", 
*original.HostName)
-       }
-       if original.StatusID == nil {
-               sysErr = errors.New("original server had no status ID")
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
-       }
-       if original.Status == nil {
-               sysErr = errors.New("original server had no status name")
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
-       }
-       if original.CachegroupID == nil {
-               sysErr = errors.New("original server had no Cache Group ID")
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
+               log.Warnf("original server %s (#%d) had no XMPPID", 
original.HostName, original.ID)
        }
        if original.StatusLastUpdated == nil {
                log.Warnln("original server had no Status Last Updated time")
-               if original.LastUpdated == nil {
-                       sysErr = errors.New("original server had no Last 
Updated time")
-                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
nil, sysErr)
-                       return
-               }
-               original.StatusLastUpdated = &original.LastUpdated.Time
+               original.StatusLastUpdated = util.Ptr(original.LastUpdated)
        }
 
        var originalXMPPID string
        if original.XMPPID != nil {
                originalXMPPID = *original.XMPPID
        }
-       originalStatusID := *original.StatusID
+       originalStatusID := original.StatusID
 
-       var server tc.ServerV40
+       var server tc.ServerV5
        var serverV3 tc.ServerV30
        var statusLastUpdatedTime time.Time
+       tx := inf.Tx.Tx
 
-       if inf.Version.Major >= 4 {
-               server.ID = new(int)
-               *server.ID = inf.IntParams["id"]
-               if err := json.NewDecoder(r.Body).Decode(&server); err != nil {
-                       api.HandleErr(w, r, tx, http.StatusBadRequest, err, nil)
-                       return
+       if inf.Version.Major >= 5 {
+               server.ID = inf.IntParams["id"]
+               if err := inf.DecodeBody(&server); err != nil {
+                       return http.StatusBadRequest, err, nil
+               }
+               if server.StatusID != originalStatusID {
+                       currentTime := time.Now()
+                       server.StatusLastUpdated = &currentTime
+                       statusLastUpdatedTime = currentTime
+               } else {
+                       server.StatusLastUpdated = original.StatusLastUpdated
+                       statusLastUpdatedTime = *original.StatusLastUpdated
+               }
+               tmp := server.Downgrade()
+               _, userErr, sysErr := validateV4(&tmp, tx)
+               if userErr != nil || sysErr != nil {
+                       if sysErr != nil {
+                               return http.StatusInternalServerError, userErr, 
sysErr
+                       }
+                       return http.StatusBadRequest, userErr, sysErr
+               }
+               server = tmp.Upgrade()
+       } else if inf.Version.Major >= 4 {

Review Comment:
   This should use `Version.GreaterThanOrEqualTo`



##########
traffic_ops/traffic_ops_golang/server/servers.go:
##########
@@ -671,74 +667,47 @@ and p.id = $1
 }
 
 // Read is the handler for GET requests to /servers.
-func Read(w http.ResponseWriter, r *http.Request) {
-       var maxTime *time.Time
-       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()
-
-       // Middleware should've already handled this, so idk why this is a 
pointer at all tbh
+func Read(inf *api.APIInfo) (int, error, error) {
+       useIMS := inf.UseIMS()
        version := inf.Version
-       if version == nil {
-               middleware.NotImplementedHandler().ServeHTTP(w, r)
-               return
-       }
-
-       servers := []tc.ServerV40{}
-       var serverCount uint64
-       cfg, e := api.GetConfig(r.Context())
-       useIMS := false
-       if e == nil && cfg != nil {
-               useIMS = cfg.UseIMS
-       } else {
-               log.Warnf("Couldn't get config %v", e)
-       }
 
-       servers, serverCount, userErr, sysErr, errCode, maxTime = 
getServers(r.Header, inf.Params, inf.Tx, inf.User, useIMS, *version, 
inf.Config.RoleBasedPermissions)
-       if maxTime != nil && api.SetLastModifiedHeader(r, useIMS) {
-               api.AddLastModifiedHdr(w, *maxTime)
+       servers, serverCount, userErr, sysErr, errCode, maxTime := 
getServers(inf.RequestHeaders(), inf.Params, inf.Tx, inf.User, useIMS, 
*version, inf.Config.RoleBasedPermissions)
+       if useIMS && maxTime != nil {
+               inf.SetLastModified(*maxTime)
        }
        if errCode == http.StatusNotModified {
-               w.WriteHeader(errCode)
-               api.WriteResp(w, r, []tc.ServerV40{})
-               return
+               return inf.WriteNotModifiedResponse([]tc.ServerV5{})
        }
        if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        }
-       if version.Major >= 4 {
-               if version.Minor >= 1 {
-                       api.WriteRespWithSummary(w, r, servers, serverCount)
-                       return
-               }
-               v40Servers := make([]tc.ServerV40, 0)
-               for _, server := range servers {
-                       v40Servers = append(v40Servers, server)
-               }
-               api.WriteRespWithSummary(w, r, v40Servers, serverCount)
-               return
+       if version.Major >= 5 {

Review Comment:
   This should use `Version.GreaterThanOrEqualTo`



##########
traffic_ops/traffic_ops_golang/server/servers.go:
##########
@@ -1421,230 +1365,200 @@ func Update(w http.ResponseWriter, r *http.Request) {
                }
                _, userErr, sysErr := validateV3(&serverV3, tx)
                if userErr != nil || sysErr != nil {
-                       code := http.StatusBadRequest
                        if sysErr != nil {
-                               code = http.StatusInternalServerError
+                               return http.StatusInternalServerError, userErr, 
sysErr
                        }
-                       api.HandleErr(w, r, tx, code, userErr, sysErr)
-                       return
+                       return http.StatusBadRequest, userErr, sysErr
                }
 
                profileName, exists, err := 
dbhelpers.GetProfileNameFromID(*serverV3.ProfileID, tx)
                if err != nil {
-                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
nil, err)
-                       return
+                       return http.StatusInternalServerError, nil, err
                }
                if !exists {
-                       api.HandleErr(w, r, tx, http.StatusNotFound, 
errors.New("profile does not exist"), nil)
-                       return
+                       return http.StatusNotFound, errors.New("profile does 
not exist"), nil
                }
                profileNames := []string{profileName}
 
-               server, err = serverV3.UpgradeToV40(profileNames)
+               upgraded, err := serverV3.UpgradeToV40(profileNames)
                if err != nil {
-                       sysErr = fmt.Errorf("error upgrading valid V3 server to 
V4 structure: %v", err)
-                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
nil, sysErr)
-                       return
+                       return http.StatusInternalServerError, nil, 
fmt.Errorf("error upgrading valid V3 server to V4 structure: %w", err)
                }
+               server = upgraded.Upgrade()
        }
 
-       if *original.CachegroupID != *server.CachegroupID || *original.CDNID != 
*server.CDNID {
-               hasDSOnCDN, err := 
dbhelpers.CachegroupHasTopologyBasedDeliveryServicesOnCDN(tx, 
*original.CachegroupID, *original.CDNID)
+       if original.CacheGroupID != server.CacheGroupID || original.CDNID != 
server.CDNID {
+               hasDSOnCDN, err := 
dbhelpers.CachegroupHasTopologyBasedDeliveryServicesOnCDN(tx, 
original.CacheGroupID, original.CDNID)
                if err != nil {
-                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
nil, err)
-                       return
+                       return http.StatusInternalServerError, nil, err
                }
                CDNIDs := []int{}
                if hasDSOnCDN {
-                       CDNIDs = append(CDNIDs, *original.CDNID)
+                       CDNIDs = append(CDNIDs, original.CDNID)
                }
-               cacheGroupIds := []int{*original.CachegroupID}
-               serverIds := []int{*original.ID}
-               if err = topology_validation.CheckForEmptyCacheGroups(inf.Tx, 
cacheGroupIds, CDNIDs, true, serverIds); err != nil {
-                       api.HandleErr(w, r, tx, http.StatusBadRequest, 
errors.New("server is the last one in its cachegroup, which is used by a 
topology, so it cannot be moved to another cachegroup: "+err.Error()), nil)
-                       return
+               if err = topology_validation.CheckForEmptyCacheGroups(inf.Tx, 
[]int{original.CacheGroupID}, CDNIDs, true, []int{original.ID}); err != nil {
+                       return http.StatusBadRequest, fmt.Errorf("server is the 
last one in its Cache Group, which is used by a Topology, so it cannot be moved 
to another Cache Group: %w", err), nil
                }
        }
 
-       status, ok, err := dbhelpers.GetStatusByID(*server.StatusID, tx)
+       status, ok, err := dbhelpers.GetStatusByID(server.StatusID, tx)
        if err != nil {
-               sysErr = fmt.Errorf("getting server #%d status (#%d): %v", id, 
*server.StatusID, err)
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
+               return http.StatusInternalServerError, nil, fmt.Errorf("getting 
server #%d status (#%d): %v", id, server.StatusID, err)
        }
        if !ok {
-               log.Warnf("previously existent status #%d not found when 
fetching later", *server.StatusID)
-               userErr = fmt.Errorf("no such Status: #%d", *server.StatusID)
-               api.HandleErr(w, r, tx, http.StatusBadRequest, userErr, nil)
-               return
+               log.Warnf("previously existent status #%d not found when 
fetching later", server.StatusID)
+               return http.StatusBadRequest, fmt.Errorf("no such Status: #%d", 
server.StatusID), nil
        }
        if status.Name == nil {
-               sysErr = fmt.Errorf("status #%d had no name", *server.StatusID)
-               api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, 
sysErr)
-               return
+               return http.StatusInternalServerError, nil, fmt.Errorf("status 
#%d had no name", server.StatusID)
        }
        if *status.Name != string(tc.CacheStatusOnline) && *status.Name != 
string(tc.CacheStatusReported) {
                dsIDs, err := 
getActiveDeliveryServicesThatOnlyHaveThisServerAssigned(id, original.Type, tx)
                if err != nil {
-                       sysErr = fmt.Errorf("getting Delivery Services to which 
server #%d is assigned that have no other servers: %v", id, err)
-                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
nil, sysErr)
-                       return
+                       return http.StatusInternalServerError,
+                               nil,
+                               fmt.Errorf("getting Delivery Services to which 
server #%d is assigned that have no other servers: %w", id, err)
                }
                if len(dsIDs) > 0 {
                        prefix := fmt.Sprintf("setting server status to '%s' 
would leave Active Delivery Service", *status.Name)
                        alertText := 
InvalidStatusForDeliveryServicesAlertText(prefix, original.Type, dsIDs)
-                       api.WriteAlerts(w, r, http.StatusConflict, 
tc.CreateAlerts(tc.ErrorLevel, alertText))
-                       return
+                       return http.StatusConflict, errors.New(alertText), nil
                }
        }
 
        if userErr, sysErr, errCode = checkTypeChangeSafety(server, inf.Tx); 
userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        }
 
        if server.XMPPID != nil && *server.XMPPID != "" && originalXMPPID != "" 
&& *server.XMPPID != originalXMPPID {
-               api.WriteAlerts(w, r, http.StatusBadRequest, 
tc.CreateAlerts(tc.ErrorLevel, fmt.Sprintf("server cannot be updated due to 
requested XMPPID change. XMPIDD is immutable")))
-               return
+               return http.StatusBadRequest, errors.New("server cannot be 
updated due to requested XMPPID change. XMPIDD is immutable"), nil
        }
 
-       userErr, sysErr, statusCode := api.CheckIfUnModified(r.Header, inf.Tx, 
*server.ID, "server")
+       userErr, sysErr, statusCode := 
api.CheckIfUnModified(inf.RequestHeaders(), inf.Tx, server.ID, "server")
        if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, tx, statusCode, userErr, sysErr)
-               return
+               return statusCode, userErr, sysErr
        }
 
-       if server.CDNName != nil {
-               userErr, sysErr, statusCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDN(inf.Tx.Tx, *server.CDNName, 
inf.User.UserName)
+       if server.CDN != "" {
+               userErr, sysErr, statusCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDN(inf.Tx.Tx, server.CDN, 
inf.User.UserName)
                if userErr != nil || sysErr != nil {
-                       api.HandleErr(w, r, inf.Tx.Tx, statusCode, userErr, 
sysErr)
-                       return
+                       return statusCode, userErr, sysErr
                }
-       } else if server.CDNID != nil {
-               userErr, sysErr, statusCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDNWithID(inf.Tx.Tx, int64(*server.CDNID), 
inf.User.UserName)
+       } else {
+               userErr, sysErr, statusCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDNWithID(inf.Tx.Tx, int64(server.CDNID), 
inf.User.UserName)
                if userErr != nil || sysErr != nil {
-                       api.HandleErr(w, r, inf.Tx.Tx, statusCode, userErr, 
sysErr)
-                       return
+                       return statusCode, userErr, sysErr
                }
        }
 
        if inf.Version.Major >= 4 {
-               if err = dbhelpers.UpdateServerProfilesForV4(*server.ID, 
server.ProfileNames, tx); err != nil {
+               if err = dbhelpers.UpdateServerProfilesForV4(server.ID, 
server.Profiles, tx); err != nil {
                        userErr, sysErr, errCode := api.ParseDBError(err)
-                       api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
-                       return
+                       return errCode, userErr, sysErr
                }
        } else {
-               if err = dbhelpers.UpdateServerProfileTableForV3(serverV3.ID, 
serverV3.ProfileID, (original.ProfileNames)[0], tx); err != nil {
-                       api.HandleErr(w, r, tx, http.StatusInternalServerError, 
nil, fmt.Errorf("failed to update server_profile: %w", err))
-                       return
+               if err = dbhelpers.UpdateServerProfileTableForV3(serverV3.ID, 
serverV3.ProfileID, (original.Profiles)[0], tx); err != nil {
+                       return http.StatusInternalServerError, nil, 
fmt.Errorf("failed to update server_profile: %w", err)
                }
        }
 
        serverID, errCode, userErr, sysErr := updateServer(inf.Tx, server)
        if userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        }
 
        if userErr, sysErr, errCode = deleteInterfaces(id, tx); userErr != nil 
|| sysErr != nil {
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        }
 
        if userErr, sysErr, errCode = createInterfaces(id, server.Interfaces, 
tx); userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
-               return
+               return errCode, userErr, sysErr
        }
 
        where := `WHERE s.id = $1`
        var selquery string
-       if version.Major <= 4 {
+       if inf.Version.Major <= 4 {

Review Comment:
   This should use `Version.LessThan` (or `Version.LessThanOrEqualTo` if you 
want to add it)



-- 
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