Repository: skupperproject/skupper
Pull request #1684 (2024-09-24 17:23:53)

Add fields to /routerlinks collector API
Expose additional context around a link. Adds router name, destination/peer router ID and name, renames peer to routerAccessId for clarity.


Patch:
diff --git a/cmd/network-console-collector/internal/api/types_gen.go b/cmd/network-console-collector/internal/api/types_gen.go
index dc01fe8a..60b931f0 100644
--- a/cmd/network-console-collector/internal/api/types_gen.go
+++ b/cmd/network-console-collector/internal/api/types_gen.go
@@ -474,10 +474,16 @@ type RouterLinkRecord struct {
 	// Cost When connected, cost will be set to the link cost attribute
 	Cost *uint64 `json:"cost"`
 
+	// DestinationRouterId When connected, the identity of the destitation (peer) router.
+	DestinationRouterId *string `json:"destinationRouterId"`
+
+	// DestinationRouterName When connected, the name of the destitation (peer) router.
+	DestinationRouterName *string `json:"destinationRouterName"`
+
 	// DestinationSiteId When connected, the identity of the destitation (peer) site.
 	DestinationSiteId *string `json:"destinationSiteId"`
 
-	// DestinationSiteName When connected, the identity of the destitation (peer) site.
+	// DestinationSiteName When connected, the name of the destitation (peer) site.
 	DestinationSiteName *string `json:"destinationSiteName"`
 
 	// EndTime The end time in microseconds of the record in Unix timestamp format.
@@ -489,14 +495,15 @@ type RouterLinkRecord struct {
 	Octets        uint64 `json:"octets"`
 	OctetsReverse uint64 `json:"octetsReverse"`
 
-	// Peer When connected, peer will be set to the identity of a peer router access
-	Peer *string `json:"peer"`
-
 	// Role The class of skupper link
-	Role           LinkRoleType `json:"role"`
-	RouterId       string       `json:"routerId"`
-	SourceSiteId   string       `json:"sourceSiteId"`
-	SourceSiteName string       `json:"sourceSiteName"`
+	Role LinkRoleType `json:"role"`
+
+	// RouterAccessId When connected, the identity of the destitation (peer) router access.
+	RouterAccessId *string `json:"routerAccessId"`
+	RouterId       string  `json:"routerId"`
+	RouterName     string  `json:"routerName"`
+	SourceSiteId   string  `json:"sourceSiteId"`
+	SourceSiteName string  `json:"sourceSiteName"`
 
 	// StartTime The creation time in microseconds of the record in Unix timestamp format. The value 0 means that the record is not terminated
 	StartTime uint64         `json:"startTime"`
diff --git a/cmd/network-console-collector/internal/server/views/views.go b/cmd/network-console-collector/internal/server/views/views.go
index 7e79df11..06aa3a75 100644
--- a/cmd/network-console-collector/internal/server/views/views.go
+++ b/cmd/network-console-collector/internal/server/views/views.go
@@ -396,14 +396,21 @@ func NewRouterLinkProvider(graph collector.Graph) func(vanflow.LinkRecord) (api.
 		if link.Parent == nil {
 			return out, false
 		}
-		siteNode := graph.Link(link.ID).Parent().Parent()
+		routerNode := graph.Link(link.ID).Parent()
+		sourceRouter, found := routerNode.GetRecord()
+		if !found {
+			return out, false
+		}
+		siteNode := routerNode.Parent()
 		sourceSite, found := siteNode.GetRecord()
 		if !found {
 			return out, false
 		}
+
+		out.RouterId = sourceRouter.ID
 		out.SourceSiteId = sourceSite.ID
+		setOpt(&out.RouterName, sourceRouter.Name)
 		setOpt(&out.SourceSiteName, sourceSite.Name)
-		setOpt(&out.RouterId, link.Parent)
 		setOpt(&out.Name, link.Name)
 
 		if link.Role != nil {
@@ -422,11 +429,20 @@ func NewRouterLinkProvider(graph collector.Graph) func(vanflow.LinkRecord) (api.
 		if link.Peer == nil {
 			return out, true
 		}
-		out.Peer = link.Peer
+		out.RouterAccessId = link.Peer
 		out.Cost = link.LinkCost
 
 		raN := graph.RouterAccess(*link.Peer)
-		raSiteN := raN.Parent().Parent()
+		raRouterN := raN.Parent()
+		raSiteN := raRouterN.Parent()
+		if destRouter, found := raRouterN.GetRecord(); found {
+			out.DestinationRouterId = &destRouter.ID
+			if destRouter.Name == nil {
+				tmp := unknownStr
+				destRouter.Name = &tmp
+			}
+			out.DestinationRouterName = destRouter.Name
+		}
 		if destSite, found := raSiteN.GetRecord(); found {
 			out.DestinationSiteId = &destSite.ID
 			if destSite.Name == nil {
@@ -447,6 +463,7 @@ func defaultRouterLink(id string) api.RouterLinkRecord {
 		Name:           unknownStr,
 		Role:           api.LinkRoleTypeUnknown,
 		RouterId:       unknownStr,
+		RouterName:     unknownStr,
 		SourceSiteId:   unknownStr,
 		SourceSiteName: unknownStr,
 		Status:         api.Down,
diff --git a/cmd/network-console-collector/spec/openapi.yaml b/cmd/network-console-collector/spec/openapi.yaml
index fa8463cb..b6ca594c 100644
--- a/cmd/network-console-collector/spec/openapi.yaml
+++ b/cmd/network-console-collector/spec/openapi.yaml
@@ -1138,20 +1138,25 @@ components:
         - type: object
           required:
             - routerId
+            - routerName
             - name
             - cost
             - role
-            - peer
             - status
             - octets
             - octetsReverse
             - sourceSiteId
-            - destinationSiteId
             - sourceSiteName
+            - destinationSiteId
             - destinationSiteName
+            - routerAccessId
+            - destinationRouterId
+            - destinationRouterName
           properties:
             routerId:
               type: string
+            routerName:
+              type: string
             name:
               type: string
             cost:
@@ -1161,10 +1166,6 @@ components:
               description: When connected, cost will be set to the link cost attribute
             role:
               $ref: '#/components/schemas/linkRoleType'
-            peer:
-              type: string
-              nullable: true
-              description: When connected, peer will be set to the identity of a peer router access
             status:
               $ref: '#/components/schemas/operStatusType'
             octets:
@@ -1173,6 +1174,18 @@ components:
             octetsReverse:
               type: integer
               format: uint64
+            routerAccessId:
+              type: string
+              nullable: true
+              description: When connected, the identity of the destitation (peer) router access.
+            destinationRouterId:
+              type: string
+              nullable: true
+              description: When connected, the identity of the destitation (peer) router.
+            destinationRouterName:
+              type: string
+              nullable: true
+              description: When connected, the name of the destitation (peer) router.
             sourceSiteId:
               type: string
             sourceSiteName:
@@ -1184,7 +1197,7 @@ components:
             destinationSiteName:
               type: string
               nullable: true
-              description: When connected, the identity of the destitation (peer) site.
+              description: When connected, the name of the destitation (peer) site.
     RouterAccessRecord:
       allOf:
         - $ref: '#/components/schemas/baseRecord'


Test patch:
diff --git a/cmd/network-console-collector/internal/server/links_test.go b/cmd/network-console-collector/internal/server/links_test.go
index c799265c..ee44ff01 100644
--- a/cmd/network-console-collector/internal/server/links_test.go
+++ b/cmd/network-console-collector/internal/server/links_test.go
@@ -57,6 +57,7 @@ func TestRouterlinks(t *testing.T) {
 						Name:       ptrTo("linkb2"),
 						Status:     ptrTo("up"),
 						Peer:       ptrTo("routeraccess-a-1"),
+						LinkCost:   ptrTo(uint64(3)),
 					},
 				)...,
 			),
@@ -69,16 +70,20 @@ func TestRouterlinks(t *testing.T) {
 				assert.Equal(t, string(link1.Status), "down")
 				assert.Equal(t, link2.SourceSiteName, "site b")
 				assert.DeepEqual(t, link2, api.RouterLinkRecord{
-					Identity:            "link2",
-					Status:              api.Up,
-					Name:                "linkb2",
-					Role:                "unknown",
-					RouterId:            "router-b-2",
-					SourceSiteId:        "site-b",
-					SourceSiteName:      "site b",
-					Peer:                ptrTo("routeraccess-a-1"),
-					DestinationSiteId:   ptrTo("site-a"),
-					DestinationSiteName: ptrTo("site a"),
+					Identity:              "link2",
+					Cost:                  ptrTo(uint64(3)),
+					Status:                api.Up,
+					Name:                  "linkb2",
+					Role:                  "unknown",
+					RouterId:              "router-b-2",
+					RouterName:            "router b.2",
+					SourceSiteId:          "site-b",
+					SourceSiteName:        "site b",
+					RouterAccessId:        ptrTo("routeraccess-a-1"),
+					DestinationSiteId:     ptrTo("site-a"),
+					DestinationSiteName:   ptrTo("site a"),
+					DestinationRouterId:   ptrTo("router-a-1"),
+					DestinationRouterName: ptrTo("router a.1"),
 				})
 			},
 		},