You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by de...@apache.org on 2018/03/01 20:17:29 UTC

[incubator-trafficcontrol] branch master updated (270d069 -> 7ddd35e)

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

dewrich pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-trafficcontrol.git.


    from 270d069  Added info on xml to lua
     new c75cbc7  add asn validation on POST/PUT with tests; fix signatures on read-only methods in asns
     new bb5a2d2  add cdn validation on POST/PUT with tests; fix signatures on read-only methods in cdns
     new 2b89d53  adds nullable versions of ASN and CDN structs
     new fe2fc2d  update ASN to nullable struct
     new 7ddd35e  update CDN to nullable struct

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 lib/go-tc/asns.go                               | 18 ++++--
 lib/go-tc/cdns.go                               | 20 +++++--
 traffic_ops/traffic_ops_golang/asn/asns.go      | 43 +++++++++------
 traffic_ops/traffic_ops_golang/asn/asns_test.go | 18 +++++-
 traffic_ops/traffic_ops_golang/cdn/cdns.go      | 73 ++++++++++++++++++-------
 traffic_ops/traffic_ops_golang/cdn/cdns_test.go | 47 +++++++++++++++-
 6 files changed, 169 insertions(+), 50 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
dewrich@apache.org.

[incubator-trafficcontrol] 02/05: add cdn validation on POST/PUT with tests; fix signatures on read-only methods in cdns

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit bb5a2d23efff9221f90613d7711d505696294f6f
Author: Dan Kirkwood <da...@apache.org>
AuthorDate: Wed Feb 28 11:30:56 2018 -0700

    add cdn validation on POST/PUT with tests; fix signatures on read-only methods in cdns
---
 traffic_ops/traffic_ops_golang/cdn/cdns.go      | 47 +++++++++++++++++++------
 traffic_ops/traffic_ops_golang/cdn/cdns_test.go | 34 ++++++++++++++++++
 2 files changed, 70 insertions(+), 11 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/cdn/cdns.go b/traffic_ops/traffic_ops_golang/cdn/cdns.go
index c1b7510..309c1e6 100644
--- a/traffic_ops/traffic_ops_golang/cdn/cdns.go
+++ b/traffic_ops/traffic_ops_golang/cdn/cdns.go
@@ -22,13 +22,16 @@ package cdn
 import (
 	"errors"
 	"fmt"
+	"strings"
 
 	"github.com/apache/incubator-trafficcontrol/lib/go-log"
 	"github.com/apache/incubator-trafficcontrol/lib/go-tc"
-
 	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/api"
 	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
+	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tovalidate"
+	"github.com/asaskevich/govalidator"
+	validation "github.com/go-ozzo/ozzo-validation"
 	"github.com/jmoiron/sqlx"
 	"github.com/lib/pq"
 )
@@ -44,15 +47,15 @@ func GetRefType() *TOCDN {
 }
 
 //Implementation of the Identifier, Validator interface functions
