github.com/slackhq/nebula@v1.9.0/punchy.go (about)

     1  package nebula
     2  
     3  import (
     4  	"sync/atomic"
     5  	"time"
     6  
     7  	"github.com/sirupsen/logrus"
     8  	"github.com/slackhq/nebula/config"
     9  )
    10  
    11  type Punchy struct {
    12  	punch           atomic.Bool
    13  	respond         atomic.Bool
    14  	delay           atomic.Int64
    15  	respondDelay    atomic.Int64
    16  	punchEverything atomic.Bool
    17  	l               *logrus.Logger
    18  }
    19  
    20  func NewPunchyFromConfig(l *logrus.Logger, c *config.C) *Punchy {
    21  	p := &Punchy{l: l}
    22  
    23  	p.reload(c, true)
    24  	c.RegisterReloadCallback(func(c *config.C) {
    25  		p.reload(c, false)
    26  	})
    27  
    28  	return p
    29  }
    30  
    31  func (p *Punchy) reload(c *config.C, initial bool) {
    32  	if initial {
    33  		var yes bool
    34  		if c.IsSet("punchy.punch") {
    35  			yes = c.GetBool("punchy.punch", false)
    36  		} else {
    37  			// Deprecated fallback
    38  			yes = c.GetBool("punchy", false)
    39  		}
    40  
    41  		p.punch.Store(yes)
    42  		if yes {
    43  			p.l.Info("punchy enabled")
    44  		} else {
    45  			p.l.Info("punchy disabled")
    46  		}
    47  
    48  	} else if c.HasChanged("punchy.punch") || c.HasChanged("punchy") {
    49  		//TODO: it should be relatively easy to support this, just need to be able to cancel the goroutine and boot it up from here
    50  		p.l.Warn("Changing punchy.punch with reload is not supported, ignoring.")
    51  	}
    52  
    53  	if initial || c.HasChanged("punchy.respond") || c.HasChanged("punch_back") {
    54  		var yes bool
    55  		if c.IsSet("punchy.respond") {
    56  			yes = c.GetBool("punchy.respond", false)
    57  		} else {
    58  			// Deprecated fallback
    59  			yes = c.GetBool("punch_back", false)
    60  		}
    61  
    62  		p.respond.Store(yes)
    63  
    64  		if !initial {
    65  			p.l.Infof("punchy.respond changed to %v", p.GetRespond())
    66  		}
    67  	}
    68  
    69  	//NOTE: this will not apply to any in progress operations, only the next one
    70  	if initial || c.HasChanged("punchy.delay") {
    71  		p.delay.Store((int64)(c.GetDuration("punchy.delay", time.Second)))
    72  		if !initial {
    73  			p.l.Infof("punchy.delay changed to %s", p.GetDelay())
    74  		}
    75  	}
    76  
    77  	if initial || c.HasChanged("punchy.target_all_remotes") {
    78  		p.punchEverything.Store(c.GetBool("punchy.target_all_remotes", false))
    79  		if !initial {
    80  			p.l.WithField("target_all_remotes", p.GetTargetEverything()).Info("punchy.target_all_remotes changed")
    81  		}
    82  	}
    83  
    84  	if initial || c.HasChanged("punchy.respond_delay") {
    85  		p.respondDelay.Store((int64)(c.GetDuration("punchy.respond_delay", 5*time.Second)))
    86  		if !initial {
    87  			p.l.Infof("punchy.respond_delay changed to %s", p.GetRespondDelay())
    88  		}
    89  	}
    90  }
    91  
    92  func (p *Punchy) GetPunch() bool {
    93  	return p.punch.Load()
    94  }
    95  
    96  func (p *Punchy) GetRespond() bool {
    97  	return p.respond.Load()
    98  }
    99  
   100  func (p *Punchy) GetDelay() time.Duration {
   101  	return (time.Duration)(p.delay.Load())
   102  }
   103  
   104  func (p *Punchy) GetRespondDelay() time.Duration {
   105  	return (time.Duration)(p.respondDelay.Load())
   106  }
   107  
   108  func (p *Punchy) GetTargetEverything() bool {
   109  	return p.punchEverything.Load()
   110  }