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 e890c04 Validating pattern for POST regex call in DS (#5017)
e890c04 is described below
commit e890c0473767f562becd3668cc14911d0ade0e83
Author: rimashah25 <[email protected]>
AuthorDate: Fri Sep 18 13:47:29 2020 -0600
Validating pattern for POST regex call in DS (#5017)
* Validating pattern for POST regex call in DS
* Added test case to validate pattern for DS regex
* Updated Changelog
* Combined DS regex validation functions
* Combined DS regex validation functions-1
* Added test case for v3-client
* Resolved conflict in CHANGELOG.md
* Added v2-client test case and updated unit test.
* Fixed unit test.
* Removed fmt statement.
* Updated per review comments.
---
CHANGELOG.md | 1 +
.../testing/api/v2/deliveryservicesregexes_test.go | 30 ++++++++-
traffic_ops/testing/api/v2/tc-fixtures.json | 6 ++
.../testing/api/v3/deliveryservicesregexes_test.go | 32 +++++++++-
traffic_ops/testing/api/v3/tc-fixtures.json | 6 ++
.../deliveryservicesregexes.go | 45 +++++++------
.../deliveryservicesregexes_test.go | 73 ++++++++++++++--------
traffic_ops/v2-client/deliveryservice_regexes.go | 21 +++++++
traffic_ops/v3-client/deliveryservice_regexes.go | 25 ++++++++
9 files changed, 186 insertions(+), 53 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d019414..bf1f94e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -46,6 +46,7 @@ The format is based on [Keep a
Changelog](http://keepachangelog.com/en/1.0.0/).
### Fixed
- Fixed Reference urls for Cache Config on Delivery service pages (HTTP, DNS)
in Traffic Portal.
+- Fixed #4981 - Cannot create routing regular expression with a blank pattern
param in Delivery Service [Related github
issues](https://github.com/apache/trafficcontrol/issues/4981)
- Fixed #4979 - Returns a Bad Request error during server creation with
missing profileId [Related github
issue](https://github.com/apache/trafficcontrol/issues/4979)
- Fixed #3400 - Allow "0" as a TTL value for Static DNS entries
- Fixed #4743 - Validate absolute DNS name requirement on Static DNS entry for
CNAME type [Related github
issue](https://github.com/apache/trafficcontrol/issues/4743)
diff --git a/traffic_ops/testing/api/v2/deliveryservicesregexes_test.go
b/traffic_ops/testing/api/v2/deliveryservicesregexes_test.go
index d074043..c123bbf 100644
--- a/traffic_ops/testing/api/v2/deliveryservicesregexes_test.go
+++ b/traffic_ops/testing/api/v2/deliveryservicesregexes_test.go
@@ -26,6 +26,7 @@ import (
func TestDeliveryServicesRegexes(t *testing.T) {
WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles,
Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers,
DeliveryServices, DeliveryServicesRegexes}, func() {
QueryDSRegexTest(t)
+ CreateTestDSRegexWithMissingPattern(t)
})
}
@@ -93,6 +94,31 @@ func DeleteTestDeliveryServicesRegexes(t *testing.T) {
}
}
+func CreateTestDSRegexWithMissingPattern(t *testing.T) {
+ var regex = testData.DeliveryServicesRegexes[3]
+ ds, _, err := TOSession.GetDeliveryServiceByXMLIDNullable(regex.DSName)
+ if err != nil {
+ t.Fatalf("unable to get ds %v: %v", regex.DSName, err)
+ }
+ if len(ds) == 0 {
+ t.Fatalf("unable to get ds %v", regex.DSName)
+ }
+
+ var dsID int
+ if ds[0].ID == nil {
+ t.Fatal("ds has a nil id")
+ } else {
+ dsID = *ds[0].ID
+ }
+
+ regexPost := tc.DeliveryServiceRegexPost{Type: regex.Type, SetNumber:
regex.SetNumber, Pattern: regex.Pattern}
+
+ _, _, err = TOSession.PostDeliveryServiceRegexesByDSID(dsID, regexPost)
+ if err == nil {
+ t.Fatalf("Expected: 400 Bad Request but got: %v", err)
+ }
+}
+
func loadDSRegexIDs(t *testing.T, test *tc.DeliveryServiceRegexesTest) {
dsTypes, _, err := TOSession.GetTypeByName(test.TypeName)
if err != nil {
@@ -132,8 +158,8 @@ func QueryDSRegexTest(t *testing.T) {
if err != nil {
t.Fatal("unable to get ds_regex by id " + strconv.Itoa(dsID))
}
- if len(dsRegexes) != 3 {
- t.Fatal("expected to get 3 ds_regex, got " +
strconv.Itoa(len(dsRegexes)))
+ if len(dsRegexes) != 4 {
+ t.Fatal("expected to get 4 ds_regex, got " +
strconv.Itoa(len(dsRegexes)))
}
params := make(map[string]string)
diff --git a/traffic_ops/testing/api/v2/tc-fixtures.json
b/traffic_ops/testing/api/v2/tc-fixtures.json
index a30a338..4856985 100644
--- a/traffic_ops/testing/api/v2/tc-fixtures.json
+++ b/traffic_ops/testing/api/v2/tc-fixtures.json
@@ -717,6 +717,12 @@
"typeName": "HOST_REGEXP",
"setNumber": 1,
"pattern" : ".*"
+ },
+ {
+ "dsName": "ds1",
+ "typeName": "HOST_REGEXP",
+ "setNumber": 3,
+ "pattern" : ""
}
],
"deliveryservicesRequiredCapabilities": [
diff --git a/traffic_ops/testing/api/v3/deliveryservicesregexes_test.go
b/traffic_ops/testing/api/v3/deliveryservicesregexes_test.go
index fc58337..02c0ecd 100644
--- a/traffic_ops/testing/api/v3/deliveryservicesregexes_test.go
+++ b/traffic_ops/testing/api/v3/deliveryservicesregexes_test.go
@@ -17,12 +17,12 @@ package v3
import (
"fmt"
- "github.com/apache/trafficcontrol/lib/go-rfc"
"net/http"
"strconv"
"testing"
"time"
+ "github.com/apache/trafficcontrol/lib/go-rfc"
"github.com/apache/trafficcontrol/lib/go-tc"
)
@@ -30,6 +30,7 @@ func TestDeliveryServicesRegexes(t *testing.T) {
WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles,
Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies,
DeliveryServices, DeliveryServicesRegexes}, func() {
QueryDSRegexTest(t)
QueryDSRegexTestIMS(t)
+ CreateTestDSRegexWithMissingPattern(t)
})
}
@@ -97,6 +98,31 @@ func DeleteTestDeliveryServicesRegexes(t *testing.T) {
}
}
+func CreateTestDSRegexWithMissingPattern(t *testing.T) {
+ var regex = testData.DeliveryServicesRegexes[3]
+ ds, _, err :=
TOSession.GetDeliveryServiceByXMLIDNullableWithHdr(regex.DSName, nil)
+ if err != nil {
+ t.Fatalf("unable to get ds %v: %v", regex.DSName, err)
+ }
+ if len(ds) == 0 {
+ t.Fatalf("unable to get ds %v", regex.DSName)
+ }
+
+ var dsID int
+ if ds[0].ID == nil {
+ t.Fatal("ds has a nil id")
+ } else {
+ dsID = *ds[0].ID
+ }
+
+ regexPost := tc.DeliveryServiceRegexPost{Type: regex.Type, SetNumber:
regex.SetNumber, Pattern: regex.Pattern}
+
+ _, reqInfo, _ := TOSession.PostDeliveryServiceRegexesByDSID(dsID,
regexPost)
+ if reqInfo.StatusCode != http.StatusBadRequest {
+ t.Errorf("Expected: %v, but got: %v", http.StatusBadRequest,
reqInfo.StatusCode)
+ }
+}
+
func loadDSRegexIDs(t *testing.T, test *tc.DeliveryServiceRegexesTest) {
dsTypes, _, err := TOSession.GetTypeByName(test.TypeName)
if err != nil {
@@ -151,8 +177,8 @@ func QueryDSRegexTest(t *testing.T) {
if err != nil {
t.Fatal("unable to get ds_regex by id " + strconv.Itoa(dsID))
}
- if len(dsRegexes) != 3 {
- t.Fatal("expected to get 3 ds_regex, got " +
strconv.Itoa(len(dsRegexes)))
+ if len(dsRegexes) != 4 {
+ t.Fatal("expected to get 4 ds_regex, got " +
strconv.Itoa(len(dsRegexes)))
}
params := make(map[string]string)
diff --git a/traffic_ops/testing/api/v3/tc-fixtures.json
b/traffic_ops/testing/api/v3/tc-fixtures.json
index ce5b78c..ad28c14 100644
--- a/traffic_ops/testing/api/v3/tc-fixtures.json
+++ b/traffic_ops/testing/api/v3/tc-fixtures.json
@@ -932,6 +932,12 @@
"typeName": "HOST_REGEXP",
"setNumber": 1,
"pattern" : ".*"
+ },
+ {
+ "dsName": "ds1",
+ "typeName": "HOST_REGEXP",
+ "setNumber": 3,
+ "pattern" : ""
}
],
"deliveryservicesRequiredCapabilities": [
diff --git
a/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes.go
b/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes.go
index 75fbb65..a441aa0 100644
---
a/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes.go
+++
b/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes.go
@@ -28,10 +28,12 @@ import (
"strconv"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
"github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
+ validation "github.com/go-ozzo/ozzo-validation"
"github.com/lib/pq"
)
@@ -221,12 +223,7 @@ func Post(w http.ResponseWriter, r *http.Request) {
return
}
- if err := validateDSRegexType(tx, dsr.Type); err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil)
- return
- }
-
- if err := validateDSRegexOrder(tx, inf.IntParams["dsid"],
dsr.SetNumber); err != nil {
+ if err := validateDSRegex(tx, dsr, inf.IntParams["dsid"]); err != nil {
api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil)
return
}
@@ -303,12 +300,7 @@ func Put(w http.ResponseWriter, r *http.Request) {
return
}
- if err := validateDSRegexOrder(tx, inf.IntParams["dsid"],
dsr.SetNumber); err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil)
- return
- }
-
- if err := validateDSRegexType(tx, dsr.Type); err != nil {
+ if err := validateDSRegex(tx, dsr, inf.IntParams["dsid"]); err != nil {
api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil)
return
}
@@ -337,24 +329,31 @@ func Put(w http.ResponseWriter, r *http.Request) {
api.WriteRespAlertObj(w, r, tc.SuccessLevel, "Delivery service regex
creation was successful.", respObj)
}
-func validateDSRegexType(tx *sql.Tx, typeID int) error {
- _, err := tc.ValidateTypeID(tx, &typeID, "regex")
- return err
-}
-
-func validateDSRegexOrder(tx *sql.Tx, dsID int, order int) error {
+// Validate POST/PUT regex struct
+func validateDSRegex(tx *sql.Tx, dsr tc.DeliveryServiceRegexPost, dsID int)
error {
var ds int
- if order < 0 {
+ var setNumberErr error
+ if dsr.SetNumber < 0 {
return errors.New("cannot add regex with order < 0")
}
err := tx.QueryRow(`
-select deliveryservice from deliveryservice_regex
+select deliveryservice from deliveryservice_regex
where deliveryservice = $1 and set_number = $2`,
- dsID, order).Scan(&ds)
+ dsID, dsr.SetNumber).Scan(&ds)
if err == nil {
- return errors.New("cannot add regex, another regex with the
same order exists")
+ setNumberErr = errors.New("cannot add regex, another regex with
the same order exists")
+ } else {
+ setNumberErr = nil
}
- return nil
+
+ _, typeErr := tc.ValidateTypeID(tx, &dsr.Type, "regex")
+
+ errs := validation.Errors{
+ "type": typeErr,
+ "setNumber": setNumberErr,
+ "pattern": validation.Validate(dsr.Pattern,
validation.Required)}
+
+ return util.JoinErrs(tovalidate.ToErrors(errs))
}
func Delete(w http.ResponseWriter, r *http.Request) {
diff --git
a/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes_test.go
b/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes_test.go
index 2a9bf5e..11e8f6b 100644
---
a/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes_test.go
+++
b/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes_test.go
@@ -1,11 +1,5 @@
package deliveryservicesregexes
-import (
- "github.com/jmoiron/sqlx"
- "gopkg.in/DATA-DOG/go-sqlmock.v1"
- "testing"
-)
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -25,42 +19,71 @@ import (
* under the License.
*/
-func TestValidateDSRegexOrder(t *testing.T) {
- expected := `cannot add regex, another regex with the same order exists`
+import (
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/jmoiron/sqlx"
+ "gopkg.in/DATA-DOG/go-sqlmock.v1"
+ "testing"
+)
+
+func TestValidateDSRegexOrderExisting(t *testing.T) {
+ expected := `'setNumber' cannot add regex, another regex with the same
order exists`
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub
database connection", err)
}
defer mockDB.Close()
-
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
- cols := []string{"deliveryservice"}
+ cols := []string{"name", "use_in_table"}
rows := sqlmock.NewRows(cols)
rows = rows.AddRow(
+ "HTTP",
+ "regex",
+ )
+ cols2 := []string{"deliveryservice"}
+ rows2 := sqlmock.NewRows(cols2)
+ rows2 = rows2.AddRow(
1,
)
+
+ regex := tc.DeliveryServiceRegexPost{Type: 33, SetNumber: 3, Pattern:
".*"}
mock.ExpectBegin()
- mock.ExpectQuery("select").WithArgs(1, 3).WillReturnRows(rows)
+ mock.ExpectQuery("select").WithArgs(1,
regex.SetNumber).WillReturnRows(rows2)
+ mock.ExpectQuery("SELECT").WithArgs(regex.Type).WillReturnRows(rows)
+ mock.ExpectCommit()
tx := db.MustBegin().Tx
- err = validateDSRegexOrder(tx, 1, 3)
+ err = validateDSRegex(tx, regex, 1)
if err == nil {
- t.Fatal("Expected error but got nil")
+ t.Fatalf("Expected error '%v' but got none", expected)
}
- if err.Error() != expected {
- t.Fatalf("Expected error was %v, got %v", expected, err.Error())
+}
+
+func TestValidateDSRegex(t *testing.T) {
+ mockDB, mock, err := sqlmock.New()
+ if err != nil {
+ t.Fatalf("an error '%s' was not expected when opening a stub
database connection", err)
}
- mock.ExpectQuery("select").WithArgs(1, 4).WillReturnRows(nil)
+ defer mockDB.Close()
+ db := sqlx.NewDb(mockDB, "sqlmock")
+ defer db.Close()
+ cols := []string{"name", "use_in_table"}
+ rows := sqlmock.NewRows(cols)
+ rows = rows.AddRow(
+ "HTTP",
+ "regex",
+ )
+ cols2 := []string{"deliveryservice"}
+ rows2 := sqlmock.NewRows(cols2)
+
+ regex := tc.DeliveryServiceRegexPost{Type: 33, SetNumber: 3, Pattern:
".*"}
+ mock.ExpectBegin()
+ mock.ExpectQuery("select").WithArgs(1,
regex.SetNumber).WillReturnRows(rows2)
+ mock.ExpectQuery("SELECT").WithArgs(regex.Type).WillReturnRows(rows)
mock.ExpectCommit()
- err = validateDSRegexOrder(tx, 1, 3)
+ tx := db.MustBegin().Tx
+ err = validateDSRegex(tx, regex, 1)
if err != nil {
- t.Fatalf("Expect no error, got %v", err.Error())
- }
- err = validateDSRegexOrder(tx, 1, -1)
- if err == nil {
- t.Fatal("Expect error saying cannot add regex with order < 0,
got nothing")
- }
- if err.Error() != "cannot add regex with order < 0" {
- t.Errorf("Expected error detail to be 'cannot add regex with
order <0', got %v", err.Error())
+ t.Fatalf("Expected no error but got %v", err.Error())
}
}
diff --git a/traffic_ops/v2-client/deliveryservice_regexes.go
b/traffic_ops/v2-client/deliveryservice_regexes.go
index e2bbd70..85901e2 100644
--- a/traffic_ops/v2-client/deliveryservice_regexes.go
+++ b/traffic_ops/v2-client/deliveryservice_regexes.go
@@ -16,7 +16,10 @@
package client
import (
+ "encoding/json"
"fmt"
+ "net"
+ "net/http"
"github.com/apache/trafficcontrol/lib/go-tc"
)
@@ -39,3 +42,21 @@ func (to *Session) GetDeliveryServiceRegexesByDSID(dsID int,
params map[string]s
}
return response.Response, reqInf, nil
}
+
+func (to *Session) PostDeliveryServiceRegexesByDSID(dsID int, regex
tc.DeliveryServiceRegexPost) (tc.Alerts, ReqInf, error) {
+ var alerts tc.Alerts
+ var remoteAddr net.Addr
+ reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr:
remoteAddr}
+ reqBody, err := json.Marshal(regex)
+ if err != nil {
+ return alerts, reqInf, err
+ }
+
+ _, remoteAddr, err = to.request(http.MethodPost,
fmt.Sprintf(API_DS_REGEXES, dsID), reqBody)
+ reqInf.RemoteAddr = remoteAddr
+ if err != nil {
+ return alerts, reqInf, err
+ }
+
+ return alerts, reqInf, nil
+}
diff --git a/traffic_ops/v3-client/deliveryservice_regexes.go
b/traffic_ops/v3-client/deliveryservice_regexes.go
index d9dbd42..3e412df 100644
--- a/traffic_ops/v3-client/deliveryservice_regexes.go
+++ b/traffic_ops/v3-client/deliveryservice_regexes.go
@@ -16,7 +16,10 @@
package client
import (
+ "encoding/json"
"fmt"
+ "net"
+ "net/http"
"github.com/apache/trafficcontrol/lib/go-tc"
)
@@ -39,3 +42,25 @@ func (to *Session) GetDeliveryServiceRegexesByDSID(dsID int,
params map[string]s
}
return response.Response, reqInf, nil
}
+
+func (to *Session) PostDeliveryServiceRegexesByDSID(dsID int, regex
tc.DeliveryServiceRegexPost) (tc.Alerts, ReqInf, error) {
+ var alerts tc.Alerts
+ var remoteAddr net.Addr
+ reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr:
remoteAddr}
+ reqBody, err := json.Marshal(regex)
+ if err != nil {
+ return alerts, reqInf, err
+ }
+
+ resp, remoteAddr, err := to.request(http.MethodPost,
fmt.Sprintf(API_DS_REGEXES, dsID), reqBody, nil)
+ reqInf.RemoteAddr = remoteAddr
+ if resp != nil {
+ reqInf.StatusCode = resp.StatusCode
+ }
+ if err != nil {
+ return alerts, reqInf, err
+ }
+ defer resp.Body.Close()
+
+ return alerts, reqInf, nil
+}