blob: 232f9b0da71f77b0001cd751b8ae01a1a27cae5a [file] [log] [blame]
Serge Bazanskia758ef52018-10-06 17:54:25 +01001package state
2
3import (
Serge Bazanski16e4ba22018-10-07 00:22:52 +01004 "context"
5 "fmt"
6 "sync"
7
8 "google.golang.org/grpc"
9
Serge Bazanski26f1ee82018-10-25 12:45:00 +010010 ipb "code.hackerspace.pl/hscloud/go/proto/infra"
Serge Bazanski477ffe72018-10-25 05:36:18 -070011 pb "code.hackerspace.pl/hscloud/go/svc/topo/proto"
Serge Bazanski16e4ba22018-10-07 00:22:52 +010012
Serge Bazanskiab55cca2018-10-25 12:35:55 +010013 "code.hackerspace.pl/hscloud/go/pki"
Serge Bazanskia758ef52018-10-06 17:54:25 +010014)
15
16type SwitchportState struct {
Serge Bazanski26f1ee82018-10-25 12:45:00 +010017 Proto *ipb.SwitchPort
Serge Bazanskia758ef52018-10-06 17:54:25 +010018}
19
20type SwitchState struct {
21 Name string
22 Ports []*SwitchportState
Serge Bazanski26f1ee82018-10-25 12:45:00 +010023 Stub ipb.SwitchControlClient
Serge Bazanski16e4ba22018-10-07 00:22:52 +010024}
25
26func (s *SwitchState) Fetch(ctx context.Context) error {
Serge Bazanski26f1ee82018-10-25 12:45:00 +010027 req := ipb.GetPortsRequest{}
Serge Bazanski16e4ba22018-10-07 00:22:52 +010028 res, err := s.Stub.GetPorts(ctx, &req)
29 if err != nil {
30 return fmt.Errorf("GetPorts: %v", err)
31 }
32 s.Ports = make([]*SwitchportState, len(res.Ports))
33 for i, port := range res.Ports {
34 s.Ports[i] = &SwitchportState{port}
35 }
36 return nil
Serge Bazanskia758ef52018-10-06 17:54:25 +010037}
38
39type StateManager struct {
40 Switches map[string]*SwitchState
Serge Bazanski16e4ba22018-10-07 00:22:52 +010041 Conns map[string]*grpc.ClientConn
42 Mu sync.RWMutex
Serge Bazanskia758ef52018-10-06 17:54:25 +010043}
44
45func NewManager() *StateManager {
46 return &StateManager{
47 Switches: make(map[string]*SwitchState),
Serge Bazanski16e4ba22018-10-07 00:22:52 +010048 Conns: make(map[string]*grpc.ClientConn),
Serge Bazanskia758ef52018-10-06 17:54:25 +010049 }
50}
Serge Bazanski16e4ba22018-10-07 00:22:52 +010051
Serge Bazanski477ffe72018-10-25 05:36:18 -070052func (s *StateManager) FetchState(ctx context.Context, conf *pb.Config) error {
Serge Bazanski16e4ba22018-10-07 00:22:52 +010053 s.Mu.Lock()
54 defer s.Mu.Unlock()
55 for _, sw := range conf.Switch {
56 conn, ok := s.Conns[sw.ControlAddress]
57 if !ok {
58 var err error
Serge Bazanskiab55cca2018-10-25 12:35:55 +010059 conn, err = grpc.Dial(sw.ControlAddress, pki.WithClientHSPKI())
Serge Bazanski16e4ba22018-10-07 00:22:52 +010060 if err != nil {
61 return fmt.Errorf("when connecting to switch %s: %v", sw.Name, err)
62 }
63 s.Conns[sw.ControlAddress] = conn
64 }
65
66 s.Switches[sw.Name] = &SwitchState{
67 Name: sw.Name,
Serge Bazanski26f1ee82018-10-25 12:45:00 +010068 Stub: ipb.NewSwitchControlClient(conn),
Serge Bazanski16e4ba22018-10-07 00:22:52 +010069 }
70 err := s.Switches[sw.Name].Fetch(ctx)
71 if err != nil {
72 return fmt.Errorf("%q.Fetch: %v", sw.Name, err)
73 }
74 }
75 return nil
76}