hscloud/go/svc/topo/state/state.go

77 lines
1.6 KiB
Go

package state
import (
"context"
"fmt"
"sync"
"google.golang.org/grpc"
ipb "code.hackerspace.pl/hscloud/go/proto/infra"
confpb "code.hackerspace.pl/hscloud/go/svc/topo/proto/config"
"code.hackerspace.pl/hscloud/go/pki"
)
type SwitchportState struct {
Proto *ipb.SwitchPort
}
type SwitchState struct {
Name string
Ports []*SwitchportState
Stub ipb.SwitchControlClient
}
func (s *SwitchState) Fetch(ctx context.Context) error {
req := ipb.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 *confpb.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: ipb.NewSwitchControlClient(conn),
}
err := s.Switches[sw.Name].Fetch(ctx)
if err != nil {
return fmt.Errorf("%q.Fetch: %v", sw.Name, err)
}
}
return nil
}