You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by dy...@apache.org on 2018/09/07 16:19:47 UTC

[trafficcontrol] 02/03: Fix TO versioned structs so latest is unversioned

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

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

commit f6906d3e159b62cbcae7ac5eeb777d72925088c7
Author: Robert Butts <ro...@apache.org>
AuthorDate: Tue Sep 4 08:27:44 2018 -0600

    Fix TO versioned structs so latest is unversioned
---
 lib/go-tc/deliveryservice_regexes.go               |  16 ---
 lib/go-tc/deliveryservice_requests.go              |  52 ++++-----
 lib/go-tc/deliveryservices.go                      |  80 ++++++-------
 lib/go-tc/enum_test.go                             |   2 +-
 lib/go-tc/federation.go                            |  64 +++++++++++
 lib/go-tc/steeringtarget.go                        |  63 ++++++++++
 traffic_ops/client/deliveryservice.go              |  16 +--
 traffic_ops/client/dsuser.go                       |   4 +-
 .../testing/api/v13/deliveryservices_test.go       |   6 +-
 traffic_ops/testing/api/v13/servers_test.go        |   2 +-
 traffic_ops/testing/api/v13/traffic_control.go     |   2 +-
 traffic_ops/traffic_ops_golang/asn/asns_test.go    |   1 +
 .../deliveryservice/deliveryservicesv12.go         |   4 +-
 .../deliveryservice/deliveryservicesv13.go         | 128 ++++++++++-----------
 .../deliveryservice/request/requests_test.go       |  20 ++--
 traffic_ops/traffic_ops_golang/tenant/tenancy.go   |   3 +-
 .../traffic_ops_golang/user/deliveryservices.go    |  10 +-
 17 files changed, 289 insertions(+), 184 deletions(-)

diff --git a/lib/go-tc/deliveryservice_regexes.go b/lib/go-tc/deliveryservice_regexes.go
index 117d61f..6bb7da0 100644
--- a/lib/go-tc/deliveryservice_regexes.go
+++ b/lib/go-tc/deliveryservice_regexes.go
@@ -32,14 +32,6 @@ type DeliveryServiceRegex struct {
 	Pattern   string `json:"pattern"`
 }
 
-type DeliveryServiceRegexV12 struct {
-	DeliveryServiceRegex
-}
-
-type DeliveryServiceRegexV13 struct {
-	DeliveryServiceRegexV12
-}
-
 type DeliveryServiceIDRegexResponse struct {
 	Response []DeliveryServiceIDRegex `json:"response"`
 }
@@ -52,14 +44,6 @@ type DeliveryServiceIDRegex struct {
 	Pattern   string `json:"pattern"`
 }
 
