This is an automated email from the ASF dual-hosted git repository.
ocket8888 pushed a commit to branch 5.1.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/5.1.x by this push:
new 9455a88 Fix servers?dsID=<> route to return mids correctly (#5538)
(#5588)
9455a88 is described below
commit 9455a882b68a4f5c434e971cce71330f40c16f8a
Author: ocket8888 <[email protected]>
AuthorDate: Fri Feb 26 17:04:41 2021 -0500
Fix servers?dsID=<> route to return mids correctly (#5538) (#5588)
* fix servers?dsID=<> route to return mids correctly
* code review fixes
* code review fixes
(cherry picked from commit f0130ff48caa3dc07dbf4350193a39308759afd0)
Co-authored-by: Srijeet Chatterjee
<[email protected]>
---
.../testing/api/v3/serverservercapability_test.go | 96 +++++++++++
traffic_ops/testing/api/v3/tc-fixtures.json | 192 +++++++++++++++++++++
traffic_ops/traffic_ops_golang/server/servers.go | 80 +++++++--
.../traffic_ops_golang/server/servers_test.go | 2 +-
4 files changed, 353 insertions(+), 17 deletions(-)
diff --git a/traffic_ops/testing/api/v3/serverservercapability_test.go
b/traffic_ops/testing/api/v3/serverservercapability_test.go
index eb5903e..f971f0d 100644
--- a/traffic_ops/testing/api/v3/serverservercapability_test.go
+++ b/traffic_ops/testing/api/v3/serverservercapability_test.go
@@ -19,6 +19,7 @@ import (
"net/http"
"net/url"
"sort"
+ "strconv"
"testing"
"time"
@@ -32,6 +33,7 @@ func TestServerServerCapabilities(t *testing.T) {
SortTestServerServerCapabilities(t)
GetTestServerServerCapabilitiesIMS(t)
GetTestServerServerCapabilities(t)
+ GetDeliveryServiceServersWithCapabilities(t)
})
}
@@ -385,3 +387,97 @@ func DeleteTestServerServerCapabilitiesForTopologies(t
*testing.T) {
}
}
+
+func GetDeliveryServiceServersWithCapabilities(t *testing.T) {
+ dses, _, err := TOSession.GetDeliveryServicesV30WithHdr(nil,
url.Values{"xmlId": []string{"ds4"}})
+ if err != nil {
+ t.Fatalf("Failed to get Delivery Services: %v", err)
+ }
+ if len(dses) < 1 {
+ t.Fatal("Failed to get at least one Delivery Service")
+ }
+
+ ds := dses[0]
+ if ds.ID == nil {
+ t.Fatal("Got Delivery Service with nil ID")
+ }
+
+ // Get an edge
+ params := url.Values{}
+ params.Add("hostName", "atlanta-edge-16")
+ rs, _, err := TOSession.GetServersWithHdr(¶ms, nil)
+ if err != nil {
+ t.Fatalf("Failed to fetch server information: %v", err)
+ } else if len(rs.Response) == 0 {
+ t.Fatalf("Failed to fetch server information: No results
returned!")
+ }
+ edgeID := *rs.Response[0].ID
+
+ // Get a MID
+ params = url.Values{}
+ params.Add("hostName", "atlanta-mid-02")
+ rs, _, err = TOSession.GetServersWithHdr(¶ms, nil)
+ if err != nil {
+ t.Fatalf("Failed to fetch server information: %v", err)
+ } else if len(rs.Response) == 0 {
+ t.Fatalf("Failed to fetch server information: No results
returned!")
+ }
+ midID := *rs.Response[0].ID
+ // assign edge and mid
+ _, _, err = TOSession.CreateDeliveryServiceServers(*ds.ID,
[]int{edgeID, midID}, true)
+ if err != nil {
+ t.Fatalf("expected no error while assigning servers to DS, but
got %s", err.Error())
+ }
+ params = url.Values{}
+ params.Add("dsId", strconv.Itoa(*ds.ID))
+ servers, _, err := TOSession.GetServersWithHdr(¶ms, nil)
+ if err != nil {
+ t.Fatalf("Failed to get server by Delivery Service ID: %v", err)
+ }
+ if len(servers.Response) != 2 {
+ t.Fatalf("expected to get 2 servers for Delivery Service: %d,
actual: %d", *ds.ID, len(servers.Response))
+ }
+
+ // now assign a capability
+ reqCap := tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: ds.ID,
+ RequiredCapability: util.StrPtr("blah"),
+ }
+ _, _, err = TOSession.CreateDeliveryServicesRequiredCapability(reqCap)
+ // this should fail because the mid doesn't have the reqd capability
+ if err == nil {
+ t.Fatalf("expected error creating DS reqd capability, but got
nothing")
+ }
+ ssc := tc.ServerServerCapability{
+ ServerID: &midID,
+ ServerCapability: util.StrPtr("blah"),
+ }
+ // assign the capability to the mid
+ _, _, err = TOSession.CreateServerServerCapability(ssc)
+ if err != nil {
+ t.Fatalf("couldn't assign server capability to server with ID
%d, err: %s", midID, err.Error())
+ }
+ _, _, err = TOSession.CreateDeliveryServicesRequiredCapability(reqCap)
+ // this should pass now because the mid has the reqd capability
+ if err != nil {
+ t.Fatalf("expected no error creating DS reqd capability, but
got %s", err.Error())
+ }
+
+ params = url.Values{}
+ params.Add("dsId", strconv.Itoa(*ds.ID))
+ servers, _, err = TOSession.GetServersWithHdr(¶ms, nil)
+ if err != nil {
+ t.Fatalf("Failed to get server by Delivery Service ID: %v", err)
+ }
+ if len(servers.Response) != 2 {
+ t.Fatalf("expected to get 2 servers for Delivery Service: %d,
actual: %d", *ds.ID, len(servers.Response))
+ }
+ _, _, err = TOSession.DeleteDeliveryServiceServer(*ds.ID, edgeID)
+ if err != nil {
+ t.Errorf("error trying to delete delivery service server: %s",
err.Error())
+ }
+ _, _, err = TOSession.DeleteDeliveryServiceServer(*ds.ID, midID)
+ if err != nil {
+ t.Errorf("error trying to delete delivery service server: %s",
err.Error())
+ }
+}
diff --git a/traffic_ops/testing/api/v3/tc-fixtures.json
b/traffic_ops/testing/api/v3/tc-fixtures.json
index 03ce021..bb24c57 100644
--- a/traffic_ops/testing/api/v3/tc-fixtures.json
+++ b/traffic_ops/testing/api/v3/tc-fixtures.json
@@ -41,6 +41,13 @@
{
"latitude": 0,
"longitude": 0,
+ "name": "parentCachegroup3",
+ "shortName": "pg3",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
"name": "secondaryCachegroup",
"shortName": "sg1",
"typeName": "MID_LOC"
@@ -118,6 +125,19 @@
{
"latitude": 0,
"longitude": 0,
+ "name": "cachegroup4",
+ "parentCachegroupName": "parentCachegroup3",
+ "shortName": "cg4",
+ "localizationMethods": [
+ "CZ",
+ "DEEP_CZ",
+ "GEO"
+ ],
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
"name": "cachegroup3",
"parentCachegroupName": "parentCachegroup",
"secondaryParentCachegroupName": "secondaryCachegroup",
@@ -1437,6 +1457,75 @@
"type": "HTTP",
"xmlId": "test-ds-server-assignments",
"maxRequestHeaderBytes": 131072
+ },
+ {
+ "active": false,
+ "cdnName": "cdn1",
+ "cacheurl": "cacheUrl3",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": null,
+ "deepCachingType": "NEVER",
+ "displayName": "d s 4",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": "edgeRewrite1\nedgeHeader2",
+ "exampleURLs": [
+ "http://ccr.ds4.example.net",
+ "https://ccr.ds4x.example.net"
+ ],
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "d s 4",
+ "longDesc1": "ds4",
+ "longDesc2": "ds4",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds4\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "maxOriginConnections": 0,
+ "midHeaderRewrite": "midHeader1\nmidHeader2",
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://origin.ds4.example.net",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": "rr1\nrr2",
+ "regionalGeoBlocking": false,
+ "remapText": "@plugin=tslua.so
@pparam=/opt/trafficserver/etc/trafficserver/ds4plugin.lua",
+ "routingName": "ccr-ds4",
+ "signed": false,
+ "signingAlgorithm": "url_sig",
+ "sslKeyVersion": 2,
+ "tenant": "tenant3",
+ "tenantName": "tenant3",
+ "type": "HTTP_LIVE",
+ "xmlId": "ds4",
+ "anonymousBlockingEnabled": true,
+ "maxRequestHeaderBytes": 131072
}
],
"deliveryServicesRegexes": [
@@ -4420,6 +4509,102 @@
"tcpPort": 80,
"type": "EDGE",
"updPending": false
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-edge-16",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.1.0.21/30",
+ "gateway": "127.1.0.21",
+ "serviceAddress": true
+ },
+ {
+ "address": "2346:1234:12:8::1/64",
+ "gateway": "2346:1234:12:8::1",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "atlanta-edge-16\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "parentCachegroup3",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-mid-02",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.1.0.2/30",
+ "gateway": "127.1.0.2",
+ "serviceAddress": true
+ },
+ {
+ "address": "2346:1234:12:9::10/64",
+ "gateway": "2346:1234:12:9::10",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "MID1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false,
+ "xmppId": "atlanta-mid-02\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
}
],
"serverCapabilities": [
@@ -4437,6 +4622,9 @@
},
{
"name": "asdf"
+ },
+ {
+ "name": "blah"
}
],
"serverServerCapabilities": [
@@ -4511,6 +4699,10 @@
{
"serverHostName": "dtrc-mid-04",
"serverCapability": "asdf"
+ },
+ {
+ "serverHostName": "atlanta-edge-16",
+ "serverCapability": "blah"
}
],
"serviceCategories": [
diff --git a/traffic_ops/traffic_ops_golang/server/servers.go
b/traffic_ops/traffic_ops_golang/server/servers.go
index 3094cf1..abcbdce 100644
--- a/traffic_ops/traffic_ops_golang/server/servers.go
+++ b/traffic_ops/traffic_ops_golang/server/servers.go
@@ -153,6 +153,22 @@ SELECT
s.status_last_updated
` + serversFromAndJoin
+const selectIDQuery = `
+SELECT
+ s.id
+` + serversFromAndJoin
+
+const midWhereClause = `
+WHERE t.name = :cache_type_mid AND s.cachegroup IN (
+ SELECT cg.parent_cachegroup_id FROM cachegroup AS cg
+ WHERE cg.id IN (
+ SELECT s.cachegroup FROM server AS s
+ WHERE s.id = ANY(:edge_ids)))
+ AND (SELECT d.topology
+ FROM deliveryservice d
+ WHERE d.id = :ds_id) IS NULL
+`
+
const insertQueryV3 = `
INSERT INTO server (
cachegroup,
@@ -400,9 +416,9 @@ RETURNING
`
const originServerQuery = `
-JOIN deliveryservice_server dsorg
-ON dsorg.server = s.id
-WHERE t.name = '` + tc.OriginTypeName + `'
+JOIN deliveryservice_server dsorg
+ON dsorg.server = s.id
+WHERE t.name = '` + tc.OriginTypeName + `'
AND dsorg.deliveryservice=:dsId
`
const deleteServerQuery = `DELETE FROM server WHERE id=$1`
@@ -937,10 +953,11 @@ func getServers(h http.Header, params map[string]string,
tx *sqlx.Tx, user *auth
// if ds requested uses mid-tier caches, add those to the list as well
if usesMids {
- midIDs, userErr, sysErr, errCode := getMidServers(ids, servers,
dsID, cdnID, tx)
+ midIDs, userErr, sysErr, errCode := getMidServers(ids, servers,
dsID, cdnID, tx, dsHasRequiredCapabilities)
log.Debugf("getting mids: %v, %v, %s\n", userErr, sysErr,
http.StatusText(errCode))
+ serverCount = serverCount + uint64(len(midIDs))
if userErr != nil || sysErr != nil {
return nil, serverCount, userErr, sysErr, errCode, nil
}
@@ -1028,7 +1045,7 @@ func getServers(h http.Header, params map[string]string,
tx *sqlx.Tx, user *auth
}
// getMidServers gets the mids used by the edges provided with an option to
filter for a given cdn
-func getMidServers(edgeIDs []int, servers map[int]tc.ServerNullable, dsID int,
cdnID int, tx *sqlx.Tx) ([]int, error, error, int) {
+func getMidServers(edgeIDs []int, servers map[int]tc.ServerNullable, dsID int,
cdnID int, tx *sqlx.Tx, includeCapabilities bool) ([]int, error, error, int) {
if len(edgeIDs) == 0 {
return nil, nil, nil, http.StatusOK
}
@@ -1039,17 +1056,48 @@ func getMidServers(edgeIDs []int, servers
map[int]tc.ServerNullable, dsID int, c
"ds_id": dsID,
}
- // TODO: include secondary parent?
- query := selectQuery + `
- WHERE t.name = :cache_type_mid AND s.cachegroup IN (
- SELECT cg.parent_cachegroup_id FROM cachegroup AS cg
- WHERE cg.id IN (
- SELECT s.cachegroup FROM server AS s
- WHERE s.id = ANY(:edge_ids)))
- AND (SELECT d.topology
- FROM deliveryservice d
- WHERE d.id = :ds_id) IS NULL
- `
+ midIDs := []int{}
+ query := ""
+ if includeCapabilities {
+ // Query to select the associated mids for this DS
+ q := selectIDQuery + midWhereClause
+ rows, err := tx.NamedQuery(q, filters)
+ if err != nil {
+ return nil, err, nil, http.StatusBadRequest
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ var midID int
+ if err := rows.Scan(&midID); err != nil {
+ log.Errorf("could not scan mid server id:
%s\n", err)
+ return nil, nil, err,
http.StatusInternalServerError
+ }
+ midIDs = append(midIDs, midID)
+ }
+ filters["mid_ids"] = pq.Array(midIDs)
+
+ // Query to select only those mids that match the required
capabilities of the DS
+ query = selectQuery + midWhereClause + `
+ AND s.id IN (
+ WITH capabilities AS (
+ SELECT ARRAY_AGG(ssc.server_capability), server
+ FROM server_server_capability ssc
+ WHERE ssc.server = ANY(:mid_ids)
+ GROUP BY server)
+ SELECT server
+ FROM capabilities WHERE
+ capabilities.array_agg
+ @>
+ (
+ SELECT ARRAY_AGG(drc.required_capability)
+ FROM deliveryservices_required_capability drc
+ WHERE drc.deliveryservice_id=:ds_id)
+ )`
+ } else {
+ // TODO: include secondary parent?
+ query = selectQuery + midWhereClause
+ }
if cdnID > 0 {
query += ` AND s.cdn_id = :cdn_id`
diff --git a/traffic_ops/traffic_ops_golang/server/servers_test.go
b/traffic_ops/traffic_ops_golang/server/servers_test.go
index ae7a55a..f8bf3fa 100644
--- a/traffic_ops/traffic_ops_golang/server/servers_test.go
+++ b/traffic_ops/traffic_ops_golang/server/servers_test.go
@@ -479,7 +479,7 @@ func TestGetMidServers(t *testing.T) {
mock.ExpectBegin()
mock.ExpectQuery("SELECT").WillReturnRows(rows2)
- mid, userErr, sysErr, errCode := getMidServers(serverIDs, serverMap, 0,
0, db.MustBegin())
+ mid, userErr, sysErr, errCode := getMidServers(serverIDs, serverMap, 0,
0, db.MustBegin(), false)
if userErr != nil || sysErr != nil {
t.Fatalf("getMidServers expected: no errors, actual: %v %v with
status: %s", userErr, sysErr, http.StatusText(errCode))