Serge Bazanski | a758ef5 | 2018-10-06 17:54:25 +0100 | [diff] [blame] | 1 | package state |
| 2 | |
| 3 | import ( |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 4 | "context" |
| 5 | "fmt" |
| 6 | "sync" |
| 7 | |
| 8 | "google.golang.org/grpc" |
| 9 | |
| 10 | cpb "code.hackerspace.pl/q3k/topo/proto/config" |
Serge Bazanski | a758ef5 | 2018-10-06 17:54:25 +0100 | [diff] [blame] | 11 | pb "code.hackerspace.pl/q3k/topo/proto/control" |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 12 | |
| 13 | "code.hackerspace.pl/q3k/hspki" |
Serge Bazanski | a758ef5 | 2018-10-06 17:54:25 +0100 | [diff] [blame] | 14 | ) |
| 15 | |
| 16 | type SwitchportState struct { |
| 17 | Proto *pb.SwitchPort |
| 18 | } |
| 19 | |
| 20 | type SwitchState struct { |
| 21 | Name string |
| 22 | Ports []*SwitchportState |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 23 | Stub pb.SwitchControlClient |
| 24 | } |
| 25 | |
| 26 | func (s *SwitchState) Fetch(ctx context.Context) error { |
| 27 | req := pb.GetPortsRequest{} |
| 28 | 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 Bazanski | a758ef5 | 2018-10-06 17:54:25 +0100 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | type StateManager struct { |
| 40 | Switches map[string]*SwitchState |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 41 | Conns map[string]*grpc.ClientConn |
| 42 | Mu sync.RWMutex |
Serge Bazanski | a758ef5 | 2018-10-06 17:54:25 +0100 | [diff] [blame] | 43 | } |
| 44 | |
| 45 | func NewManager() *StateManager { |
| 46 | return &StateManager{ |
| 47 | Switches: make(map[string]*SwitchState), |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 48 | Conns: make(map[string]*grpc.ClientConn), |
Serge Bazanski | a758ef5 | 2018-10-06 17:54:25 +0100 | [diff] [blame] | 49 | } |
| 50 | } |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 51 | |
| 52 | func (s *StateManager) FetchState(ctx context.Context, conf *cpb.Config) error { |
| 53 | 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 |
| 59 | conn, err = grpc.Dial(sw.ControlAddress, hspki.WithClientHSPKI()) |
| 60 | 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, |
| 68 | Stub: pb.NewSwitchControlClient(conn), |
| 69 | } |
| 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 | } |