-
Notifications
You must be signed in to change notification settings - Fork 33
/
parser.go
134 lines (118 loc) · 4.26 KB
/
parser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
Copyright 2019 HAProxy Technologies
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package parser
import (
"bytes"
"io"
"os"
"strings"
"sync"
"github.com/haproxytech/config-parser/v5/common"
"github.com/haproxytech/config-parser/v5/options"
)
type Section string
const (
Comments Section = "#"
Defaults Section = "defaults"
Global Section = "global"
Resolvers Section = "resolvers"
UserList Section = "userlist"
Peers Section = "peers"
Mailers Section = "mailers"
Frontends Section = "frontend"
Backends Section = "backend"
Listen Section = "listen"
Cache Section = "cache"
Program Section = "program"
HTTPErrors Section = "http-errors"
Ring Section = "ring"
LogForward Section = "log-forward"
FCGIApp Section = "fcgi-app"
CrtStore Section = "crt-store"
// spoe sections
SPOEAgent Section = "spoe-agent"
SPOEGroup Section = "spoe-group"
SPOEMessage Section = "spoe-message"
)
const (
CommentsSectionName = "data"
GlobalSectionName = "data"
)
var DefaultSectionName = "" //nolint:gochecknoglobals
type Parser interface {
LoadData(path string) error
Process(reader io.Reader) error
String() string
Save(filename string) error
StringWithHash() (string, error)
Get(sectionType Section, sectionName string, attribute string, createIfNotExist ...bool) (common.ParserData, error)
GetResult(sectionType Section, sectionName string, attribute string) ([]common.ReturnResultLine, error)
GetPreComments(sectionType Section, sectionName string, attribute string) ([]string, error)
GetOne(sectionType Section, sectionName string, attribute string, index ...int) (common.ParserData, error)
SectionsGet(sectionType Section) ([]string, error)
SectionAttributesGet(sectionType Section, sectionName string, existingOnly bool) ([]string, error)
SectionsDelete(sectionType Section, sectionName string) error
SectionsCreate(sectionType Section, sectionName string) error
SectionsDefaultsFromGet(sectionType Section, sectionName string) (string, error)
SectionsDefaultsFromSet(sectionType Section, sectionName, defaultsSection string) error
Set(sectionType Section, sectionName string, attribute string, data common.ParserData, index ...int) error
SetPreComments(sectionType Section, sectionName string, attribute string, preComment []string) error
Delete(sectionType Section, sectionName string, attribute string, index ...int) error
Insert(sectionType Section, sectionName string, attribute string, data common.ParserData, index ...int) error
HasParser(sectionType Section, attribute string) bool
SetLoggerState(active bool) error
}
type UnlockError struct{}
func (e UnlockError) Error() string {
return "failed funclock"
}
// configParser reads and writes configuration on given file
type configParser struct {
Parsers map[Section]map[string]*Parsers
Options options.Parser
lastDefaultsSectionName string
mutex *sync.Mutex
}
func New(opt ...options.ParserOption) (Parser, error) {
p := &configParser{
Options: options.Parser{},
lastDefaultsSectionName: "",
}
var err error
for _, option := range opt {
err = option.Set(&p.Options)
if err != nil {
return nil, err
}
}
if p.Options.Path != "" {
if p.Options.Log {
p.Options.Logger.Infof("%sreading configuration from file: %s", p.Options.LogPrefix, p.Options.Path)
}
dat, err := os.ReadFile(p.Options.Path)
if err != nil {
return nil, err
}
return p, p.Process(bytes.NewReader(dat))
}
if p.Options.Reader != nil {
if p.Options.Log {
p.Options.Logger.Infof("%sreading configuration from reader", p.Options.LogPrefix)
}
return p, p.Process(p.Options.Reader)
}
if p.Options.Log {
p.Options.Logger.Warningf("%sno configuration source provided", p.Options.LogPrefix)
}
return p, p.Process(strings.NewReader(""))
}