Skip to content

Commit f54ba9f

Browse files
committed
feat: implement dynamic defaulting feature
- file/codegen/main.go and corresponding schema change This is to relax the schema of kong entities that are used as input for defaults. The relaxation is necessary as otherwise the user will have to specify a name in default values. This doesn't have any side-effects because the *kong.Type is not used anywhere else in Content. - file/builder.go file/reader.go - defaulter instantiation has been moved inside builder, this feels natural, defaulter being instantiated outside the builder seems odd and the only explanation is that I simply didn't think through when implementing defaulter - other changes override the default values that are registered Fix #89
1 parent 84035a6 commit f54ba9f

File tree

7 files changed

+454
-66
lines changed

7 files changed

+454
-66
lines changed

file/builder.go

+10
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ func (b *stateBuilder) build() (*utils.KongRawState, *utils.KonnectRawState, err
4747
return nil, nil, err
4848
}
4949

50+
// defaulter
51+
var kongDefaults KongDefaults
52+
if b.targetContent.Info != nil {
53+
kongDefaults = b.targetContent.Info.Defaults
54+
}
55+
b.defaulter, err = defaulter(kongDefaults)
56+
if err != nil {
57+
return nil, nil, fmt.Errorf("creating defaulter: %w", err)
58+
}
59+
5060
// build
5161
b.certificates()
5262
b.caCertificates()

file/builder_test.go

