You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by mi...@apache.org on 2020/08/14 20:52:04 UTC
[trafficcontrol] branch master updated: Prevents DS regexes with
non-consecutive order from generating invalid CRconfig/Snapshot (#4910)
This is an automated email from the ASF dual-hosted git repository.
mitchell852 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 43c098b Prevents DS regexes with non-consecutive order from generating invalid CRconfig/Snapshot (#4910)
43c098b is described below
commit 43c098b3128e20668ba443d36ed09a33adb76f4c
Author: Srijeet Chatterjee <30...@users.noreply.github.com>
AuthorDate: Fri Aug 14 14:51:51 2020 -0600
Prevents DS regexes with non-consecutive order from generating invalid CRconfig/Snapshot (#4910)
* Making sure we have only one regex per order, and the missing orders dont show up as nulls
* go fmt
* Code review fixes
* changelog entry
* Add comment
* formatting
---
CHANGELOG.md | 1 +
.../traffic_ops_golang/crconfig/deliveryservice.go | 20 ++++---
traffic_ops/traffic_ops_golang/crconfig/handler.go | 1 -
.../deliveryservicesregexes.go | 25 ++++++++
.../deliveryservicesregexes_test.go | 66 ++++++++++++++++++++++
5 files changed, 105 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eaf25ca..78d6d1b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -55,6 +55,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Fixed ORT atstccfg helper log to append and not overwrite old logs. Also changed to log to /var/log/ort and added a logrotate to the RPM. See the ORT README.md for details.
- Added Delivery Service Raw Remap `__RANGE_DIRECTIVE__` directive to allow inserting the Range Directive after the Raw Remap text. This allows Raw Remaps which manipulate the Range.
- Added an option for `coordinateRange` in the RGB configuration file, so that in case a client doesn't have a postal code, we can still determine if it should be allowed or not, based on whether or not the latitude/ longitude of the client falls within the supplied ranges. [Related github issue](https://github.com/apache/trafficcontrol/issues/4372)
+- Fixed #3548 - Prevents DS regexes with non-consecutive order from generating invalid CRconfig/snapshot.
### Changed
- Changed some Traffic Ops Go Client methods to use `DeliveryServiceNullable` inputs and outputs.
diff --git a/traffic_ops/traffic_ops_golang/crconfig/deliveryservice.go b/traffic_ops/traffic_ops_golang/crconfig/deliveryservice.go
index 96fd277..028ee7e 100644
--- a/traffic_ops/traffic_ops_golang/crconfig/deliveryservice.go
+++ b/traffic_ops/traffic_ops_golang/crconfig/deliveryservice.go
@@ -481,6 +481,8 @@ order by dr.set_number asc
return nil, nil, errors.New("querying deliveryservices: " + err.Error())
}
defer rows.Close()
+ // a map to keep track of the ds name and the last order of the regex for that ds
+ dsNameOrderMap := make(map[string]int)
for rows.Next() {
pattern := ""
@@ -491,12 +493,14 @@ order by dr.set_number asc
if err := rows.Scan(&pattern, &ttype, &dstype, &setnum, &dsname); err != nil {
return nil, nil, errors.New("scanning deliveryservice regexes: " + err.Error())
}
-
+ if _, ok := dsNameOrderMap[dsname]; !ok {
+ dsNameOrderMap[dsname] = 0
+ } else {
+ dsNameOrderMap[dsname] = dsNameOrderMap[dsname] + 1
+ }
protocolStr := getProtocolStr(dstype)
- for len(dsmatchsets[dsname]) <= setnum {
- dsmatchsets[dsname] = append(dsmatchsets[dsname], nil) // TODO change to not insert empties? Current behavior emulates old Perl CRConfig
- }
+ dsmatchsets[dsname] = append(dsmatchsets[dsname], nil)
matchType := ""
switch ttype {
@@ -511,10 +515,12 @@ order by dr.set_number asc
continue
}
- if dsmatchsets[dsname][setnum] == nil {
- dsmatchsets[dsname][setnum] = &tc.MatchSet{}
+ // If there are gaps between two or more DS regex orders, do not add these missing orders in the final list.
+ // Instead, skip over them and add the next regex with a valid order.
+ if dsmatchsets[dsname][dsNameOrderMap[dsname]] == nil {
+ dsmatchsets[dsname][dsNameOrderMap[dsname]] = &tc.MatchSet{}
}
- matchset := dsmatchsets[dsname][setnum]
+ matchset := dsmatchsets[dsname][dsNameOrderMap[dsname]]
matchset.Protocol = protocolStr
matchset.MatchList = append(matchset.MatchList, tc.MatchList{MatchType: matchType, Regex: pattern})
diff --git a/traffic_ops/traffic_ops_golang/crconfig/handler.go b/traffic_ops/traffic_ops_golang/crconfig/handler.go
index 327edf7..21da66e 100644
--- a/traffic_ops/traffic_ops_golang/crconfig/handler.go
+++ b/traffic_ops/traffic_ops_golang/crconfig/handler.go
@@ -219,7 +219,6 @@ func snapshotHandler(w http.ResponseWriter, r *http.Request, deprecated bool) {
api.HandleErrOptionalDeprecation(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err, deprecated, &alt)
return
}
-
monitoringJSON, err := monitoring.GetMonitoringJSON(inf.Tx.Tx, cdn)
if err != nil {
api.HandleErrOptionalDeprecation(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New(r.RemoteAddr+" getting monitoring.json data: "+err.Error()), deprecated, &alt)
diff --git a/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes.go b/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes.go
index 0f4952c..75fbb65 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes.go
@@ -226,6 +226,11 @@ func Post(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
+ }
+
regexID := 0
if err := tx.QueryRow(`INSERT INTO regex (pattern, type) VALUES ($1, $2) RETURNING id`, dsr.Pattern, dsr.Type).Scan(®exID); err != nil {
api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("inserting deliveryserviceregex regex: "+err.Error()))
@@ -298,6 +303,11 @@ 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 {
api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil)
return
@@ -332,6 +342,21 @@ func validateDSRegexType(tx *sql.Tx, typeID int) error {
return err
}
+func validateDSRegexOrder(tx *sql.Tx, dsID int, order int) error {
+ var ds int
+ if order < 0 {
+ return errors.New("cannot add regex with order < 0")
+ }
+ err := tx.QueryRow(`
+select deliveryservice from deliveryservice_regex
+where deliveryservice = $1 and set_number = $2`,
+ dsID, order).Scan(&ds)
+ if err == nil {
+ return errors.New("cannot add regex, another regex with the same order exists")
+ }
+ return nil
+}
+
func Delete(w http.ResponseWriter, r *http.Request) {
inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"dsid", "regexid"}, []string{"dsid", "regexid"})
if userErr != nil || sysErr != nil {
diff --git a/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes_test.go b/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes_test.go
new file mode 100644
index 0000000..2a9bf5e
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/deliveryservicesregexes/deliveryservicesregexes_test.go
@@ -0,0 +1,66 @@
+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
+ * 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.
+ */
+
+func TestValidateDSRegexOrder(t *testing.T) {
+ expected := `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"}
+ rows := sqlmock.NewRows(cols)
+ rows = rows.AddRow(
+ 1,
+ )
+ mock.ExpectBegin()
+ mock.ExpectQuery("select").WithArgs(1, 3).WillReturnRows(rows)
+ tx := db.MustBegin().Tx
+ err = validateDSRegexOrder(tx, 1, 3)
+ if err == nil {
+ t.Fatal("Expected error but got nil")
+ }
+ if err.Error() != expected {
+ t.Fatalf("Expected error was %v, got %v", expected, err.Error())
+ }
+ mock.ExpectQuery("select").WithArgs(1, 4).WillReturnRows(nil)
+ mock.ExpectCommit()
+ err = validateDSRegexOrder(tx, 1, 3)
+ 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())
+ }
+}