Skip to content

Commit

Permalink
Refactor server handling in configuration rendering to multi-domain s…
Browse files Browse the repository at this point in the history
…upport
  • Loading branch information
wpjunior committed Jan 29, 2025
1 parent 84f0e6a commit acf2879
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 54 deletions.
62 changes: 38 additions & 24 deletions internal/pkg/rpaas/nginx/configuration_render.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ type ConfigurationData struct {
Config *v1alpha1.NginxConfig
Instance *v1alpha1.RpaasInstance
NginxTLS []nginxv1alpha1.NginxTLS
Servers []*Server

// Modules is a map of installed modules, using a map instead of a slice
// DEPRECATED: Modules is a map of installed modules, using a map instead of a slice
// allow us to use `hasKey` inside templates.
Modules map[string]interface{}
}
Expand All @@ -53,6 +54,9 @@ type rpaasConfigurationRenderer struct {

func (r *rpaasConfigurationRenderer) Render(c ConfigurationData) (string, error) {
buffer := &bytes.Buffer{}
if c.Servers == nil {
c.Servers = produceServers(&c.Instance.Spec, c.NginxTLS)
}
err := r.t.Execute(buffer, c)
if err != nil {
return "", err
Expand Down Expand Up @@ -268,6 +272,7 @@ var internalTemplateFuncs = template.FuncMap(map[string]interface{}{
"tlsSessionTicketKeys": tlsSessionTicketKeys,
"tlsSessionTicketTimeout": tlsSessionTicketTimeout,
"defaultCertificate": defaultCertificate,
"serverBlock": serverBlock,
"iterate": func(n int) []int {
v := make([]int, n)
for i := 0; i < n; i++ {
Expand All @@ -277,6 +282,18 @@ var internalTemplateFuncs = template.FuncMap(map[string]interface{}{
},
})

func serverBlock(server *Server) (string, error) {
if len(server.Blocks) == 0 {
return "", nil
}
serverBlock, ok := server.Blocks[v1alpha1.BlockTypeServer]
if !ok {
return "", nil
}

return serverBlock.Value, nil
}

var templateFuncs = func() template.FuncMap {
funcs := sprig.GenericFuncMap()
for k, v := range internalTemplateFuncs {
Expand All @@ -299,6 +316,7 @@ var rawNginxConfiguration = `
{{- $config := .Config -}}
{{- $instance := .Instance -}}
{{- $nginxTLS := .NginxTLS -}}
{{- $servers := .Servers -}}
{{- $httpBlock := renderInnerTemplate "http" . -}}
# This file was generated by RPaaS (https://github.com/tsuru/rpaas-operator.git)
Expand Down Expand Up @@ -476,32 +494,22 @@ http {
{{- end }}
}
{{- range $_, $server := $servers }}
server {
listen {{ httpPort $instance }} default_server
{{- with $config.HTTPListenOptions }} {{ . }}{{ end }};
{{- template "rpaasv2.internal.server" $all }}
}
{{- range $_, $tls := $nginxTLS }}
server {
listen {{ httpPort $instance }}{{ with $server.Default }} default_server{{ end }};
{{- if $server.TLS }}
listen {{ httpsPort $instance }} ssl http2
{{- with $config.HTTPSListenOptions }} {{ . }}{{ end }};
{{- end }}
server_name {{ range $index, $host := $tls.Hosts }}{{ if $index }} {{ end }}{{ $host }}{{ end }};
ssl_certificate certs/{{ $tls.SecretName }}/tls.crt;
ssl_certificate_key certs/{{ $tls.SecretName }}/tls.key;
{{ template "rpaasv2.internal.server" $all }}
}
{{- end }}
}
{{- with $server.Name }}
server_name {{ . }};
{{- end }}
{{- define "rpaasv2.internal.server" }}
{{- $all := . -}}
{{- $config := .Config -}}
{{- $instance := .Instance -}}
{{- if $server.TLS }}
ssl_certificate certs/{{ $server.TLSSecretName }}/tls.crt;
ssl_certificate_key certs/{{ $server.TLSSecretName }}/tls.key;
{{- end }}
{{- if boolValue $config.CacheEnabled }}
proxy_cache rpaas;
Expand All @@ -519,8 +527,8 @@ http {
return 200 "WORKING\n";
}
{{- if $instance.Spec.Locations }}
{{- range $_, $location := $instance.Spec.Locations }}
{{- if $server.Locations }}
{{- range $_, $location := $server.Locations }}
location {{ $location.Path }} {
{{- if $location.Destination }}
{{- if $location.ForceHTTPS }}
Expand Down Expand Up @@ -560,6 +568,12 @@ http {
{{- end}}
{{- end}}
{{- if $server.HasBlockServer }}
{{ serverBlock $server }}
{{- else }}
{{ template "server" $all }}
{{- end }}
}
{{- end }}
}
`
47 changes: 46 additions & 1 deletion internal/pkg/rpaas/nginx/configuration_render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,17 @@ func TestRpaasConfigurationRenderer_Render(t *testing.T) {
\s+ssl_certificate_key certs/my-cert-01/tls.key;`, result)

assert.Regexp(t, `listen 8443 ssl http2;
\s+server_name www.example.org blog.example.org shop.example.org;
\s+server_name www.example.org;
\s+ssl_certificate certs/my-cert-02/tls.crt;
\s+ssl_certificate_key certs/my-cert-02/tls.key;`, result)

assert.Regexp(t, `listen 8443 ssl http2;
\s+server_name blog.example.org;
\s+ssl_certificate certs/my-cert-02/tls.crt;
\s+ssl_certificate_key certs/my-cert-02/tls.key;`, result)

assert.Regexp(t, `listen 8443 ssl http2;
\s+server_name shop.example.org;
\s+ssl_certificate certs/my-cert-02/tls.crt;
\s+ssl_certificate_key certs/my-cert-02/tls.key;`, result)
},
Expand Down Expand Up @@ -602,6 +612,41 @@ func TestRpaasConfigurationRenderer_Render(t *testing.T) {
assert.Regexp(t, `\s+resolver kube-dns\.kube-system\.svc\.cluster\.local\. 169\.196\.255\.254:3553 ttl=30m;\n`, result)
},
},
{
name: "with multi domain support",
data: ConfigurationData{
Config: &v1alpha1.NginxConfig{},
Instance: &v1alpha1.RpaasInstance{
Spec: v1alpha1.RpaasInstanceSpec{
ServerBlocks: []v1alpha1.ServerBlock{
{
Type: v1alpha1.BlockTypeServer,
ServerName: "blog.example.com",
Content: &v1alpha1.Value{
Value: "server_scope_config_for blog.example.com;",
},
},
},
},
},
NginxTLS: []nginxv1alpha1.NginxTLS{
{SecretName: "my-cert-01", Hosts: []string{"blog.example.com"}},
{SecretName: "my-cert-02", Hosts: []string{"www.example.org"}},
},
},
assertion: func(t *testing.T, result string) {
assert.Regexp(t, `listen 8443 ssl http2;
\s+server_name www.example.org;
\s+ssl_certificate certs/my-cert-02/tls.crt;
\s+ssl_certificate_key certs/my-cert-02/tls.key;`, result)

assert.Regexp(t, `listen 8443 ssl http2;
\s+server_name blog.example.com;
\s+ssl_certificate certs/my-cert-01/tls.crt;
\s+ssl_certificate_key certs/my-cert-01/tls.key;`, result)

},
},
}

for _, tt := range tests {
Expand Down
17 changes: 13 additions & 4 deletions internal/pkg/rpaas/nginx/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

type Server struct {
Name string `json:"names"`
Name string `json:"name"`
TLS bool `json:"tls"`
TLSSecretName string `json:"secretName"`
Default bool `json:"default,omitempty"`
Expand All @@ -24,7 +24,12 @@ type Server struct {
Locations []v1alpha1.Location `json:"locations,omitempty"`
}

func ProduceServers(spec *v1alpha1.RpaasInstanceSpec) []*Server {
func (s *Server) HasBlockServer() bool {
_, ok := s.Blocks[v1alpha1.BlockTypeServer]
return ok
}

func produceServers(spec *v1alpha1.RpaasInstanceSpec, nginxTLS []nginxv1alpha1.NginxTLS) []*Server {
defaultServer := &Server{
Default: true,
Blocks: deepCopyBlocks(spec.Blocks),
Expand All @@ -51,6 +56,10 @@ func ProduceServers(spec *v1alpha1.RpaasInstanceSpec) []*Server {
}
}

if mapServerNames[serverBlock.ServerName].Blocks == nil {
mapServerNames[serverBlock.ServerName].Blocks = make(map[v1alpha1.BlockType]v1alpha1.Value)
}

_, hasDefaultBlock := defaultServer.Blocks[serverBlock.Type]
if serverBlock.Extend && hasDefaultBlock {
mapServerNames[serverBlock.ServerName].Blocks[serverBlock.Type] = v1alpha1.Value{
Expand Down Expand Up @@ -90,7 +99,7 @@ func ProduceServers(spec *v1alpha1.RpaasInstanceSpec) []*Server {

wildCardTLS := map[string]nginxv1alpha1.NginxTLS{}

for _, tls := range spec.TLS {
for _, tls := range nginxTLS {
for _, host := range tls.Hosts {
if isWildCard(host) {
wildCardTLS[host] = tls
Expand All @@ -114,7 +123,7 @@ func ProduceServers(spec *v1alpha1.RpaasInstanceSpec) []*Server {

}

for _, tls := range spec.TLS {
for _, tls := range nginxTLS {
for _, host := range tls.Hosts {
appendTLSServer(host, tls.SecretName)
}
Expand Down
50 changes: 25 additions & 25 deletions internal/pkg/rpaas/nginx/servers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func TestProduceServers(t *testing.T) {
tests := []struct {
name string
spec *v1alpha1.RpaasInstanceSpec
nginxTLS []nginxv1alpha1.NginxTLS
expected []*Server
}{

Expand Down Expand Up @@ -150,12 +151,11 @@ func TestProduceServers(t *testing.T) {

{
name: "spec with tls",
spec: &v1alpha1.RpaasInstanceSpec{
TLS: []nginxv1alpha1.NginxTLS{
{
SecretName: "example.org",
Hosts: []string{"example.org"},
},
spec: &v1alpha1.RpaasInstanceSpec{},
nginxTLS: []nginxv1alpha1.NginxTLS{
{
SecretName: "example.org",
Hosts: []string{"example.org"},
},
},
expected: []*Server{
Expand All @@ -173,12 +173,6 @@ func TestProduceServers(t *testing.T) {
{
name: "spec with tls and locations",
spec: &v1alpha1.RpaasInstanceSpec{
TLS: []nginxv1alpha1.NginxTLS{
{
SecretName: "example.org",
Hosts: []string{"example.org"},
},
},
Locations: []v1alpha1.Location{
{
Path: "/",
Expand All @@ -188,6 +182,12 @@ func TestProduceServers(t *testing.T) {
},
},
},
nginxTLS: []nginxv1alpha1.NginxTLS{
{
SecretName: "example.org",
Hosts: []string{"example.org"},
},
},
expected: []*Server{
{
Default: true,
Expand Down Expand Up @@ -219,12 +219,6 @@ func TestProduceServers(t *testing.T) {
{
name: "spec with tls with wildcard",
spec: &v1alpha1.RpaasInstanceSpec{
TLS: []nginxv1alpha1.NginxTLS{
{
SecretName: "wild-card-example.org",
Hosts: []string{"*.example.org"},
},
},
Locations: []v1alpha1.Location{
{
Path: "/",
Expand All @@ -234,6 +228,12 @@ func TestProduceServers(t *testing.T) {
},
},
},
nginxTLS: []nginxv1alpha1.NginxTLS{
{
SecretName: "wild-card-example.org",
Hosts: []string{"*.example.org"},
},
},
expected: []*Server{
{
Default: true,
Expand Down Expand Up @@ -265,12 +265,6 @@ func TestProduceServers(t *testing.T) {
{
name: "spec with tls with wildcard ad specific blocks",
spec: &v1alpha1.RpaasInstanceSpec{
TLS: []nginxv1alpha1.NginxTLS{
{
SecretName: "wild-card-example.org",
Hosts: []string{"*.example.org"},
},
},
Locations: []v1alpha1.Location{
{
Path: "/",
Expand All @@ -288,6 +282,12 @@ func TestProduceServers(t *testing.T) {
},
},
},
nginxTLS: []nginxv1alpha1.NginxTLS{
{
SecretName: "wild-card-example.org",
Hosts: []string{"*.example.org"},
},
},
expected: []*Server{
{
Default: true,
Expand Down Expand Up @@ -479,7 +479,7 @@ func TestProduceServers(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ProduceServers(tt.spec)
result := produceServers(tt.spec, tt.nginxTLS)
assert.Equal(t, tt.expected, result)
})
}
Expand Down

0 comments on commit acf2879

Please sign in to comment.