Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add entities defaults from their schemas #573

Merged
merged 16 commits into from
Feb 11, 2022
Merged
84 changes: 53 additions & 31 deletions file/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type stateBuilder struct {

schemasCache map[string]map[string]interface{}

disableDynamicDefaults bool

err error
}

Expand All @@ -51,15 +53,11 @@ func (b *stateBuilder) build() (*utils.KongRawState, *utils.KonnectRawState, err
return nil, nil, err
}

// defaulter
var kongDefaults KongDefaults
if b.targetContent.Info != nil {
kongDefaults = b.targetContent.Info.Defaults
}
b.defaulter, err = defaulter(kongDefaults)
defaulter, err := defaulter(b.ctx, b.client, b.targetContent, b.disableDynamicDefaults)
if err != nil {
return nil, nil, fmt.Errorf("creating defaulter: %w", err)
return nil, nil, err
}
b.defaulter = defaulter

// build
b.certificates()
Expand Down Expand Up @@ -748,6 +746,32 @@ func (b *stateBuilder) plugins() {
}
}

// strip_path schema default value is 'true', but it cannot be set when
// protocols include 'grpc' and/or 'grpcs'. When users explicitly set
// strip_path to 'true' with grpc/s protocols, deck returns a schema violation error.
// When strip_path is not set and protocols include grpc/s, deck sets strip_path to 'false',
// despite its default value would be 'true' under normal circumstances.
func getStripPathBasedOnProtocols(initialStripPath *bool, route kong.Route) (*bool, error) {
var grpcProtocols bool
for _, tag := range route.Protocols {
if *tag == "grpc" || *tag == "grpcs" {
grpcProtocols = true
}
}

if grpcProtocols {
if initialStripPath != nil {
if *initialStripPath {
return nil, fmt.Errorf("schema violation (strip_path: cannot set " +
"'strip_path' when 'protocols' is 'grpc' or 'grpcs')")
}
return initialStripPath, nil
}
return kong.Bool(false), nil
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: If strip path can't be set when protocol is grpc, why return false on the two returns above?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strip_path is a required field, so when protocol is grpc it needs to be set to false (true being the schema default)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

	for _, p := range route.Protocols {
		if *p == "grpc" || *p == "grpcs" {
			if stripPath != nil { return nil, fmt.Errorf("strip path not allowed")
      return kong.Bool(false), nil
		}
	}

Is that not sufficient?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly...I just reworked/cleaned a bit the code to have something like you are suggesting (67d1dcc)

return route.StripPath, nil
}

func (b *stateBuilder) ingestRoute(r FRoute) error {
if utils.Empty(r.ID) {
route, err := b.currentState.Routes.Get(*r.Name)
Expand All @@ -761,10 +785,17 @@ func (b *stateBuilder) ingestRoute(r FRoute) error {
}

utils.MustMergeTags(&r, b.selectTags)

initialStripPath := r.Route.StripPath
b.defaulter.MustSet(&r.Route)
stripPath, err := getStripPathBasedOnProtocols(initialStripPath, r.Route)
if err != nil {
return err
}
r.Route.StripPath = stripPath

b.rawState.Routes = append(b.rawState.Routes, &r.Route)
err := b.intermediate.Routes.Add(state.Route{Route: r.Route})
err = b.intermediate.Routes.Add(state.Route{Route: r.Route})
if err != nil {
return err
}
Expand Down Expand Up @@ -868,30 +899,21 @@ func pluginRelations(plugin *kong.Plugin) (cID, rID, sID string) {
return
}

func defaulter(defaults KongDefaults) (*utils.Defaulter, error) {
d, err := utils.GetKongDefaulter()
if err != nil {
return nil, err
}
if defaults.Route != nil {
if err = d.Register(defaults.Route); err != nil {
return nil, err
}
}
if defaults.Service != nil {
if err = d.Register(defaults.Service); err != nil {
return nil, err
}
func defaulter(
ctx context.Context, client *kong.Client, fileContent *Content, disableDynamicDefaults bool,
) (*utils.Defaulter, error) {
var kongDefaults KongDefaults
if fileContent.Info != nil {
kongDefaults = fileContent.Info.Defaults
}
if defaults.Upstream != nil {
if err = d.Register(defaults.Upstream); err != nil {
return nil, err
}
opts := utils.DefaulterOpts{
Client: client,
KongDefaults: kongDefaults,
DisableDynamicDefaults: disableDynamicDefaults,
}
if defaults.Target != nil {
if err = d.Register(defaults.Target); err != nil {
return nil, err
}
defaulter, err := utils.GetDefaulter(ctx, opts)
if err != nil {
return nil, fmt.Errorf("creating defaulter: %w", err)
}
return d, nil
return defaulter, nil
}
Loading