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 1d584ba6af9cd2be8773a5a12a01e3af368159b4 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 (cherry picked from commit 4fa582da58484abb97042fdc32f4bf5a90da67a8) --- 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
