@@ -3,6 +3,7 @@ package uyuni
33import (
44 "errors"
55 "log"
6+ "sync"
67
78 "github.com/uyuni-project/hub-xmlrpc-api/gateway"
89)
@@ -12,17 +13,24 @@ const (
1213 listSystemsWithEntitlementPath = "system.listSystemsWithEntitlement"
1314 listSystemFQDNsPath = "system.listFqdns"
1415 listUserSystemsPath = "system.listUserSystems"
16+ listPeripheralServersPath = "sync.hub.listPeripheralServers"
1517 systemIDField = "id"
1618 peripheralServerEntitlement = "peripheral_server"
1719)
1820
1921type uyuniTopologyInfoRetriever struct {
2022 uyuniCallExecutor * uyuniCallExecutor
2123 useSSL bool
24+ serverEndpoints map [int64 ]string
25+ mu sync.RWMutex
2226}
2327
2428func NewUyuniTopologyInfoRetriever (uyuniCallExecutor * uyuniCallExecutor , useSSL bool ) * uyuniTopologyInfoRetriever {
25- return & uyuniTopologyInfoRetriever {uyuniCallExecutor , useSSL }
29+ return & uyuniTopologyInfoRetriever {
30+ uyuniCallExecutor : uyuniCallExecutor ,
31+ useSSL : useSSL ,
32+ serverEndpoints : make (map [int64 ]string ),
33+ }
2634}
2735
2836func (h * uyuniTopologyInfoRetriever ) RetrieveUserServerIDs (endpoint , sessionKey , username string ) ([]int64 , error ) {
@@ -60,14 +68,41 @@ func contains(s []int64, v int64) bool {
6068}
6169
6270func (h * uyuniTopologyInfoRetriever ) ListServerIDs (endpoint , sessionKey string ) ([]int64 , error ) {
71+ peripheralServers , err := h .uyuniCallExecutor .ExecuteCall (endpoint , listPeripheralServersPath , []interface {}{sessionKey })
72+ if err != nil {
73+ log .Printf ("Error occured while calling listPeripheralServersPath: %v" , err )
74+ } else {
75+ serversSlice := peripheralServers .([]interface {})
76+ systemIDs := make ([]int64 , len (serversSlice ))
77+ h .mu .Lock ()
78+ defer h .mu .Unlock ()
79+ for i , s := range serversSlice {
80+ server := s .(map [string ]interface {})
81+ id := server ["id" ].(int64 )
82+ fqdn := server ["fqdn" ].(string )
83+ rootCA := server ["root_ca" ].(string )
84+ systemIDs [i ] = id
85+
86+ serverEndpoint := constructEndpoint (fqdn , h .useSSL )
87+ h .serverEndpoints [id ] = serverEndpoint
88+ if rootCA != "" {
89+ err := h .uyuniCallExecutor .client .AddRootCA ([]byte (rootCA ))
90+ if err != nil {
91+ log .Printf ("Error ocurred while adding root CA for serverID %v: %v" , id , err )
92+ }
93+ }
94+ }
95+ return systemIDs , nil
96+ }
97+
6398 systemList , err := h .uyuniCallExecutor .ExecuteCall (endpoint , listSystemsWithEntitlementPath , []interface {}{sessionKey , peripheralServerEntitlement })
6499 if err != nil {
65100 log .Printf ("Error occured while retrieving the list of serverIDs: %v" , err )
66101 return nil , err
67102 }
68103 systemsSlice := systemList .([]interface {})
69104 if len (systemsSlice ) == 0 {
70- // No entitled servers - fallback to full list, for legacy HUB server
105+ // No entitled servers - fallback to full list, for legacy HUB server
71106 systemList , err = h .uyuniCallExecutor .ExecuteCall (endpoint , listSystemsPath , []interface {}{sessionKey })
72107 if err != nil {
73108 log .Printf ("Error occured while retrieving the list of serverIDs: %v" , err )
@@ -87,12 +122,21 @@ func (h *uyuniTopologyInfoRetriever) RetrieveServerAPIEndpoints(endpoint, sessio
87122 serverAPIEndpointByServer := make (map [int64 ]string )
88123 failedServers := make (map [int64 ]string )
89124 for _ , serverID := range serverIDs {
90- serverAPIEndpoint , err := h .retrieveServerAPIEndpoint (endpoint , sessionKey , serverID )
91- if err != nil {
92- failedServers [serverID ] = err .Error ()
93- } else {
94- serverAPIEndpointByServer [serverID ] = serverAPIEndpoint
125+ h .mu .RLock ()
126+ serverAPIEndpoint , ok := h .serverEndpoints [serverID ]
127+ h .mu .RUnlock ()
128+ if ! ok {
129+ var err error
130+ serverAPIEndpoint , err = h .retrieveServerAPIEndpoint (endpoint , sessionKey , serverID )
131+ if err != nil {
132+ failedServers [serverID ] = err .Error ()
133+ continue
134+ }
135+ h .mu .Lock ()
136+ h .serverEndpoints [serverID ] = serverAPIEndpoint
137+ h .mu .Unlock ()
95138 }
139+ serverAPIEndpointByServer [serverID ] = serverAPIEndpoint
96140 }
97141 return & gateway.RetrieveServerAPIEndpointsResponse {serverAPIEndpointByServer , failedServers }, nil
98142}
@@ -122,9 +166,13 @@ func parseFQDN(fqdnResponse interface{}, useSSL bool) (string, error) {
122166 log .Printf ("Error ocurred when parsing the FQDNs of peripheral servers" )
123167 return "" , errors .New ("Error ocurred when parsing the FQDNs of peripheral servers" )
124168 }
169+ return constructEndpoint (firstFqdn , useSSL ), nil
170+ }
171+
172+ func constructEndpoint (fqdn string , useSSL bool ) string {
125173 protocol := "http://"
126174 if useSSL {
127175 protocol = "https://"
128176 }
129- return protocol + firstFqdn + "/rpc/api" , nil
177+ return protocol + fqdn + "/rpc/api"
130178}
0 commit comments