diff --git a/CHANGELOG.md b/CHANGELOG.md index 47ecd946c3..b8e85c1d01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Correction where using the placeholder __HOSTNAME__ in "unknown" files (others than the defaults ones), was being replaced by the full FQDN instead of the shot hostname. - [#6800](https://github.com/apache/trafficcontrol/issues/6800) Fixed incorrect error message for `/server/details` associated with query parameters. - [#6712](https://github.com/apache/trafficcontrol/issues/6712) - Fixed error when loading the Traffic Vault schema from `create_tables.sql` more than once. +- [#6834](https://github.com/apache/trafficcontrol/issues/6834) - In API 4.0, fixed `GET` for `/servers` to display all profiles irrespective of the index position. Also, replaced query param `profileId` with `profileName`. ### Removed - Remove traffic\_portal dependencies to mitigate `npm audit` issues, specifically `grunt-concurrent`, `grunt-contrib-concat`, `grunt-contrib-cssmin`, `grunt-contrib-jsmin`, `grunt-contrib-uglify`, `grunt-contrib-htmlmin`, `grunt-newer`, and `grunt-wiredep` diff --git a/docs/source/api/v4/servers.rst b/docs/source/api/v4/servers.rst index 92bdbb6020..78e5d1f397 100644 --- a/docs/source/api/v4/servers.rst +++ b/docs/source/api/v4/servers.rst @@ -51,7 +51,7 @@ Request Structure +----------------+----------+-------------------------------------------------------------------------------------------------------------------+ | id | no | Return only the server with this integral, unique identifier | +----------------+----------+-------------------------------------------------------------------------------------------------------------------+ - | profileId | no | Return only those servers that are using the :term:`Profile` that has this :ref:`profile-id` | + | profileName | no | Return only those servers that are using the :term:`Profile` that has this :ref:`profile-name` | +----------------+----------+-------------------------------------------------------------------------------------------------------------------+ | status | no | Return only those servers with this status - see :ref:`health-proto` | +----------------+----------+-------------------------------------------------------------------------------------------------------------------+ diff --git a/traffic_ops/testing/api/v4/cdn_queue_updates_by_type_profile_test.go b/traffic_ops/testing/api/v4/cdn_queue_updates_by_type_profile_test.go index 74179ce5cf..1a1bccbdd9 100644 --- a/traffic_ops/testing/api/v4/cdn_queue_updates_by_type_profile_test.go +++ b/traffic_ops/testing/api/v4/cdn_queue_updates_by_type_profile_test.go @@ -175,7 +175,7 @@ func QueueUpdatesByProfile(t *testing.T) { // Get all the servers for the same CDN and profile as that of the first server opts.QueryParameters.Set("cdn", strconv.Itoa(cdns.Response[0].ID)) - opts.QueryParameters.Set("profileId", strconv.Itoa(profiles.Response[0].ID)) + opts.QueryParameters.Set("profileName", profiles.Response[0].Name) serverIDMap := make(map[int]bool, 0) resp, _, err := TOSession.GetServers(opts) if err != nil { diff --git a/traffic_ops/testing/api/v4/servers_test.go b/traffic_ops/testing/api/v4/servers_test.go index a6f1680a4d..af9adf9dd5 100644 --- a/traffic_ops/testing/api/v4/servers_test.go +++ b/traffic_ops/testing/api/v4/servers_test.go @@ -935,12 +935,12 @@ func GetTestServersQueryParameters(t *testing.T) { if len(pr.Response) != 1 { t.Error("Found server with no Profile ID") } else { - profileID := pr.Response[0].ID - opts.QueryParameters.Add("profileId", strconv.Itoa(profileID)) + profileName := pr.Response[0].Name + opts.QueryParameters.Add("profileName", profileName) if resp, _, err := TOSession.GetServers(opts); err != nil { t.Errorf("Error getting servers by Profile ID: %v - alerts: %+v", err, resp.Alerts) } - opts.QueryParameters.Del("profileId") + opts.QueryParameters.Del("profileName") } cgs, _, err := TOSession.GetCacheGroups(client.RequestOptions{}) diff --git a/traffic_ops/traffic_ops_golang/server/servers.go b/traffic_ops/traffic_ops_golang/server/servers.go index 205fe98077..76040416da 100644 --- a/traffic_ops/traffic_ops_golang/server/servers.go +++ b/traffic_ops/traffic_ops_golang/server/servers.go @@ -62,6 +62,9 @@ JOIN status st ON s.status = st.id JOIN type t ON s.type = t.id ` +const joinProfileV4 = `JOIN server_profile sp ON p.name = sp.profile_name AND s.id = sp.server +` + /* language=SQL */ const dssTopologiesJoinSubquery = ` (SELECT @@ -899,7 +902,6 @@ func getServers(h http.Header, params map[string]string, tx *sqlx.Tx, user *auth "id": {Column: "s.id", Checker: api.IsInt}, "hostName": {Column: "s.host_name", Checker: nil}, "physLocation": {Column: "s.phys_location", Checker: api.IsInt}, - "profileId": {Column: "s.profile", Checker: api.IsInt}, "status": {Column: "st.name", Checker: nil}, "topology": {Column: "tc.topology", Checker: nil}, "type": {Column: "t.name", Checker: nil}, @@ -913,6 +915,20 @@ func getServers(h http.Header, params map[string]string, tx *sqlx.Tx, user *auth } } + if version.Major <= 3 { + queryParamsToSQLCols["profileId"] = dbhelpers.WhereColumnInfo{ + Column: "s.profile", + Checker: api.IsInt, + } + } + + if version.Major >= 4 { + queryParamsToSQLCols["profileName"] = dbhelpers.WhereColumnInfo{ + Column: "sp.profile_name", + Checker: nil, + } + } + usesMids := false queryAddition := "" dsHasRequiredCapabilities := false @@ -974,10 +990,22 @@ func getServers(h http.Header, params map[string]string, tx *sqlx.Tx, user *auth return nil, 0, util.JoinErrs(errs), nil, http.StatusBadRequest, nil } - countQuery := serverCountQuery + queryAddition + where + var queryString, countQueryString string + queryString = selectQuery + countQueryString = serverCountQuery + if version.Major >= 4 { + if _, ok := params["profileName"]; ok { + queryString = selectQuery + `JOIN server_profile sp ON s.id = sp.server` + } else { + queryString = selectQuery + joinProfileV4 + } + countQueryString = serverCountQuery + joinProfileV4 + } + + countQuery := countQueryString + queryAddition + where // If we are querying for a DS that has reqd capabilities, we need to make sure that we also include all the ORG servers directly assigned to this DS if _, ok := params["dsId"]; ok && dsHasRequiredCapabilities { - countQuery = `SELECT (` + countQuery + `) + (` + serverCountQuery + originServerQuery + `) AS total` + countQuery = `SELECT (` + countQuery + `) + (` + countQueryString + originServerQuery + `) AS total` } serverCount, err = getServerCount(tx, countQuery, queryValues) if err != nil { @@ -996,10 +1024,10 @@ func getServers(h http.Header, params map[string]string, tx *sqlx.Tx, user *auth log.Debugln("Non IMS request") } - query := selectQuery + queryAddition + where + orderBy + pagination + query := queryString + queryAddition + where + orderBy + pagination // If you're looking to get the servers for a particular delivery service, make sure you're also querying the ORG servers from the deliveryservice_server table if _, ok := params[`dsId`]; ok { - query = `(` + selectQuery + queryAddition + where + orderBy + pagination + `) UNION ` + selectQuery + originServerQuery + query = `(` + queryString + queryAddition + where + orderBy + pagination + `) UNION ` + queryString + originServerQuery } log.Debugln("Query is ", query) @@ -1669,7 +1697,12 @@ func Update(w http.ResponseWriter, r *http.Request) { } where := `WHERE s.id = $1` - selquery := selectQuery + where + var selquery string + if version.Major <= 4 { + selquery = selectQuery + joinProfileV4 + where + } else { + selquery = selectQuery + where + } var srvr tc.ServerV40 err = inf.Tx.QueryRow(selquery, serverID).Scan(&srvr.Cachegroup, &srvr.CachegroupID, @@ -2191,7 +2224,7 @@ func createV4(inf *api.APIInfo, w http.ResponseWriter, r *http.Request) { } where := `WHERE s.id = $1` - selquery := selectQuery + where + selquery := selectQuery + joinProfileV4 + where var srvr tc.ServerV40 err = inf.Tx.QueryRow(selquery, serverID).Scan(&srvr.Cachegroup, &srvr.CachegroupID,