From 1f364483e30cdc8317c237d7378e7fda3b2d9c86 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sun, 20 Sep 2015 17:12:45 -0700 Subject: [PATCH] Add list of servers, for controller args. --- controller-rpc.go | 97 +++++++++++++++++++++++++++++++----------- controller_rpc_test.go | 18 +++++--- rpc-definitions.go | 36 ++++++++++------ server-rpc.go | 21 +++------ 4 files changed, 113 insertions(+), 59 deletions(-) diff --git a/controller-rpc.go b/controller-rpc.go index 450200bf7..91ceb18a6 100644 --- a/controller-rpc.go +++ b/controller-rpc.go @@ -19,6 +19,7 @@ package main import ( "errors" "net/http" + "net/url" "os" "strings" @@ -29,7 +30,7 @@ import ( ) type controllerRPCService struct { - serverList []ServerArg + serverList []ServerRep } func makeDonut(args *DonutArgs, reply *DefaultRep) *probe.Error { @@ -171,46 +172,92 @@ func (s *controllerRPCService) ResetAuth(r *http.Request, args *AuthArgs, reply return nil } -func proxyRequest(method string, url string, arg interface{}, res interface{}) error { - // can be configured to something else in future +func proxyRequest(method, host string, ssl bool, res interface{}) *probe.Error { + u := &url.URL{ + Scheme: func() string { + if ssl { + return "https" + } + return "http" + }(), + Host: host, + Path: "/rpc", + } op := rpcOperation{ Method: method, - Request: arg, + Request: ServerArg{}, } - request, _ := newRPCRequest(url, op, nil) - resp, err := request.Do() + request, err := newRPCRequest(u.String(), op, nil) if err != nil { - return probe.WrapError(err) + return err.Trace() } - decodeerr := json.DecodeClientResponse(resp.Body, res) - return decodeerr -} - -func (s *controllerRPCService) AddServer(r *http.Request, arg *ServerArg, res *DefaultRep) error { - err := proxyRequest("Server.Add", arg.URL, arg, res) - if err == nil { - s.serverList = append(s.serverList, *arg) + var resp *http.Response + resp, err = request.Do() + if err != nil { + return err.Trace() } - return err + if err := json.DecodeClientResponse(resp.Body, res); err != nil { + return probe.NewError(err) + } + return nil } -func (s *controllerRPCService) GetServerMemStats(r *http.Request, arg *ServerArg, res *MemStatsRep) error { - return proxyRequest("Server.MemStats", arg.URL, arg, res) +func (s *controllerRPCService) AddServer(r *http.Request, args *ControllerArgs, res *ServerRep) error { + for _, host := range args.Hosts { + err := proxyRequest("Server.Add", host, args.SSL, res) + if err != nil { + return probe.WrapError(err) + } + s.serverList = append(s.serverList, *res) + } + return nil } -func (s *controllerRPCService) GetServerDiskStats(r *http.Request, arg *ServerArg, res *DiskStatsRep) error { - return proxyRequest("Server.DiskStats", arg.URL, arg, res) +func (s *controllerRPCService) GetServerMemStats(r *http.Request, args *ControllerArgs, res *MemStatsRep) error { + for _, host := range args.Hosts { + err := proxyRequest("Server.MemStats", host, args.SSL, res) + if err != nil { + return probe.WrapError(err) + } + return nil + } + return errors.New("Invalid argument") } -func (s *controllerRPCService) GetServerSysInfo(r *http.Request, arg *ServerArg, res *SysInfoRep) error { - return proxyRequest("Server.SysInfo", arg.URL, arg, res) +func (s *controllerRPCService) GetServerDiskStats(r *http.Request, args *ControllerArgs, res *DiskStatsRep) error { + for _, host := range args.Hosts { + err := proxyRequest("Server.DiskStats", host, args.SSL, res) + if err != nil { + return probe.WrapError(err) + } + return nil + } + return errors.New("Invalid argument") } -func (s *controllerRPCService) ListServers(r *http.Request, arg *ServerArg, res *ListRep) error { +func (s *controllerRPCService) GetServerSysInfo(r *http.Request, args *ControllerArgs, res *SysInfoRep) error { + for _, host := range args.Hosts { + err := proxyRequest("Server.SysInfo", host, args.SSL, res) + if err != nil { + return probe.WrapError(err) + } + return nil + } + return errors.New("Invalid argument") +} + +func (s *controllerRPCService) ListServers(r *http.Request, args *ControllerArgs, res *ListRep) error { res.List = s.serverList return nil } -func (s *controllerRPCService) GetServerVersion(r *http.Request, arg *ServerArg, res *VersionRep) error { - return proxyRequest("Server.Version", arg.URL, arg, res) +func (s *controllerRPCService) GetServerVersion(r *http.Request, args *ControllerArgs, res *VersionRep) error { + for _, host := range args.Hosts { + err := proxyRequest("Server.Version", host, args.SSL, res) + if err != nil { + return probe.WrapError(err) + } + return nil + } + return errors.New("Invalid argument") } diff --git a/controller_rpc_test.go b/controller_rpc_test.go index 233ac0325..f83ceb673 100644 --- a/controller_rpc_test.go +++ b/controller_rpc_test.go @@ -20,6 +20,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "net/url" "os" "github.com/gorilla/rpc/v2/json" @@ -29,6 +30,7 @@ import ( type ControllerRPCSuite struct { root string + url *url.URL } var _ = Suite(&ControllerRPCSuite{}) @@ -48,6 +50,10 @@ func (s *ControllerRPCSuite) SetUpSuite(c *C) { testServerRPC = httptest.NewUnstartedServer(getServerRPCHandler()) testServerRPC.Config.Addr = ":9002" testServerRPC.Start() + + url, gerr := url.Parse(testServerRPC.URL) + c.Assert(gerr, IsNil) + s.url = url } func (s *ControllerRPCSuite) TearDownSuite(c *C) { @@ -59,7 +65,7 @@ func (s *ControllerRPCSuite) TearDownSuite(c *C) { func (s *ControllerRPCSuite) TestMemStats(c *C) { op := rpcOperation{ Method: "Controller.GetServerMemStats", - Request: ServerArg{URL: testServerRPC.URL + "/rpc"}, + Request: ControllerArgs{Hosts: []string{s.url.Host}}, } req, err := newRPCRequest(testControllerRPC.URL+"/rpc", op, http.DefaultTransport) c.Assert(err, IsNil) @@ -77,7 +83,7 @@ func (s *ControllerRPCSuite) TestMemStats(c *C) { func (s *ControllerRPCSuite) TestDiskStats(c *C) { op := rpcOperation{ Method: "Controller.GetServerDiskStats", - Request: ServerArg{URL: testServerRPC.URL + "/rpc"}, + Request: ControllerArgs{Hosts: []string{s.url.Host}}, } req, err := newRPCRequest(testControllerRPC.URL+"/rpc", op, http.DefaultTransport) c.Assert(err, IsNil) @@ -95,7 +101,7 @@ func (s *ControllerRPCSuite) TestDiskStats(c *C) { func (s *ControllerRPCSuite) TestSysInfo(c *C) { op := rpcOperation{ Method: "Controller.GetServerSysInfo", - Request: ServerArg{URL: testServerRPC.URL + "/rpc"}, + Request: ControllerArgs{Hosts: []string{s.url.Host}}, } req, err := newRPCRequest(testControllerRPC.URL+"/rpc", op, http.DefaultTransport) c.Assert(err, IsNil) @@ -113,7 +119,7 @@ func (s *ControllerRPCSuite) TestSysInfo(c *C) { func (s *ControllerRPCSuite) TestServerList(c *C) { op := rpcOperation{ Method: "Controller.ListServers", - Request: ServerArg{URL: testServerRPC.URL + "/rpc"}, + Request: ControllerArgs{Hosts: []string{s.url.Host}}, } req, err := newRPCRequest(testControllerRPC.URL+"/rpc", op, http.DefaultTransport) c.Assert(err, IsNil) @@ -125,13 +131,13 @@ func (s *ControllerRPCSuite) TestServerList(c *C) { var reply ServerListRep c.Assert(json.DecodeClientResponse(resp.Body, &reply), IsNil) resp.Body.Close() - c.Assert(reply, Not(DeepEquals), ServerListRep{}) + c.Assert(reply, Not(DeepEquals), ServerListRep{List: []ServerRep{}}) } func (s *ControllerRPCSuite) TestServerAdd(c *C) { op := rpcOperation{ Method: "Controller.AddServer", - Request: ServerArg{URL: testServerRPC.URL + "/rpc"}, + Request: ControllerArgs{Hosts: []string{s.url.Host}}, } req, err := newRPCRequest(testControllerRPC.URL+"/rpc", op, http.DefaultTransport) c.Assert(err, IsNil) diff --git a/rpc-definitions.go b/rpc-definitions.go index 477084868..5edd1a75a 100644 --- a/rpc-definitions.go +++ b/rpc-definitions.go @@ -16,6 +16,8 @@ package main +//// In memory metadata + //// RPC params // AuthArgs auth params @@ -31,20 +33,22 @@ type DonutArgs struct { Disks []string } -// ServerArg server metadata to identify a server -type ServerArg struct { - Name string `json:"name"` - URL string `json:"url"` - ID string `json:"id"` +// ServerArg server params +type ServerArg struct{} + +// ControllerArgs controller params +type ControllerArgs struct { + Hosts []string `json:"hosts"` // hosts is a collection of host or host:port + SSL bool `json:"ssl"` + ID string `json:"id"` } //// RPC replies // ServerRep server reply container for Server.List type ServerRep struct { - Name string `json:"name"` - Address string `json:"address"` - ID string `json:"id"` + Host string `json:"host"` + ID string `json:"id"` } // DefaultRep default reply @@ -69,13 +73,17 @@ type MemStatsRep struct { Free uint64 `json:"free"` } +// Network metadata of a server +type Network struct { + IP string `json:"address"` + NetMask string `json:"netmask"` + Hostname string `json:"hostname"` + Ethernet string `json:"networkInterface"` +} + // NetStatsRep network statistics of a server type NetStatsRep struct { - Interfaces []struct { - IP string `json:"address"` - Mask string `json:"netmask"` - Ethernet string `json:"networkInterface"` - } + Interfaces []Network } // SysInfoRep system information of a server @@ -90,7 +98,7 @@ type SysInfoRep struct { // ListRep all servers list type ListRep struct { - List []ServerArg `json:"list"` + List []ServerRep `json:"list"` } // VersionRep version reply diff --git a/server-rpc.go b/server-rpc.go index c1498256e..14b9a2395 100644 --- a/server-rpc.go +++ b/server-rpc.go @@ -26,9 +26,11 @@ import ( type serverRPCService struct{} -func (s *serverRPCService) Add(r *http.Request, arg *ServerArg, rep *DefaultRep) error { - rep.Message = "Server " + arg.URL + " added successfully" - rep.Error = nil +func (s *serverRPCService) Add(r *http.Request, arg *ServerArg, rep *ServerRep) error { + rep = &ServerRep{ + Host: "192.168.1.1:9002", + ID: "6F27CB16-493D-40FA-B035-2A2E5646066A", + } return nil } @@ -58,17 +60,8 @@ func (s *serverRPCService) SysInfo(r *http.Request, arg *ServerArg, rep *SysInfo } func (s *serverRPCService) NetStats(r *http.Request, arg *ServerArg, rep *NetStatsRep) error { - rep.Interfaces = []struct { - IP string `json:"address"` - Mask string `json:"netmask"` - Ethernet string `json:"networkInterface"` - }{ - { - "192.168.1.1", - "255.255.255.0", - "eth0", - }, - } + rep.Interfaces = make([]Network, 0) + rep.Interfaces = append(rep.Interfaces, Network{IP: "192.168.1.1", NetMask: "255.255.255.0", Hostname: "hostname1", Ethernet: "eth0"}) return nil }