You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by zr...@apache.org on 2022/04/21 18:35:44 UTC

[trafficcontrol] branch master updated: Layered profile for ds servers [`GET` API endpoint `deliveryservices/{id}/servers/)` and `/deliveryservices/{id}/servers/eligible`] (#6711)

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

zrhoffman 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 44fcc78594 Layered profile for ds servers [`GET` API endpoint `deliveryservices/{id}/servers/)` and `/deliveryservices/{id}/servers/eligible`] (#6711)
44fcc78594 is described below

commit 44fcc785940708cf5d817eb31a7eb59b8c6c3079
Author: Rima Shah <22...@users.noreply.github.com>
AuthorDate: Thu Apr 21 12:35:39 2022 -0600

    Layered profile for ds servers [`GET` API endpoint `deliveryservices/{id}/servers/)` and `/deliveryservices/{id}/servers/eligible`] (#6711)
    
    * Updated DSServerBaseV4 struct and its usage.
    
    * Added changelog entry and updated doc
    Updated profile to profileNames and changed type from *string to []string
    
    * Updated unit test.
    
    * Updated unit test-1 and fixed go vet issue
    
    * updated based on review comments.
---
 CHANGELOG.md                                       |  3 ++-
 docs/source/api/v4/deliveryservices_id_servers.rst |  8 ++------
 lib/go-tc/deliveryservice_servers.go               | 16 ++++++----------
 .../traffic_ops_golang/dbhelpers/db_helpers.go     |  9 +++++++++
 .../traffic_ops_golang/deliveryservice/eligible.go | 22 ++++++++++++++--------
 .../deliveryservice/eligible_test.go               | 10 ++++------
 .../deliveryservice/servers/servers.go             | 14 ++++++--------
 .../deliveryservice/servers/servers_test.go        | 22 ++++++++++------------
 8 files changed, 53 insertions(+), 51 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9ac6841b14..e99527e52d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,8 +17,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 - Traffic Monitor: Add support for `access.log` to TM.
 - Added functionality for login to provide a Bearer token and for that token to be later used for authorization.
 - [Traffic Ops | Traffic Go Clients | T3C] Add additional timestamp fields to server for queuing and dequeueing config and revalidate updates.
-- Added layered profile feature to 4.0 for `GET` servers/, `POST` servers/, `PUT` servers/{id} and `DELETE` servers/{id}.
+- Added layered profile feature to 4.0 for `GET` /servers/, `POST` /servers/, `PUT` /servers/{id} and `DELETE` /servers/{id}.
 - Added a Traffic Ops endpoint and Traffic Portal page to view all CDNi configuration update requests and approve or deny.
+- Added layered profile feature to 4.0 for `GET` /deliveryservices/{id}/servers/ and /deliveryservices/{id}/servers/eligible.
 
 ### Fixed
 - Update traffic\_portal dependencies to mitigate `npm audit` issues.
diff --git a/docs/source/api/v4/deliveryservices_id_servers.rst b/docs/source/api/v4/deliveryservices_id_servers.rst
index 898c0056e3..19bd5f5e26 100644
--- a/docs/source/api/v4/deliveryservices_id_servers.rst
+++ b/docs/source/api/v4/deliveryservices_id_servers.rst
@@ -78,9 +78,7 @@ Response Structure
 :offlineReason:  A user-entered reason why the server is in ADMIN_DOWN or OFFLINE status (will be empty if not offline)
 :physLocation:   The name of the :term:`Physical Location` at which the server resides
 :physLocationId: An integral, unique identifier for the :term:`Physical Location` at which the server resides
-:profile:        The :ref:`profile-name` of the :term:`Profile` assigned to this server
-:profileDesc:    A :ref:`profile-description` of the :term:`Profile` assigned to this server
-:profileId:      The :ref:`profile-id` of the :term:`Profile` assigned to this server
+:profile:        List of :ref:`profile-name` of the :term:`Profiles` assigned to this server
 :rack:           A string indicating "rack" location
 :routerHostName: The human-readable name of the router
 :routerPortName: The human-readable name of the router port
@@ -135,9 +133,7 @@ Response Structure
 			"offlineReason": "",
 			"physLocation": "Apachecon North America 2018",
 			"physLocationId": 1,
-			"profile": "ATS_EDGE_TIER_CACHE",
-			"profileDesc": "Edge Cache - Apache Traffic Server",
-			"profileId": 9,
+			"profileNames": ["ATS_EDGE_TIER_CACHE"],
 			"rack": "",
 			"routerHostName": "",
 			"routerPortName": "",
diff --git a/lib/go-tc/deliveryservice_servers.go b/lib/go-tc/deliveryservice_servers.go
index 3bc0844b96..7f1d1a1570 100644
--- a/lib/go-tc/deliveryservice_servers.go
+++ b/lib/go-tc/deliveryservice_servers.go
@@ -156,9 +156,7 @@ type DSServerBaseV4 struct {
 	OfflineReason               *string              `json:"offlineReason" db:"offline_reason"`
 	PhysLocation                *string              `json:"physLocation" db:"phys_location"`
 	PhysLocationID              *int                 `json:"physLocationId" db:"phys_location_id"`
-	Profile                     *string              `json:"profile" db:"profile"`
-	ProfileDesc                 *string              `json:"profileDesc" db:"profile_desc"`
-	ProfileID                   *int                 `json:"profileId" db:"profile_id"`
+	ProfileNames                []string             `json:"profileNames" db:"profile_name"`
 	Rack                        *string              `json:"rack" db:"rack"`
 	Status                      *string              `json:"status" db:"status"`
 	StatusID                    *int                 `json:"statusId" db:"status_id"`
@@ -235,9 +233,7 @@ func (oldBase DSServerBase) ToDSServerBaseV4() DSServerBaseV4 {
 	dsServerBaseV4.OfflineReason = oldBase.OfflineReason
 	dsServerBaseV4.PhysLocation = oldBase.PhysLocation
 	dsServerBaseV4.PhysLocationID = oldBase.PhysLocationID
-	dsServerBaseV4.Profile = oldBase.Profile
-	dsServerBaseV4.ProfileDesc = oldBase.ProfileDesc
-	dsServerBaseV4.ProfileID = oldBase.ProfileID
+	dsServerBaseV4.ProfileNames = []string{*oldBase.Profile}
 	dsServerBaseV4.Rack = oldBase.Rack
 	dsServerBaseV4.Status = oldBase.Status
 	dsServerBaseV4.StatusID = oldBase.StatusID
@@ -252,7 +248,7 @@ func (oldBase DSServerBase) ToDSServerBaseV4() DSServerBaseV4 {
 
 // ToDSServerBase downgrades the DSServerBaseV4 to the structure used by the
 // Traffic Ops API in versions earlier than 4.0.
-func (baseV4 DSServerBaseV4) ToDSServerBase(routerHostName, routerPort *string) DSServerBase {
+func (baseV4 DSServerBaseV4) ToDSServerBase(routerHostName, routerPort, pDesc *string, pID *int) DSServerBase {
 	var dsServerBase DSServerBase
 	dsServerBase.Cachegroup = baseV4.Cachegroup
 	dsServerBase.CachegroupID = baseV4.CachegroupID
@@ -278,9 +274,9 @@ func (baseV4 DSServerBaseV4) ToDSServerBase(routerHostName, routerPort *string)
 	dsServerBase.OfflineReason = baseV4.OfflineReason
 	dsServerBase.PhysLocation = baseV4.PhysLocation
 	dsServerBase.PhysLocationID = baseV4.PhysLocationID
-	dsServerBase.Profile = baseV4.Profile
-	dsServerBase.ProfileDesc = baseV4.ProfileDesc
-	dsServerBase.ProfileID = baseV4.ProfileID
+	dsServerBase.Profile = &baseV4.ProfileNames[0]
+	dsServerBase.ProfileDesc = pDesc
+	dsServerBase.ProfileID = pID
 	dsServerBase.Rack = baseV4.Rack
 	dsServerBase.Status = baseV4.Status
 	dsServerBase.StatusID = baseV4.StatusID
diff --git a/traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go b/traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go
index 024ed7fd83..e024126d01 100644
--- a/traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go
+++ b/traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go
@@ -2090,3 +2090,12 @@ func UpdateServerProfileTableForV2V3(id *int, newProfile *string, origProfile st
 
 	return profileName, nil
 }
+
+// GetProfileIDDesc gets profile ID and desc for V3 servers
+func GetProfileIDDesc(tx *sql.Tx, name string) (id int, desc string) {
+	err := tx.QueryRow(`SELECT id, description from "profile" p WHERE p.name=$1`, name).Scan(&id, &desc)
+	if err != nil {
+		log.Errorf("scanning id and description in GetProfileIDDesc: " + err.Error())
+	}
+	return
+}
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go b/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go
index 4f7ab63ff0..bfefdaf33b 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go
@@ -82,7 +82,12 @@ func GetServersEligible(w http.ResponseWriter, r *http.Request) {
 				return
 			}
 			v11server := tc.DSServerV11{}
-			v11server.DSServerBase = srv.DSServerBaseV4.ToDSServerBase(&routerHostName, &routerPort)
+			if len(srv.ProfileNames) == 0 {
+				api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("profile name for server: "+*srv.HostName+" not found"), nil)
+				return
+			}
+			pid, pdesc := dbhelpers.GetProfileIDDesc(inf.Tx.Tx, srv.ProfileNames[0])
+			v11server.DSServerBase = srv.DSServerBaseV4.ToDSServerBase(&routerHostName, &routerPort, &pdesc, &pid)
 
 			v11server.LegacyInterfaceDetails = legacyInterface
 
@@ -107,7 +112,12 @@ func GetServersEligible(w http.ResponseWriter, r *http.Request) {
 				return
 			}
 			v3server := tc.DSServer{}
-			v3server.DSServerBase = srv.DSServerBaseV4.ToDSServerBase(&routerHostName, &routerPort)
+			if len(srv.ProfileNames) == 0 {
+				api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("profile name for server: "+*srv.HostName+" not found"), nil)
+				return
+			}
+			pid, pdesc := dbhelpers.GetProfileIDDesc(inf.Tx.Tx, srv.ProfileNames[0])
+			v3server.DSServerBase = srv.DSServerBaseV4.ToDSServerBase(&routerHostName, &routerPort, &pdesc, &pid)
 
 			v3server.ServerInterfaces = &v3Interfaces
 
@@ -158,9 +168,7 @@ s.mgmt_ip_netmask,
 s.offline_reason,
 pl.name as phys_location,
 s.phys_location as phys_location_id,
-p.name as profile,
-p.description as profile_desc,
-s.profile as profile_id,
+(SELECT ARRAY_AGG(profile_name) FROM server_profile WHERE server_profile.server=s.id) as profile_name,
 s.rack,
 st.name as status,
 s.status as status_id,
@@ -221,9 +229,7 @@ ARRAY(select drc.required_capability from deliveryservices_required_capability d
 			&s.OfflineReason,
 			&s.PhysLocation,
 			&s.PhysLocationID,
-			&s.Profile,
-			&s.ProfileDesc,
-			&s.ProfileID,
+			pq.Array(&s.ProfileNames),
 			&s.Rack,
 			&s.Status,
 			&s.StatusID,
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/eligible_test.go b/traffic_ops/traffic_ops_golang/deliveryservice/eligible_test.go
index d1afdb4a50..a45833aac8 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/eligible_test.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/eligible_test.go
@@ -16,7 +16,9 @@ package deliveryservice
 */
 
 import (
+	"fmt"
 	"strconv"
+	"strings"
 	"testing"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
@@ -73,9 +75,7 @@ func TestGetEligibleServers(t *testing.T) {
 		"offline_reason",
 		"phys_location",
 		"phys_location_id",
-		"profile",
-		"profile_desc",
-		"profile_id",
+		"profile_name",
 		"rack",
 		"status",
 		"status_id",
@@ -110,9 +110,7 @@ func TestGetEligibleServers(t *testing.T) {
 			s.OfflineReason,
 			s.PhysLocation,
 			s.PhysLocationID,
-			s.Profile,
-			s.ProfileDesc,
-			s.ProfileID,
+			fmt.Sprintf("{%s}", strings.Join(s.ProfileNames, ",")),
 			s.Rack,
 			s.Status,
 			s.StatusID,
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index 985fcd31a4..2e67f33e66 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -710,7 +710,8 @@ func GetReadAssigned(w http.ResponseWriter, r *http.Request) {
 				return
 			}
 			v11server := tc.DSServerV11{}
-			v11server.DSServerBase = srv.DSServerBaseV4.ToDSServerBase(&routerHostName, &routerPort)
+			pid, pdesc := dbhelpers.GetProfileIDDesc(inf.Tx.Tx, srv.ProfileNames[0])
+			v11server.DSServerBase = srv.DSServerBaseV4.ToDSServerBase(&routerHostName, &routerPort, &pdesc, &pid)
 
 			v11server.LegacyInterfaceDetails = legacyInterface
 
@@ -735,7 +736,8 @@ func GetReadAssigned(w http.ResponseWriter, r *http.Request) {
 				return
 			}
 			v3server := tc.DSServer{}
-			v3server.DSServerBase = srv.DSServerBaseV4.ToDSServerBase(&routerHostName, &routerPort)
+			pid, pdesc := dbhelpers.GetProfileIDDesc(inf.Tx.Tx, srv.ProfileNames[0])
+			v3server.DSServerBase = srv.DSServerBaseV4.ToDSServerBase(&routerHostName, &routerPort, &pdesc, &pid)
 
 			v3server.ServerInterfaces = &v3Interfaces
 
@@ -771,9 +773,7 @@ s.mgmt_ip_netmask,
 s.offline_reason,
 pl.name as phys_location,
 s.phys_location as phys_location_id,
-p.name as profile,
-p.description as profile_desc,
-s.profile as profile_id,
+(SELECT ARRAY_AGG(profile_name) FROM server_profile WHERE server_profile.server=s.id) as profile_name,
 s.rack,
 st.name as status,
 s.status as status_id,
@@ -847,9 +847,7 @@ WHERE s.id in (select server from deliveryservice_server where deliveryservice =
 			&s.OfflineReason,
 			&s.PhysLocation,
 			&s.PhysLocationID,
-			&s.Profile,
-			&s.ProfileDesc,
-			&s.ProfileID,
+			pq.Array(&s.ProfileNames),
 			&s.Rack,
 			&s.Status,
 			&s.StatusID,
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers_test.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers_test.go
index 6f7eb9f0e6..9c04a80ff3 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers_test.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers_test.go
@@ -20,7 +20,9 @@ package servers
  */
 
 import (
+	"fmt"
 	"strconv"
+	"strings"
 	"testing"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
@@ -106,9 +108,7 @@ func TestReadServers(t *testing.T) {
 		"offline_reason",
 		"phys_location",
 		"phys_location_id",
-		"profile",
-		"profile_desc",
-		"profile_id",
+		"profile_name",
 		"rack",
 		"status",
 		"status_id",
@@ -142,9 +142,7 @@ func TestReadServers(t *testing.T) {
 			s.OfflineReason,
 			s.PhysLocation,
 			s.PhysLocationID,
-			s.Profile,
-			s.ProfileDesc,
-			s.ProfileID,
+			fmt.Sprintf("{%s}", strings.Join(s.ProfileNames, ",")),
 			s.Rack,
 			s.Status,
 			s.StatusID,
@@ -185,8 +183,8 @@ func TestReadServers(t *testing.T) {
 	}
 }
 
-func getMockDSServers() []tc.DSServer {
-	base := tc.DSServerBase{
+func getMockDSServers() []tc.DSServerV4 {
+	base := tc.DSServerBaseV4{
 		ID:           util.IntPtr(1),
 		Cachegroup:   util.StrPtr("cgTest"),
 		CachegroupID: util.IntPtr(1),
@@ -194,11 +192,11 @@ func getMockDSServers() []tc.DSServer {
 		CDNName:      util.StrPtr("cdnTest"),
 		DomainName:   util.StrPtr("domain"),
 	}
-	srv := tc.DSServer{
-		DSServerBase:     base,
-		ServerInterfaces: &[]tc.ServerInterfaceInfo{}, // left empty because it must be written as json above since sqlmock does not support nested arrays
+	srv := tc.DSServerV4{
+		DSServerBaseV4:   base,
+		ServerInterfaces: &[]tc.ServerInterfaceInfoV40{}, // left empty because it must be written as json above since sqlmock does not support nested arrays
 	}
-	srvsExpected := []tc.DSServer{srv}
+	srvsExpected := []tc.DSServerV4{srv}
 	return srvsExpected
 }