dewrich closed pull request #2451: Fix delivery service validation URL: https://github.com/apache/trafficcontrol/pull/2451
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/lib/go-tc/deliveryservices.go b/lib/go-tc/deliveryservices.go index 354b76d5b..9f8f56e0e 100644 --- a/lib/go-tc/deliveryservices.go +++ b/lib/go-tc/deliveryservices.go @@ -241,15 +241,21 @@ func (ds *DeliveryServiceNullableV12) Sanitize() { } } -func getTypeName(tx *sql.Tx, id int) (string, bool, error) { +// getTypeData returns the type's name and use_in_table, true/false if the query returned data, and any error +func getTypeData(tx *sql.Tx, id int) (string, string, bool, error) { name := "" - if err := tx.QueryRow(`SELECT name from type where id=$1`, id).Scan(&name); err != nil { + var useInTablePtr *string + if err := tx.QueryRow(`SELECT name, use_in_table from type where id=$1`, id).Scan(&name, &useInTablePtr); err != nil { if err == sql.ErrNoRows { - return "", false, nil + return "", "", false, nil } - return "", false, errors.New("querying type name: " + err.Error()) + return "", "", false, errors.New("querying type data: " + err.Error()) } - return name, true, nil + useInTable := "" + if useInTablePtr != nil { + useInTable = *useInTablePtr + } + return name, useInTable, true, nil } func requiredIfMatchesTypeName(patterns []string, typeName string) func(interface{}) error { @@ -296,25 +302,35 @@ func (ds *DeliveryServiceNullableV12) validateTypeFields(tx *sql.Tx) error { DNSRegexType := "^DNS.*$" HTTPRegexType := "^HTTP.*$" SteeringRegexType := "^STEERING.*$" + latitudeErr := "Must be a floating point number within the range +-90" + longitudeErr := "Must be a floating point number within the range +-180" if ds.TypeID == nil { return errors.New("missing type") } - typeName, ok, err := getTypeName(tx, *ds.TypeID) + typeName, useInTable, ok, err := getTypeData(tx, *ds.TypeID) if err != nil { return errors.New("getting type name: " + err.Error()) } if !ok { return errors.New("type not found") } + if useInTable != "deliveryservice" { + return errors.New("type is not a valid deliveryservice type") + } errs := validation.Errors{ "initialDispersion": validation.Validate(ds.InitialDispersion, - validation.By(requiredIfMatchesTypeName([]string{HTTPRegexType}, typeName))), + validation.By(requiredIfMatchesTypeName([]string{HTTPRegexType}, typeName)), + validation.By(tovalidate.IsGreaterThanZero)), "ipv6RoutingEnabled": validation.Validate(ds.IPV6RoutingEnabled, validation.By(requiredIfMatchesTypeName([]string{SteeringRegexType, DNSRegexType, HTTPRegexType}, typeName))), "missLat": validation.Validate(ds.MissLat, - validation.By(requiredIfMatchesTypeName([]string{DNSRegexType, HTTPRegexType}, typeName))), + validation.By(requiredIfMatchesTypeName([]string{DNSRegexType, HTTPRegexType}, typeName)), + validation.Min(-90.0).Error(latitudeErr), + validation.Max(90.0).Error(latitudeErr)), "missLong": validation.Validate(ds.MissLong, - validation.By(requiredIfMatchesTypeName([]string{DNSRegexType, HTTPRegexType}, typeName))), + validation.By(requiredIfMatchesTypeName([]string{DNSRegexType, HTTPRegexType}, typeName)), + validation.Min(-180.0).Error(longitudeErr), + validation.Max(180.0).Error(longitudeErr)), "multiSiteOrigin": validation.Validate(ds.MultiSiteOrigin, validation.By(requiredIfMatchesTypeName([]string{DNSRegexType, HTTPRegexType}, typeName))), "orgServerFqdn": validation.Validate(ds.OrgServerFQDN, diff --git a/lib/go-tc/tovalidate/rules.go b/lib/go-tc/tovalidate/rules.go index aeb1b9b8d..1e8640758 100644 --- a/lib/go-tc/tovalidate/rules.go +++ b/lib/go-tc/tovalidate/rules.go @@ -13,6 +13,8 @@ package tovalidate import ( + "errors" + "fmt" "strings" ) @@ -46,3 +48,19 @@ func IsOneOfStringICase(set ...string) func(string) bool { } return IsOneOfString(lowcased...) } + +func IsGreaterThanZero(value interface{}) error { + switch v := value.(type) { + case *int: + if v == nil || *v > 0 { + return nil + } + case *float64: + if v == nil || *v > 0 { + return nil + } + default: + return fmt.Errorf("IsGreaterThanZero validation failure: unknown type %T", value) + } + return errors.New("must be greater than zero") +} diff --git a/traffic_ops/testing/api/v13/deliveryservice_requests_test.go b/traffic_ops/testing/api/v13/deliveryservice_requests_test.go index 6f83fb17c..6d974ae14 100644 --- a/traffic_ops/testing/api/v13/deliveryservice_requests_test.go +++ b/traffic_ops/testing/api/v13/deliveryservice_requests_test.go @@ -56,10 +56,10 @@ func CreateTestDeliveryServiceRequests(t *testing.T) { respCDN := resp[0] // Attach Type - typ := testData.Types[19] - respTypes, _, err := TOSession.GetTypeByName(typ.Name) + typ := testData.DeliveryServiceRequests[dsrGood].DeliveryService.Type.String() + respTypes, _, err := TOSession.GetTypeByName(typ) if err != nil { - t.Errorf("cannot GET Type by name: %v - %v\n", typ.Name, err) + t.Errorf("cannot GET Type by name: %v - %v\n", typ, err) } respTyp := respTypes[0] diff --git a/traffic_ops/testing/api/v13/tc-fixtures.json b/traffic_ops/testing/api/v13/tc-fixtures.json index 6ce32b163..c41eb8b02 100644 --- a/traffic_ops/testing/api/v13/tc-fixtures.json +++ b/traffic_ops/testing/api/v13/tc-fixtures.json @@ -103,6 +103,7 @@ "regionalGeoBlocking": true, "routingName": "goodroute", "tenantId": 2, + "type": "HTTP", "xmlId": "test-ds1" }, "status": "draft" @@ -122,6 +123,7 @@ "longDesc": "long desc", "regionalGeoBlocking": false, "tenantId": 1, + "type": "HTTP", "xmlId": "test-ds1" }, "status": "draft" @@ -143,6 +145,7 @@ "regionalGeoBlocking": true, "routingName": "x routing", "tenantId": 2, + "type": "HTTP", "xmlId": "test ds1" }, "status": "draft" @@ -163,6 +166,7 @@ "regionalGeoBlocking": true, "routingName": "goodroute", "tenantId": 2, + "type": "HTTP", "xmlId": "test-transitions" }, "status": "draft" ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services