Skip to content

Commit

Permalink
configuration_render: add function to parser inner template blocks to…
Browse files Browse the repository at this point in the history
… a var (#142)

* configuration_render: add function to parser inner template blocks to a var

* configuration_render: avoid possible loop using renderInnnerTemplate
  • Loading branch information
morpheu authored Jan 19, 2024
1 parent 232e6c7 commit 80079da
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 13 deletions.
33 changes: 24 additions & 9 deletions internal/pkg/rpaas/nginx/configuration_render.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
)

var trimTrailingSpacesRegex = regexp.MustCompile(`[ \t]+?\n`)
var nginxTemplate = &template.Template{}
var errRenderInnerTemplate = fmt.Errorf("template contains renderInnerTemplate")

type ConfigurationRenderer interface {
Render(ConfigurationData) (string, error)
Expand Down Expand Up @@ -58,39 +60,50 @@ func (r *rpaasConfigurationRenderer) Render(c ConfigurationData) (string, error)
}

func NewConfigurationRenderer(cb ConfigurationBlocks) (ConfigurationRenderer, error) {
tpl, err := defaultMainTemplate.Clone()
var err error
nginxTemplate, err = defaultMainTemplate.Clone()
if err != nil {
return nil, err
}

if cb.MainBlock != "" {
tpl, err = template.New("main").Funcs(templateFuncs).Parse(cb.MainBlock)
nginxTemplate, err = template.New("main").Funcs(templateFuncs).Parse(cb.MainBlock)
if err != nil {
return nil, err
}
}

if _, err = tpl.New("root").Parse(cb.RootBlock); err != nil {
if _, err = nginxTemplate.New("root").Parse(cb.RootBlock); err != nil {
return nil, err
}

if _, err = tpl.New("http").Parse(cb.HttpBlock); err != nil {
if _, err = nginxTemplate.New("http").Parse(cb.HttpBlock); err != nil {
return nil, err
}

if _, err = tpl.New("server").Parse(cb.ServerBlock); err != nil {
if _, err = nginxTemplate.New("server").Parse(cb.ServerBlock); err != nil {
return nil, err
}

if _, err = tpl.New("lua-server").Parse(cb.LuaServerBlock); err != nil {
if _, err = nginxTemplate.New("lua-server").Parse(cb.LuaServerBlock); err != nil {
return nil, err
}

if _, err = tpl.New("lua-worker").Parse(cb.LuaWorkerBlock); err != nil {
if _, err = nginxTemplate.New("lua-worker").Parse(cb.LuaWorkerBlock); err != nil {
return nil, err
}

return &rpaasConfigurationRenderer{t: tpl}, nil
return &rpaasConfigurationRenderer{t: nginxTemplate}, nil
}

func renderInnerTemplate(name string, nginx ConfigurationData) (string, error) {
tpl := nginxTemplate.Lookup(name)
parsedTemplate := tpl.Tree.Root.String()
if strings.Contains(parsedTemplate, "renderInnerTemplate") {
return "", errRenderInnerTemplate
}
r := &rpaasConfigurationRenderer{t: tpl}
return r.Render(nginx)
}

func buildLocationKey(prefix, path string) string {
Expand Down Expand Up @@ -232,6 +245,7 @@ func defaultCertificate(instance *v1alpha1.RpaasInstance) *nginxv1alpha1.NginxTL
}

var internalTemplateFuncs = template.FuncMap(map[string]interface{}{
"renderInnerTemplate": renderInnerTemplate,
"boolValue": v1alpha1.BoolValue,
"buildLocationKey": buildLocationKey,
"hasRootPath": hasRootPath,
Expand Down Expand Up @@ -282,6 +296,7 @@ var rawNginxConfiguration = `
{{- $all := . -}}
{{- $config := .Config -}}
{{- $instance := .Instance -}}
{{- $httpBlock := renderInnerTemplate "http" . -}}
# This file was generated by RPaaS (https://github.com/tsuru/rpaas-operator.git)
# Do not modify this file, any change will be lost.
Expand Down Expand Up @@ -437,7 +452,7 @@ http {
{{ template "lua-worker" . }}
}
{{ template "http" . }}
{{ $httpBlock }}
server {
listen {{ managePort $instance }};
Expand Down
28 changes: 24 additions & 4 deletions internal/pkg/rpaas/nginx/configuration_render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ func TestRpaasConfigurationRenderer_Render(t *testing.T) {
size300MB := resource.MustParse("300Mi")

tests := []struct {
name string
blocks ConfigurationBlocks
data ConfigurationData
assertion func(*testing.T, string)
name string
blocks ConfigurationBlocks
data ConfigurationData
assertion func(*testing.T, string)
expectedError string
}{
{
name: "with false values",
Expand Down Expand Up @@ -271,6 +272,21 @@ func TestRpaasConfigurationRenderer_Render(t *testing.T) {
assert.Regexp(t, `\s# some custom conf at init_worker_by_lua_block context`, result)
},
},
{
name: "with invalid recursive renderInnnerTemplate inside config blocks",
blocks: ConfigurationBlocks{
RootBlock: `# some custom conf at {{ "root" }} context`,
HttpBlock: "# some custom conf at {{ $var := renderInnerTemplate \"http\" .}} context",
ServerBlock: "# some custom conf at server context",
LuaServerBlock: "# some custom conf at init_by_lua_block context",
LuaWorkerBlock: "# some custom conf at init_worker_by_lua_block context",
},
data: ConfigurationData{
Config: &v1alpha1.NginxConfig{},
Instance: &v1alpha1.RpaasInstance{},
},
expectedError: errRenderInnerTemplate.Error(),
},
{
name: "with app bound",
data: ConfigurationData{
Expand Down Expand Up @@ -602,6 +618,10 @@ func TestRpaasConfigurationRenderer_Render(t *testing.T) {
cr, err := NewConfigurationRenderer(tt.blocks)
require.NoError(t, err)
result, err := cr.Render(tt.data)
if tt.expectedError != "" {
assert.ErrorContains(t, err, tt.expectedError)
return
}
require.NoError(t, err)
tt.assertion(t, result)
})
Expand Down

0 comments on commit 80079da

Please sign in to comment.