| package state |
| |
| import ( |
| "context" |
| "fmt" |
| "sync" |
| |
| "google.golang.org/grpc" |
| |
| dpb "code.hackerspace.pl/hscloud/dc/proto" |
| "code.hackerspace.pl/hscloud/go/pki" |
| |
| pb "code.hackerspace.pl/hscloud/dc/topo/proto" |
| ) |
| |
| type SwitchportState struct { |
| Proto *dpb.SwitchPort |
| } |
| |
| type SwitchState struct { |
| Name string |
| Ports []*SwitchportState |
| Stub dpb.SwitchControlClient |
| } |
| |
| func (s *SwitchState) Fetch(ctx context.Context) error { |
| req := dpb.GetPortsRequest{} |
| res, err := s.Stub.GetPorts(ctx, &req) |
| if err != nil { |
| return fmt.Errorf("GetPorts: %v", err) |
| } |
| s.Ports = make([]*SwitchportState, len(res.Ports)) |
| for i, port := range res.Ports { |
| s.Ports[i] = &SwitchportState{port} |
| } |
| return nil |
| } |
| |
| type StateManager struct { |
| Switches map[string]*SwitchState |
| Conns map[string]*grpc.ClientConn |
| Mu sync.RWMutex |
| } |
| |
| func NewManager() *StateManager { |
| return &StateManager{ |
| Switches: make(map[string]*SwitchState), |
| Conns: make(map[string]*grpc.ClientConn), |
| } |
| } |
| |
| func (s *StateManager) FetchState(ctx context.Context, conf *pb.Config) error { |
| s.Mu.Lock() |
| defer s.Mu.Unlock() |
| for _, sw := range conf.Switch { |
| conn, ok := s.Conns[sw.ControlAddress] |
| if !ok { |
| var err error |
| conn, err = grpc.Dial(sw.ControlAddress, pki.WithClientHSPKI()) |
| if err != nil { |
| return fmt.Errorf("when connecting to switch %s: %v", sw.Name, err) |
| } |
| s.Conns[sw.ControlAddress] = conn |
| } |
| |
| s.Switches[sw.Name] = &SwitchState{ |
| Name: sw.Name, |
| Stub: dpb.NewSwitchControlClient(conn), |
| } |
| err := s.Switches[sw.Name].Fetch(ctx) |
| if err != nil { |
| return fmt.Errorf("%q.Fetch: %v", sw.Name, err) |
| } |
| } |
| return nil |
| } |