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 | |
Serge Bazanski | 26f1ee8 | 2018-10-25 12:45:00 +0100 | [diff] [blame] | 10 | ipb "code.hackerspace.pl/hscloud/go/proto/infra" |
Serge Bazanski | 477ffe7 | 2018-10-25 05:36:18 -0700 | [diff] [blame] | 11 | pb "code.hackerspace.pl/hscloud/go/svc/topo/proto" |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 12 | |
Serge Bazanski | ab55cca | 2018-10-25 12:35:55 +0100 | [diff] [blame] | 13 | "code.hackerspace.pl/hscloud/go/pki" |
Serge Bazanski | a758ef5 | 2018-10-06 17:54:25 +0100 | [diff] [blame] | 14 | ) |
| 15 | |
| 16 | type SwitchportState struct { |
Serge Bazanski | 26f1ee8 | 2018-10-25 12:45:00 +0100 | [diff] [blame] | 17 | Proto *ipb.SwitchPort |
Serge Bazanski | a758ef5 | 2018-10-06 17:54:25 +0100 | [diff] [blame] | 18 | } |
| 19 | |
| 20 | type SwitchState struct { |
| 21 | Name string |
| 22 | Ports []*SwitchportState |
Serge Bazanski | 26f1ee8 | 2018-10-25 12:45:00 +0100 | [diff] [blame] | 23 | Stub ipb.SwitchControlClient |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 24 | } |
| 25 | |
| 26 | func (s *SwitchState) Fetch(ctx context.Context) error { |
Serge Bazanski | 26f1ee8 | 2018-10-25 12:45:00 +0100 | [diff] [blame] | 27 | req := ipb.GetPortsRequest{} |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 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 | |
Serge Bazanski | 477ffe7 | 2018-10-25 05:36:18 -0700 | [diff] [blame] | 52 | func (s *StateManager) FetchState(ctx context.Context, conf *pb.Config) error { |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 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 |
Serge Bazanski | ab55cca | 2018-10-25 12:35:55 +0100 | [diff] [blame] | 59 | conn, err = grpc.Dial(sw.ControlAddress, pki.WithClientHSPKI()) |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 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, |
Serge Bazanski | 26f1ee8 | 2018-10-25 12:45:00 +0100 | [diff] [blame] | 68 | Stub: ipb.NewSwitchControlClient(conn), |
Serge Bazanski | 16e4ba2 | 2018-10-07 00:22:52 +0100 | [diff] [blame] | 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 | } |