-func (cdn *TOCDN) GetID() (int, bool) {
+func (cdn TOCDN) GetID() (int, bool) {
 	return cdn.ID, true
 }
 
-func (cdn *TOCDN) GetAuditName() string {
+func (cdn TOCDN) GetAuditName() string {
 	return cdn.Name
 }
 
-func (cdn *TOCDN) GetType() string {
+func (cdn TOCDN) GetType() string {
 	return "cdn"
 }
 
@@ -60,15 +63,37 @@ func (cdn *TOCDN) SetID(i int) {
 	cdn.ID = i
 }
 
-func (cdn *TOCDN) Validate(db *sqlx.DB) []error {
-	errs := []error{}
-	if len(cdn.Name) < 1 {
-		errs = append(errs, errors.New(`CDN 'name' is required.`))
+func isValidCDNchar(r rune) bool {
+	if r >= 'a' && r <= 'z' {
+		return true
+	}
+	if r >= 'A' && r <= 'Z' {
+		return true
+	}
+	if r == '.' || r == '_' {
+		return true
+	}
+	return false
+}
+
+// IsValidCDNName returns true if the name contains only characters valid for a CDN name
+func IsValidCDNName(str string) bool {
+	i := strings.IndexFunc(str, func(r rune) bool { return !isValidCDNchar(r) })
+	return i == -1
+}
+
+// Validate fulfills the api.Validator interface
+func (cdn TOCDN) Validate(db *sqlx.DB) []error {
+	validName := validation.NewStringRule(IsValidCDNName, "invalid characters found")
+	validDomainName := validation.NewStringRule(govalidator.IsDNSName, "not a valid domain name")
+	errs := validation.Errors{
+		"name":       validation.Validate(cdn.Name, validation.Required, validName),
+		"domainName": validation.Validate(cdn.DomainName, validation.Required, validDomainName),
 	}
-	if len(cdn.DomainName) < 1 {
-		errs = append(errs, errors.New("Domain Name is required."))
+	if errs != nil {
+		return tovalidate.ToErrors(errs)
 	}
-	return errs
+	return nil
 }
 
 //The TOCDN implementation of the Creator interface
diff --git a/traffic_ops/traffic_ops_golang/cdn/cdns_test.go b/traffic_ops/traffic_ops_golang/cdn/cdns_test.go
index 38c9abd..eb92b42 100644
--- a/traffic_ops/traffic_ops_golang/cdn/cdns_test.go
+++ b/traffic_ops/traffic_ops_golang/cdn/cdns_test.go
@@ -20,6 +20,9 @@ package cdn
  */
 
 import (
+	"errors"
+	"reflect"
+	"strings"
 	"testing"
 	"time"
 
@@ -89,6 +92,21 @@ func TestReadCDNs(t *testing.T) {
 	}
 }
 
+func TestFuncs(t *testing.T) {
+	if strings.Index(selectQuery(), "SELECT") != 0 {
+		t.Errorf("expected selectQuery to start with SELECT")
+	}
+	if strings.Index(insertQuery(), "INSERT") != 0 {
+		t.Errorf("expected insertQuery to start with INSERT")
+	}
+	if strings.Index(updateQuery(), "UPDATE") != 0 {
+		t.Errorf("expected updateQuery to start with UPDATE")
+	}
+	if strings.Index(deleteQuery(), "DELETE") != 0 {
+		t.Errorf("expected deleteQuery to start with DELETE")
+	}
+
+}
 func TestInterfaces(t *testing.T) {
 	var i interface{}
 	i = &TOCDN{}
@@ -109,3 +127,19 @@ func TestInterfaces(t *testing.T) {
 		t.Errorf("cdn must be Identifier")
 	}
 }
+
+func TestValidate(t *testing.T) {
+	c := TOCDN{Name: "not-a-valid-cdn"}
+	errs := c.Validate(nil)
+
+	expectedErrs := []error{
+		errors.New(`'name' invalid characters found`),
+		errors.New(`'domainName' cannot be blank`),
+	}
+
+	if !reflect.DeepEqual(expectedErrs, errs) {
+		t.Errorf("expected %s, got %s", expectedErrs, errs)
+	}
+	c.Name = "This.is.2.a_Valid___CDNNAME."
+	c.DomainName = `awesome-cdn.example.net`
+}

-- 
To stop receiving notification emails like this one, please contact
dewrich@apache.org.

[incubator-trafficcontrol] 01/05: add asn validation on POST/PUT with tests; fix signatures on read-only methods in asns

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c75cbc71d5167e43b4eca194b4eed0107cc7aab8
Author: Dan Kirkwood <da...@apache.org>
AuthorDate: Wed Feb 28 11:29:09 2018 -0700

    add asn validation on POST/PUT with tests; fix signatures on read-only methods in asns
---
 traffic_ops/traffic_ops_golang/asn/asns.go      | 15 +++++++++------
 traffic_ops/traffic_ops_golang/asn/asns_test.go | 21 +++++++++++++++++++++
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/asn/asns.go b/traffic_ops/traffic_ops_golang/asn/asns.go
index 5037e2e..55ecc05 100644
--- a/traffic_ops/traffic_ops_golang/asn/asns.go
+++ b/traffic_ops/traffic_ops_golang/asn/asns.go
@@ -47,15 +47,15 @@ func GetRefType() *TOASN {
 }
 
 //Implementation of the Identifier, Validator interface functions
-func (asn *TOASN) GetID() (int, bool) {
+func (asn TOASN) GetID() (int, bool) {
 	return asn.ID, true
 }
 
-func (asn *TOASN) GetAuditName() string {
+func (asn TOASN) GetAuditName() string {
 	return strconv.Itoa(asn.ASN)
 }
 
-func (asn *TOASN) GetType() string {
+func (asn TOASN) GetType() string {
 	return "asn"
 }
 
@@ -63,10 +63,13 @@ func (asn *TOASN) SetID(i int) {
 	asn.ID = i
 }
 
-func (asn *TOASN) Validate(db *sqlx.DB) []error {
+func (asn TOASN) Validate(db *sqlx.DB) []error {
 	errs := []error{}
-	if asn.ASN < 1 {
-		errs = append(errs, errors.New(`ASN 'asn' is required.`))
+	if asn.ASN < 0 {
+		errs = append(errs, errors.New(`asn must be a positive integer`))
+	}
+	if asn.CachegroupID < 0 {
+		errs = append(errs, errors.New(`cachegroupId must be a positive integer`))
 	}
 	return errs
 }
diff --git a/traffic_ops/traffic_ops_golang/asn/asns_test.go b/traffic_ops/traffic_ops_golang/asn/asns_test.go
index 9d967df..4eb7203 100644
--- a/traffic_ops/traffic_ops_golang/asn/asns_test.go
+++ b/traffic_ops/traffic_ops_golang/asn/asns_test.go
@@ -20,6 +20,8 @@ package asn
  */
 
 import (
+	"errors"
+	"reflect"
 	"testing"
 	"time"
 
@@ -107,3 +109,22 @@ func TestInterfaces(t *testing.T) {
 		t.Errorf("asn must be Identifier")
 	}
 }
+
+func TestValidate(t *testing.T) {
+	asn := TOASN{ASN: -99, CachegroupID: -99}
+	/*
+		ASN          int    `json:"asn" db:"asn"`
+		Cachegroup   string `json:"cachegroup" db:"cachegroup"`
+		CachegroupID int    `json:"cachegroupId" db:"cachegroup_id"`
+		ID           int    `json:"id" db:"id"`
+		LastUpdated  Time   `json:"lastUpdated" db:"last_updated"`
+	*/
+	errs := asn.Validate(nil)
+	expected := []error{
+		errors.New(`asn must be a positive integer`),
+		errors.New(`cachegroupId must be a positive integer`),
+	}
+	if !reflect.DeepEqual(expected, errs) {
+		t.Errorf(`expected %v,  got %v`, expected, errs)
+	}
+}

-- 
To stop receiving notification emails like this one, please contact
dewrich@apache.org.

[incubator-trafficcontrol] 03/05: adds nullable versions of ASN and CDN structs

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2b89d53705b5d55ef4e230d7f2e7fb06abd2791f
Author: Dan Kirkwood <da...@apache.org>
AuthorDate: Thu Mar 1 09:48:19 2018 -0700

    adds nullable versions of ASN and CDN structs
---
 lib/go-tc/asns.go | 18 +++++++++++++-----
 lib/go-tc/cdns.go | 20 ++++++++++++++------
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/lib/go-tc/asns.go b/lib/go-tc/asns.go
index 5341ca0..ac73a57 100644
--- a/lib/go-tc/asns.go
+++ b/lib/go-tc/asns.go
@@ -24,9 +24,17 @@ type ASNsResponse struct {
 }
 
 type ASN struct {
-	ASN          int    `json:"asn" db:"asn"`
-	Cachegroup   string `json:"cachegroup" db:"cachegroup"`
-	CachegroupID int    `json:"cachegroupId" db:"cachegroup_id"`
-	ID           int    `json:"id" db:"id"`
-	LastUpdated  Time   `json:"lastUpdated" db:"last_updated"`
+	ASN          int       `json:"asn" db:"asn"`
+	Cachegroup   string    `json:"cachegroup" db:"cachegroup"`
+	CachegroupID int       `json:"cachegroupId" db:"cachegroup_id"`
+	ID           int       `json:"id" db:"id"`
+	LastUpdated  TimeNoMod `json:"lastUpdated" db:"last_updated"`
+}
+
+type ASNNullable struct {
+	ASN          *int       `json:"asn" db:"asn"`
+	Cachegroup   *string    `json:"cachegroup" db:"cachegroup"`
+	CachegroupID *int       `json:"cachegroupId" db:"cachegroup_id"`
+	ID           *int       `json:"id" db:"id"`
+	LastUpdated  *TimeNoMod `json:"lastUpdated" db:"last_updated"`
 }
diff --git a/lib/go-tc/cdns.go b/lib/go-tc/cdns.go
index 34a2974..5402e2c 100644
--- a/lib/go-tc/cdns.go
+++ b/lib/go-tc/cdns.go
@@ -24,11 +24,19 @@ type CDNsResponse struct {
 }
 
 type CDN struct {
-	DNSSECEnabled bool   `json:"dnssecEnabled" db:"dnssec_enabled"`
-	DomainName    string `json:"domainName" db:"domain_name"`
-	ID            int    `json:"id" db:"id"`
-	LastUpdated   Time   `json:"lastUpdated" db:"last_updated"`
-	Name          string `json:"name" db:"name"`
+	DNSSECEnabled bool      `json:"dnssecEnabled" db:"dnssec_enabled"`
+	DomainName    string    `json:"domainName" db:"domain_name"`
+	ID            int       `json:"id" db:"id"`
+	LastUpdated   TimeNoMod `json:"lastUpdated" db:"last_updated"`
+	Name          string    `json:"name" db:"name"`
+}
+
+type CDNNullable struct {
+	DNSSECEnabled *bool      `json:"dnssecEnabled" db:"dnssec_enabled"`
+	DomainName    *string    `json:"domainName" db:"domain_name"`
+	ID            *int       `json:"id" db:"id"`
+	LastUpdated   *TimeNoMod `json:"lastUpdated" db:"last_updated"`
+	Name          *string    `json:"name" db:"name"`
 }
 
 // CDNSSLKeysResponse ...
@@ -47,4 +55,4 @@ type CDNSSLKeys struct {
 type CDNSSLKeysCertificate struct {
 	Crt string `json:"crt"`
 	Key string `json:"key"`
-}
\ No newline at end of file
+}

-- 
To stop receiving notification emails like this one, please contact
dewrich@apache.org.

[incubator-trafficcontrol] 05/05: update CDN to nullable struct

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7ddd35e8f7eaa3f364ee2056766ecfb7e0a66646
Author: Dan Kirkwood <da...@apache.org>
AuthorDate: Thu Mar 1 09:49:15 2018 -0700

    update CDN to nullable struct
---
 traffic_ops/traffic_ops_golang/cdn/cdns.go      | 38 +++++++++++++++----------
 traffic_ops/traffic_ops_golang/cdn/cdns_test.go | 21 ++++++++++----
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/cdn/cdns.go b/traffic_ops/traffic_ops_golang/cdn/cdns.go
index 309c1e6..3501e67 100644
--- a/traffic_ops/traffic_ops_golang/cdn/cdns.go
+++ b/traffic_ops/traffic_ops_golang/cdn/cdns.go
@@ -22,6 +22,7 @@ package cdn
 import (
 	"errors"
 	"fmt"
+	"strconv"
 	"strings"
 
 	"github.com/apache/incubator-trafficcontrol/lib/go-log"
@@ -37,10 +38,10 @@ import (
 )
 
 //we need a type alias to define functions on
-type TOCDN tc.CDN
+type TOCDN tc.CDNNullable
 
 //the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOCDN(tc.CDN{})
+var refType = TOCDN{}
 
 func GetRefType() *TOCDN {
 	return &refType
@@ -48,11 +49,18 @@ func GetRefType() *TOCDN {
 
 //Implementation of the Identifier, Validator interface functions
 func (cdn TOCDN) GetID() (int, bool) {
-	return cdn.ID, true
+	if cdn.ID == nil {
+		return 0, false
+	}
+	return *cdn.ID, true
 }
 
 func (cdn TOCDN) GetAuditName() string {
-	return cdn.Name
+	if cdn.Name != nil {
+		return *cdn.Name
+	}
+	id, _ := cdn.GetID()
+	return strconv.Itoa(id)
 }
 
 func (cdn TOCDN) GetType() string {
@@ -60,7 +68,7 @@ func (cdn TOCDN) GetType() string {
 }
 
 func (cdn *TOCDN) SetID(i int) {
-	cdn.ID = i
+	cdn.ID = &i
 }
 
 func isValidCDNchar(r rune) bool {
@@ -70,7 +78,10 @@ func isValidCDNchar(r rune) bool {
 	if r >= 'A' && r <= 'Z' {
 		return true
 	}
-	if r == '.' || r == '_' {
+	if r >= '0' && r <= '9' {
+		return true
+	}
+	if r == '.' || r == '-' {
 		return true
 	}
 	return false
@@ -84,16 +95,13 @@ func IsValidCDNName(str string) bool {
 
 // Validate fulfills the api.Validator interface
 func (cdn TOCDN) Validate(db *sqlx.DB) []error {
-	validName := validation.NewStringRule(IsValidCDNName, "invalid characters found")
+	validName := validation.NewStringRule(IsValidCDNName, "invalid characters found - Use alphanumeric . or - .")
 	validDomainName := validation.NewStringRule(govalidator.IsDNSName, "not a valid domain name")
 	errs := validation.Errors{
 		"name":       validation.Validate(cdn.Name, validation.Required, validName),
 		"domainName": validation.Validate(cdn.DomainName, validation.Required, validDomainName),
 	}
-	if errs != nil {
-		return tovalidate.ToErrors(errs)
-	}
-	return nil
+	return tovalidate.ToErrors(errs)
 }
 
 //The TOCDN implementation of the Creator interface
@@ -136,7 +144,7 @@ func (cdn *TOCDN) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiError
 	defer resultRows.Close()
 
 	var id int
-	var lastUpdated tc.Time
+	var lastUpdated tc.TimeNoMod
 	rowsAffected := 0
 	for resultRows.Next() {
 		rowsAffected++
@@ -155,7 +163,7 @@ func (cdn *TOCDN) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiError
 		return tc.DBError, tc.SystemError
 	}
 	cdn.SetID(id)
-	cdn.LastUpdated = lastUpdated
+	cdn.LastUpdated = &lastUpdated
 	err = tx.Commit()
 	if err != nil {
 		log.Errorln("Could not commit transaction: ", err)
@@ -242,7 +250,7 @@ func (cdn *TOCDN) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiError
 	}
 	defer resultRows.Close()
 
-	var lastUpdated tc.Time
+	var lastUpdated tc.TimeNoMod
 	rowsAffected := 0
 	for resultRows.Next() {
 		rowsAffected++
@@ -252,7 +260,7 @@ func (cdn *TOCDN) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiError
 		}
 	}
 	log.Debugf("lastUpdated: %++v", lastUpdated)
-	cdn.LastUpdated = lastUpdated
+	cdn.LastUpdated = &lastUpdated
 	if rowsAffected != 1 {
 		if rowsAffected < 1 {
 			return errors.New("no cdn found with this id"), tc.DataMissingError
diff --git a/traffic_ops/traffic_ops_golang/cdn/cdns_test.go b/traffic_ops/traffic_ops_golang/cdn/cdns_test.go
index eb92b42..65b676f 100644
--- a/traffic_ops/traffic_ops_golang/cdn/cdns_test.go
+++ b/traffic_ops/traffic_ops_golang/cdn/cdns_test.go
@@ -42,7 +42,7 @@ func getTestCDNs() []tc.CDN {
 		DomainName:    "domainName",
 		ID:            1,
 		Name:          "cdn1",
-		LastUpdated:   tc.Time{Time: time.Now()},
+		LastUpdated:   tc.TimeNoMod{Time: time.Now()},
 	}
 	cdns = append(cdns, testCDN)
 
@@ -129,17 +129,28 @@ func TestInterfaces(t *testing.T) {
 }
 
 func TestValidate(t *testing.T) {
-	c := TOCDN{Name: "not-a-valid-cdn"}
+	// invalid name, empty domainname
+	n := "not_a_valid_cdn"
+	c := TOCDN{Name: &n}
 	errs := c.Validate(nil)
 
 	expectedErrs := []error{
-		errors.New(`'name' invalid characters found`),
+		errors.New(`'name' invalid characters found - Use alphanumeric . or - .`),
 		errors.New(`'domainName' cannot be blank`),
 	}
 
 	if !reflect.DeepEqual(expectedErrs, errs) {
 		t.Errorf("expected %s, got %s", expectedErrs, errs)
 	}
-	c.Name = "This.is.2.a_Valid___CDNNAME."
-	c.DomainName = `awesome-cdn.example.net`
+
+	//  name,  domainname both valid
+	n = "This.is.2.a-Valid---CDNNAME."
+	d := `awesome-cdn.example.net`
+	c = TOCDN{Name: &n, DomainName: &d}
+	expectedErrs = []error{}
+	errs = c.Validate(nil)
+	if !reflect.DeepEqual(expectedErrs, errs) {
+		t.Errorf("expected %s, got %s", expectedErrs, errs)
+	}
+
 }

-- 
To stop receiving notification emails like this one, please contact
dewrich@apache.org.

[incubator-trafficcontrol] 04/05: update ASN to nullable struct

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit fe2fc2d004dffcf68b10b11a586b56b48cb5cdf1
Author: Dan Kirkwood <da...@apache.org>
AuthorDate: Thu Mar 1 09:49:06 2018 -0700

    update ASN to nullable struct
---
 traffic_ops/traffic_ops_golang/asn/asns.go      | 38 ++++++++++++++-----------
 traffic_ops/traffic_ops_golang/asn/asns_test.go | 17 ++++-------
 2 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/asn/asns.go b/traffic_ops/traffic_ops_golang/asn/asns.go
index 55ecc05..ecc2c56 100644
--- a/traffic_ops/traffic_ops_golang/asn/asns.go
+++ b/traffic_ops/traffic_ops_golang/asn/asns.go
@@ -29,6 +29,8 @@ import (
 	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/api"
 	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
+	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tovalidate"
+	validation "github.com/go-ozzo/ozzo-validation"
 	"github.com/jmoiron/sqlx"
 	"github.com/lib/pq"
 )
@@ -37,10 +39,10 @@ import (
 const ASNsPrivLevel = 10
 
 //we need a type alias to define functions on
-type TOASN tc.ASN
+type TOASN tc.ASNNullable
 
 //the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOASN(tc.ASN{})
+var refType = TOASN(tc.ASNNullable{})
 
 func GetRefType() *TOASN {
 	return &refType
@@ -48,11 +50,18 @@ func GetRefType() *TOASN {
 
 //Implementation of the Identifier, Validator interface functions
 func (asn TOASN) GetID() (int, bool) {
-	return asn.ID, true
+	if asn.ID == nil {
+		return 0, false
+	}
+	return *asn.ID, true
 }
 
 func (asn TOASN) GetAuditName() string {
-	return strconv.Itoa(asn.ASN)
+	if asn.ASN == nil {
+		id, _ := asn.GetID()
+		return strconv.Itoa(id)
+	}
+	return strconv.Itoa(*asn.ASN)
 }
 
 func (asn TOASN) GetType() string {
@@ -60,18 +69,15 @@ func (asn TOASN) GetType() string {
 }
 
 func (asn *TOASN) SetID(i int) {
-	asn.ID = i
+	asn.ID = &i
 }
 
 func (asn TOASN) Validate(db *sqlx.DB) []error {
-	errs := []error{}
-	if asn.ASN < 0 {
-		errs = append(errs, errors.New(`asn must be a positive integer`))
-	}
-	if asn.CachegroupID < 0 {
-		errs = append(errs, errors.New(`cachegroupId must be a positive integer`))
+	errs := validation.Errors{
+		"asn":          validation.Validate(asn.ASN, validation.NotNil, validation.Min(0)),
+		"cachegroupId": validation.Validate(asn.CachegroupID, validation.NotNil, validation.Min(0)),
 	}
-	return errs
+	return tovalidate.ToErrors(errs)
 }
 
 //The TOASN implementation of the Creator interface
@@ -114,7 +120,7 @@ func (asn *TOASN) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiError
 	defer resultRows.Close()
 
 	var id int
-	var lastUpdated tc.Time
+	var lastUpdated tc.TimeNoMod
 	rowsAffected := 0
 	for resultRows.Next() {
 		rowsAffected++
@@ -133,7 +139,7 @@ func (asn *TOASN) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiError
 		return tc.DBError, tc.SystemError
 	}
 	asn.SetID(id)
-	asn.LastUpdated = lastUpdated
+	asn.LastUpdated = &lastUpdated
 	err = tx.Commit()
 	if err != nil {
 		log.Errorln("Could not commit transaction: ", err)
@@ -231,7 +237,7 @@ func (asn *TOASN) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiError
 	}
 	defer resultRows.Close()
 
-	var lastUpdated tc.Time
+	var lastUpdated tc.TimeNoMod
 	rowsAffected := 0
 	for resultRows.Next() {
 		rowsAffected++
@@ -241,7 +247,7 @@ func (asn *TOASN) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiError
 		}
 	}
 	log.Debugf("lastUpdated: %++v", lastUpdated)
-	asn.LastUpdated = lastUpdated
+	asn.LastUpdated = &lastUpdated
 	if rowsAffected != 1 {
 		if rowsAffected < 1 {
 			return errors.New("no asn found with this id"), tc.DataMissingError
diff --git a/traffic_ops/traffic_ops_golang/asn/asns_test.go b/traffic_ops/traffic_ops_golang/asn/asns_test.go
index 4eb7203..b1d0bb4 100644
--- a/traffic_ops/traffic_ops_golang/asn/asns_test.go
+++ b/traffic_ops/traffic_ops_golang/asn/asns_test.go
@@ -40,7 +40,7 @@ func getTestASNs() []tc.ASN {
 		ASN:         1,
 		Cachegroup:  "Yukon",
 		ID:          1,
-		LastUpdated: tc.Time{Time: time.Now()},
+		LastUpdated: tc.TimeNoMod{Time: time.Now()},
 	}
 	ASNs = append(ASNs, testCase)
 
@@ -111,18 +111,13 @@ func TestInterfaces(t *testing.T) {
 }
 
 func TestValidate(t *testing.T) {
-	asn := TOASN{ASN: -99, CachegroupID: -99}
-	/*
-		ASN          int    `json:"asn" db:"asn"`
-		Cachegroup   string `json:"cachegroup" db:"cachegroup"`
-		CachegroupID int    `json:"cachegroupId" db:"cachegroup_id"`
-		ID           int    `json:"id" db:"id"`
-		LastUpdated  Time   `json:"lastUpdated" db:"last_updated"`
-	*/
+	i := -99
+	asn := TOASN{ASN: &i, CachegroupID: &i}
+
 	errs := asn.Validate(nil)
 	expected := []error{
-		errors.New(`asn must be a positive integer`),
-		errors.New(`cachegroupId must be a positive integer`),
+		errors.New(`'asn' must be no less than 0`),
+		errors.New(`'cachegroupId' must be no less than 0`),
 	}
 	if !reflect.DeepEqual(expected, errs) {
 		t.Errorf(`expected %v,  got %v`, expected, errs)

-- 
To stop receiving notification emails like this one, please contact
dewrich@apache.org.