Skip to content

Commit

Permalink
Add stream-snippet as a ConfigMap and Annotation option (#8029)
Browse files Browse the repository at this point in the history
* stream snippet

* gofmt -s
  • Loading branch information
Eun authored Dec 23, 2021
1 parent cf6ea08 commit ce9deaa
Show file tree
Hide file tree
Showing 12 changed files with 386 additions and 4 deletions.
18 changes: 18 additions & 0 deletions docs/user-guide/nginx-configuration/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|[nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none](#cookie-affinity)|"true" or "false"|
|[nginx.ingress.kubernetes.io/ssl-redirect](#server-side-https-enforcement-through-redirect)|"true" or "false"|
|[nginx.ingress.kubernetes.io/ssl-passthrough](#ssl-passthrough)|"true" or "false"|
|[nginx.ingress.kubernetes.io/stream-snippet](#stream-snippet)|string|
|[nginx.ingress.kubernetes.io/upstream-hash-by](#custom-nginx-upstream-hashing)|string|
|[nginx.ingress.kubernetes.io/x-forwarded-prefix](#x-forwarded-prefix-header)|string|
|[nginx.ingress.kubernetes.io/load-balance](#custom-nginx-load-balancing)|string|
Expand Down Expand Up @@ -927,3 +928,20 @@ nginx.ingress.kubernetes.io/mirror-request-body: "off"
The request sent to the mirror is linked to the original request. If you have a slow mirror backend, then the original request will throttle.

For more information on the mirror module see [ngx_http_mirror_module](https://nginx.org/en/docs/http/ngx_http_mirror_module.html)


### Stream snippet

Using the annotation `nginx.ingress.kubernetes.io/stream-snippet` it is possible to add custom stream configuration.

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/stream-snippet: |
server {
listen 8000;
proxy_pass 127.0.0.1:80;
}
```
5 changes: 5 additions & 0 deletions docs/user-guide/nginx-configuration/configmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ The following table shows a configuration option's name, type, and the default v
|[main-snippet](#main-snippet)|string|""|
|[http-snippet](#http-snippet)|string|""|
|[server-snippet](#server-snippet)|string|""|
|[stream-snippet](#stream-snippet)|string|""|
|[location-snippet](#location-snippet)|string|""|
|[custom-http-errors](#custom-http-errors)|[]int|[]int{}|
|[proxy-body-size](#proxy-body-size)|string|"1m"|
Expand Down Expand Up @@ -988,6 +989,10 @@ Adds custom configuration to the http section of the nginx configuration.

Adds custom configuration to all the servers in the nginx configuration.

## stream-snippet

Adds custom configuration to the stream section of the nginx configuration.

## location-snippet

Adds custom configuration to all the locations in the nginx configuration.
Expand Down
3 changes: 3 additions & 0 deletions internal/ingress/annotations/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity"
"k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl"
"k8s.io/ingress-nginx/internal/ingress/annotations/sslcipher"
"k8s.io/ingress-nginx/internal/ingress/annotations/streamsnippet"
"k8s.io/klog/v2"

apiv1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -115,6 +116,7 @@ type Ingress struct {
InfluxDB influxdb.Config
ModSecurity modsecurity.Config
Mirror mirror.Config
StreamSnippet string
}

// Extractor defines the annotation parsers to be used in the extraction of annotations
Expand Down Expand Up @@ -165,6 +167,7 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor {
"BackendProtocol": backendprotocol.NewParser(cfg),
"ModSecurity": modsecurity.NewParser(cfg),
"Mirror": mirror.NewParser(cfg),
"StreamSnippet": streamsnippet.NewParser(cfg),
},
}
}
Expand Down
40 changes: 40 additions & 0 deletions internal/ingress/annotations/streamsnippet/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package streamsnippet

import (
networking "k8s.io/api/networking/v1"

"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
"k8s.io/ingress-nginx/internal/ingress/resolver"
)

type streamSnippet struct {
r resolver.Resolver
}

// NewParser creates a new server snippet annotation parser
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
return streamSnippet{r}
}

// Parse parses the annotations contained in the ingress rule
// used to indicate if the location/s contains a fragment of
// configuration to be included inside the paths of the rules
func (a streamSnippet) Parse(ing *networking.Ingress) (interface{}, error) {
return parser.GetStringAnnotation("stream-snippet", ing)
}
64 changes: 64 additions & 0 deletions internal/ingress/annotations/streamsnippet/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package streamsnippet

import (
"testing"

api "k8s.io/api/core/v1"
networking "k8s.io/api/networking/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
"k8s.io/ingress-nginx/internal/ingress/resolver"
)

func TestParse(t *testing.T) {
annotation := parser.GetAnnotationWithPrefix("stream-snippet")

ap := NewParser(&resolver.Mock{})
if ap == nil {
t.Fatalf("expected a parser.IngressAnnotation but returned nil")
}

testCases := []struct {
annotations map[string]string
expected string
}{
{map[string]string{annotation: "server { listen: 8000; proxy_pass 127.0.0.1:80}"},
"server { listen: 8000; proxy_pass 127.0.0.1:80}",
},
{map[string]string{annotation: "false"}, "false"},
{map[string]string{}, ""},
{nil, ""},
}

ing := &networking.Ingress{
ObjectMeta: meta_v1.ObjectMeta{
Name: "foo",
Namespace: api.NamespaceDefault,
},
Spec: networking.IngressSpec{},
}

for _, testCase := range testCases {
ing.SetAnnotations(testCase.annotations)
result, _ := ap.Parse(ing)
if result != testCase.expected {
t.Errorf("expected %v but returned %v, annotations: %s", testCase.expected, result, testCase.annotations)
}
}
}
12 changes: 8 additions & 4 deletions internal/ingress/controller/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,9 @@ type Configuration struct {
// ServerSnippet adds custom configuration to all the servers in the nginx configuration
ServerSnippet string `json:"server-snippet"`

// StreamSnippet adds custom configuration to the stream section of the nginx configuration
StreamSnippet string `json:"stream-snippet"`

// LocationSnippet adds custom configuration to all the locations in the nginx configuration
LocationSnippet string `json:"location-snippet"`

Expand Down Expand Up @@ -956,10 +959,11 @@ type TemplateConfig struct {
MaxmindEditionFiles *[]string
MonitorMaxBatchSize int

PID string
StatusPath string
StatusPort int
StreamPort int
PID string
StatusPath string
StatusPort int
StreamPort int
StreamSnippets []string
}

// ListenPorts describe the ports required to run the
Expand Down
17 changes: 17 additions & 0 deletions internal/ingress/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ func (n *NGINXController) getConfiguration(ingresses []*ingress.Ingress) (sets.S
PassthroughBackends: passUpstreams,
BackendConfigChecksum: n.store.GetBackendConfiguration().Checksum,
DefaultSSLCertificate: n.getDefaultSSLCertificate(),
StreamSnippets: n.getStreamSnippets(ingresses),
}
}

Expand All @@ -562,6 +563,11 @@ func dropSnippetDirectives(anns *annotations.Ingress, ingKey string) {
anns.ExternalAuth.AuthSnippet = ""
}

if anns.StreamSnippet != "" {
klog.V(3).Infof("Ingress %q tried to use stream-snippet and the annotation is disabled by the admin. Removing the annotation", ingKey)
anns.StreamSnippet = ""
}

}
}

Expand Down Expand Up @@ -1779,3 +1785,14 @@ func ingressForHostPath(hostname, path string, servers []*ingress.Server) []*net

return ingresses
}

func (n *NGINXController) getStreamSnippets(ingresses []*ingress.Ingress) []string {
snippets := make([]string, 0, len(ingresses))
for _, i := range ingresses {
if i.ParsedAnnotations.StreamSnippet == "" {
continue
}
snippets = append(snippets, i.ParsedAnnotations.StreamSnippet)
}
return snippets
}
1 change: 1 addition & 0 deletions internal/ingress/controller/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC
StatusPath: nginx.StatusPath,
StatusPort: nginx.StatusPort,
StreamPort: nginx.StreamPort,
StreamSnippets: append(ingressCfg.StreamSnippets, cfg.StreamSnippet),
}

tc.Cfg.Checksum = ingressCfg.ConfigurationChecksum
Expand Down
2 changes: 2 additions & 0 deletions internal/ingress/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ type Configuration struct {
ConfigurationChecksum string `json:"configurationChecksum,omitempty"`

DefaultSSLCertificate *SSLCert `json:"-"`

StreamSnippets []string
}

// Backend describes one or more remote server/s (endpoints) associated with a service
Expand Down
5 changes: 5 additions & 0 deletions rootfs/etc/nginx/template/nginx.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,11 @@ stream {
proxy_pass upstream_balancer;
}
{{ end }}

# Stream Snippets
{{ range $snippet := .StreamSnippets }}
{{ $snippet }}
{{ end }}
}

{{/* definition of templates to avoid repetitions */}}
Expand Down
Loading

0 comments on commit ce9deaa

Please sign in to comment.