-type DeliveryServiceIDRegexV12 struct {
-	DeliveryServiceIDRegex
-}
-
-type DeliveryServiceIDRegexV13 struct {
-	DeliveryServiceIDRegexV12
-}
-
 type DeliveryServiceRegexPost struct {
 	Type      int    `json:"type"`
 	SetNumber int    `json:"setNumber"`
diff --git a/lib/go-tc/deliveryservice_requests.go b/lib/go-tc/deliveryservice_requests.go
index 2ecf5ba..b4147aa 100644
--- a/lib/go-tc/deliveryservice_requests.go
+++ b/lib/go-tc/deliveryservice_requests.go
@@ -32,37 +32,37 @@ type IDNoMod int
 // DeliveryServiceRequest is used as part of the workflow to create,
 // modify, or delete a delivery service.
 type DeliveryServiceRequest struct {
-	AssigneeID      int                `json:"assigneeId,omitempty"`
-	Assignee        string             `json:"assignee,omitempty"`
-	AuthorID        IDNoMod            `json:"authorId"`
-	Author          string             `json:"author"`
-	ChangeType      string             `json:"changeType"`
-	CreatedAt       *TimeNoMod         `json:"createdAt"`
-	ID              int                `json:"id"`
-	LastEditedBy    string             `json:"lastEditedBy,omitempty"`
-	LastEditedByID  IDNoMod            `json:"lastEditedById,omitempty"`
-	LastUpdated     *TimeNoMod         `json:"lastUpdated"`
-	DeliveryService DeliveryServiceV13 `json:"deliveryService"` // TODO version DeliveryServiceRequest
-	Status          RequestStatus      `json:"status"`
-	XMLID           string             `json:"-" db:"xml_id"`
+	AssigneeID      int             `json:"assigneeId,omitempty"`
+	Assignee        string          `json:"assignee,omitempty"`
+	AuthorID        IDNoMod         `json:"authorId"`
+	Author          string          `json:"author"`
+	ChangeType      string          `json:"changeType"`
+	CreatedAt       *TimeNoMod      `json:"createdAt"`
+	ID              int             `json:"id"`
+	LastEditedBy    string          `json:"lastEditedBy,omitempty"`
+	LastEditedByID  IDNoMod         `json:"lastEditedById,omitempty"`
+	LastUpdated     *TimeNoMod      `json:"lastUpdated"`
+	DeliveryService DeliveryService `json:"deliveryService"` // TODO version DeliveryServiceRequest
+	Status          RequestStatus   `json:"status"`
+	XMLID           string          `json:"-" db:"xml_id"`
 }
 
 // DeliveryServiceRequestNullable is used as part of the workflow to create,
 // modify, or delete a delivery service.
 type DeliveryServiceRequestNullable struct {
-	AssigneeID      *int                        `json:"assigneeId,omitempty" db:"assignee_id"`
-	Assignee        *string                     `json:"assignee,omitempty"`
-	AuthorID        *IDNoMod                    `json:"authorId" db:"author_id"`
-	Author          *string                     `json:"author"`
-	ChangeType      *string                     `json:"changeType" db:"change_type"`
-	CreatedAt       *TimeNoMod                  `json:"createdAt" db:"created_at"`
-	ID              *int                        `json:"id" db:"id"`
-	LastEditedBy    *string                     `json:"lastEditedBy"`
-	LastEditedByID  *IDNoMod                    `json:"lastEditedById" db:"last_edited_by_id"`
-	LastUpdated     *TimeNoMod                  `json:"lastUpdated" db:"last_updated"`
-	DeliveryService *DeliveryServiceNullableV13 `json:"deliveryService" db:"deliveryservice"` // TODO version DeliveryServiceRequest
-	Status          *RequestStatus              `json:"status" db:"status"`
-	XMLID           *string                     `json:"-" db:"xml_id"`
+	AssigneeID      *int                     `json:"assigneeId,omitempty" db:"assignee_id"`
+	Assignee        *string                  `json:"assignee,omitempty"`
+	AuthorID        *IDNoMod                 `json:"authorId" db:"author_id"`
+	Author          *string                  `json:"author"`
+	ChangeType      *string                  `json:"changeType" db:"change_type"`
+	CreatedAt       *TimeNoMod               `json:"createdAt" db:"created_at"`
+	ID              *int                     `json:"id" db:"id"`
+	LastEditedBy    *string                  `json:"lastEditedBy"`
+	LastEditedByID  *IDNoMod                 `json:"lastEditedById" db:"last_edited_by_id"`
+	LastUpdated     *TimeNoMod               `json:"lastUpdated" db:"last_updated"`
+	DeliveryService *DeliveryServiceNullable `json:"deliveryService" db:"deliveryservice"` // TODO version DeliveryServiceRequest
+	Status          *RequestStatus           `json:"status" db:"status"`
+	XMLID           *string                  `json:"-" db:"xml_id"`
 }
 
 // UnmarshalJSON implements the json.Unmarshaller interface to suppress unmarshalling for IDNoMod
diff --git a/lib/go-tc/deliveryservices.go b/lib/go-tc/deliveryservices.go
index 3096e52..b92d549 100644
--- a/lib/go-tc/deliveryservices.go
+++ b/lib/go-tc/deliveryservices.go
@@ -40,7 +40,7 @@ type GetDeliveryServiceResponse struct {
 
 // DeliveryServicesResponse ...
 type DeliveryServicesResponse struct {
-	Response []DeliveryServiceV13 `json:"response"`
+	Response []DeliveryService `json:"response"`
 }
 
 // CreateDeliveryServiceResponse ...
@@ -66,9 +66,23 @@ type DeleteDeliveryServiceResponse struct {
 	Alerts []DeliveryServiceAlert `json:"alerts"`
 }
 
+type DeliveryService struct {
+	DeliveryServiceV12
+	DeepCachingType   DeepCachingType `json:"deepCachingType"`
+	FQPacingRate      int             `json:"fqPacingRate,omitempty"`
+	SigningAlgorithm  string          `json:"signingAlgorithm" db:"signing_algorithm"`
+	TenantName        string          `json:"tenantName,omitempty"`
+	TRRequestHeaders  string          `json:"trRequestHeaders,omitempty"`
+	TRResponseHeaders string          `json:"trResponseHeaders,omitempty"`
+}
+
+type DeliveryServiceV12 struct {
+	DeliveryServiceV11
+}
+
 // DeliveryService ...
 // TODO move contents to DeliveryServiceV12, fix references, and remove
-type DeliveryService struct {
+type DeliveryServiceV11 struct {
 	Active                   bool                   `json:"active"`
 	AnonymousBlockingEnabled bool                   `json:"anonymousBlockingEnabled"`
 	CacheURL                 string                 `json:"cacheurl"`
@@ -125,23 +139,23 @@ type DeliveryService struct {
 	XMLID                    string                 `json:"xmlId"`
 }
 
-type DeliveryServiceV12 struct {
-	DeliveryService
+type DeliveryServiceNullable struct {
+	DeliveryServiceNullableV12
+	DeepCachingType   *DeepCachingType `json:"deepCachingType" db:"deep_caching_type"`
+	FQPacingRate      *int             `json:"fqPacingRate,omitempty"`
+	SigningAlgorithm  *string          `json:"signingAlgorithm" db:"signing_algorithm"`
+	Tenant            *string          `json:"tenant,omitempty"`
+	TRResponseHeaders *string          `json:"trResponseHeaders,omitempty"`
+	TRRequestHeaders  *string          `json:"trRequestHeaders,omitempty"`
 }
 
-type DeliveryServiceV13 struct {
-	DeliveryServiceV12
-	DeepCachingType   DeepCachingType `json:"deepCachingType"`
-	FQPacingRate      int             `json:"fqPacingRate,omitempty"`
-	SigningAlgorithm  string          `json:"signingAlgorithm" db:"signing_algorithm"`
-	TenantName        string          `json:"tenantName,omitempty"`
-	TRRequestHeaders  string          `json:"trRequestHeaders,omitempty"`
-	TRResponseHeaders string          `json:"trResponseHeaders,omitempty"`
+type DeliveryServiceNullableV12 struct {
+	DeliveryServiceNullableV11
 }
 
 // DeliveryServiceNullable - a version of the deliveryservice that allows for all fields to be null
 // TODO move contents to DeliveryServiceNullableV12, fix references, and remove
-type DeliveryServiceNullable struct {
+type DeliveryServiceNullableV11 struct {
 	// NOTE: the db: struct tags are used for testing to map to their equivalent database column (if there is one)
 	//
 	Active                   *bool                   `json:"active" db:"active"`
@@ -202,23 +216,9 @@ type DeliveryServiceNullable struct {
 	ExampleURLs              []string                `json:"exampleURLs"`
 }
 
-type DeliveryServiceNullableV12 struct {
-	DeliveryServiceNullable
-}
-
-type DeliveryServiceNullableV13 struct {
-	DeliveryServiceNullableV12
-	DeepCachingType   *DeepCachingType `json:"deepCachingType" db:"deep_caching_type"`
-	FQPacingRate      *int             `json:"fqPacingRate,omitempty"`
-	SigningAlgorithm  *string          `json:"signingAlgorithm" db:"signing_algorithm"`
-	Tenant            *string          `json:"tenant,omitempty"`
-	TRResponseHeaders *string          `json:"trResponseHeaders,omitempty"`
-	TRRequestHeaders  *string          `json:"trRequestHeaders,omitempty"`
-}
-
-// NewDeliveryServiceNullableV13FromV12 creates a new V13 DS from a V12 DS, filling new fields with appropriate defaults.
-func NewDeliveryServiceNullableV13FromV12(ds DeliveryServiceNullableV12) DeliveryServiceNullableV13 {
-	newDS := DeliveryServiceNullableV13{DeliveryServiceNullableV12: ds}
+// NewDeliveryServiceNullableFromV12 creates a new V13 DS from a V12 DS, filling new fields with appropriate defaults.
+func NewDeliveryServiceNullableFromV12(ds DeliveryServiceNullableV12) DeliveryServiceNullable {
+	newDS := DeliveryServiceNullable{DeliveryServiceNullableV12: ds}
 	newDS.Sanitize()
 	return newDS
 }
@@ -383,7 +383,7 @@ func (ds *DeliveryServiceNullableV12) Validate(tx *sql.Tx) error {
 	return nil
 }
 
-func (ds *DeliveryServiceNullableV13) Sanitize() {
+func (ds *DeliveryServiceNullable) Sanitize() {
 	ds.DeliveryServiceNullableV12.Sanitize()
 	signedAlgorithm := "url_sig"
 	if ds.Signed && (ds.SigningAlgorithm == nil || *ds.SigningAlgorithm == "") {
@@ -399,7 +399,7 @@ func (ds *DeliveryServiceNullableV13) Sanitize() {
 	*ds.DeepCachingType = DeepCachingTypeFromString(string(*ds.DeepCachingType))
 }
 
-func (ds *DeliveryServiceNullableV13) Validate(tx *sql.Tx) error {
+func (ds *DeliveryServiceNullable) Validate(tx *sql.Tx) error {
 	ds.Sanitize()
 	neverOrAlways := validation.NewStringRule(tovalidate.IsOneOfStringICase("NEVER", "ALWAYS"),
 		"must be one of 'NEVER' or 'ALWAYS'")
@@ -417,14 +417,14 @@ func (ds *DeliveryServiceNullableV13) Validate(tx *sql.Tx) error {
 
 // Value implements the driver.Valuer interface
 // marshals struct to json to pass back as a json.RawMessage
-func (d *DeliveryServiceNullableV13) Value() (driver.Value, error) {
+func (d *DeliveryServiceNullable) Value() (driver.Value, error) {
 	b, err := json.Marshal(d)
 	return b, err
 }
 
 // Scan implements the sql.Scanner interface
 // expects json.RawMessage and unmarshals to a deliveryservice struct
-func (d *DeliveryServiceNullableV13) Scan(src interface{}) error {
+func (d *DeliveryServiceNullable) Scan(src interface{}) error {
 	b, ok := src.([]byte)
 	if !ok {
 		return fmt.Errorf("expected deliveryservice in byte array form; got %T", src)
@@ -549,16 +549,8 @@ type UserDeliveryServicePostResponse struct {
 	Response DeliveryServiceUserPost `json:"response"`
 }
 
-type UserDeliveryServicesResponseV13 struct {
-	Response []DeliveryServiceV13 `json:"response"`
-}
-
-type UserDeliveryServicesResponseV12 struct {
-	Response []DeliveryServiceV13 `json:"response"`
-}
-
-type UserDeliveryServicesResponse struct {
-	Response []DeliveryServiceNullableV13 `json:"response"`
+type UserDeliveryServicesNullableResponse struct {
+	Response []DeliveryServiceNullable `json:"response"`
 }
 
 type DSServerIDs struct {
diff --git a/lib/go-tc/enum_test.go b/lib/go-tc/enum_test.go
index a06e0b1..95fb64a 100644
--- a/lib/go-tc/enum_test.go
+++ b/lib/go-tc/enum_test.go
@@ -62,7 +62,7 @@ func TestDeepCachingType(t *testing.T) {
 	}
 
 	// make sure we get the right default when marshalled within a new delivery service
-	var ds DeliveryServiceV13
+	var ds DeliveryService
 	_, err := json.MarshalIndent(ds, ``, `  `)
 	if err != nil {
 		t.Errorf(err.Error())
diff --git a/lib/go-tc/federation.go b/lib/go-tc/federation.go
new file mode 100644
index 0000000..e7b1d21
--- /dev/null
+++ b/lib/go-tc/federation.go
@@ -0,0 +1,64 @@
+package tc
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+type CDNFederationResponse struct {
+	Response []CDNFederation `json:"response"`
+}
+
+type CreateCDNFederationResponse struct {
+	Response CDNFederation `json:"response"`
+	Alerts
+}
+
+type UpdateCDNFederationResponse struct {
+	Response CDNFederation `json:"response"`
+	Alerts
+}
+
+type DeleteCDNFederationResponse struct {
+	Alerts
+}
+
+type CDNFederation struct {
+	ID          *int       `json:"id" db:"id"`
+	CName       *string    `json:"cname" db:"cname"`
+	TTL         *int       `json:"ttl" db:"ttl"`
+	Description *string    `json:"description" db:"description"`
+	LastUpdated *TimeNoMod `json:"lastUpdated" db:"last_updated"`
+
+	// omitempty only works with primitive types and pointers
+	*DeliveryServiceIDs `json:"deliveryService,omitempty"`
+}
+
+type DeliveryServiceIDs struct {
+	DsId  *int    `json:"id,omitempty" db:"ds_id"`
+	XmlId *string `json:"xmlId,omitempty" db:"xml_id"`
+}
+
+type FederationNullable struct {
+	Mappings        []FederationMapping `json:"mappings"`
+	DeliveryService *string             `json:"deliveryService"`
+}
+
+type FederationMapping struct {
+	CName string `json:"cname"`
+	TTL   int    `json:"ttl"`
+}
diff --git a/lib/go-tc/steeringtarget.go b/lib/go-tc/steeringtarget.go
new file mode 100644
index 0000000..17feaa3
--- /dev/null
+++ b/lib/go-tc/steeringtarget.go
@@ -0,0 +1,63 @@
+package tc
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import (
+	"database/sql"
+	"errors"
+	"strings"
+)
+
+type SteeringTarget struct {
+	DeliveryService   DeliveryServiceName `json:"deliveryService" db:"deliveryservice_name"`
+	DeliveryServiceID int                 `json:"deliveryServiceId" db:"deliveryservice"`
+	Target            DeliveryServiceName `json:"target" db:"target_name"`
+	TargetID          int                 `json:"targetId" db:"target"`
+	Type              string              `json:"type" db:"type"`      // TODO enum?
+	TypeID            int                 `json:"typeId" db:"type_id"` // TODO enum?
+	Value             int                 `json:"value" db:"value"`
+}
+
+type SteeringTargetNullable struct {
+	DeliveryService   *DeliveryServiceName `json:"deliveryService" db:"deliveryservice_name"`
+	DeliveryServiceID *uint64              `json:"deliveryServiceId" db:"deliveryservice"`
+	Target            *DeliveryServiceName `json:"target" db:"target_name"`
+	TargetID          *uint64              `json:"targetId" db:"target"`
+	Type              *string              `json:"type" db:"type_name"` // TODO enum?
+	TypeID            *int                 `json:"typeId" db:"type_id"` // TODO enum?
+	Value             *uint64              `json:"value" db:"value"`
+}
+
+func (st SteeringTargetNullable) Validate(tx *sql.Tx) error {
+	errs := []string{}
+	if st.TargetID == nil {
+		errs = append(errs, "missing target")
+	}
+	if st.TypeID == nil {
+		errs = append(errs, "missing typeId")
+	}
+	if st.Value == nil {
+		errs = append(errs, "missing value")
+	}
+	if len(errs) > 0 {
+		return errors.New(strings.Join(errs, "; "))
+	}
+	return nil
+}
diff --git a/traffic_ops/client/deliveryservice.go b/traffic_ops/client/deliveryservice.go
index 1357ae0..bfa5d74 100644
--- a/traffic_ops/client/deliveryservice.go
+++ b/traffic_ops/client/deliveryservice.go
@@ -24,12 +24,12 @@ import (
 
 // DeliveryServices gets an array of DeliveryServices
 // Deprecated: use GetDeliveryServices
-func (to *Session) DeliveryServices() ([]tc.DeliveryServiceV13, error) {
+func (to *Session) DeliveryServices() ([]tc.DeliveryService, error) {
 	dses, _, err := to.GetDeliveryServices()
 	return dses, err
 }
 
-func (to *Session) GetDeliveryServices() ([]tc.DeliveryServiceV13, ReqInf, error) {
+func (to *Session) GetDeliveryServices() ([]tc.DeliveryService, ReqInf, error) {
 	var data tc.DeliveryServicesResponse
 	reqInf, err := get(to, deliveryServicesEp(), &data)
 	if err != nil {
@@ -41,12 +41,12 @@ func (to *Session) GetDeliveryServices() ([]tc.DeliveryServiceV13, ReqInf, error
 
 // DeliveryServicesByServer gets an array of all DeliveryServices with the given server ID assigend.
 // Deprecated: use GetDeliveryServicesByServer
-func (to *Session) DeliveryServicesByServer(id int) ([]tc.DeliveryServiceV13, error) {
+func (to *Session) DeliveryServicesByServer(id int) ([]tc.DeliveryService, error) {
 	dses, _, err := to.GetDeliveryServicesByServer(id)
 	return dses, err
 }
 
-func (to *Session) GetDeliveryServicesByServer(id int) ([]tc.DeliveryServiceV13, ReqInf, error) {
+func (to *Session) GetDeliveryServicesByServer(id int) ([]tc.DeliveryService, ReqInf, error) {
 	var data tc.DeliveryServicesResponse
 	reqInf, err := get(to, deliveryServicesByServerEp(strconv.Itoa(id)), &data)
 	if err != nil {
@@ -68,12 +68,12 @@ func (to *Session) GetDeliveryServiceByXMLID(XMLID string) ([]tc.DeliveryService
 
 // DeliveryService gets the DeliveryService for the ID it's passed
 // Deprecated: use GetDeliveryService
-func (to *Session) DeliveryService(id string) (*tc.DeliveryServiceV13, error) {
+func (to *Session) DeliveryService(id string) (*tc.DeliveryService, error) {
 	ds, _, err := to.GetDeliveryService(id)
 	return ds, err
 }
 
-func (to *Session) GetDeliveryService(id string) (*tc.DeliveryServiceV13, ReqInf, error) {
+func (to *Session) GetDeliveryService(id string) (*tc.DeliveryService, ReqInf, error) {
 	var data tc.DeliveryServicesResponse
 	reqInf, err := get(to, deliveryServiceEp(id), &data)
 	if err != nil {
@@ -86,7 +86,7 @@ func (to *Session) GetDeliveryService(id string) (*tc.DeliveryServiceV13, ReqInf
 }
 
 // CreateDeliveryService creates the DeliveryService it's passed
-func (to *Session) CreateDeliveryService(ds *tc.DeliveryServiceV13) (*tc.CreateDeliveryServiceResponse, error) {
+func (to *Session) CreateDeliveryService(ds *tc.DeliveryService) (*tc.CreateDeliveryServiceResponse, error) {
 	var data tc.CreateDeliveryServiceResponse
 	jsonReq, err := json.Marshal(ds)
 	if err != nil {
@@ -102,7 +102,7 @@ func (to *Session) CreateDeliveryService(ds *tc.DeliveryServiceV13) (*tc.CreateD
 
 // UpdateDeliveryService updates the DeliveryService matching the ID it's passed with
 // the DeliveryService it is passed
-func (to *Session) UpdateDeliveryService(id string, ds *tc.DeliveryServiceV13) (*tc.UpdateDeliveryServiceResponse, error) {
+func (to *Session) UpdateDeliveryService(id string, ds *tc.DeliveryService) (*tc.UpdateDeliveryServiceResponse, error) {
 	var data tc.UpdateDeliveryServiceResponse
 	jsonReq, err := json.Marshal(ds)
 	if err != nil {
diff --git a/traffic_ops/client/dsuser.go b/traffic_ops/client/dsuser.go
index 1a5a184..f39137b 100644
--- a/traffic_ops/client/dsuser.go
+++ b/traffic_ops/client/dsuser.go
@@ -23,9 +23,9 @@ import (
 )
 
 // GetUserDeliveryServices gets the delivery services associated with the given user.
-func (to *Session) GetUserDeliveryServices(userID int) (*tc.UserDeliveryServicesResponse, ReqInf, error) {
+func (to *Session) GetUserDeliveryServices(userID int) (*tc.UserDeliveryServicesNullableResponse, ReqInf, error) {
 	uri := apiBase + `/users/` + strconv.Itoa(userID) + `/deliveryservices`
-	resp := tc.UserDeliveryServicesResponse{}
+	resp := tc.UserDeliveryServicesNullableResponse{}
 	reqInf, err := get(to, uri, &resp)
 	if err != nil {
 		return nil, reqInf, err
diff --git a/traffic_ops/testing/api/v13/deliveryservices_test.go b/traffic_ops/testing/api/v13/deliveryservices_test.go
index 9f93d6d..13c4e0d 100644
--- a/traffic_ops/testing/api/v13/deliveryservices_test.go
+++ b/traffic_ops/testing/api/v13/deliveryservices_test.go
@@ -113,7 +113,7 @@ func GetTestDeliveryServices(t *testing.T) {
 		t.Fatalf("cannot GET DeliveryServices: %v - %v\n", err, actualDSes)
 		failed = true
 	}
-	actualDSMap := map[string]tc.DeliveryServiceV13{}
+	actualDSMap := map[string]tc.DeliveryService{}
 	for _, ds := range actualDSes {
 		actualDSMap[ds.XMLID] = ds
 	}
@@ -138,7 +138,7 @@ func UpdateTestDeliveryServices(t *testing.T) {
 		t.Fatalf("cannot GET Delivery Services: %v\n", err)
 	}
 
-	remoteDS := tc.DeliveryServiceV13{}
+	remoteDS := tc.DeliveryService{}
 	found := false
 	for _, ds := range dses {
 		if ds.XMLID == firstDS.XMLID {
@@ -190,7 +190,7 @@ func DeleteTestDeliveryServices(t *testing.T) {
 		t.Fatalf("cannot GET Servers: %v\n", err)
 	}
 	for _, testDS := range testData.DeliveryServices {
-		ds := tc.DeliveryServiceV13{}
+		ds := tc.DeliveryService{}
 		found := false
 		for _, realDS := range dses {
 			if realDS.XMLID == testDS.XMLID {
diff --git a/traffic_ops/testing/api/v13/servers_test.go b/traffic_ops/testing/api/v13/servers_test.go
index a81b662..d3399ae 100644
--- a/traffic_ops/testing/api/v13/servers_test.go
+++ b/traffic_ops/testing/api/v13/servers_test.go
@@ -80,7 +80,7 @@ func CreateTestServers(t *testing.T) {
 	// loop through servers, assign FKs and create
 	for _, server := range testData.Servers {
 		// GET EDGE type
-		respTypes, _, err := TOSession.GetTypeByName(server.TypeName)
+		respTypes, _, err := TOSession.GetTypeByName(server.Type)
 		if err != nil {
 			t.Errorf("cannot GET Division by name: EDGE - %v\n", err)
 		}
diff --git a/traffic_ops/testing/api/v13/traffic_control.go b/traffic_ops/testing/api/v13/traffic_control.go
index 050ac79..ba96dcb 100644
--- a/traffic_ops/testing/api/v13/traffic_control.go
+++ b/traffic_ops/testing/api/v13/traffic_control.go
@@ -26,7 +26,7 @@ type TrafficControl struct {
 	CacheGroups                    []tc.CacheGroupNullable            `json:"cachegroups"`
 	DeliveryServiceRequests        []tc.DeliveryServiceRequest        `json:"deliveryServiceRequests"`
 	DeliveryServiceRequestComments []tc.DeliveryServiceRequestComment `json:"deliveryServiceRequestComments"`
-	DeliveryServices               []tc.DeliveryServiceV13            `json:"deliveryservices"`
+	DeliveryServices               []tc.DeliveryService               `json:"deliveryservices"`
 	Divisions                      []tc.Division                      `json:"divisions"`
 	Federations                    []tc.CDNFederation                 `json:"federations"`
 	Coordinates                    []tc.Coordinate                    `json:"coordinates"`
diff --git a/traffic_ops/traffic_ops_golang/asn/asns_test.go b/traffic_ops/traffic_ops_golang/asn/asns_test.go
index f08697f..0e49111 100644
--- a/traffic_ops/traffic_ops_golang/asn/asns_test.go
+++ b/traffic_ops/traffic_ops_golang/asn/asns_test.go
@@ -71,6 +71,7 @@ func TestGetASNs(t *testing.T) {
 	for _, ts := range testCase {
 		rows = rows.AddRow(
 			*ts.ASN,
+			*ts.Cachegroup,
 			*ts.CachegroupID,
 			*ts.ID,
 			*ts.LastUpdated,
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
index b6bc3b0..f8b15a6 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
@@ -218,7 +218,7 @@ func CreateV12() http.HandlerFunc {
 			api.HandleErr(w, r, http.StatusBadRequest, errors.New("decoding: "+err.Error()), nil)
 			return
 		}
-		dsv13 := tc.NewDeliveryServiceNullableV13FromV12(ds)
+		dsv13 := tc.NewDeliveryServiceNullableFromV12(ds)
 		if authorized, err := isTenantAuthorized(inf.User, inf.Tx, &ds); err != nil {
 			api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
 			return
@@ -337,7 +337,7 @@ func UpdateV12() http.HandlerFunc {
 			api.HandleErr(w, r, http.StatusBadRequest, errors.New("decoding: "+err.Error()), nil)
 			return
 		}
-		dsv13 := tc.NewDeliveryServiceNullableV13FromV12(ds)
+		dsv13 := tc.NewDeliveryServiceNullableFromV12(ds)
 		if authorized, err := isTenantAuthorized(inf.User, inf.Tx, &ds); err != nil {
 			api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
 			return
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
index 6ed7ffe..abd56df 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
@@ -46,7 +46,7 @@ import (
 
 type TODeliveryServiceV13 struct {
 	ReqInfo *api.APIInfo
-	tc.DeliveryServiceNullableV13
+	tc.DeliveryServiceNullable
 }
 
 func (ds *TODeliveryServiceV13) V12() *TODeliveryServiceV12 {
@@ -54,15 +54,15 @@ func (ds *TODeliveryServiceV13) V12() *TODeliveryServiceV12 {
 }
 
 func (ds TODeliveryServiceV13) MarshalJSON() ([]byte, error) {
-	return json.Marshal(ds.DeliveryServiceNullableV13)
+	return json.Marshal(ds.DeliveryServiceNullable)
 }
 func (ds *TODeliveryServiceV13) UnmarshalJSON(data []byte) error {
-	return json.Unmarshal(data, ds.DeliveryServiceNullableV13)
+	return json.Unmarshal(data, ds.DeliveryServiceNullable)
 }
 
 func GetTypeV13Factory() api.CRUDFactory {
 	return func(reqInfo *api.APIInfo) api.CRUDer {
-		toReturn := TODeliveryServiceV13{reqInfo, tc.DeliveryServiceNullableV13{}}
+		toReturn := TODeliveryServiceV13{reqInfo, tc.DeliveryServiceNullable{}}
 		return &toReturn
 	}
 }
@@ -90,7 +90,7 @@ func (ds *TODeliveryServiceV13) GetType() string {
 }
 
 func (ds *TODeliveryServiceV13) Validate() error {
-	return ds.DeliveryServiceNullableV13.Validate(ds.ReqInfo.Tx.Tx)
+	return ds.DeliveryServiceNullable.Validate(ds.ReqInfo.Tx.Tx)
 }
 
 // Create is unimplemented, needed to satisfy CRUDer, since the framework doesn't allow a create to return an array of one
@@ -109,7 +109,7 @@ func CreateV13() http.HandlerFunc {
 		}
 		defer inf.Close()
 
-		ds := tc.DeliveryServiceNullableV13{}
+		ds := tc.DeliveryServiceNullable{}
 		if err := api.Parse(r.Body, inf.Tx.Tx, &ds); err != nil {
 			api.HandleErr(w, r, http.StatusBadRequest, errors.New("decoding: "+err.Error()), nil)
 			return
@@ -135,12 +135,12 @@ func CreateV13() http.HandlerFunc {
 			return
 		}
 		*inf.CommitTx = true
-		api.WriteRespAlertObj(w, r, tc.SuccessLevel, "Deliveryservice creation was successful.", []tc.DeliveryServiceNullableV13{ds})
+		api.WriteRespAlertObj(w, r, tc.SuccessLevel, "Deliveryservice creation was successful.", []tc.DeliveryServiceNullable{ds})
 	}
 }
 
 // create creates the given ds in the database, and returns the DS with its id and other fields created on insert set. On error, the HTTP status code, user error, and system error are returned. The status code SHOULD NOT be used, if both errors are nil.
-func create(tx *sql.Tx, cfg config.Config, user *auth.CurrentUser, ds tc.DeliveryServiceNullableV13) (tc.DeliveryServiceNullableV13, int, error, error) {
+func create(tx *sql.Tx, cfg config.Config, user *auth.CurrentUser, ds tc.DeliveryServiceNullable) (tc.DeliveryServiceNullable, int, error, error) {
 	// TODO change DeepCachingType to implement sql.Valuer and sql.Scanner, so sqlx struct scan can be used.
 	deepCachingType := tc.DeepCachingType("").String()
 	if ds.DeepCachingType != nil {
@@ -151,86 +151,86 @@ func create(tx *sql.Tx, cfg config.Config, user *auth.CurrentUser, ds tc.Deliver
 	if err != nil {
 		if pqerr, ok := err.(*pq.Error); ok {
 			err, _ := dbhelpers.ParsePQUniqueConstraintError(pqerr)
-			return tc.DeliveryServiceNullableV13{}, http.StatusBadRequest, errors.New("a delivery service with " + err.Error()), nil
+			return tc.DeliveryServiceNullable{}, http.StatusBadRequest, errors.New("a delivery service with " + err.Error()), nil
 		}
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("inserting ds: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("inserting ds: " + err.Error())
 	}
 	defer resultRows.Close()
 
 	id := 0
 	lastUpdated := tc.TimeNoMod{}
 	if !resultRows.Next() {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("no deliveryservice request inserted, no id was returned")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("no deliveryservice request inserted, no id was returned")
 	}
 	if err := resultRows.Scan(&id, &lastUpdated); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("could not scan id from insert: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("could not scan id from insert: " + err.Error())
 	}
 	if resultRows.Next() {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("too many ids returned from deliveryservice request insert")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("too many ids returned from deliveryservice request insert")
 	}
 	ds.ID = &id
 
 	if ds.ID == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("missing id after insert")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("missing id after insert")
 	}
 	if ds.XMLID == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("missing xml_id after insert")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("missing xml_id after insert")
 	}
 	if ds.TypeID == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("missing type after insert")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("missing type after insert")
 	}
 	dsType, err := getTypeFromID(*ds.TypeID, tx)
 	if err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("getting delivery service type: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("getting delivery service type: " + err.Error())
 	}
 	ds.Type = &dsType
 
 	if err := createDefaultRegex(tx, *ds.ID, *ds.XMLID); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating default regex: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating default regex: " + err.Error())
 	}
 
 	matchlists, err := GetDeliveryServicesMatchLists([]string{*ds.XMLID}, tx)
 	if err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating DS: reading matchlists: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating DS: reading matchlists: " + err.Error())
 	}
 	if matchlist, ok := matchlists[*ds.XMLID]; !ok {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating DS: reading matchlists: not found")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating DS: reading matchlists: not found")
 	} else {
 		ds.MatchList = &matchlist
 	}
 
 	cdnName, cdnDomain, dnssecEnabled, err := getCDNNameDomainDNSSecEnabled(*ds.ID, tx)
 	if err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating DS: getting CDN info: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating DS: getting CDN info: " + err.Error())
 	}
 
 	ds.ExampleURLs = MakeExampleURLs(ds.Protocol, *ds.Type, *ds.RoutingName, *ds.MatchList, cdnDomain)
 
 	if err := ensureHeaderRewriteParams(tx, *ds.ID, *ds.XMLID, ds.EdgeHeaderRewrite, edgeTier, *ds.Type); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating edge header rewrite parameters: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating edge header rewrite parameters: " + err.Error())
 	}
 	if err := ensureHeaderRewriteParams(tx, *ds.ID, *ds.XMLID, ds.MidHeaderRewrite, midTier, *ds.Type); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating mid header rewrite parameters: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating mid header rewrite parameters: " + err.Error())
 	}
 	if err := ensureRegexRemapParams(tx, *ds.ID, *ds.XMLID, ds.RegexRemap); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating regex remap parameters: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating regex remap parameters: " + err.Error())
 	}
 	if err := ensureCacheURLParams(tx, *ds.ID, *ds.XMLID, ds.CacheURL); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating cache url parameters: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating cache url parameters: " + err.Error())
 	}
 	if dnssecEnabled {
 		if err := PutDNSSecKeys(tx, &cfg, *ds.XMLID, cdnName, ds.ExampleURLs); err != nil {
-			return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating DNSSEC keys: " + err.Error())
+			return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating DNSSEC keys: " + err.Error())
 		}
 	}
 
 	if err := createPrimaryOrigin(tx, user, ds); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating delivery service: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating delivery service: " + err.Error())
 	}
 
 	ds.LastUpdated = &lastUpdated
 	if err := api.CreateChangeLogRawErr(api.ApiChange, "Created ds: "+*ds.XMLID+" id: "+strconv.Itoa(*ds.ID), user, tx); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("error writing to audit log: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("error writing to audit log: " + err.Error())
 	}
 	return ds, http.StatusOK, nil, nil
 }
@@ -265,7 +265,7 @@ func createDefaultRegex(tx *sql.Tx, dsID int, xmlID string) error {
 	return nil
 }
 
-func createPrimaryOrigin(tx *sql.Tx, user *auth.CurrentUser, ds tc.DeliveryServiceNullableV13) error {
+func createPrimaryOrigin(tx *sql.Tx, user *auth.CurrentUser, ds tc.DeliveryServiceNullable) error {
 	if ds.OrgServerFQDN == nil {
 		return nil
 	}
@@ -286,7 +286,7 @@ func createPrimaryOrigin(tx *sql.Tx, user *auth.CurrentUser, ds tc.DeliveryServi
 	return nil
 }
 
-func updatePrimaryOrigin(tx *sql.Tx, user *auth.CurrentUser, ds tc.DeliveryServiceNullableV13) error {
+func updatePrimaryOrigin(tx *sql.Tx, user *auth.CurrentUser, ds tc.DeliveryServiceNullable) error {
 	count := 0
 	q := `SELECT count(*) FROM origin WHERE deliveryservice = $1 AND is_primary`
 	if err := tx.QueryRow(q, *ds.ID).Scan(&count); err != nil {
@@ -387,7 +387,7 @@ func UpdateV13() http.HandlerFunc {
 
 		id := inf.IntParams["id"]
 
-		ds := tc.DeliveryServiceNullableV13{}
+		ds := tc.DeliveryServiceNullable{}
 		if err := json.NewDecoder(r.Body).Decode(&ds); err != nil {
 			api.HandleErr(w, r, http.StatusBadRequest, errors.New("malformed JSON: "+err.Error()), nil)
 			return
@@ -414,7 +414,7 @@ func UpdateV13() http.HandlerFunc {
 		}
 
 		*inf.CommitTx = true
-		api.WriteRespAlertObj(w, r, tc.SuccessLevel, "Deliveryservice update was successful.", []tc.DeliveryServiceNullableV13{ds})
+		api.WriteRespAlertObj(w, r, tc.SuccessLevel, "Deliveryservice update was successful.", []tc.DeliveryServiceNullable{ds})
 	}
 }
 
@@ -429,20 +429,20 @@ func getDSType(tx *sql.Tx, xmlid string) (tc.DSType, bool, error) {
 	return tc.DSTypeFromString(name), true, nil
 }
 
-func update(tx *sql.Tx, cfg config.Config, user *auth.CurrentUser, ds *tc.DeliveryServiceNullableV13) (tc.DeliveryServiceNullableV13, int, error, error) {
+func update(tx *sql.Tx, cfg config.Config, user *auth.CurrentUser, ds *tc.DeliveryServiceNullable) (tc.DeliveryServiceNullable, int, error, error) {
 	if ds.XMLID == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusBadRequest, errors.New("missing xml_id"), nil
+		return tc.DeliveryServiceNullable{}, http.StatusBadRequest, errors.New("missing xml_id"), nil
 	}
 	if ds.ID == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusBadRequest, errors.New("missing id"), nil
+		return tc.DeliveryServiceNullable{}, http.StatusBadRequest, errors.New("missing id"), nil
 	}
 
 	dsType, ok, err := getDSType(tx, *ds.XMLID)
 	if !ok {
-		return tc.DeliveryServiceNullableV13{}, http.StatusNotFound, errors.New("delivery service '" + *ds.XMLID + "' not found"), nil
+		return tc.DeliveryServiceNullable{}, http.StatusNotFound, errors.New("delivery service '" + *ds.XMLID + "' not found"), nil
 	}
 	if err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("getting delivery service type during update: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("getting delivery service type during update: " + err.Error())
 	}
 
 	// oldHostName will be used to determine if SSL Keys need updating - this will be empty if the DS doesn't have SSL keys, because DS types without SSL keys may not have regexes, and thus will fail to get a host name.
@@ -450,7 +450,7 @@ func update(tx *sql.Tx, cfg config.Config, user *auth.CurrentUser, ds *tc.Delive
 	if dsType.HasSSLKeys() {
 		oldHostName, err = getOldHostName(*ds.ID, tx)
 		if err != nil {
-			return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("getting existing delivery service hostname: " + err.Error())
+			return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("getting existing delivery service hostname: " + err.Error())
 		}
 	}
 
@@ -466,49 +466,49 @@ func update(tx *sql.Tx, cfg config.Config, user *auth.CurrentUser, ds *tc.Delive
 		if err, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(err)
 			if eType == tc.DataConflictError {
-				return tc.DeliveryServiceNullableV13{}, http.StatusBadRequest, errors.New("a delivery service with " + err.Error()), nil
+				return tc.DeliveryServiceNullable{}, http.StatusBadRequest, errors.New("a delivery service with " + err.Error()), nil
 			}
-			return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("query updating delivery service: pq: " + err.Error())
+			return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("query updating delivery service: pq: " + err.Error())
 		}
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("query updating delivery service: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("query updating delivery service: " + err.Error())
 	}
 	defer resultRows.Close()
 	if !resultRows.Next() {
-		return tc.DeliveryServiceNullableV13{}, http.StatusNotFound, errors.New("no delivery service found with this id"), nil
+		return tc.DeliveryServiceNullable{}, http.StatusNotFound, errors.New("no delivery service found with this id"), nil
 	}
 	lastUpdated := tc.TimeNoMod{}
 	if err := resultRows.Scan(&lastUpdated); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("scan updating delivery service: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("scan updating delivery service: " + err.Error())
 	}
 	if resultRows.Next() {
 		xmlID := ""
 		if ds.XMLID != nil {
 			xmlID = *ds.XMLID
 		}
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("updating delivery service " + xmlID + ": " + "this update affected too many rows: > 1")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("updating delivery service " + xmlID + ": " + "this update affected too many rows: > 1")
 	}
 
 	if ds.ID == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("missing id after update")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("missing id after update")
 	}
 	if ds.XMLID == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("missing xml_id after update")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("missing xml_id after update")
 	}
 	if ds.TypeID == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("missing type after update")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("missing type after update")
 	}
 	if ds.RoutingName == nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("missing routing name after update")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("missing routing name after update")
 	}
 	newDSType, err := getTypeFromID(*ds.TypeID, tx)
 	if err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("getting delivery service type after update: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("getting delivery service type after update: " + err.Error())
 	}
 	ds.Type = &newDSType
 
 	cdnDomain, err := getCDNDomain(*ds.ID, tx) // need to get the domain again, in case it changed.
 	if err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("getting CDN domain after update: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("getting CDN domain after update: " + err.Error())
 	}
 
 	// newHostName will be used to determine if SSL Keys need updating - this will be empty if the DS doesn't have SSL keys, because DS types without SSL keys may not have regexes, and thus will fail to get a host name.
@@ -516,47 +516,47 @@ func update(tx *sql.Tx, cfg config.Config, user *auth.CurrentUser, ds *tc.Delive
 	if dsType.HasSSLKeys() {
 		newHostName, err = getHostName(ds.Protocol, *ds.Type, *ds.RoutingName, *ds.MatchList, cdnDomain)
 		if err != nil {
-			return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("getting hostname after update: " + err.Error())
+			return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("getting hostname after update: " + err.Error())
 		}
 	}
 
 	matchLists, err := GetDeliveryServicesMatchLists([]string{*ds.XMLID}, tx)
 	if err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("getting matchlists after update: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("getting matchlists after update: " + err.Error())
 	}
 	if ml, ok := matchLists[*ds.XMLID]; !ok {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("no matchlists after update")
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("no matchlists after update")
 	} else {
 		ds.MatchList = &ml
 	}
 
 	if newDSType.HasSSLKeys() && oldHostName != newHostName {
 		if err := updateSSLKeys(ds, newHostName, tx, cfg); err != nil {
-			return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("updating delivery service " + *ds.XMLID + ": updating SSL keys: " + err.Error())
+			return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("updating delivery service " + *ds.XMLID + ": updating SSL keys: " + err.Error())
 		}
 	}
 
 	if err := ensureHeaderRewriteParams(tx, *ds.ID, *ds.XMLID, ds.EdgeHeaderRewrite, edgeTier, *ds.Type); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating edge header rewrite parameters: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating edge header rewrite parameters: " + err.Error())
 	}
 	if err := ensureHeaderRewriteParams(tx, *ds.ID, *ds.XMLID, ds.MidHeaderRewrite, midTier, *ds.Type); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating mid header rewrite parameters: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating mid header rewrite parameters: " + err.Error())
 	}
 	if err := ensureRegexRemapParams(tx, *ds.ID, *ds.XMLID, ds.RegexRemap); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating mid regex remap parameters: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating mid regex remap parameters: " + err.Error())
 	}
 	if err := ensureCacheURLParams(tx, *ds.ID, *ds.XMLID, ds.CacheURL); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("creating mid cacheurl parameters: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("creating mid cacheurl parameters: " + err.Error())
 	}
 
 	if err := updatePrimaryOrigin(tx, user, *ds); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("updating delivery service: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("updating delivery service: " + err.Error())
 	}
 
 	ds.LastUpdated = &lastUpdated
 
 	if err := api.CreateChangeLogRawErr(api.ApiChange, "Updated ds: "+*ds.XMLID+" id: "+strconv.Itoa(*ds.ID), user, tx); err != nil {
-		return tc.DeliveryServiceNullableV13{}, http.StatusInternalServerError, nil, errors.New("writing change log entry: " + err.Error())
+		return tc.DeliveryServiceNullable{}, http.StatusInternalServerError, nil, errors.New("writing change log entry: " + err.Error())
 	}
 	return *ds, http.StatusOK, nil, nil
 }
@@ -572,7 +572,7 @@ func (ds *TODeliveryServiceV13) IsTenantAuthorized(user *auth.CurrentUser) (bool
 	return ds.V12().IsTenantAuthorized(user)
 }
 
-func readGetDeliveryServices(params map[string]string, tx *sqlx.Tx, user *auth.CurrentUser) ([]tc.DeliveryServiceNullableV13, []error, tc.ApiErrorType) {
+func readGetDeliveryServices(params map[string]string, tx *sqlx.Tx, user *auth.CurrentUser) ([]tc.DeliveryServiceNullable, []error, tc.ApiErrorType) {
 	if strings.HasSuffix(params["id"], ".json") {
 		params["id"] = params["id"][:len(params["id"])-len(".json")]
 	}
@@ -625,10 +625,10 @@ func readGetDeliveryServices(params map[string]string, tx *sqlx.Tx, user *auth.C
 	}
 	defer rows.Close()
 
-	dses := []tc.DeliveryServiceNullableV13{}
+	dses := []tc.DeliveryServiceNullable{}
 	dsCDNDomains := map[string]string{}
 	for rows.Next() {
-		ds := tc.DeliveryServiceNullableV13{}
+		ds := tc.DeliveryServiceNullable{}
 		cdnDomain := ""
 		err := rows.Scan(&ds.Active, &ds.AnonymousBlockingEnabled, &ds.CacheURL, &ds.CCRDNSTTL, &ds.CDNID, &ds.CDNName, &ds.CheckPath, &ds.DeepCachingType, &ds.DisplayName, &ds.DNSBypassCNAME, &ds.DNSBypassIP, &ds.DNSBypassIP6, &ds.DNSBypassTTL, &ds.DSCP, &ds.EdgeHeaderRewrite, &ds.GeoLimitRedirectURL, &ds.GeoLimit, &ds.GeoLimitCountries, &ds.GeoProvider, &ds.GlobalMaxMBPS, &ds.GlobalMaxTPS, &ds.FQPacingRate, &ds.HTTPBypassFQDN, &ds.ID, &ds.InfoURL, &ds.InitialDispersion, &ds.IPV6RoutingEnable [...]
 		if err != nil {
@@ -664,7 +664,7 @@ func readGetDeliveryServices(params map[string]string, tx *sqlx.Tx, user *auth.C
 	return dses, nil, tc.NoError
 }
 
-func updateSSLKeys(ds *tc.DeliveryServiceNullableV13, hostName string, tx *sql.Tx, cfg config.Config) error {
+func updateSSLKeys(ds *tc.DeliveryServiceNullable, hostName string, tx *sql.Tx, cfg config.Config) error {
 	if ds.XMLID == nil {
 		return errors.New("delivery services has no XMLID!")
 	}
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/request/requests_test.go b/traffic_ops/traffic_ops_golang/deliveryservice/request/requests_test.go
index d22033a..2ddd489 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/request/requests_test.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/request/requests_test.go
@@ -61,9 +61,9 @@ func TestGetDeliveryServiceRequest(t *testing.T) {
 	r := &TODeliveryServiceRequest{DeliveryServiceRequestNullable: tc.DeliveryServiceRequestNullable{
 		ChangeType: &u,
 		Status:     &st,
-		DeliveryService: &tc.DeliveryServiceNullableV13{
+		DeliveryService: &tc.DeliveryServiceNullable{
 			DeliveryServiceNullableV12: tc.DeliveryServiceNullableV12{
-				DeliveryServiceNullable: tc.DeliveryServiceNullable{
+				DeliveryServiceNullableV11: tc.DeliveryServiceNullableV11{
 					XMLID:       &s,
 					CDNID:       &i,
 					LogsEnabled: &b,
@@ -77,14 +77,14 @@ func TestGetDeliveryServiceRequest(t *testing.T) {
 	}}
 
 	expectedErrors := []string{
-	/*
-		`'regionalGeoBlocking' is required`,
-		`'xmlId' cannot contain spaces`,
-		`'dscp' is required`,
-		`'displayName' cannot be blank`,
-		`'geoProvider' is required`,
-		`'typeId' is required`,
-	*/
+		/*
+			`'regionalGeoBlocking' is required`,
+			`'xmlId' cannot contain spaces`,
+			`'dscp' is required`,
+			`'displayName' cannot be blank`,
+			`'geoProvider' is required`,
+			`'typeId' is required`,
+		*/
 	}
 
 	r.SetKeys(map[string]interface{}{"id": 10})
diff --git a/traffic_ops/traffic_ops_golang/tenant/tenancy.go b/traffic_ops/traffic_ops_golang/tenant/tenancy.go
index 7fdc812..b269dc1 100644
--- a/traffic_ops/traffic_ops_golang/tenant/tenancy.go
+++ b/traffic_ops/traffic_ops_golang/tenant/tenancy.go
@@ -47,7 +47,8 @@ func (dsInfo DeliveryServiceTenantInfo) IsTenantAuthorized(user *auth.CurrentUse
 
 // GetDeliveryServiceTenantInfo returns tenant information for a deliveryservice
 func GetDeliveryServiceTenantInfo(xmlID string, tx *sql.Tx) (*DeliveryServiceTenantInfo, error) {
-	ds := DeliveryServiceTenantInfo{XMLID: util.StrPtr(xmlID)}
+	ds := DeliveryServiceTenantInfo{}
+	ds.XMLID = util.StrPtr(xmlID)
 	if err := tx.QueryRow(`SELECT tenant_id FROM deliveryservice where xml_id = $1`, &ds.XMLID).Scan(&ds.TenantID); err != nil {
 		if err == sql.ErrNoRows {
 			return &ds, errors.New("a deliveryservice with xml_id '" + xmlID + "' was not found")
diff --git a/traffic_ops/traffic_ops_golang/user/deliveryservices.go b/traffic_ops/traffic_ops_golang/user/deliveryservices.go
index 2b52355..5812d82 100644
--- a/traffic_ops/traffic_ops_golang/user/deliveryservices.go
+++ b/traffic_ops/traffic_ops_golang/user/deliveryservices.go
@@ -76,8 +76,8 @@ func GetAvailableDSes(w http.ResponseWriter, r *http.Request) {
 	api.WriteResp(w, r, dses)
 }
 
-func filterAuthorized(tx *sql.Tx, dses []tc.DeliveryServiceNullableV13, user *auth.CurrentUser) ([]tc.DeliveryServiceNullableV13, error) {
-	authorizedDSes := []tc.DeliveryServiceNullableV13{}
+func filterAuthorized(tx *sql.Tx, dses []tc.DeliveryServiceNullable, user *auth.CurrentUser) ([]tc.DeliveryServiceNullable, error) {
+	authorizedDSes := []tc.DeliveryServiceNullable{}
 	for _, ds := range dses {
 		if ds.TenantID == nil {
 			continue
@@ -112,7 +112,7 @@ func filterAvailableAuthorized(tx *sql.Tx, dses []tc.UserAvailableDS, user *auth
 	return authorizedDSes, nil
 }
 
-func getUserDSes(tx *sql.Tx, userID int) ([]tc.DeliveryServiceNullableV13, error) {
+func getUserDSes(tx *sql.Tx, userID int) ([]tc.DeliveryServiceNullable, error) {
 	q := `
 SELECT
 ds.active,
@@ -189,9 +189,9 @@ WHERE dsu.tm_user_id = $1
 		return nil, errors.New("querying user delivery services: " + err.Error())
 	}
 	defer rows.Close()
-	dses := []tc.DeliveryServiceNullableV13{}
+	dses := []tc.DeliveryServiceNullable{}
 	for rows.Next() {
-		ds := tc.DeliveryServiceNullableV13{}
+		ds := tc.DeliveryServiceNullable{}
 		err := rows.Scan(&ds.Active, &ds.AnonymousBlockingEnabled, &ds.CacheURL, &ds.CCRDNSTTL, &ds.CDNID, &ds.CDNName, &ds.CheckPath, &ds.DeepCachingType, &ds.DisplayName, &ds.DNSBypassCNAME, &ds.DNSBypassIP, &ds.DNSBypassIP6, &ds.DNSBypassTTL, &ds.DSCP, &ds.EdgeHeaderRewrite, &ds.GeoLimitRedirectURL, &ds.GeoLimit, &ds.GeoLimitCountries, &ds.GeoProvider, &ds.GlobalMaxMBPS, &ds.GlobalMaxTPS, &ds.FQPacingRate, &ds.HTTPBypassFQDN, &ds.ID, &ds.InfoURL, &ds.InitialDispersion, &ds.IPV6RoutingEnable [...]
 		if err != nil {
 			return nil, errors.New("scanning user delivery services : " + err.Error())