Skip to content

Commit

Permalink
feat: Report deleted configs in stunnerctl
Browse files Browse the repository at this point in the history
  • Loading branch information
rg0now committed Feb 7, 2024
1 parent 8b7f545 commit 530320c
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
4 changes: 4 additions & 0 deletions cmd/stunnerctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ func runConfig(cmd *cobra.Command, args []string) error {
}

for c := range confChan {
if cdsclient.IsConfigDeleted(c) {
fmt.Printf("Gateway: %s <deleted>\n", c.Admin.Name)
continue
}
switch output {
case "yaml":
if out, err := yaml.Marshal(c); err != nil {
Expand Down
6 changes: 2 additions & 4 deletions pkg/config/cds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -946,17 +946,15 @@ func TestServerAPI(t *testing.T) {
assert.NotNil(t, findConfById(lst, "ns3/gw1"))
assert.True(t, findConfById(lst, "ns3/gw1").DeepEqual(sc4), "deepeq")
assert.NotNil(t, findConfById(lst, "ns1/gw2"))
gw2zero := client.ZeroConfig("ns1/gw2") // deleted!
assert.NoError(t, gw2zero.Validate())
assert.True(t, findConfById(lst, "ns1/gw2").DeepEqual(gw2zero), "deepeq")
assert.True(t, client.IsConfigDeleted(findConfById(lst, "ns1/gw2")), "deepeq")

// 1 config from client2 watch (removed config never updated)
s1 = watchConfig(ch2, 50*time.Millisecond)
assert.NotNil(t, s1)
s2 = watchConfig(ch2, 50*time.Millisecond)
assert.NotNil(t, s2)
assert.True(t, s1.DeepEqual(sc1), "deepeq")
assert.True(t, s2.DeepEqual(gw2zero), "deepeq") // deleted!
assert.True(t, client.IsConfigDeleted(s2), "deepeq") // deleted!

// no config from client3 watch
s = watchConfig(ch3, 50*time.Millisecond)
Expand Down
16 changes: 16 additions & 0 deletions pkg/config/client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,19 @@ func parseRaw(c []byte) (*stnrv1.StunnerConfig, error) {

return &s, nil
}

// IsConfigDeleted is a helper that allows to decide whether a config is being deleted. When a
// config is being removed (say, because the corresponding Gateway is deleted), the CDS server
// sends a validated zero-config for the client. This function is a quick helper to decide whether
// the config received is such a zero-config.
func IsConfigDeleted(conf *stnrv1.StunnerConfig) bool {
if conf == nil {
return false
}
zeroConf := ZeroConfig(conf.Admin.Name)
// zeroconfs have to be explcitly validated before deepEq (the cds client validates)
if err := zeroConf.Validate(); err != nil {
return false
}
return conf.DeepEqual(zeroConf)
}
12 changes: 5 additions & 7 deletions pkg/config/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ func (s *Server) Start(ctx context.Context) error {
s.broadcastConfig(c)

case c := <-s.deleteCh:
// delayed config deletion
s.log.V(2).Info("initiating deleyed config deletion", "id", c.Id)

go func() {
select {
case <-ctx.Done():
Expand Down Expand Up @@ -206,15 +207,12 @@ func (s *Server) sendConfig(conn *Conn, e *stnrv1.StunnerConfig) {

json, err := json.Marshal(c)
if err != nil {
s.log.Error(err, "cannor JSON serialize config", "event", e.String())
s.log.Error(err, "cannot JSON serialize config", "event", e.String())
return
}

s.sendJSONConfig(conn, json)
}

func (s *Server) sendJSONConfig(conn *Conn, json []byte) {
s.log.V(2).Info("sending configuration to client", "client", conn.Id())
s.log.V(2).Info("sending configuration to client", "client", conn.Id(),
"config", c.String())

if err := conn.WriteMessage(websocket.TextMessage, json); err != nil {
s.log.Error(err, "error sending config update", "client", conn.Id())
Expand Down

0 comments on commit 530320c

Please sign in to comment.