Skip to content

Commit cd11581

Browse files
hdurand0710mjuraga
authored andcommitted
MEDIUM: add parser option allowing to not serialize a section with a given name
1 parent d4d07f0 commit cd11581

File tree

5 files changed

+177
-11
lines changed

5 files changed

+177
-11
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
Copyright 2021 HAProxy Technologies
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package options
18+
19+
type defaultSectionsSkipOnWrite struct {
20+
sectionNames map[string]struct{}
21+
}
22+
23+
func (o defaultSectionsSkipOnWrite) Set(p *Parser) error {
24+
p.DefaultSectionsSkipOnWrite = o.sectionNames
25+
return nil
26+
}
27+
28+
// sectionNames is a list of defaults section that the parser will not serialize even if existing in the configuration
29+
func DefaultSectionsSkipOnWrite(sectionNames []string) ParserOption {
30+
names := make(map[string]struct{}, len(sectionNames))
31+
for _, s := range sectionNames {
32+
names[s] = struct{}{}
33+
}
34+
return defaultSectionsSkipOnWrite{
35+
sectionNames: names,
36+
}
37+
}

config-parser/options/options.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,17 @@ import (
2323
)
2424

2525
type Parser struct {
26-
Path string
27-
Reader io.Reader
28-
Logger logger.Format // we always will have p.Options.LogPrefix
29-
UseV2HTTPCheck bool
30-
UseMd5Hash bool
31-
UseListenSectionParsers bool
32-
DisableUnProcessed bool
33-
Log bool
34-
LogPrefix string
35-
NoNamedDefaultsFrom bool
26+
Path string
27+
Reader io.Reader
28+
Logger logger.Format // we always will have p.Options.LogPrefix
29+
UseV2HTTPCheck bool
30+
UseMd5Hash bool
31+
UseListenSectionParsers bool
32+
DisableUnProcessed bool
33+
Log bool
34+
LogPrefix string
35+
NoNamedDefaultsFrom bool
36+
DefaultSectionsSkipOnWrite map[string]struct{}
3637
}
3738

3839
type ParserOption interface {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Copyright 2019 HAProxy Technologies
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package configs
17+
18+
const configDefaultSectionsSkipOnWrite_WithSectionName = `# _version=1
19+
# HAProxy Technologies
20+
# https://www.haproxy.com/
21+
22+
global
23+
master-worker
24+
25+
defaults A
26+
log global
27+
28+
defaults B from A
29+
maxconn 10
30+
31+
defaults to_not_serialize
32+
33+
frontend http from A
34+
mode http
35+
bind 0.0.0.0:80 name bind_1
36+
bind :::80 v4v6 name bind_2
37+
default_backend default_backend
38+
39+
backend default_backend from A
40+
mode http
41+
http-request deny deny_status 400 # deny
42+
`
43+
44+
const configDefaultSectionsSkipOnWrite_WithoutSectionName = `# _version=1
45+
# HAProxy Technologies
46+
# https://www.haproxy.com/
47+
48+
global
49+
master-worker
50+
51+
defaults A
52+
log global
53+
54+
defaults B from A
55+
maxconn 10
56+
57+
frontend http from A
58+
mode http
59+
bind 0.0.0.0:80 name bind_1
60+
bind :::80 v4v6 name bind_2
61+
default_backend default_backend
62+
63+
backend default_backend from A
64+
mode http
65+
http-request deny deny_status 400 # deny
66+
`

config-parser/tests/configs/parser_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,48 @@ func TestListenSectionParsers(t *testing.T) {
153153
t.Fatalf("configurations does not match")
154154
}
155155
}
156+
157+
func TestDefaultSectionsSkipOnWriteParsers(t *testing.T) {
158+
tests := []struct {
159+
Name string
160+
Config string
161+
Result string
162+
DefaultsSectionToSkip []string
163+
}{
164+
{
165+
"with option DefaultSectionsSkipOnWrite and section present",
166+
configDefaultSectionsSkipOnWrite_WithSectionName, configDefaultSectionsSkipOnWrite_WithoutSectionName,
167+
[]string{"to_not_serialize"},
168+
},
169+
{
170+
"with option DefaultSectionsSkipOnWrite and section present - multiple options",
171+
configDefaultSectionsSkipOnWrite_WithSectionName, configDefaultSectionsSkipOnWrite_WithoutSectionName,
172+
[]string{"to_not_serialize", "to_not_serialize2"},
173+
},
174+
{
175+
"no option DefaultSectionsSkipOnWrite and section absent",
176+
configDefaultSectionsSkipOnWrite_WithoutSectionName, configDefaultSectionsSkipOnWrite_WithoutSectionName,
177+
[]string{"to_not_serialize"},
178+
},
179+
{
180+
"with option DefaultSectionsSkipOnWrite and section present different option name",
181+
configDefaultSectionsSkipOnWrite_WithSectionName, configDefaultSectionsSkipOnWrite_WithSectionName,
182+
[]string{"other"},
183+
},
184+
}
185+
186+
for _, tt := range tests {
187+
var buffer bytes.Buffer
188+
buffer.WriteString(tt.Config)
189+
p, err := parser.New(options.DefaultSectionsSkipOnWrite(tt.DefaultsSectionToSkip), options.Reader(&buffer))
190+
if err != nil {
191+
t.Fatal(err.Error())
192+
}
193+
194+
result := p.String() //nolint:ifshort
195+
if result != tt.Result {
196+
compare(t, tt.Config, tt.Result)
197+
t.Fatalf("configurations does not match")
198+
}
199+
}
200+
}

config-parser/writer.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,29 @@ func (p *configParser) String() string {
8181
} else {
8282
sName = string(section)
8383
}
84-
p.writeParsers(sName, p.Parsers[section][sectionName], &result, true)
84+
serializeOk := p.shouldSerialize(section, sectionName)
85+
if serializeOk {
86+
p.writeParsers(sName, p.Parsers[section][sectionName], &result, true)
87+
}
8588
}
8689
}
8790
return result.String()
8891
}
8992

93+
func (p *configParser) shouldSerialize(section Section, sectionName string) bool {
94+
if section != Defaults {
95+
return true
96+
}
97+
98+
// For Defaults section, look if option DefaultSectionsSkipOnWrite is set
99+
// if set, take it into into account to not serialize the defaults section with the option name
100+
if len(p.Options.DefaultSectionsSkipOnWrite) == 0 {
101+
return true
102+
}
103+
_, sectionToSkip := p.Options.DefaultSectionsSkipOnWrite[sectionName]
104+
return !sectionToSkip
105+
}
106+
90107
func (p *configParser) Save(filename string) error {
91108
if p.Options.Log {
92109
p.Options.Logger.Debugf("%ssaving configuration to file %s", p.Options.LogPrefix, filename)

0 commit comments

Comments
 (0)