package parser import ( "fmt" "github.com/buger/jsonparser" "github.com/magiconair/properties" "github.com/pkg/errors" "go.uber.org/zap" "os" ) type ConfigurationParser string // The file parsing options that are available for a server configuration file. const ( File = "file" Yaml = "yaml" Properties = "properties" Ini = "ini" Json = "json" Xml = "xml" ) // Defines a configuration file for the server startup. These will be looped over // and modified before the server finishes booting. type ConfigurationFile struct { FileName string `json:"file"` Parser ConfigurationParser `json:"parser"` Replace []ConfigurationFileReplacement `json:"replace"` } // Defines a single find/replace instance for a given server configuration file. type ConfigurationFileReplacement struct { Match string `json:"match"` Value string `json:"value"` ValueType jsonparser.ValueType `json:"-"` } func (cfr *ConfigurationFileReplacement) UnmarshalJSON(data []byte) error { if m, err := jsonparser.GetString(data, "match"); err != nil { return err } else { cfr.Match = m } if v, dt, _, err := jsonparser.Get(data, "value"); err != nil { return err } else { if dt != jsonparser.String && dt != jsonparser.Number && dt != jsonparser.Boolean { return errors.New( fmt.Sprintf("cannot parse JSON: received unexpected replacement value type: %d", dt), ) } cfr.Value = string(v) cfr.ValueType = dt } return nil } // Parses a given configuration file and updates all of the values within as defined // in the API response from the Panel. func (f *ConfigurationFile) Parse(path string) error { zap.S().Debugw("parsing configuration file", zap.String("path", path), zap.String("parser", string(f.Parser))) switch f.Parser { case Properties: f.parsePropertiesFile(path) break } return nil } // Parses a properties file and updates the values within it to match those that // are passed. Writes the file once completed. func (f *ConfigurationFile) parsePropertiesFile(path string) error { p, err := properties.LoadFile(path, properties.UTF8) if err != nil { return errors.WithStack(err) } for _, replace := range f.Replace { if _, _, err := p.Set(replace.Match, replace.Value); err != nil { return errors.WithStack(err) } } w, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0644); if err != nil { return errors.WithStack(err) } _, err = p.Write(w, properties.UTF8) return err }