+306-3
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,6 @@ func Test_stateBuilder_services(t *testing.T) {
372372
targetContent: tt.fields.targetContent,
373373
currentState: tt.fields.currentState,
374374
}
375-
d, _ := utils.GetKongDefaulter()
376-
b.defaulter = d
377375
b.build()
378376
assert.Equal(tt.want, b.rawState)
379377
})
@@ -1845,7 +1843,6 @@ func Test_stateBuilder_documents(t *testing.T) {
18451843

18461844
func Test_stateBuilder(t *testing.T) {
18471845
assert := assert.New(t)
1848-
rand.Seed(42)
18491846
type fields struct {
18501847
targetContent *Content
18511848
currentState *state.KongState
@@ -2091,9 +2088,315 @@ func Test_stateBuilder(t *testing.T) {
20912088
},
20922089
},
20932090
},
2091+
{
2092+
name: "entities with configurable defaults",
2093+
fields: fields{
2094+
targetContent: &Content{
2095+
Info: &Info{
2096+
SelectorTags: []string{"tag1"},
2097+
Defaults: KongDefaults{
2098+
Route: &kong.Route{
2099+
PathHandling: kong.String("v0"),
2100+
PreserveHost: kong.Bool(false),
2101+
RegexPriority: kong.Int(0),
2102+
StripPath: kong.Bool(false),
2103+
Protocols: kong.StringSlice("http", "https"),
2104+
RequestBuffering: kong.Bool(false),
2105+
},
2106+
Service: &kong.Service{
2107+
Port: kong.Int(443),
2108+
Protocol: kong.String("https"),
2109+
ConnectTimeout: kong.Int(5000),
2110+
WriteTimeout: kong.Int(5000),
2111+
ReadTimeout: kong.Int(5000),
2112+
},
2113+
Upstream: &kong.Upstream{
2114+
Slots: kong.Int(100),
2115+
Healthchecks: &kong.Healthcheck{
2116+
Active: &kong.ActiveHealthcheck{
2117+
Concurrency: kong.Int(5),
2118+
Healthy: &kong.Healthy{
2119+
HTTPStatuses: []int{200, 302},
2120+
Interval: kong.Int(0),
2121+
Successes: kong.Int(0),
2122+
},
2123+
HTTPPath: kong.String("/"),
2124+
Type: kong.String("http"),
2125+
Timeout: kong.Int(1),
2126+
Unhealthy: &kong.Unhealthy{
2127+
HTTPFailures: kong.Int(0),
2128+
TCPFailures: kong.Int(0),
2129+
Timeouts: kong.Int(0),
2130+
Interval: kong.Int(0),
2131+
HTTPStatuses: []int{429, 404, 500, 501, 502, 503, 504, 505},
2132+
},
2133+
},
2134+
Passive: &kong.PassiveHealthcheck{
2135+
Healthy: &kong.Healthy{
2136+
HTTPStatuses: []int{
2137+
200, 201, 202, 203, 204, 205,
2138+
206, 207, 208, 226, 300, 301, 302, 303, 304, 305,
2139+
306, 307, 308,
2140+
},
2141+
Successes: kong.Int(0),
2142+
},
2143+
Unhealthy: &kong.Unhealthy{
2144+
HTTPFailures: kong.Int(0),
2145+
TCPFailures: kong.Int(0),
2146+
Timeouts: kong.Int(0),
2147+
HTTPStatuses: []int{429, 500, 503},
2148+
},
2149+
},
2150+
},
2151+
HashOn: kong.String("none"),
2152+
HashFallback: kong.String("none"),
2153+
HashOnCookiePath: kong.String("/"),
2154+
},
2155+
},
2156+
},
2157+
Services: []FService{
2158+
{
2159+
Service: kong.Service{
2160+
Name: kong.String("foo-service"),
2161+
},
2162+
Routes: []*FRoute{
2163+
{
2164+
Route: kong.Route{
2165+
Name: kong.String("foo-route1"),
2166+
},
2167+
},
2168+
{
2169+
Route: kong.Route{
2170+
ID: kong.String("d125e79a-297c-414b-bc00-ad3a87be6c2b"),
2171+
Name: kong.String("foo-route2"),
2172+
},
2173+
},
2174+
},
2175+
},
2176+
{
2177+
Service: kong.Service{
2178+
Name: kong.String("bar-service"),
2179+
},
2180+
Routes: []*FRoute{
2181+
{
2182+
Route: kong.Route{
2183+
Name: kong.String("bar-route1"),
2184+
},
2185+
},
2186+
{
2187+
Route: kong.Route{
2188+
Name: kong.String("bar-route2"),
2189+
},
2190+
},
2191+
},
2192+
},
2193+
{
2194+
Service: kong.Service{
2195+
Name: kong.String("large-payload-service"),
2196+
},
2197+
Routes: []*FRoute{
2198+
{
2199+
Route: kong.Route{
2200+
Name: kong.String("dont-buffer-these"),
2201+
RequestBuffering: kong.Bool(false),
2202+
ResponseBuffering: kong.Bool(false),
2203+
},
2204+
},
2205+
{
2206+
Route: kong.Route{
2207+
Name: kong.String("buffer-these"),
2208+
RequestBuffering: kong.Bool(true),
2209+
ResponseBuffering: kong.Bool(true),
2210+
},
2211+
},
2212+
},
2213+
},
2214+
},
2215+
Upstreams: []FUpstream{
2216+
{
2217+
Upstream: kong.Upstream{
2218+
Name: kong.String("foo"),
2219+
Slots: kong.Int(42),
2220+
},
2221+
},
2222+
},
2223+
},
2224+
currentState: existingServiceState(),
2225+
},
2226+
want: &utils.KongRawState{
2227+
Services: []*kong.Service{
2228+
{
2229+
ID: kong.String("538c7f96-b164-4f1b-97bb-9f4bb472e89f"),
2230+
Name: kong.String("foo-service"),
2231+
Port: kong.Int(443),
2232+
Protocol: kong.String("https"),
2233+
ConnectTimeout: kong.Int(5000),
2234+
WriteTimeout: kong.Int(5000),
2235+
ReadTimeout: kong.Int(5000),
2236+
Tags: kong.StringSlice("tag1"),
2237+
},
2238+
{
2239+
ID: kong.String("dfd79b4d-7642-4b61-ba0c-9f9f0d3ba55b"),
2240+
Name: kong.String("bar-service"),
2241+
Port: kong.Int(443),
2242+
Protocol: kong.String("https"),
2243+
ConnectTimeout: kong.Int(5000),
2244+
WriteTimeout: kong.Int(5000),
2245+
ReadTimeout: kong.Int(5000),
2246+
Tags: kong.StringSlice("tag1"),
2247+
},
2248+
{
2249+
ID: kong.String("9e6f82e5-4e74-4e81-a79e-4bbd6fe34cdc"),
2250+
Name: kong.String("large-payload-service"),
2251+
Port: kong.Int(443),
2252+
Protocol: kong.String("https"),
2253+
ConnectTimeout: kong.Int(5000),
2254+
WriteTimeout: kong.Int(5000),
2255+
ReadTimeout: kong.Int(5000),
2256+
Tags: kong.StringSlice("tag1"),
2257+
},
2258+
},
2259+
Routes: []*kong.Route{
2260+
{
2261+
ID: kong.String("5b1484f2-5209-49d9-b43e-92ba09dd9d52"),
2262+
Name: kong.String("foo-route1"),
2263+
PreserveHost: kong.Bool(false),
2264+
RegexPriority: kong.Int(0),
2265+
StripPath: kong.Bool(false),
2266+
Protocols: kong.StringSlice("http", "https"),
2267+
RequestBuffering: kong.Bool(false),
2268+
PathHandling: kong.String("v0"),
2269+
Service: &kong.Service{
2270+
ID: kong.String("538c7f96-b164-4f1b-97bb-9f4bb472e89f"),
2271+
},
2272+
Tags: kong.StringSlice("tag1"),
2273+
},
2274+
{
2275+
ID: kong.String("d125e79a-297c-414b-bc00-ad3a87be6c2b"),
2276+
Name: kong.String("foo-route2"),
2277+
PreserveHost: kong.Bool(false),
2278+
RegexPriority: kong.Int(0),
2279+
StripPath: kong.Bool(false),
2280+
Protocols: kong.StringSlice("http", "https"),
2281+
RequestBuffering: kong.Bool(false),
2282+
PathHandling: kong.String("v0"),
2283+
Service: &kong.Service{
2284+
ID: kong.String("538c7f96-b164-4f1b-97bb-9f4bb472e89f"),
2285+
},
2286+
Tags: kong.StringSlice("tag1"),
2287+
},
2288+
{
2289+
ID: kong.String("0cc0d614-4c88-4535-841a-cbe0709b0758"),
2290+
Name: kong.String("bar-route1"),
2291+
PreserveHost: kong.Bool(false),
2292+
RegexPriority: kong.Int(0),
2293+
StripPath: kong.Bool(false),
2294+
Protocols: kong.StringSlice("http", "https"),
2295+
RequestBuffering: kong.Bool(false),
2296+
PathHandling: kong.String("v0"),
2297+
Service: &kong.Service{
2298+
ID: kong.String("dfd79b4d-7642-4b61-ba0c-9f9f0d3ba55b"),
2299+
},
2300+
Tags: kong.StringSlice("tag1"),
2301+
},
2302+
{
2303+
ID: kong.String("083f61d3-75bc-42b4-9df4-f91929e18fda"),
2304+
Name: kong.String("bar-route2"),
2305+
PreserveHost: kong.Bool(false),
2306+
RegexPriority: kong.Int(0),
2307+
StripPath: kong.Bool(false),
2308+
Protocols: kong.StringSlice("http", "https"),
2309+
RequestBuffering: kong.Bool(false),
2310+
PathHandling: kong.String("v0"),
2311+
Service: &kong.Service{
2312+
ID: kong.String("dfd79b4d-7642-4b61-ba0c-9f9f0d3ba55b"),
2313+
},
2314+
Tags: kong.StringSlice("tag1"),
2315+
},
2316+
{
2317+
ID: kong.String("ba843ee8-d63e-4c4f-be1c-ebea546d8fac"),
2318+
Name: kong.String("dont-buffer-these"),
2319+
PreserveHost: kong.Bool(false),
2320+
RegexPriority: kong.Int(0),
2321+
StripPath: kong.Bool(false),
2322+
Protocols: kong.StringSlice("http", "https"),
2323+
PathHandling: kong.String("v0"),
2324+
Service: &kong.Service{
2325+
ID: kong.String("9e6f82e5-4e74-4e81-a79e-4bbd6fe34cdc"),
2326+
},
2327+
Tags: kong.StringSlice("tag1"),
2328+
RequestBuffering: kong.Bool(false),
2329+
ResponseBuffering: kong.Bool(false),
2330+
},
2331+
{
2332+
ID: kong.String("13dd1aac-04ce-4ea2-877c-5579cfa2c78e"),
2333+
Name: kong.String("buffer-these"),
2334+
PreserveHost: kong.Bool(false),
2335+
RegexPriority: kong.Int(0),
2336+
StripPath: kong.Bool(false),
2337+
Protocols: kong.StringSlice("http", "https"),
2338+
PathHandling: kong.String("v0"),
2339+
Service: &kong.Service{
2340+
ID: kong.String("9e6f82e5-4e74-4e81-a79e-4bbd6fe34cdc"),
2341+
},
2342+
Tags: kong.StringSlice("tag1"),
2343+
RequestBuffering: kong.Bool(true),
2344+
ResponseBuffering: kong.Bool(true),
2345+
},
2346+
},
2347+
Upstreams: []*kong.Upstream{
2348+
{
2349+
ID: kong.String("1b0bafae-881b-42a7-9110-8a42ed3c903c"),
2350+
Name: kong.String("foo"),
2351+
Slots: kong.Int(42),
2352+
Healthchecks: &kong.Healthcheck{
2353+
Active: &kong.ActiveHealthcheck{
2354+
Concurrency: kong.Int(5),
2355+
Healthy: &kong.Healthy{
2356+
HTTPStatuses: []int{200, 302},
2357+
Interval: kong.Int(0),
2358+
Successes: kong.Int(0),
2359+
},
2360+
HTTPPath: kong.String("/"),
2361+
Type: kong.String("http"),
2362+
Timeout: kong.Int(1),
2363+
Unhealthy: &kong.Unhealthy{
2364+
HTTPFailures: kong.Int(0),
2365+
TCPFailures: kong.Int(0),
2366+
Timeouts: kong.Int(0),
2367+
Interval: kong.Int(0),
2368+
HTTPStatuses: []int{429, 404, 500, 501, 502, 503, 504, 505},
2369+
},
2370+
},
2371+
Passive: &kong.PassiveHealthcheck{
2372+
Healthy: &kong.Healthy{
2373+
HTTPStatuses: []int{
2374+
200, 201, 202, 203, 204, 205,
2375+
206, 207, 208, 226, 300, 301, 302, 303, 304, 305,
2376+
306, 307, 308,
2377+
},
2378+
Successes: kong.Int(0),
2379+
},
2380+
Unhealthy: &kong.Unhealthy{
2381+
HTTPFailures: kong.Int(0),
2382+
TCPFailures: kong.Int(0),
2383+
Timeouts: kong.Int(0),
2384+
HTTPStatuses: []int{429, 500, 503},
2385+
},
2386+
},
2387+
},
2388+
HashOn: kong.String("none"),
2389+
HashFallback: kong.String("none"),
2390+
HashOnCookiePath: kong.String("/"),
2391+
Tags: kong.StringSlice("tag1"),
2392+
},
2393+
},
2394+
},
2395+
},
20942396
}
20952397
for _, tt := range tests {
20962398
t.Run(tt.name, func(t *testing.T) {
2399+
rand.Seed(42)
20972400
b := &stateBuilder{
20982401
targetContent: tt.fields.targetContent,
20992402
currentState: tt.fields.currentState,

file/codegen/main.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,16 @@ func main() {
5858
return nil
5959
}
6060
schema := reflector.Reflect(file.Content{})
61-
schema.Definitions["Service"].AnyOf = anyOfNameOrID
61+
// schema.Definitions["Service"].AnyOf = anyOfNameOrID
6262
schema.Definitions["FService"].AnyOf = anyOfNameOrID
6363

64-
schema.Definitions["Route"].AnyOf = anyOfNameOrID
64+
// schema.Definitions["Route"].AnyOf = anyOfNameOrID
6565
schema.Definitions["FRoute"].AnyOf = anyOfNameOrID
6666

67-
schema.Definitions["Consumer"].AnyOf = anyOfUsernameOrID
67+
// schema.Definitions["Consumer"].AnyOf = anyOfUsernameOrID
6868
schema.Definitions["FConsumer"].AnyOf = anyOfUsernameOrID
6969

70-
schema.Definitions["Upstream"].Required = []string{"name"}
70+
// schema.Definitions["Upstream"].Required = []string{"name"}
7171
schema.Definitions["FUpstream"].Required = []string{"name"}
7272

7373
schema.Definitions["FTarget"].Required = []string{"target"}

0 commit comments

Comments
 (0)