@ -95,6 +95,33 @@ type Policy struct {
PublicID logtail . PublicID
PublicID logtail . PublicID
}
}
// NewConfig creates a Config with collection and a newly generated PrivateID.
func NewConfig ( collection string ) * Config {
id , err := logtail . NewPrivateID ( )
if err != nil {
panic ( "logtail.NewPrivateID should never fail" )
}
return & Config {
Collection : collection ,
PrivateID : id ,
PublicID : id . Public ( ) ,
}
}
// Validate verifies that the Config matches the collection,
// and that the PrivateID and PublicID pair are sensible.
func ( c * Config ) Validate ( collection string ) error {
switch {
case c . Collection != collection :
return fmt . Errorf ( "config collection %q does not match %q" , c . Collection , collection )
case c . PrivateID . IsZero ( ) :
return errors . New ( "config has zero PrivateID" )
case c . PrivateID . Public ( ) != c . PublicID :
return errors . New ( "config PrivateID does not match PublicID" )
}
return nil
}
// ToBytes returns the JSON representation of c.
// ToBytes returns the JSON representation of c.
func ( c * Config ) ToBytes ( ) [ ] byte {
func ( c * Config ) ToBytes ( ) [ ] byte {
data , err := json . MarshalIndent ( c , "" , "\t" )
data , err := json . MarshalIndent ( c , "" , "\t" )
@ -105,7 +132,7 @@ func (c *Config) ToBytes() []byte {
}
}
// Save writes the JSON representation of c to stateFile.
// Save writes the JSON representation of c to stateFile.
func ( c * Config ) s ave( stateFile string ) error {
func ( c * Config ) S ave( stateFile string ) error {
c . PublicID = c . PrivateID . Public ( )
c . PublicID = c . PrivateID . Public ( )
if err := os . MkdirAll ( filepath . Dir ( stateFile ) , 0750 ) ; err != nil {
if err := os . MkdirAll ( filepath . Dir ( stateFile ) , 0750 ) ; err != nil {
return err
return err
@ -117,7 +144,16 @@ func (c *Config) save(stateFile string) error {
return nil
return nil
}
}
// ConfigFromBytes parses a a Config from its JSON encoding.
// ConfigFromFile reads a Config from a JSON file.
func ConfigFromFile ( statefile string ) ( * Config , error ) {
b , err := os . ReadFile ( statefile )
if err != nil {
return nil , err
}
return ConfigFromBytes ( b )
}
// ConfigFromBytes parses a Config from its JSON encoding.
func ConfigFromBytes ( jsonEnc [ ] byte ) ( * Config , error ) {
func ConfigFromBytes ( jsonEnc [ ] byte ) ( * Config , error ) {
c := & Config { }
c := & Config { }
if err := json . Unmarshal ( jsonEnc , c ) ; err != nil {
if err := json . Unmarshal ( jsonEnc , c ) ; err != nil {
@ -470,38 +506,16 @@ func New(collection string) *Policy {
}
}
}
}
var oldc * Config
newc , err := ConfigFromFile ( cfgPath )
data , err := ioutil . ReadFile ( cfgPath )
if err != nil {
if err != nil {
earlyLogf ( "logpolicy.Read %v: %v" , cfgPath , err )
earlyLogf ( "logpolicy.ConfigFromFile %v: %v" , cfgPath , err )
oldc = & Config { }
newc = NewConfig ( collection )
oldc . Collection = collection
}
} else {
if err := newc . Validate ( collection ) ; err != nil {
oldc , err = ConfigFromBytes ( data )
earlyLogf ( "logpolicy.Config.Validate for %q: %v" , cfgPath , err )
if err != nil {
newc := NewConfig ( collection )
earlyLogf ( "logpolicy.Config unmarshal: %v" , err )
if err := newc . Save ( cfgPath ) ; err != nil {
oldc = & Config { }
earlyLogf ( "logpolicy.Config.Save for %v: %v" , cfgPath , err )
}
}
newc := * oldc
if newc . Collection != collection {
log . Printf ( "logpolicy.Config: config collection %q does not match %q" , newc . Collection , collection )
// We picked up an incompatible config file.
// Regenerate the private ID.
newc . PrivateID = logtail . PrivateID { }
newc . Collection = collection
}
if newc . PrivateID . IsZero ( ) {
newc . PrivateID , err = logtail . NewPrivateID ( )
if err != nil {
log . Fatalf ( "logpolicy: NewPrivateID() should never fail" )
}
}
newc . PublicID = newc . PrivateID . Public ( )
if newc != * oldc {
if err := newc . save ( cfgPath ) ; err != nil {
earlyLogf ( "logpolicy.Config.Save: %v" , err )
}
}
}
}