99 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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
 | |
| }
 |