You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by zr...@apache.org on 2020/11/06 18:55:42 UTC

[trafficcontrol] branch master updated: Fix servers client methods changing call signatures (#5248)

This is an automated email from the ASF dual-hosted git repository.

zrhoffman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 3bc4726  Fix servers client methods changing call signatures (#5248)
3bc4726 is described below

commit 3bc4726f976abcd7fdef0eb8a3cbadecf39081c4
Author: ocket8888 <oc...@apache.org>
AuthorDate: Fri Nov 6 11:55:27 2020 -0700

    Fix servers client methods changing call signatures (#5248)
    
    * Fix servers client methods changing call signatures
    
    * extract helper functions
---
 infrastructure/cdn-in-a-box/enroller/enroller.go   |  4 +-
 lib/go-tc/servers.go                               | 95 +++++++++++++++++++++-
 traffic_monitor/towrap/towrap.go                   | 24 +++---
 .../api/v3/cachegroupsdeliveryservices_test.go     |  8 +-
 traffic_ops/testing/api/v3/crconfig_test.go        |  6 +-
 .../testing/api/v3/deliveryserviceservers_test.go  | 46 +++++------
 traffic_ops/testing/api/v3/monitoring_test.go      |  4 +-
 traffic_ops/testing/api/v3/servers_test.go         | 42 +++++-----
 .../servers_to_deliveryservice_assignment_test.go  | 10 +--
 .../testing/api/v3/serverservercapability_test.go  |  4 +-
 .../testing/api/v3/serverupdatestatus_test.go      | 34 ++++----
 traffic_ops/testing/api/v3/traffic_control_test.go |  2 +-
 traffic_ops/v3-client/server.go                    | 70 ++++++++++------
 traffic_ops_ort/atstccfg/toreqnew/toreqnew.go      |  8 +-
 14 files changed, 232 insertions(+), 125 deletions(-)

diff --git a/infrastructure/cdn-in-a-box/enroller/enroller.go b/infrastructure/cdn-in-a-box/enroller/enroller.go
index c16ab3e..3d95973 100644
--- a/infrastructure/cdn-in-a-box/enroller/enroller.go
+++ b/infrastructure/cdn-in-a-box/enroller/enroller.go
@@ -635,14 +635,14 @@ func enrollProfile(toSession *session, r io.Reader) error {
 // enrollServer takes a json file and creates a Server object using the TO API
 func enrollServer(toSession *session, r io.Reader) error {
 	dec := json.NewDecoder(r)
-	var s tc.ServerNullable
+	var s tc.ServerV30
 	err := dec.Decode(&s)
 	if err != nil {
 		log.Infof("error decoding Server: %s\n", err)
 		return err
 	}
 
-	alerts, _, err := toSession.CreateServer(s)
+	alerts, _, err := toSession.CreateServerWithHdr(s, nil)
 	if err != nil {
 		log.Infof("error creating Server: %s\n", err)
 		return err
diff --git a/lib/go-tc/servers.go b/lib/go-tc/servers.go
index 53c8d49..975e016 100644
--- a/lib/go-tc/servers.go
+++ b/lib/go-tc/servers.go
@@ -34,7 +34,7 @@ import (
 
 // ServersV3Response is the format of a response to a GET request for /servers.
 type ServersV3Response struct {
-	Response []ServerNullable `json:"response"`
+	Response []ServerV30 `json:"response"`
 	Summary  struct {
 		Count uint64 `json:"count"`
 	} `json:"summary"`
@@ -348,6 +348,9 @@ func InterfaceInfoToLegacyInterfaces(serverInterfaces []ServerInterfaceInfo) (Le
 	return legacyDetails, errors.New("no service addresses found")
 }
 
+// Server is a non-"nullable" representation of a Server as it appeared in API
+// version 2.0
+// Deprecated: Please use versioned and nullable structures from now on.
 type Server struct {
 	Cachegroup       string              `json:"cachegroup" db:"cachegroup"`
 	CachegroupID     int                 `json:"cachegroupId" db:"cachegroup_id"`
@@ -574,11 +577,97 @@ func (s Server) ToNullable() ServerNullableV2 {
 	}
 }
 
+func coerceBool(b *bool) bool {
+	if b == nil {
+		return false
+	}
+	return *b
+}
+func coerceInt(i *int) int {
+	if i == nil {
+		return 0
+	}
+	return *i
+}
+
+func coerceString(s *string) string {
+	if s == nil {
+		return ""
+	}
+	return *s
+}
+
+// ToNonNullable converts the ServerNullableV2 safely to a Server structure.
+func (s ServerNullableV2) ToNonNullable() Server {
+	ret := Server{
+		Cachegroup:     coerceString(s.Cachegroup),
+		CachegroupID:   coerceInt(s.CachegroupID),
+		CDNID:          coerceInt((s.CDNID)),
+		CDNName:        coerceString(s.CDNName),
+		DomainName:     coerceString(s.DomainName),
+		FQDN:           s.FQDN,
+		FqdnTime:       s.FqdnTime,
+		GUID:           coerceString(s.GUID),
+		HostName:       coerceString(s.HostName),
+		HTTPSPort:      coerceInt(s.HTTPSPort),
+		ID:             coerceInt(s.ID),
+		ILOIPAddress:   coerceString(s.ILOIPAddress),
+		ILOIPGateway:   coerceString(s.ILOIPGateway),
+		ILOIPNetmask:   coerceString(s.ILOIPNetmask),
+		ILOPassword:    coerceString(s.ILOPassword),
+		ILOUsername:    coerceString(s.ILOUsername),
+		InterfaceMtu:   coerceInt(s.InterfaceMtu),
+		InterfaceName:  coerceString(s.InterfaceName),
+		IP6Address:     coerceString(s.IP6Address),
+		IP6IsService:   coerceBool(s.IP6IsService),
+		IP6Gateway:     coerceString(s.IP6Gateway),
+		IPAddress:      coerceString(s.IPAddress),
+		IPIsService:    coerceBool(s.IPIsService),
+		IPGateway:      coerceString(s.IPGateway),
+		IPNetmask:      coerceString(s.IPNetmask),
+		MgmtIPAddress:  coerceString(s.MgmtIPAddress),
+		MgmtIPGateway:  coerceString(s.MgmtIPGateway),
+		MgmtIPNetmask:  coerceString(s.MgmtIPNetmask),
+		OfflineReason:  coerceString(s.OfflineReason),
+		PhysLocation:   coerceString(s.PhysLocation),
+		PhysLocationID: coerceInt(s.PhysLocationID),
+		Profile:        coerceString(s.Profile),
+		ProfileDesc:    coerceString(s.ProfileDesc),
+		ProfileID:      coerceInt(s.ProfileID),
+		Rack:           coerceString(s.Rack),
+		RevalPending:   coerceBool(s.RevalPending),
+		RouterHostName: coerceString(s.RouterHostName),
+		RouterPortName: coerceString(s.RouterPortName),
+		Status:         coerceString(s.Status),
+		StatusID:       coerceInt(s.StatusID),
+		TCPPort:        coerceInt(s.TCPPort),
+		Type:           s.Type,
+		TypeID:         coerceInt(s.TypeID),
+		UpdPending:     coerceBool(s.UpdPending),
+		XMPPID:         coerceString(s.XMPPID),
+		XMPPPasswd:     coerceString(s.XMPPPasswd),
+	}
+
+	if s.DeliveryServices == nil {
+		ret.DeliveryServices = nil
+	} else {
+		ret.DeliveryServices = *s.DeliveryServices
+	}
+
+	if s.LastUpdated == nil {
+		ret.LastUpdated = TimeNoMod{}
+	} else {
+		ret.LastUpdated = *s.LastUpdated
+	}
+
+	return ret
+}
+
 // Upgrade upgrades the ServerNullableV2 to the new ServerNullable structure.
 //
 // Note that this makes "shallow" copies of all underlying data, so changes to
 // the original will affect the upgraded copy.
-func (s ServerNullableV2) Upgrade() (ServerNullable, error) {
+func (s ServerNullableV2) Upgrade() (ServerV30, error) {
 	ipv4IsService := false
 	if s.IPIsService != nil {
 		ipv4IsService = *s.IPIsService
@@ -588,7 +677,7 @@ func (s ServerNullableV2) Upgrade() (ServerNullable, error) {
 		ipv6IsService = *s.IP6IsService
 	}
 
-	upgraded := ServerNullable{
+	upgraded := ServerV30{
 		CommonServerProperties: s.CommonServerProperties,
 	}
 
diff --git a/traffic_monitor/towrap/towrap.go b/traffic_monitor/towrap/towrap.go
index b3ec070..577f490 100644
--- a/traffic_monitor/towrap/towrap.go
+++ b/traffic_monitor/towrap/towrap.go
@@ -520,25 +520,25 @@ func (s TrafficOpsSessionThreadsafe) TrafficMonitorConfigMap(cdn string) (*tc.Tr
 	return mc, nil
 }
 
-func (s TrafficOpsSessionThreadsafe) fetchServerByHostname(hostName string) (tc.ServerNullable, error) {
+func (s TrafficOpsSessionThreadsafe) fetchServerByHostname(hostName string) (tc.ServerV30, error) {
 	ss := s.get()
 	if ss == nil {
-		return tc.ServerNullable{}, ErrNilSession
+		return tc.ServerV30{}, ErrNilSession
 	}
 
 	params := url.Values{}
 	params.Set("hostName", hostName)
 	resp, _, err := ss.GetServersWithHdr(&params, nil)
 	if err != nil {
-		return tc.ServerNullable{}, fmt.Errorf("fetching server by hostname '%s': %v", hostName, err)
+		return tc.ServerV30{}, fmt.Errorf("fetching server by hostname '%s': %v", hostName, err)
 	}
 
 	respLen := len(resp.Response)
 	if respLen < 1 {
-		return tc.ServerNullable{}, fmt.Errorf("no server '%s' found in Traffic Ops", hostName)
+		return tc.ServerV30{}, fmt.Errorf("no server '%s' found in Traffic Ops", hostName)
 	}
 
-	var server tc.ServerNullable
+	var server tc.ServerV30
 	var num int
 	found := false
 	for i, srv := range resp.Response {
@@ -550,7 +550,7 @@ func (s TrafficOpsSessionThreadsafe) fetchServerByHostname(hostName string) (tc.
 		}
 	}
 	if !found {
-		return tc.ServerNullable{}, fmt.Errorf("either no server '%s' found in Traffic Ops, or none by that hostName had non-nil CDN", hostName)
+		return tc.ServerV30{}, fmt.Errorf("either no server '%s' found in Traffic Ops, or none by that hostName had non-nil CDN", hostName)
 	}
 
 	if respLen > 1 {
@@ -560,20 +560,20 @@ func (s TrafficOpsSessionThreadsafe) fetchServerByHostname(hostName string) (tc.
 	return server, nil
 }
 
-func (s TrafficOpsSessionThreadsafe) fetchLegacyServerByHostname(hostName string) (tc.ServerNullable, error) {
+func (s TrafficOpsSessionThreadsafe) fetchLegacyServerByHostname(hostName string) (tc.ServerV30, error) {
 	ss := s.getLegacy()
 	if ss == nil {
-		return tc.ServerNullable{}, ErrNilSession
+		return tc.ServerV30{}, ErrNilSession
 	}
 
 	resp, _, err := ss.GetServerByHostName(hostName)
 	if err != nil {
-		return tc.ServerNullable{}, fmt.Errorf("fetching legacy server by hostname '%s': %v", hostName, err)
+		return tc.ServerV30{}, fmt.Errorf("fetching legacy server by hostname '%s': %v", hostName, err)
 	}
 
 	respLen := len(resp)
 	if respLen < 1 {
-		return tc.ServerNullable{}, fmt.Errorf("no server '%s' found in Traffic Ops", hostName)
+		return tc.ServerV30{}, fmt.Errorf("no server '%s' found in Traffic Ops", hostName)
 	}
 
 	var server tc.ServerNullableV2
@@ -589,7 +589,7 @@ func (s TrafficOpsSessionThreadsafe) fetchLegacyServerByHostname(hostName string
 
 	}
 	if !found {
-		return tc.ServerNullable{}, fmt.Errorf("either no server '%s' found in Traffic Ops, or none by that hostName had non-empty CDN", hostName)
+		return tc.ServerV30{}, fmt.Errorf("either no server '%s' found in Traffic Ops, or none by that hostName had non-empty CDN", hostName)
 	}
 	if respLen > 1 {
 		log.Warnf("Getting monitor server by hostname '%s' returned %d servers - selecting #%d", hostName, respLen, num)
@@ -606,7 +606,7 @@ func (s TrafficOpsSessionThreadsafe) fetchLegacyServerByHostname(hostName string
 // MonitorCDN returns the name of the CDN of a Traffic Monitor with the given
 // hostName.
 func (s TrafficOpsSessionThreadsafe) MonitorCDN(hostName string) (string, error) {
-	var server tc.ServerNullable
+	var server tc.ServerV30
 	var err error
 
 	if s.useLegacy {
diff --git a/traffic_ops/testing/api/v3/cachegroupsdeliveryservices_test.go b/traffic_ops/testing/api/v3/cachegroupsdeliveryservices_test.go
index 63ca685..6f701d5 100644
--- a/traffic_ops/testing/api/v3/cachegroupsdeliveryservices_test.go
+++ b/traffic_ops/testing/api/v3/cachegroupsdeliveryservices_test.go
@@ -111,16 +111,12 @@ func CreateTestCachegroupsDeliveryServices(t *testing.T) {
 		if err != nil {
 			t.Fatalf("getting server: %v", err)
 		}
-		servers := resp.Response
+		servers := resp
 		if len(servers) != 1 {
 			t.Fatalf("getting servers: expected 1 got %v", len(servers))
 		}
 		server := servers[0]
-		if server.ID == nil {
-			t.Errorf("Server %s had nil ID", serverName)
-			continue
-		}
-		serverID := *server.ID
+		serverID := server.ID
 
 		serverDSes, _, err := TOSession.GetDeliveryServicesByServer(serverID)
 
diff --git a/traffic_ops/testing/api/v3/crconfig_test.go b/traffic_ops/testing/api/v3/crconfig_test.go
index 3786d52..1a651f7 100644
--- a/traffic_ops/testing/api/v3/crconfig_test.go
+++ b/traffic_ops/testing/api/v3/crconfig_test.go
@@ -55,11 +55,11 @@ func UpdateTestCRConfigSnapshot(t *testing.T) {
 	if err != nil {
 		t.Fatalf("GetServers err expected nil, actual %+v", err)
 	}
-	servers := resp.Response
+	servers := resp
 	serverID := 0
 	for _, server := range servers {
-		if server.Type == "EDGE" && server.CDNName != nil && *server.CDNName == "cdn1" && server.ID != nil {
-			serverID = *server.ID
+		if server.Type == "EDGE" && server.CDNName == "cdn1" {
+			serverID = server.ID
 			break
 		}
 	}
diff --git a/traffic_ops/testing/api/v3/deliveryserviceservers_test.go b/traffic_ops/testing/api/v3/deliveryserviceservers_test.go
index 936e447..69324c1 100644
--- a/traffic_ops/testing/api/v3/deliveryserviceservers_test.go
+++ b/traffic_ops/testing/api/v3/deliveryserviceservers_test.go
@@ -56,9 +56,9 @@ func AssignServersToTopologyBasedDeliveryService(t *testing.T) {
 		t.Fatal("expected delivery service: 'ds-top' to have a non-nil Topology, actual: nil")
 	}
 	serversResp, _, err := TOSession.GetServers(nil)
-	servers := []tc.ServerNullable{}
-	for _, s := range serversResp.Response {
-		if s.CDNID != nil && *s.CDNID == *ds[0].CDNID && s.Type == tc.CacheTypeEdge.String() {
+	servers := []tc.Server{}
+	for _, s := range serversResp {
+		if s.CDNID == *ds[0].CDNID && s.Type == tc.CacheTypeEdge.String() {
 			servers = append(servers, s)
 		}
 	}
@@ -67,8 +67,8 @@ func AssignServersToTopologyBasedDeliveryService(t *testing.T) {
 	}
 	serverNames := []string{}
 	for _, s := range servers {
-		if s.CDNID != nil && *s.CDNID == *ds[0].CDNID && s.Type == tc.CacheTypeEdge.String() && s.HostName != nil {
-			serverNames = append(serverNames, *s.HostName)
+		if s.CDNID == *ds[0].CDNID && s.Type == tc.CacheTypeEdge.String() {
+			serverNames = append(serverNames, s.HostName)
 		} else {
 			t.Fatalf("expected only EDGE servers in cdn '%s', actual: %v", *ds[0].CDNName, servers)
 		}
@@ -81,7 +81,7 @@ func AssignServersToTopologyBasedDeliveryService(t *testing.T) {
 		t.Fatalf("assigning servers to topology-based delivery service - expected: 400-level status code, actual: %d", reqInf.StatusCode)
 	}
 
-	_, reqInf, err = TOSession.CreateDeliveryServiceServers(*ds[0].ID, []int{*servers[0].ID}, false)
+	_, reqInf, err = TOSession.CreateDeliveryServiceServers(*ds[0].ID, []int{servers[0].ID}, false)
 	if err == nil {
 		t.Fatal("creating deliveryserviceserver assignment for topology-based delivery service - expected: error, actual: nil error")
 	}
@@ -182,24 +182,20 @@ func CreateTestDeliveryServiceServersWithRequiredCapabilities(t *testing.T) {
 			if err != nil {
 				t.Fatalf("cannot GET Server by hostname: %v", err)
 			}
-			servers := resp.Response
-			server := servers[0]
-			if server.ID == nil {
-				t.Fatalf("server %s had nil ID", ctc.serverName)
-			}
+			server := resp[0]
 
 			_, _, err = TOSession.CreateDeliveryServicesRequiredCapability(ctc.capability)
 			if err != nil {
 				t.Fatalf("*POST delivery service required capability: %v", err)
 			}
 
-			ctc.ssc.ServerID = server.ID
+			ctc.ssc.ServerID = &server.ID
 			_, _, err = TOSession.CreateServerServerCapability(ctc.ssc)
 			if err != nil {
 				t.Fatalf("could not POST the server capability %v to server %v: %v", *ctc.ssc.ServerCapability, *ctc.ssc.Server, err)
 			}
 
-			_, _, got := TOSession.CreateDeliveryServiceServers(*ctc.capability.DeliveryServiceID, []int{*server.ID}, true)
+			_, _, got := TOSession.CreateDeliveryServiceServers(*ctc.capability.DeliveryServiceID, []int{server.ID}, true)
 			if (ctc.err == nil && got != nil) || (ctc.err != nil && !strings.Contains(got.Error(), ctc.err.Error())) {
 				t.Fatalf("expected ctc.err to contain %v, got %v", ctc.err, got)
 			}
@@ -230,18 +226,15 @@ func CreateTestMSODSServerWithReqCap(t *testing.T) {
 	if err != nil {
 		t.Fatalf("GET server denver-mso-org-01: %v", err)
 	}
-	servers := resp.Response
+	servers := resp
 	if len(servers) != 1 {
 		t.Fatal("expected 1 server with hostname denver-mso-org-01")
 	}
 
 	s := servers[0]
-	if s.ID == nil {
-		t.Fatal("server 'denver-mso-org-01' had nil ID")
-	}
 
 	// Make sure server has no caps to ensure test correctness
-	sccs, _, err := TOSession.GetServerServerCapabilities(s.ID, nil, nil)
+	sccs, _, err := TOSession.GetServerServerCapabilities(&s.ID, nil, nil)
 	if err != nil {
 		t.Fatalf("GET server server capabilities for denver-mso-org-01: %v", err)
 	}
@@ -265,7 +258,7 @@ func CreateTestMSODSServerWithReqCap(t *testing.T) {
 		t.Fatal("expected to find origin server denver-mso-org-01 to be in eligible server return even though it is missing a required capability")
 	}
 
-	if _, _, err = TOSession.CreateDeliveryServiceServers(*dsReqCap[0].DeliveryServiceID, []int{*s.ID}, true); err != nil {
+	if _, _, err = TOSession.CreateDeliveryServiceServers(*dsReqCap[0].DeliveryServiceID, []int{s.ID}, true); err != nil {
 		t.Fatalf("POST delivery service origin servers without capabilities: %v", err)
 	}
 
@@ -344,7 +337,7 @@ func DeleteTestDeliveryServiceServers(t *testing.T) {
 	}
 }
 
-func getServerAndDSofSameCDN(t *testing.T) (tc.DeliveryServiceNullable, tc.ServerNullable) {
+func getServerAndDSofSameCDN(t *testing.T) (tc.DeliveryServiceNullable, tc.ServerV30) {
 	dses, _, err := TOSession.GetDeliveryServicesNullable()
 	if err != nil {
 		t.Fatalf("cannot GET DeliveryServices: %v", err)
@@ -357,19 +350,24 @@ func getServerAndDSofSameCDN(t *testing.T) (tc.DeliveryServiceNullable, tc.Serve
 	if err != nil {
 		t.Fatalf("cannot GET Servers: %v", err)
 	}
-	servers := resp.Response
+	servers := resp
 	if len(servers) < 1 {
 		t.Fatal("GET Servers returned no dses, must have at least 1 to test ds-servers")
 	}
 
 	for _, ds := range dses {
 		for _, s := range servers {
-			if ds.CDNName != nil && s.CDNName != nil && *ds.CDNName == *s.CDNName {
-				return ds, s
+			if ds.CDNName != nil && *ds.CDNName == s.CDNName {
+				upgraded, err := s.ToNullable().Upgrade()
+				if err != nil {
+					t.Errorf("upgrading server: %v", err)
+					continue
+				}
+				return ds, upgraded
 			}
 		}
 	}
 	t.Fatal("expected at least one delivery service and server in the same CDN")
 
-	return tc.DeliveryServiceNullable{}, tc.ServerNullable{}
+	return tc.DeliveryServiceNullable{}, tc.ServerV30{}
 }
diff --git a/traffic_ops/testing/api/v3/monitoring_test.go b/traffic_ops/testing/api/v3/monitoring_test.go
index e624960..e58c080 100644
--- a/traffic_ops/testing/api/v3/monitoring_test.go
+++ b/traffic_ops/testing/api/v3/monitoring_test.go
@@ -32,7 +32,7 @@ func TestMonitoring(t *testing.T) {
 // This MUST NOT be run after a different function in the same Test creates a Snapshot, or the test will be invalid.
 // This prevents a critical bug of upgrading to 4.x bringing a CDN down until a Snapshot is performed.
 func GetTestMonitoringConfigNoSnapshotOnTheFly(t *testing.T) {
-	server := tc.ServerNullable{}
+	server := tc.ServerV30{}
 	for _, sv := range testData.Servers {
 		if sv.Type != "EDGE" {
 			continue
@@ -54,7 +54,7 @@ func GetTestMonitoringConfigNoSnapshotOnTheFly(t *testing.T) {
 
 func AllCDNsCanSnapshot(t *testing.T) {
 
-	serversByHost := make(map[string]tc.ServerNullable)
+	serversByHost := make(map[string]tc.ServerV30)
 
 	for _, server := range testData.Servers {
 		serversByHost[*server.HostName] = server
diff --git a/traffic_ops/testing/api/v3/servers_test.go b/traffic_ops/testing/api/v3/servers_test.go
index 35b034c..1af5300 100644
--- a/traffic_ops/testing/api/v3/servers_test.go
+++ b/traffic_ops/testing/api/v3/servers_test.go
@@ -90,13 +90,13 @@ func LastServerInTopologyCacheGroup(t *testing.T) {
 		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
 	}
 
-	_, _, err = TOSession.UpdateServerByID(*server.ID, server)
+	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
 	if err != nil {
 		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
 	}
 
 	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByID(*server.ID, server)
+	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
 	if err == nil {
 		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
 	}
@@ -120,7 +120,7 @@ func UpdateTestServerStatus(t *testing.T) {
 	params.Add("hostName", hostName)
 
 	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServers(&params)
+	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
 	if err != nil {
 		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
 	}
@@ -156,12 +156,12 @@ func UpdateTestServerStatus(t *testing.T) {
 	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
 	remoteServer.StatusID = &originalStatusID
 
-	alerts, _, err := TOSession.UpdateServerByID(*remoteServer.ID, remoteServer)
+	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
 	if err != nil {
 		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
 	}
 
-	resp, _, err = TOSession.GetServers(&idParam)
+	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
 	if err != nil {
 		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
 	}
@@ -183,12 +183,12 @@ func UpdateTestServerStatus(t *testing.T) {
 	// Changing the status, perform an update and make sure that statusLastUpdated changed
 	remoteServer.StatusID = &updatedStatusID
 
-	alerts, _, err = TOSession.UpdateServerByID(*remoteServer.ID, remoteServer)
+	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
 	if err != nil {
 		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
 	}
 
-	resp, _, err = TOSession.GetServers(&idParam)
+	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
 	if err != nil {
 		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
 	}
@@ -209,12 +209,12 @@ func UpdateTestServerStatus(t *testing.T) {
 	// Changing the status, perform an update and make sure that statusLastUpdated changed
 	remoteServer.StatusID = &originalStatusID
 
-	alerts, _, err = TOSession.UpdateServerByID(*remoteServer.ID, remoteServer)
+	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
 	if err != nil {
 		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
 	}
 
-	resp, _, err = TOSession.GetServers(&idParam)
+	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
 	if err != nil {
 		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
 	}
@@ -363,7 +363,7 @@ func CreateTestServers(t *testing.T) {
 			t.Errorf("found server with nil hostname: %+v", server)
 			continue
 		}
-		resp, _, err := TOSession.CreateServer(server)
+		resp, _, err := TOSession.CreateServerWithHdr(server, nil)
 		t.Log("Response: ", *server.HostName, " ", resp)
 		if err != nil {
 			t.Errorf("could not CREATE servers: %v", err)
@@ -383,14 +383,14 @@ func CreateTestBlankFields(t *testing.T) {
 	originalHost := server.HostName
 
 	server.HostName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServerByID(*server.ID, server)
+	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
 	if err == nil {
 		t.Fatal("should not be able to update server with blank HostName")
 	}
 
 	server.HostName = originalHost
 	server.DomainName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServerByID(*server.ID, server)
+	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
 	if err == nil {
 		t.Fatal("should not be able to update server with blank DomainName")
 	}
@@ -414,7 +414,7 @@ func CreateTestServerWithoutProfileId(t *testing.T) {
 
 	*server.Profile = ""
 	server.ProfileID = nil
-	response, reqInfo, errs := TOSession.CreateServer(server)
+	response, reqInfo, errs := TOSession.CreateServerWithHdr(server, nil)
 	t.Log("Response: ", *server.HostName, " ", response)
 	if reqInfo.StatusCode != 400 {
 		t.Fatalf("Expected status code: %v but got: %v", "400", reqInfo.StatusCode)
@@ -422,7 +422,7 @@ func CreateTestServerWithoutProfileId(t *testing.T) {
 
 	//Reverting it back for further tests
 	*server.Profile = originalProfile
-	response, _, errs = TOSession.CreateServer(server)
+	response, _, errs = TOSession.CreateServerWithHdr(server, nil)
 	t.Log("Response: ", *server.HostName, " ", response)
 	if errs != nil {
 		t.Fatalf("could not CREATE servers: %v", errs)
@@ -708,7 +708,7 @@ func UniqueIPProfileTestServers(t *testing.T) {
 	}
 	xmppId := "unique"
 	server := serversResp.Response[0]
-	_, _, err = TOSession.CreateServer(tc.ServerNullable{
+	_, _, err = TOSession.CreateServerWithHdr(tc.ServerV30{
 		CommonServerProperties: tc.CommonServerProperties{
 			Cachegroup: server.Cachegroup,
 			CDNName:    server.CDNName,
@@ -729,7 +729,7 @@ func UniqueIPProfileTestServers(t *testing.T) {
 			XMPPID:       &xmppId,
 		},
 		Interfaces: server.Interfaces,
-	})
+	}, nil)
 
 	if err == nil {
 		t.Error("expected an error when updating a server with an ipaddress that already exists on another server with the same profile")
@@ -760,7 +760,7 @@ func UniqueIPProfileTestServers(t *testing.T) {
 	if !changed {
 		t.Fatal("did not find ip address to update")
 	}
-	_, _, err = TOSession.UpdateServerByID(*server.ID, server)
+	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
 	if err != nil {
 		t.Fatalf("expected update to pass: %s", err)
 	}
@@ -823,7 +823,7 @@ func UpdateTestServers(t *testing.T) {
 	remoteServer.Rack = &updatedServerRack
 	remoteServer.HostName = &updatedHostName
 
-	alerts, _, err := TOSession.UpdateServerByID(*remoteServer.ID, remoteServer)
+	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
 	if err != nil {
 		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
 	}
@@ -872,7 +872,7 @@ func UpdateTestServers(t *testing.T) {
 
 	//Check to verify XMPPID never gets updated
 	remoteServer.XMPPID = &updatedXMPPID
-	al, reqInf, err := TOSession.UpdateServerByID(*remoteServer.ID, remoteServer)
+	al, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
 	if err != nil && reqInf.StatusCode != http.StatusBadRequest {
 		t.Logf("error making sure that XMPPID does not get updated, %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, al)
 	}
@@ -880,7 +880,7 @@ func UpdateTestServers(t *testing.T) {
 	//Change back hostname and xmppid to its original name for other tests to pass
 	remoteServer.HostName = &originalHostname
 	remoteServer.XMPPID = &originalXMPIDD
-	alert, _, err := TOSession.UpdateServerByID(*remoteServer.ID, remoteServer)
+	alert, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
 	if err != nil {
 		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alert)
 	}
@@ -919,7 +919,7 @@ func UpdateTestServers(t *testing.T) {
 	}
 
 	// Attempt Update - should fail
-	alerts, _, err = TOSession.UpdateServerByID(*remoteServer.ID, remoteServer)
+	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
 	if err == nil {
 		t.Errorf("expected error when updating Server Type of a server assigned to DSes")
 	} else {
diff --git a/traffic_ops/testing/api/v3/servers_to_deliveryservice_assignment_test.go b/traffic_ops/testing/api/v3/servers_to_deliveryservice_assignment_test.go
index 5a16d75..74f2fe3 100644
--- a/traffic_ops/testing/api/v3/servers_to_deliveryservice_assignment_test.go
+++ b/traffic_ops/testing/api/v3/servers_to_deliveryservice_assignment_test.go
@@ -45,7 +45,7 @@ func AssignTestDeliveryService(t *testing.T) {
 	params := url.Values{}
 	params.Add("hostName", *server.HostName)
 
-	rs, _, err := TOSession.GetServers(&params)
+	rs, _, err := TOSession.GetServersWithHdr(&params, nil)
 	if err != nil {
 		t.Fatalf("Failed to fetch server information: %v", err)
 	} else if len(rs.Response) == 0 {
@@ -103,7 +103,7 @@ func AssignTestDeliveryService(t *testing.T) {
 }
 
 func AssignIncorrectTestDeliveryService(t *testing.T) {
-	var server *tc.ServerNullable
+	var server *tc.ServerV30
 	for _, s := range testData.Servers {
 		if s.CDNName != nil && *s.CDNName == "cdn2" {
 			server = &s
@@ -120,7 +120,7 @@ func AssignIncorrectTestDeliveryService(t *testing.T) {
 
 	params := url.Values{}
 	params.Add("hostName", hostname)
-	rs, _, err := TOSession.GetServers(&params)
+	rs, _, err := TOSession.GetServersWithHdr(&params, nil)
 	if err != nil {
 		t.Fatalf("Failed to fetch server information: %v - %v", err, rs.Alerts)
 	} else if len(rs.Response) == 0 {
@@ -168,7 +168,7 @@ func AssignIncorrectTestDeliveryService(t *testing.T) {
 }
 
 func AssignTopologyBasedDeliveryService(t *testing.T) {
-	var server *tc.ServerNullable
+	var server *tc.ServerV30
 	for _, s := range testData.Servers {
 		if s.CDNName != nil && *s.CDNName == "cdn1" && s.Type == string(tc.CacheTypeEdge) {
 			server = &s
@@ -181,7 +181,7 @@ func AssignTopologyBasedDeliveryService(t *testing.T) {
 
 	params := url.Values{}
 	params.Add("hostName", *server.HostName)
-	rs, _, err := TOSession.GetServers(&params)
+	rs, _, err := TOSession.GetServersWithHdr(&params, nil)
 	if err != nil {
 		t.Fatalf("Failed to fetch server information: %v", err)
 	} else if len(rs.Response) == 0 {
diff --git a/traffic_ops/testing/api/v3/serverservercapability_test.go b/traffic_ops/testing/api/v3/serverservercapability_test.go
index 06af56d..dd77207 100644
--- a/traffic_ops/testing/api/v3/serverservercapability_test.go
+++ b/traffic_ops/testing/api/v3/serverservercapability_test.go
@@ -312,8 +312,8 @@ func DeleteTestServerServerCapabilitiesForTopologiesValidation(t *testing.T) {
 	// dtrc-edge-01 and dtrc-edge-02 (capabilities = ram, disk) are assigned to
 	// ds-top-req-cap (topology = top-for-ds-req; required capabilities = ram, disk) and
 	// ds-top-req-cap2 (topology = top-for-ds-req2; required capabilities = ram)
-	var edge1 tc.ServerNullable
-	var edge2 tc.ServerNullable
+	var edge1 tc.ServerV30
+	var edge2 tc.ServerV30
 
 	servers, _, err := TOSession.GetServersWithHdr(nil, nil)
 	if err != nil {
diff --git a/traffic_ops/testing/api/v3/serverupdatestatus_test.go b/traffic_ops/testing/api/v3/serverupdatestatus_test.go
index 661c94c..0682d85 100644
--- a/traffic_ops/testing/api/v3/serverupdatestatus_test.go
+++ b/traffic_ops/testing/api/v3/serverupdatestatus_test.go
@@ -30,17 +30,17 @@ import (
 func TestServerUpdateStatus(t *testing.T) {
 	WithObjs(t, []TCObj{CDNs, Types, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers}, func() {
 		//TODO: DON'T hard-code server hostnames!
-		var edge1cdn1 tc.ServerNullable
-		var edge2cdn1 tc.ServerNullable
-		var mid1cdn1 tc.ServerNullable
-		var edge1cdn2 tc.ServerNullable
+		var edge1cdn1 tc.ServerV30
+		var edge2cdn1 tc.ServerV30
+		var mid1cdn1 tc.ServerV30
+		var edge1cdn2 tc.ServerV30
 
 		params := url.Values{}
 
 		getServers := func() {
 			for _, s := range []struct {
 				name   string
-				server *tc.ServerNullable
+				server *tc.ServerV30
 			}{
 				{
 					"atlanta-edge-01",
@@ -60,7 +60,7 @@ func TestServerUpdateStatus(t *testing.T) {
 				},
 			} {
 				params.Set("hostName", s.name)
-				resp, _, err := TOSession.GetServers(&params)
+				resp, _, err := TOSession.GetServersWithHdr(&params, nil)
 				if err != nil {
 					t.Errorf("cannot GET Server by hostname '%s': %v - %v", s.name, err, resp.Alerts)
 				}
@@ -83,7 +83,7 @@ func TestServerUpdateStatus(t *testing.T) {
 		getServers()
 
 		// assert that servers don't have updates pending
-		for _, s := range []tc.ServerNullable{
+		for _, s := range []tc.ServerV30{
 			edge1cdn1,
 			edge2cdn1,
 			mid1cdn1,
@@ -206,10 +206,10 @@ func TestServerQueueUpdate(t *testing.T) {
 			true:  "queue",
 		}
 
-		var s tc.ServerNullable
+		var s tc.ServerV30
 		params := url.Values{}
 		params.Add("hostName", serverName)
-		resp, _, err := TOSession.GetServers(&params)
+		resp, _, err := TOSession.GetServersWithHdr(&params, nil)
 		if err != nil {
 			t.Fatalf("failed to GET Server by hostname '%s': %v - %v", serverName, err, resp.Alerts)
 		}
@@ -249,7 +249,7 @@ func TestServerQueueUpdate(t *testing.T) {
 				}
 
 				// assert that the server has updates queued
-				resp, _, err = TOSession.GetServers(&params)
+				resp, _, err = TOSession.GetServersWithHdr(&params, nil)
 				if err != nil {
 					t.Fatalf("failed to GET Server by hostname '%s': %v - %v", serverName, err, resp.Alerts)
 				}
@@ -309,7 +309,7 @@ func TestSetServerUpdateStatuses(t *testing.T) {
 		params := url.Values{}
 		params.Add("hostName", *testServer.HostName)
 		testVals := func(queue *bool, reval *bool) {
-			resp, _, err := TOSession.GetServers(&params)
+			resp, _, err := TOSession.GetServersWithHdr(&params, nil)
 			if err != nil {
 				t.Errorf("cannot GET Server by name '%s': %v - %v", *testServer.HostName, err, resp.Alerts)
 			} else if len(resp.Response) != 1 {
@@ -329,7 +329,7 @@ func TestSetServerUpdateStatuses(t *testing.T) {
 				t.Fatalf("UpdateServerStatuses error expected: nil, actual: %v", err)
 			}
 
-			resp, _, err = TOSession.GetServers(&params)
+			resp, _, err = TOSession.GetServersWithHdr(&params, nil)
 			if err != nil {
 				t.Errorf("cannot GET Server by name '%s': %v - %v", *testServer.HostName, err, resp.Alerts)
 			} else if len(resp.Response) != 1 {
@@ -388,7 +388,7 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
 			midCacheGroup       = "topology-mid-cg-04"
 		)
 		cacheGroupNames := []string{edgeCacheGroup, otherEdgeCacheGroup, midCacheGroup}
-		cachesByCacheGroup := map[string]tc.ServerNullable{}
+		cachesByCacheGroup := map[string]tc.ServerV30{}
 		updateStatusByCacheGroup := map[string]tc.ServerUpdateStatus{}
 
 		forkedTopology, _, err := TOSession.GetTopology(topologyName)
@@ -417,7 +417,7 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
 			cacheGroup := cacheGroups[0]
 
 			params := url.Values{"cachegroup": []string{strconv.Itoa(*cacheGroup.ID)}}
-			cachesByCacheGroup[cacheGroupName], _, err = TOSession.GetFirstServer(&params)
+			cachesByCacheGroup[cacheGroupName], _, err = TOSession.GetFirstServer(&params, nil)
 			if err != nil {
 				t.Fatalf("unable to get a server from cachegroup %s: %s", cacheGroupName, err.Error())
 			}
@@ -433,7 +433,7 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
 
 		for _, cacheGroupName := range cacheGroupNames {
 			params := url.Values{"cachegroup": []string{strconv.Itoa(*cachesByCacheGroup[cacheGroupName].CachegroupID)}}
-			cachesByCacheGroup[cacheGroupName], _, err = TOSession.GetFirstServer(&params)
+			cachesByCacheGroup[cacheGroupName], _, err = TOSession.GetFirstServer(&params, nil)
 			if err != nil {
 				t.Fatalf("unable to get a server from cachegroup %s: %s", cacheGroupName, err.Error())
 			}
@@ -485,7 +485,7 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
 
 		edgeHostName := *cachesByCacheGroup[edgeCacheGroup].HostName
 		*cachesByCacheGroup[edgeCacheGroup].HostName = *cachesByCacheGroup[midCacheGroup].HostName
-		_, _, err = TOSession.UpdateServerByID(*cachesByCacheGroup[edgeCacheGroup].ID, cachesByCacheGroup[edgeCacheGroup])
+		_, _, err = TOSession.UpdateServerByIDWithHdr(*cachesByCacheGroup[edgeCacheGroup].ID, cachesByCacheGroup[edgeCacheGroup], nil)
 		if err != nil {
 			t.Fatalf("unable to update %s's hostname to %s: %s", edgeHostName, *cachesByCacheGroup[midCacheGroup].HostName, err)
 		}
@@ -496,7 +496,7 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
 		}
 
 		*cachesByCacheGroup[edgeCacheGroup].HostName = edgeHostName
-		_, _, err = TOSession.UpdateServerByID(*cachesByCacheGroup[edgeCacheGroup].ID, cachesByCacheGroup[edgeCacheGroup])
+		_, _, err = TOSession.UpdateServerByIDWithHdr(*cachesByCacheGroup[edgeCacheGroup].ID, cachesByCacheGroup[edgeCacheGroup], nil)
 		if err != nil {
 			t.Fatalf("unable to revert %s's hostname back to %s: %s", edgeHostName, edgeHostName, err)
 		}
diff --git a/traffic_ops/testing/api/v3/traffic_control_test.go b/traffic_ops/testing/api/v3/traffic_control_test.go
index 9b858a9..7149597 100644
--- a/traffic_ops/testing/api/v3/traffic_control_test.go
+++ b/traffic_ops/testing/api/v3/traffic_control_test.go
@@ -43,7 +43,7 @@ type TrafficControl struct {
 	PhysLocations                                     []tc.PhysLocation                       `json:"physLocations"`
 	Regions                                           []tc.Region                             `json:"regions"`
 	Roles                                             []tc.Role                               `json:"roles"`
-	Servers                                           []tc.ServerNullable                     `json:"servers"`
+	Servers                                           []tc.ServerV30                          `json:"servers"`
 	ServerServerCapabilities                          []tc.ServerServerCapability             `json:"serverServerCapabilities"`
 	ServerCapabilities                                []tc.ServerCapability                   `json:"serverCapabilities"`
 	ServiceCategories                                 []tc.ServiceCategory                    `json:"serviceCategories"`
diff --git a/traffic_ops/v3-client/server.go b/traffic_ops/v3-client/server.go
index 41e5351..b63deda 100644
--- a/traffic_ops/v3-client/server.go
+++ b/traffic_ops/v3-client/server.go
@@ -39,7 +39,18 @@ func needAndCanFetch(id *int, name *string) bool {
 }
 
 // CreateServer creates a Server.
-func (to *Session) CreateServer(server tc.ServerNullable) (tc.Alerts, ReqInf, error) {
+// Deprecated: CreateServer will be removed in 6.0. Use CreateServerWithHdr.
+func (to *Session) CreateServer(server tc.Server) (tc.Alerts, ReqInf, error) {
+	upgraded, err := server.ToNullable().Upgrade()
+	if err != nil {
+		return tc.Alerts{}, ReqInf{}, fmt.Errorf("upgrading server: %v", err)
+	}
+	return to.CreateServerWithHdr(upgraded, nil)
+}
+
+// CreateServerWithHdr creates the given server, with whatever headers are
+// passed added to the request.
+func (to *Session) CreateServerWithHdr(server tc.ServerV30, hdr http.Header) (tc.Alerts, ReqInf, error) {
 
 	var alerts tc.Alerts
 	var remoteAddr net.Addr
@@ -114,7 +125,7 @@ func (to *Session) CreateServer(server tc.ServerNullable) (tc.Alerts, ReqInf, er
 		return alerts, reqInf, err
 	}
 
-	resp, remoteAddr, err := to.request(http.MethodPost, API_SERVERS, reqBody, nil)
+	resp, remoteAddr, err := to.request(http.MethodPost, API_SERVERS, reqBody, hdr)
 	reqInf.RemoteAddr = remoteAddr
 	if resp != nil {
 		reqInf.StatusCode = resp.StatusCode
@@ -128,7 +139,7 @@ func (to *Session) CreateServer(server tc.ServerNullable) (tc.Alerts, ReqInf, er
 	return alerts, reqInf, err
 }
 
-func (to *Session) UpdateServerByIDWithHdr(id int, server tc.ServerNullable, header http.Header) (tc.Alerts, ReqInf, error) {
+func (to *Session) UpdateServerByIDWithHdr(id int, server tc.ServerV30, header http.Header) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
 	var remoteAddr net.Addr
 	reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr: remoteAddr}
@@ -156,8 +167,12 @@ func (to *Session) UpdateServerByIDWithHdr(id int, server tc.ServerNullable, hea
 
 // UpdateServerByID updates a Server by ID.
 // Deprecated: UpdateServerByID will be removed in 6.0. Use UpdateServerByIDWithHdr.
-func (to *Session) UpdateServerByID(id int, server tc.ServerNullable) (tc.Alerts, ReqInf, error) {
-	return to.UpdateServerByIDWithHdr(id, server, nil)
+func (to *Session) UpdateServerByID(id int, server tc.Server) (tc.Alerts, ReqInf, error) {
+	upgraded, err := server.ToNullable().Upgrade()
+	if err != nil {
+		return tc.Alerts{}, ReqInf{}, fmt.Errorf("upgrading server: %v", err)
+	}
+	return to.UpdateServerByIDWithHdr(id, upgraded, nil)
 }
 
 // GetServersWithHdr retrieves a list of servers using the given optional query
@@ -193,13 +208,33 @@ func (to *Session) GetServersWithHdr(params *url.Values, header http.Header) (tc
 // It returns, in order, the API response that Traffic Ops returned, a request
 // info object, and any error that occurred.
 // Deprecated: GetServers will be removed in 6.0. Use GetServersWithHdr.
-func (to *Session) GetServers(params *url.Values) (tc.ServersV3Response, ReqInf, error) {
-	return to.GetServersWithHdr(params, nil)
+func (to *Session) GetServers(params *url.Values) ([]tc.Server, ReqInf, error) {
+	srvs, inf, err := to.GetServersWithHdr(params, nil)
+	if err != nil {
+		return []tc.Server{}, inf, err
+	}
+
+	servers := make([]tc.Server, 0, len(srvs.Response))
+	for _, srv := range srvs.Response {
+		nullable := tc.ServerNullable(srv)
+		v2, err := nullable.ToServerV2()
+		if err != nil {
+			return []tc.Server{}, inf, fmt.Errorf("converting server to v2: %v", err)
+		}
+		servers = append(servers, v2.ToNonNullable())
+	}
+	return servers, inf, nil
 }
 
-func (to *Session) GetFirstServerWithHdr(params *url.Values, header http.Header) (tc.ServerNullable, ReqInf, error) {
-	serversResponse, reqInf, err := to.GetServers(params)
-	var firstServer tc.ServerNullable
+// GetFirstServer returns the first server in a servers GET response.
+// If no servers match, an error is returned.
+// The 'params' parameter can be used to optionally pass URL "query string
+// parameters" in the request.
+// It returns, in order, the API response that Traffic Ops returned, a request
+// info object, and any error that occurred.
+func (to *Session) GetFirstServer(params *url.Values, header http.Header) (tc.ServerV30, ReqInf, error) {
+	serversResponse, reqInf, err := to.GetServersWithHdr(params, nil)
+	var firstServer tc.ServerV30
 	if err != nil || reqInf.StatusCode == http.StatusNotModified {
 		return firstServer, reqInf, err
 	}
@@ -211,17 +246,6 @@ func (to *Session) GetFirstServerWithHdr(params *url.Values, header http.Header)
 	return firstServer, reqInf, err
 }
 
-// GetFirstServer returns the first server in a servers GET response.
-// If no servers match, an error is returned.
-// The 'params' parameter can be used to optionally pass URL "query string
-// parameters" in the request.
-// It returns, in order, the API response that Traffic Ops returned, a request
-// info object, and any error that occurred.
-// Deprecated: GetFirstServer will be removed in 6.0. Use GetFirstServerWithHdr.
-func (to *Session) GetFirstServer(params *url.Values) (tc.ServerNullable, ReqInf, error) {
-	return to.GetFirstServerWithHdr(params, nil)
-}
-
 func (to *Session) GetServerDetailsByHostNameWithHdr(hostName string, header http.Header) ([]tc.ServerDetailV30, ReqInf, error) {
 	v := url.Values{}
 	v.Add("hostName", hostName)
@@ -276,7 +300,7 @@ func (to *Session) GetServerFQDNWithHdr(n string, header http.Header) (string, t
 	params := url.Values{}
 	params.Add("hostName", n)
 
-	resp, reqInf, err := to.GetServers(&params)
+	resp, reqInf, err := to.GetServersWithHdr(&params, nil)
 	if err != nil {
 		return "", resp.Alerts, reqInf, err
 	}
@@ -304,7 +328,7 @@ func (to *Session) GetServerFQDN(n string) (string, tc.Alerts, ReqInf, error) {
 
 func (to *Session) GetServersShortNameSearchWithHdr(shortname string, header http.Header) ([]string, tc.Alerts, ReqInf, error) {
 	var serverlst []string
-	resp, reqInf, err := to.GetServers(nil)
+	resp, reqInf, err := to.GetServersWithHdr(nil, nil)
 	if err != nil {
 		return serverlst, resp.Alerts, reqInf, err
 	}
diff --git a/traffic_ops_ort/atstccfg/toreqnew/toreqnew.go b/traffic_ops_ort/atstccfg/toreqnew/toreqnew.go
index c7f20d1..1e62772 100644
--- a/traffic_ops_ort/atstccfg/toreqnew/toreqnew.go
+++ b/traffic_ops_ort/atstccfg/toreqnew/toreqnew.go
@@ -149,11 +149,11 @@ func (cl *TOClient) GetServerUpdateStatus(cacheHostName tc.CacheName) (tc.Server
 	return status, false, nil
 }
 
-func (cl *TOClient) GetServers() ([]tc.ServerNullable, bool, error) {
-	servers := []tc.ServerNullable{}
+func (cl *TOClient) GetServers() ([]tc.ServerV30, bool, error) {
+	servers := []tc.ServerV30{}
 	unsupported := false
 	err := torequtil.GetRetry(cl.NumRetries, "servers", &servers, func(obj interface{}) error {
-		toServers, reqInf, err := cl.C.GetServers(nil)
+		toServers, reqInf, err := cl.C.GetServersWithHdr(nil, nil)
 		if err != nil {
 			if IsUnsupportedErr(err) {
 				unsupported = true
@@ -161,7 +161,7 @@ func (cl *TOClient) GetServers() ([]tc.ServerNullable, bool, error) {
 			}
 			return errors.New("getting servers from Traffic Ops '" + torequtil.MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
 		}
-		servers := obj.(*[]tc.ServerNullable)
+		servers := obj.(*[]tc.ServerV30)
 		*servers = toServers.Response
 		return nil
 	})