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

zrhoffman pushed a commit to branch 6.0.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit 2168aaac012c97b95c8f1c3315ba0a3492c73700
Author: Srijeet Chatterjee <[email protected]>
AuthorDate: Mon Oct 18 12:05:43 2021 -0500

    Fix /cdns/{name}/federations?id=# to search for CDN (#6287)
    
    * Fix /cdns/{name}/federations?id=# to search for CDN
    
    * fix tests
---
 CHANGELOG.md                                       |  3 +
 traffic_ops/testing/api/v2/cdnfederations_test.go  | 25 ++++--
 traffic_ops/testing/api/v2/federations_test.go     |  4 +-
 traffic_ops/testing/api/v2/tc-fixtures.json        | 12 ++-
 traffic_ops/testing/api/v3/cdnfederations_test.go  | 38 +++++----
 traffic_ops/testing/api/v3/federations_test.go     |  4 +-
 traffic_ops/testing/api/v3/tc-fixtures.json        | 12 ++-
 traffic_ops/testing/api/v4/cdnfederations_test.go  | 40 ++++++----
 traffic_ops/testing/api/v4/federations_test.go     |  4 +-
 traffic_ops/testing/api/v4/tc-fixtures.json        | 12 ++-
 .../cdnfederation/cdnfederations.go                | 89 +++++++++++++++++-----
 .../traffic_ops_golang/dbhelpers/db_helpers.go     | 11 +++
 12 files changed, 191 insertions(+), 63 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 65bedb4..61632ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this 
file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 
 ## [6.0.1] - 2021-11-04
+### Fixed
+- [#6125](https://github.com/apache/trafficcontrol/issues/6125) - Fix 
`/cdns/{name}/federations?id=#` to search for CDN.
+
 ### Changed
 - [#5927](https://github.com/apache/trafficcontrol/issues/5927) Updated 
CDN-in-a-Box to not run a Riak container by default but instead only run it if 
the optional flag is provided.
 
diff --git a/traffic_ops/testing/api/v2/cdnfederations_test.go 
b/traffic_ops/testing/api/v2/cdnfederations_test.go
index 0f0d50d..7e811ed 100644
--- a/traffic_ops/testing/api/v2/cdnfederations_test.go
+++ b/traffic_ops/testing/api/v2/cdnfederations_test.go
@@ -49,7 +49,7 @@ func CreateTestCDNFederations(t *testing.T) {
                        break
                }
 
-               data, _, err := TOSession.CreateCDNFederationByName(f, 
testData.CDNs[i].Name)
+               data, _, err := TOSession.CreateCDNFederationByName(f, "cdn1")
                if err != nil {
                        t.Errorf("could not POST federations: " + err.Error())
                }
@@ -61,6 +61,17 @@ func CreateTestCDNFederations(t *testing.T) {
                        t.Error("Federation id is nil after posting")
                } else {
                        fedIDs = append(fedIDs, *data.Response.ID)
+                       resp, _, err := 
TOSession.GetDeliveryServiceByXMLIDNullable("ds1")
+                       if err != nil {
+                               t.Errorf("could not get delivery service by xml 
ID: %v", err)
+                       }
+                       if len(resp) != 1 {
+                               t.Fatalf("expected one response for delivery 
service, but got %d", len(resp))
+                       }
+                       _, err = 
TOSession.CreateFederationDeliveryServices(*data.Response.ID, 
[]int{*resp[0].ID}, false)
+                       if err != nil {
+                               t.Errorf("could not create federation delivery 
service: %v", err)
+                       }
                }
        }
 }
@@ -68,21 +79,21 @@ func CreateTestCDNFederations(t *testing.T) {
 func UpdateTestCDNFederations(t *testing.T) {
 
        for _, id := range fedIDs {
-               fed, _, err := TOSession.GetCDNFederationsByID("foo", id)
+               fed, _, err := TOSession.GetCDNFederationsByID("cdn1", id)
                if err != nil {
                        t.Errorf("cannot GET federation by id: %v", err)
                }
 
                expectedCName := "new.cname."
                fed.Response[0].CName = &expectedCName
-               resp, _, err := 
TOSession.UpdateCDNFederationsByID(fed.Response[0], "foo", id)
+               resp, _, err := 
TOSession.UpdateCDNFederationsByID(fed.Response[0], "cdn1", id)
                if err != nil {
                        t.Errorf("cannot PUT federation by id: %v", err)
                }
                bytes, _ := json.Marshal(resp)
                t.Logf("PUT Response: %s\n", bytes)
 
-               resp2, _, err := TOSession.GetCDNFederationsByID("foo", id)
+               resp2, _, err := TOSession.GetCDNFederationsByID("cdn1", id)
                if err != nil {
                        t.Errorf("cannot GET federation by id after PUT: %v", 
err)
                }
@@ -106,7 +117,7 @@ func GetTestCDNFederations(t *testing.T) {
        // clean up fedIDs connection?)
 
        for _, id := range fedIDs {
-               data, _, err := TOSession.GetCDNFederationsByID("foo", id)
+               data, _, err := TOSession.GetCDNFederationsByID("cdn1", id)
                if err != nil {
                        t.Errorf("could not GET federations: " + err.Error())
                }
@@ -227,14 +238,14 @@ func GetTestFederationFederationResolvers(t *testing.T) {
 func DeleteTestCDNFederations(t *testing.T) {
 
        for _, id := range fedIDs {
-               resp, _, err := TOSession.DeleteCDNFederationByID("foo", id)
+               resp, _, err := TOSession.DeleteCDNFederationByID("cdn1", id)
                if err != nil {
                        t.Errorf("cannot DELETE federation by id: '%d' %v", id, 
err)
                }
                bytes, err := json.Marshal(resp)
                t.Logf("DELETE Response: %s\n", bytes)
 
-               data, _, err := TOSession.GetCDNFederationsByID("foo", id)
+               data, _, err := TOSession.GetCDNFederationsByID("cdn1", id)
                if len(data.Response) != 0 {
                        t.Error("expected federation to be deleted")
                }
diff --git a/traffic_ops/testing/api/v2/federations_test.go 
b/traffic_ops/testing/api/v2/federations_test.go
index 356eac5..8787805 100644
--- a/traffic_ops/testing/api/v2/federations_test.go
+++ b/traffic_ops/testing/api/v2/federations_test.go
@@ -42,8 +42,8 @@ func GetTestFederations(t *testing.T) {
                t.Errorf("getting federations: " + err.Error())
        }
 
-       if len(feds) != 1 {
-               t.Errorf("federations expected 1, actual: %+v", len(feds))
+       if len(feds) < 1 {
+               t.Errorf("expected atleast 1 federation, but got none")
        }
        fed := feds[0]
 
diff --git a/traffic_ops/testing/api/v2/tc-fixtures.json 
b/traffic_ops/testing/api/v2/tc-fixtures.json
index 59f090f..b7165e0 100644
--- a/traffic_ops/testing/api/v2/tc-fixtures.json
+++ b/traffic_ops/testing/api/v2/tc-fixtures.json
@@ -756,12 +756,20 @@
         {
             "cname": "the.cname.com.",
             "ttl": 48,
-            "description": "the description"
+            "description": "the description",
+            "deliveryService":
+            {
+                "xmlId": "ds1"
+            }
         },
         {
             "cname": "booya.com.",
             "ttl": 34,
-            "description": "fooya"
+            "description": "fooya",
+            "deliveryService":
+            {
+                "xmlId": "ds1"
+            }
         }
     ],
     "federation_resolvers": [
diff --git a/traffic_ops/testing/api/v3/cdnfederations_test.go 
b/traffic_ops/testing/api/v3/cdnfederations_test.go
index a240e1b..a920bc8 100644
--- a/traffic_ops/testing/api/v3/cdnfederations_test.go
+++ b/traffic_ops/testing/api/v3/cdnfederations_test.go
@@ -49,14 +49,14 @@ func TestCDNFederations(t *testing.T) {
 
 func UpdateTestCDNFederationsWithHeaders(t *testing.T, h http.Header) {
        for _, id := range fedIDs {
-               fed, _, err := TOSession.GetCDNFederationsByIDWithHdr("foo", 
id, h)
+               fed, _, err := TOSession.GetCDNFederationsByIDWithHdr("cdn1", 
id, h)
                if err != nil {
                        t.Errorf("cannot GET federation by id: %v", err)
                }
                if fed != nil && len(fed.Response) > 0 {
                        expectedCName := "new.cname."
                        fed.Response[0].CName = &expectedCName
-                       _, reqInf, err := 
TOSession.UpdateCDNFederationsByIDWithHdr(fed.Response[0], "foo", id, h)
+                       _, reqInf, err := 
TOSession.UpdateCDNFederationsByIDWithHdr(fed.Response[0], "cdn1", id, h)
                        if err == nil {
                                t.Errorf("Expected an error saying precondition 
failed, but got none")
                        }
@@ -84,7 +84,7 @@ func CreateTestCDNFederations(t *testing.T) {
                        break
                }
 
-               data, _, err := TOSession.CreateCDNFederationByName(f, 
testData.CDNs[i].Name)
+               data, _, err := TOSession.CreateCDNFederationByName(f, "cdn1")
                if err != nil {
                        t.Errorf("could not POST federations: " + err.Error())
                }
@@ -96,13 +96,23 @@ func CreateTestCDNFederations(t *testing.T) {
                        t.Error("Federation id is nil after posting")
                } else {
                        fedIDs = append(fedIDs, *data.Response.ID)
+                       resp, _, err := 
TOSession.GetDeliveryServiceByXMLIDNullable("ds1")
+                       if err != nil {
+                               t.Errorf("could not get delivery service by xml 
ID: %v", err)
+                       }
+                       if len(resp) != 1 {
+                               t.Fatalf("expected one response for delivery 
service, but got %d", len(resp))
+                       }
+                       _, err = 
TOSession.CreateFederationDeliveryServices(*data.Response.ID, 
[]int{*resp[0].ID}, false)
+                       if err != nil {
+                               t.Errorf("could not create federation delivery 
service: %v", err)
+                       }
                }
        }
 }
 
 // This test will not work unless a given CDN has more than one federation 
associated with it.
 func SortTestCDNFederations(t *testing.T) {
-       var header http.Header
        var sortedList []string
 
        //Create a new federation under the same CDN
@@ -119,12 +129,14 @@ func SortTestCDNFederations(t *testing.T) {
        id := *data.Response.ID
 
        //Get list of federations for one type of cdn
-       resp, _, err := 
TOSession.GetCDNFederationsByNameWithHdrReturnList("cdn1", header)
+       opts := http.Header{}
+       opts.Set("orderby", "cname")
+       resp, _, err := TOSession.GetCDNFederationsByNameWithHdr("cdn1", opts)
        if err != nil {
                t.Fatalf("Expected no error, but got %v", err.Error())
        }
-       for i, _ := range resp {
-               sortedList = append(sortedList, *resp[i].CName)
+       for i, _ := range resp.Response {
+               sortedList = append(sortedList, *resp.Response[i].CName)
        }
 
        // Check if list was sorted
@@ -147,21 +159,21 @@ func SortTestCDNFederations(t *testing.T) {
 func UpdateTestCDNFederations(t *testing.T) {
 
        for _, id := range fedIDs {
-               fed, _, err := TOSession.GetCDNFederationsByID("foo", id)
+               fed, _, err := TOSession.GetCDNFederationsByID("cdn1", id)
                if err != nil {
                        t.Errorf("cannot GET federation by id: %v", err)
                }
 
                expectedCName := "new.cname."
                fed.Response[0].CName = &expectedCName
-               resp, _, err := 
TOSession.UpdateCDNFederationsByID(fed.Response[0], "foo", id)
+               resp, _, err := 
TOSession.UpdateCDNFederationsByID(fed.Response[0], "cdn1", id)
                if err != nil {
                        t.Errorf("cannot PUT federation by id: %v", err)
                }
                bytes, _ := json.Marshal(resp)
                t.Logf("PUT Response: %s\n", bytes)
 
-               resp2, _, err := TOSession.GetCDNFederationsByID("foo", id)
+               resp2, _, err := TOSession.GetCDNFederationsByID("cdn1", id)
                if err != nil {
                        t.Errorf("cannot GET federation by id after PUT: %v", 
err)
                }
@@ -185,7 +197,7 @@ func GetTestCDNFederations(t *testing.T) {
        // clean up fedIDs connection?)
 
        for _, id := range fedIDs {
-               data, _, err := TOSession.GetCDNFederationsByID("foo", id)
+               data, _, err := TOSession.GetCDNFederationsByID("cdn1", id)
                if err != nil {
                        t.Errorf("could not GET federations: " + err.Error())
                }
@@ -306,14 +318,14 @@ func GetTestFederationFederationResolvers(t *testing.T) {
 func DeleteTestCDNFederations(t *testing.T) {
 
        for _, id := range fedIDs {
-               resp, _, err := TOSession.DeleteCDNFederationByID("foo", id)
+               resp, _, err := TOSession.DeleteCDNFederationByID("cdn1", id)
                if err != nil {
                        t.Errorf("cannot DELETE federation by id: '%d' %v", id, 
err)
                }
                bytes, err := json.Marshal(resp)
                t.Logf("DELETE Response: %s\n", bytes)
 
-               data, _, err := TOSession.GetCDNFederationsByID("foo", id)
+               data, _, err := TOSession.GetCDNFederationsByID("cdn1", id)
                if len(data.Response) != 0 {
                        t.Error("expected federation to be deleted")
                }
diff --git a/traffic_ops/testing/api/v3/federations_test.go 
b/traffic_ops/testing/api/v3/federations_test.go
index 2b310b7..8dd4191 100644
--- a/traffic_ops/testing/api/v3/federations_test.go
+++ b/traffic_ops/testing/api/v3/federations_test.go
@@ -65,8 +65,8 @@ func GetTestFederations(t *testing.T) {
                t.Errorf("getting federations: " + err.Error())
        }
 
-       if len(feds) != 1 {
-               t.Errorf("federations expected 1, actual: %+v", len(feds))
+       if len(feds) < 1 {
+               t.Errorf("expected atleast 1 federation, but got none")
        }
        fed := feds[0]
 
diff --git a/traffic_ops/testing/api/v3/tc-fixtures.json 
b/traffic_ops/testing/api/v3/tc-fixtures.json
index 9200849..3dc315a 100644
--- a/traffic_ops/testing/api/v3/tc-fixtures.json
+++ b/traffic_ops/testing/api/v3/tc-fixtures.json
@@ -1594,12 +1594,20 @@
         {
             "cname": "the.cname.com.",
             "ttl": 48,
-            "description": "the description"
+            "description": "the description",
+            "deliveryService":
+            {
+                "xmlId": "ds1"
+            }
         },
         {
             "cname": "booya.com.",
             "ttl": 34,
-            "description": "fooya"
+            "description": "fooya",
+            "deliveryService":
+            {
+                "xmlId": "ds1"
+            }
         }
     ],
     "federation_resolvers": [
diff --git a/traffic_ops/testing/api/v4/cdnfederations_test.go 
b/traffic_ops/testing/api/v4/cdnfederations_test.go
index f66efeb..d9b9e85 100644
--- a/traffic_ops/testing/api/v4/cdnfederations_test.go
+++ b/traffic_ops/testing/api/v4/cdnfederations_test.go
@@ -54,14 +54,14 @@ func UpdateTestCDNFederationsWithHeaders(t *testing.T, h 
http.Header) {
        opts.Header = h
        for _, id := range fedIDs {
                opts.QueryParameters.Set("id", strconv.Itoa(id))
-               fed, _, err := TOSession.GetCDNFederationsByName("foo", opts)
+               fed, _, err := TOSession.GetCDNFederationsByName("cdn1", opts)
                if err != nil {
                        t.Errorf("cannot GET federation by id: %v - alerts: 
%+v", err, fed.Alerts)
                }
                if len(fed.Response) > 0 {
                        expectedCName := "new.cname."
                        fed.Response[0].CName = &expectedCName
-                       _, reqInf, err := 
TOSession.UpdateCDNFederation(fed.Response[0], "foo", id, opts)
+                       _, reqInf, err := 
TOSession.UpdateCDNFederation(fed.Response[0], "cdn1", id, opts)
                        if err == nil {
                                t.Errorf("Expected an error saying precondition 
failed, but got none")
                        }
@@ -88,8 +88,16 @@ func CreateTestCDNFederations(t *testing.T) {
                if i >= len(testData.CDNs) {
                        break
                }
-
-               data, _, err := TOSession.CreateCDNFederation(f, 
testData.CDNs[i].Name, client.RequestOptions{})
+               opts := client.NewRequestOptions()
+               opts.QueryParameters.Set("xmlId", "ds1")
+               resp, _, err := TOSession.GetDeliveryServices(opts)
+               if err != nil {
+                       t.Errorf("could not get delivery service by xml ID: 
%v", err)
+               }
+               if len(resp.Response) != 1 {
+                       t.Fatalf("expected one response for delivery service, 
but got %d", len(resp.Response))
+               }
+               data, _, err := TOSession.CreateCDNFederation(f, "cdn1", 
client.RequestOptions{})
                if err != nil {
                        t.Errorf("could not create CDN Federations: %v - 
alerts: %+v", err, data.Alerts)
                }
@@ -99,6 +107,10 @@ func CreateTestCDNFederations(t *testing.T) {
                        t.Error("Federation id is nil after posting")
                } else {
                        fedIDs = append(fedIDs, *data.Response.ID)
+                       _, _, err = 
TOSession.CreateFederationDeliveryServices(*data.Response.ID, 
[]int{*resp.Response[0].ID}, false, client.NewRequestOptions())
+                       if err != nil {
+                               t.Errorf("could not create federation delivery 
service: %v", err)
+                       }
                }
        }
 }
@@ -119,7 +131,9 @@ func SortTestCDNFederations(t *testing.T) {
        id := *data.Response.ID
 
        //Get list of federations for one type of cdn
-       resp, _, err := TOSession.GetCDNFederationsByName("cdn1", 
client.RequestOptions{})
+       opts := client.NewRequestOptions()
+       opts.QueryParameters.Set("orderby", "cname")
+       resp, _, err := TOSession.GetCDNFederationsByName("cdn1", opts)
        if err != nil {
                t.Fatalf("Expected no error, but got %v - alerts: %+v", err, 
resp.Alerts)
        }
@@ -146,7 +160,7 @@ func UpdateTestCDNFederations(t *testing.T) {
        opts := client.NewRequestOptions()
        for _, id := range fedIDs {
                opts.QueryParameters.Set("id", strconv.Itoa(id))
-               fed, _, err := TOSession.GetCDNFederationsByName("foo", opts)
+               fed, _, err := TOSession.GetCDNFederationsByName("cdn1", opts)
                if err != nil {
                        t.Errorf("cannot get federation by id: %v - alerts: 
%+v", err, fed.Alerts)
                        continue
@@ -158,12 +172,12 @@ func UpdateTestCDNFederations(t *testing.T) {
 
                expectedCName := "new.cname."
                fed.Response[0].CName = &expectedCName
-               resp, _, err := TOSession.UpdateCDNFederation(fed.Response[0], 
"foo", id, client.RequestOptions{})
+               resp, _, err := TOSession.UpdateCDNFederation(fed.Response[0], 
"cdn1", id, client.RequestOptions{})
                if err != nil {
                        t.Errorf("cannot update federation by id: %v - alerts: 
%+v", err, resp.Alerts)
                }
 
-               resp2, _, err := TOSession.GetCDNFederationsByName("foo", opts)
+               resp2, _, err := TOSession.GetCDNFederationsByName("cdn1", opts)
                if err != nil {
                        t.Errorf("cannot get federation by id after update: %v 
- alerts: %+v", err, resp2.Alerts)
                }
@@ -190,7 +204,7 @@ func GetTestCDNFederations(t *testing.T) {
        opts := client.NewRequestOptions()
        for _, id := range fedIDs {
                opts.QueryParameters.Set("id", strconv.Itoa(id))
-               data, _, err := TOSession.GetCDNFederationsByName("foo", opts)
+               data, _, err := TOSession.GetCDNFederationsByName("cdn1", opts)
                if err != nil {
                        t.Errorf("could not get federations: %v - alerts: %+v", 
err, data.Alerts)
                }
@@ -204,7 +218,7 @@ func GetTestCDNFederationsIMS(t *testing.T) {
        opts.Header.Set(rfc.IfModifiedSince, fmtFutureTime)
        for _, id := range fedIDs {
                opts.QueryParameters.Set("id", strconv.Itoa(id))
-               data, reqInf, err := TOSession.GetCDNFederationsByName("foo", 
opts)
+               data, reqInf, err := TOSession.GetCDNFederationsByName("cdn1", 
opts)
                if err != nil {
                        t.Errorf("could not get federations: %v - alerts: %+v", 
err, data.Alerts)
                }
@@ -219,7 +233,7 @@ func GetTestCDNFederationsIMS(t *testing.T) {
        opts.Header.Set(rfc.IfModifiedSince, fmtPastTime)
        for _, id := range fedIDs {
                opts.QueryParameters.Set("id", strconv.Itoa(id))
-               data, reqInf, err := TOSession.GetCDNFederationsByName("foo", 
opts)
+               data, reqInf, err := TOSession.GetCDNFederationsByName("cdn1", 
opts)
                if err != nil {
                        t.Errorf("could not get federations: %v - alerts: %+v", 
err, data.Alerts)
                }
@@ -358,13 +372,13 @@ func GetTestFederationFederationResolvers(t *testing.T) {
 func DeleteTestCDNFederations(t *testing.T) {
        opts := client.NewRequestOptions()
        for _, id := range fedIDs {
-               resp, _, err := TOSession.DeleteCDNFederation("foo", id, opts)
+               resp, _, err := TOSession.DeleteCDNFederation("cdn1", id, opts)
                if err != nil {
                        t.Errorf("cannot delete federation #%d: %v - alerts: 
%+v", id, err, resp.Alerts)
                }
 
                opts.QueryParameters.Set("id", strconv.Itoa(id))
-               data, _, err := TOSession.GetCDNFederationsByName("foo", opts)
+               data, _, err := TOSession.GetCDNFederationsByName("cdn1", opts)
                if len(data.Response) != 0 {
                        t.Error("expected federation to be deleted")
                }
diff --git a/traffic_ops/testing/api/v4/federations_test.go 
b/traffic_ops/testing/api/v4/federations_test.go
index 2e60f7e..d94f294 100644
--- a/traffic_ops/testing/api/v4/federations_test.go
+++ b/traffic_ops/testing/api/v4/federations_test.go
@@ -86,8 +86,8 @@ func GetTestFederations(t *testing.T) {
                t.Errorf("getting federations: %v - alerts: %+v", err, 
feds.Alerts)
        }
 
-       if len(feds.Response) != 1 {
-               t.Fatalf("federations expected 1, actual: %d", 
len(feds.Response))
+       if len(feds.Response) < 1 {
+               t.Errorf("expected atleast 1 federation, but got none")
        }
        fed := feds.Response[0]
 
diff --git a/traffic_ops/testing/api/v4/tc-fixtures.json 
b/traffic_ops/testing/api/v4/tc-fixtures.json
index 11df51d..f1a0738 100644
--- a/traffic_ops/testing/api/v4/tc-fixtures.json
+++ b/traffic_ops/testing/api/v4/tc-fixtures.json
@@ -1592,12 +1592,20 @@
         {
             "cname": "the.cname.com.",
             "ttl": 48,
-            "description": "the description"
+            "description": "the description",
+            "deliveryService":
+            {
+                "xmlId": "ds1"
+            }
         },
         {
             "cname": "booya.com.",
             "ttl": 34,
-            "description": "fooya"
+            "description": "fooya",
+            "deliveryService":
+            {
+                "xmlId": "ds1"
+            }
         }
     ],
     "federation_resolvers": [
diff --git a/traffic_ops/traffic_ops_golang/cdnfederation/cdnfederations.go 
b/traffic_ops/traffic_ops_golang/cdnfederation/cdnfederations.go
index 2607bcf..54a218e 100644
--- a/traffic_ops/traffic_ops_golang/cdnfederation/cdnfederations.go
+++ b/traffic_ops/traffic_ops_golang/cdnfederation/cdnfederations.go
@@ -22,6 +22,7 @@ package cdnfederation
 import (
        "database/sql"
        "errors"
+       "fmt"
        "net/http"
        "strconv"
        "strings"
@@ -52,24 +53,23 @@ func (v *TOCDNFederation) SetLastUpdated(t tc.TimeNoMod) { 
v.LastUpdated = &t }
 func (v *TOCDNFederation) InsertQuery() string           { return 
insertQuery() }
 func (v *TOCDNFederation) SelectMaxLastUpdatedQuery(where, orderBy, 
pagination, tableName string) string {
        return `SELECT max(t) from (
-        SELECT max(last_updated) as t from federation ` + where + orderBy + 
pagination +
+               SELECT max(federation.last_updated) as t from federation 
+               join federation_deliveryservice fds on fds.federation = 
federation.id 
+               join deliveryservice ds on ds.id = fds.deliveryservice 
+               join cdn c on c.id = ds.cdn_id ` + where + orderBy + pagination 
+
                ` UNION ALL
-    select max(last_updated) as t from last_deleted l where 
l.table_name='federation') as res`
+               select max(last_updated) as t from last_deleted l where 
l.table_name='federation') as res`
 }
 
 func (v *TOCDNFederation) NewReadObj() interface{} { return &TOCDNFederation{} 
}
 func (v *TOCDNFederation) SelectQuery() string {
-       if v.ID != nil {
-               return selectByID()
-       }
        return selectByCDNName()
 }
 func (v *TOCDNFederation) ParamColumns() map[string]dbhelpers.WhereColumnInfo {
        cols := map[string]dbhelpers.WhereColumnInfo{
-               "id": dbhelpers.WhereColumnInfo{Column: "federation.id", 
Checker: api.IsInt},
-       }
-       if v.ID == nil {
-               cols["name"] = dbhelpers.WhereColumnInfo{Column: "cdn.name", 
Checker: nil}
+               "id":    dbhelpers.WhereColumnInfo{Column: "federation.id", 
Checker: api.IsInt},
+               "name":  dbhelpers.WhereColumnInfo{Column: "c.name", Checker: 
nil},
+               "cname": dbhelpers.WhereColumnInfo{Column: "federation.cname", 
Checker: nil},
        }
        return cols
 }
@@ -128,13 +128,48 @@ func (fed *TOCDNFederation) Validate() error {
        return util.JoinErrs(tovalidate.ToErrors(validateErrs))
 }
 
+func (fed *TOCDNFederation) CheckIfCDNAndFederationMatch(cdnName string) 
(error, error, int) {
+       var cdnFromDS string
+       var err error
+       if fed.DeliveryServiceIDs != nil {
+               if fed.DsId != nil {
+                       cdnNames, err := 
dbhelpers.GetCDNNamesFromDSIds(fed.APIInfo().Tx.Tx, []int{*fed.DsId})
+                       if err != nil {
+                               return nil, fmt.Errorf("getting CDN names from 
DS IDs: %w", err), http.StatusInternalServerError
+                       }
+                       if len(cdnNames) != 1 {
+                               return fmt.Errorf("%d CDNs returned for one DS 
ID", len(cdnNames)), nil, http.StatusBadRequest
+                       }
+                       cdnFromDS = cdnNames[0]
+               } else if fed.XmlId != nil {
+                       cdnFromDS, err = 
dbhelpers.GetCDNNameFromDSXMLID(fed.APIInfo().Tx.Tx, *fed.XmlId)
+                       if err != nil {
+                               return nil, fmt.Errorf("getting CDN name from 
DS XMLID: %w", err), http.StatusInternalServerError
+                       }
+               }
+       }
+       if cdnFromDS != "" && cdnFromDS != cdnName {
+               return errors.New("cdn names in request path and payload do not 
match"), nil, http.StatusBadRequest
+       }
+       return nil, nil, http.StatusOK
+}
+
 // fedAPIInfo.Params["name"] is not used on creation, rather the cdn name
 // is connected when the federations/:id/deliveryservice links a federation
 // However, we use fedAPIInfo.Params["name"] to check whether or not another 
user has a hard lock on the CDN.
 // Note: cdns and deliveryservies have a 1-1 relationship
 func (fed *TOCDNFederation) Create() (error, error, int) {
        if cdn, ok := fed.APIInfo().Params["name"]; ok {
-               userErr, sysErr, errCode := 
dbhelpers.CheckIfCurrentUserCanModifyCDN(fed.APIInfo().Tx.Tx, cdn, 
fed.APIInfo().User.UserName)
+               if ok, err := dbhelpers.CDNExists(fed.APIInfo().Params["name"], 
fed.APIInfo().Tx.Tx); err != nil {
+                       return nil, errors.New("verifying CDN exists: " + 
err.Error()), http.StatusInternalServerError
+               } else if !ok {
+                       return errors.New("cdn not found"), nil, 
http.StatusNotFound
+               }
+               userErr, sysErr, errCode := 
fed.CheckIfCDNAndFederationMatch(cdn)
+               if userErr != nil || sysErr != nil {
+                       return userErr, sysErr, errCode
+               }
+               userErr, sysErr, errCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDN(fed.APIInfo().Tx.Tx, cdn, 
fed.APIInfo().User.UserName)
                if userErr != nil || sysErr != nil {
                        return userErr, sysErr, errCode
                }
@@ -177,6 +212,11 @@ func (fed *TOCDNFederation) Read(h http.Header, useIMS 
bool) ([]interface{}, err
        }
 
        api.DefaultSort(fed.APIInfo(), "cname")
+       if ok, err := dbhelpers.CDNExists(fed.APIInfo().Params["name"], 
fed.APIInfo().Tx.Tx); err != nil {
+               return nil, nil, errors.New("verifying CDN exists: " + 
err.Error()), http.StatusInternalServerError, nil
+       } else if !ok {
+               return nil, errors.New("cdn not found"), nil, 
http.StatusNotFound, nil
+       }
        federations, userErr, sysErr, errCode, maxTime := api.GenericRead(h, 
fed, useIMS)
        if userErr != nil || sysErr != nil {
                return nil, userErr, sysErr, errCode, nil
@@ -199,11 +239,6 @@ func (fed *TOCDNFederation) Read(h http.Header, useIMS 
bool) ([]interface{}, err
                if fed.ID != nil {
                        return nil, errors.New("not found"), nil, 
http.StatusNotFound, nil
                }
-               if ok, err := dbhelpers.CDNExists(fed.APIInfo().Params["name"], 
fed.APIInfo().Tx.Tx); err != nil {
-                       return nil, nil, errors.New("verifying CDN exists: " + 
err.Error()), http.StatusInternalServerError, nil
-               } else if !ok {
-                       return nil, errors.New("cdn not found"), nil, 
http.StatusNotFound, nil
-               }
        }
        return filteredFederations, nil, nil, errCode, maxTime
 }
@@ -214,7 +249,16 @@ func (fed *TOCDNFederation) Update(h http.Header) (error, 
error, int) {
                return userErr, sysErr, errCode
        }
        if cdn, ok := fed.APIInfo().Params["name"]; ok {
-               userErr, sysErr, errCode := 
dbhelpers.CheckIfCurrentUserCanModifyCDN(fed.APIInfo().Tx.Tx, cdn, 
fed.APIInfo().User.UserName)
+               if ok, err := dbhelpers.CDNExists(fed.APIInfo().Params["name"], 
fed.APIInfo().Tx.Tx); err != nil {
+                       return nil, errors.New("verifying CDN exists: " + 
err.Error()), http.StatusInternalServerError
+               } else if !ok {
+                       return errors.New("cdn not found"), nil, 
http.StatusNotFound
+               }
+               userErr, sysErr, errCode := 
fed.CheckIfCDNAndFederationMatch(cdn)
+               if userErr != nil || sysErr != nil {
+                       return userErr, sysErr, errCode
+               }
+               userErr, sysErr, errCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDN(fed.APIInfo().Tx.Tx, cdn, 
fed.APIInfo().User.UserName)
                if userErr != nil || sysErr != nil {
                        return userErr, sysErr, errCode
                }
@@ -235,7 +279,16 @@ func (fed *TOCDNFederation) Delete() (error, error, int) {
                return userErr, sysErr, errCode
        }
        if cdn, ok := fed.APIInfo().Params["name"]; ok {
-               userErr, sysErr, errCode := 
dbhelpers.CheckIfCurrentUserCanModifyCDN(fed.APIInfo().Tx.Tx, cdn, 
fed.APIInfo().User.UserName)
+               if ok, err := dbhelpers.CDNExists(fed.APIInfo().Params["name"], 
fed.APIInfo().Tx.Tx); err != nil {
+                       return nil, errors.New("verifying CDN exists: " + 
err.Error()), http.StatusInternalServerError
+               } else if !ok {
+                       return errors.New("cdn not found"), nil, 
http.StatusNotFound
+               }
+               userErr, sysErr, errCode := 
fed.CheckIfCDNAndFederationMatch(cdn)
+               if userErr != nil || sysErr != nil {
+                       return userErr, sysErr, errCode
+               }
+               userErr, sysErr, errCode = 
dbhelpers.CheckIfCurrentUserCanModifyCDN(fed.APIInfo().Tx.Tx, cdn, 
fed.APIInfo().User.UserName)
                if userErr != nil || sysErr != nil {
                        return userErr, sysErr, errCode
                }
@@ -309,7 +362,7 @@ func selectByCDNName() string {
        FROM federation
        JOIN federation_deliveryservice AS fd ON federation.id = fd.federation
        JOIN deliveryservice AS ds ON ds.id = fd.deliveryservice
-       JOIN cdn ON cdn.id = cdn_id`
+       JOIN cdn c ON c.id = ds.cdn_id`
        // WHERE cdn.name = :cdn_name (determined by dbhelper)
 }
 
diff --git a/traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go 
b/traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go
index 8d70fc3..f7ff623 100644
--- a/traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go
+++ b/traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go
@@ -1554,6 +1554,17 @@ func GetCDNNamesFromServerIds(tx *sql.Tx, serverIds 
[]int64) ([]string, error) {
        return cdns, nil
 }
 
+// GetCDNNameFromDSXMLID returns the CDN name of the DS associated with the 
supplied XML ID
+func GetCDNNameFromDSXMLID(tx *sql.Tx, dsXMLID string) (string, error) {
+       var cdnName string
+       query := `SELECT name FROM cdn JOIN deliveryservice ON cdn.id = 
deliveryservice.cdn_id WHERE deliveryservice.xml_id = $1`
+       err := tx.QueryRow(query, dsXMLID).Scan(&cdnName)
+       if err != nil {
+               return "", err
+       }
+       return cdnName, nil
+}
+
 // GetCDNNamesFromDSIds returns a list of cdn names for a list of DS IDs.
 func GetCDNNamesFromDSIds(tx *sql.Tx, dsIds []int) ([]string, error) {
        var cdns []string

Reply via email to