Fix golangci-lint errors (#10196)
* Fix golangci-lint errors Signed-off-by: z1cheng <imchench@gmail.com> * Fix dupl errors Signed-off-by: z1cheng <imchench@gmail.com> * Fix comments Signed-off-by: z1cheng <imchench@gmail.com> * Fix errcheck lint errors Signed-off-by: z1cheng <imchench@gmail.com> * Fix assert in e2e test Signed-off-by: z1cheng <imchench@gmail.com> * Not interrupt the waitForPodsReady Signed-off-by: z1cheng <imchench@gmail.com> * Replace string with constant Signed-off-by: z1cheng <imchench@gmail.com> * Fix comments Signed-off-by: z1cheng <imchench@gmail.com> * Revert write file permision Signed-off-by: z1cheng <imchench@gmail.com> --------- Signed-off-by: z1cheng <imchench@gmail.com>
This commit is contained in:
parent
46d87d3462
commit
b3060bfbd0
253 changed files with 2434 additions and 2113 deletions
|
|
@ -100,7 +100,7 @@ func matchHostnames(pattern, host string) bool {
|
|||
host = strings.TrimSuffix(host, ".")
|
||||
pattern = strings.TrimSuffix(pattern, ".")
|
||||
|
||||
if len(pattern) == 0 || len(host) == 0 {
|
||||
if pattern == "" || host == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import (
|
|||
)
|
||||
|
||||
// Name returns the healthcheck name
|
||||
func (n NGINXController) Name() string {
|
||||
func (n *NGINXController) Name() string {
|
||||
return "nginx-ingress-controller"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import (
|
|||
)
|
||||
|
||||
func TestNginxCheck(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
healthzPath string
|
||||
}{
|
||||
{"/healthz"},
|
||||
|
|
@ -42,7 +42,6 @@ func TestNginxCheck(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
testName := fmt.Sprintf("health path: %s", tt.healthzPath)
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
listener, err := tryListen("tcp", fmt.Sprintf(":%v", nginx.StatusPort))
|
||||
|
|
@ -50,7 +49,7 @@ func TestNginxCheck(t *testing.T) {
|
|||
t.Fatalf("creating tcp listener: %s", err)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
//nolint:gosec // Ignore not configured ReadHeaderTimeout in testing
|
||||
server := &httptest.Server{
|
||||
Listener: listener,
|
||||
Config: &http.Server{
|
||||
|
|
@ -103,10 +102,10 @@ func TestNginxCheck(t *testing.T) {
|
|||
}
|
||||
}()
|
||||
go func() {
|
||||
cmd.Wait() //nolint:errcheck
|
||||
cmd.Wait() //nolint:errcheck // Ignore the error
|
||||
}()
|
||||
|
||||
if _, err := pidFile.Write([]byte(fmt.Sprintf("%v", pid))); err != nil {
|
||||
if _, err := fmt.Fprintf(pidFile, "%v", pid); err != nil {
|
||||
t.Errorf("unexpected error writing the pid file: %v", err)
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +120,7 @@ func TestNginxCheck(t *testing.T) {
|
|||
})
|
||||
|
||||
// pollute pid file
|
||||
pidFile.Write([]byte("999999")) //nolint:errcheck
|
||||
pidFile.WriteString("999999") //nolint:errcheck // Ignore the error
|
||||
pidFile.Close()
|
||||
|
||||
t.Run("bad pid", func(t *testing.T) {
|
||||
|
|
@ -134,7 +133,7 @@ func TestNginxCheck(t *testing.T) {
|
|||
}
|
||||
|
||||
func callHealthz(expErr bool, healthzPath string, mux *http.ServeMux) error {
|
||||
req, err := http.NewRequest(http.MethodGet, healthzPath, nil)
|
||||
req, err := http.NewRequest(http.MethodGet, healthzPath, http.NoBody)
|
||||
if err != nil {
|
||||
return fmt.Errorf("healthz error: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,10 +29,8 @@ import (
|
|||
"k8s.io/ingress-nginx/pkg/util/runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
// EnableSSLChainCompletion Autocomplete SSL certificate chains with missing intermediate CA certificates.
|
||||
EnableSSLChainCompletion = false
|
||||
)
|
||||
// EnableSSLChainCompletion Autocomplete SSL certificate chains with missing intermediate CA certificates.
|
||||
var EnableSSLChainCompletion = false
|
||||
|
||||
const (
|
||||
// http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
|
||||
|
|
@ -91,7 +89,7 @@ const (
|
|||
|
||||
// Configuration represents the content of nginx.conf file
|
||||
type Configuration struct {
|
||||
defaults.Backend `json:",squash"` //nolint:staticcheck
|
||||
defaults.Backend `json:",squash"` //nolint:staticcheck // Ignore unknown JSON option "squash" error
|
||||
|
||||
// AllowSnippetAnnotations enable users to add their own snippets via ingress annotation.
|
||||
// If disabled, only snippets added via ConfigMap are added to ingress.
|
||||
|
|
@ -141,9 +139,9 @@ type Configuration struct {
|
|||
// By default access logs go to /var/log/nginx/access.log
|
||||
AccessLogPath string `json:"access-log-path,omitempty"`
|
||||
|
||||
// HttpAccessLogPath sets the path of the access logs for http context globally if enabled
|
||||
// HTTPAccessLogPath sets the path of the access logs for http context globally if enabled
|
||||
// http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log
|
||||
HttpAccessLogPath string `json:"http-access-log-path,omitempty"`
|
||||
HTTPAccessLogPath string `json:"http-access-log-path,omitempty"`
|
||||
|
||||
// StreamAccessLogPath sets the path of the access logs for stream context globally if enabled
|
||||
// http://nginx.org/en/docs/stream/ngx_stream_log_module.html#access_log
|
||||
|
|
@ -230,19 +228,19 @@ type Configuration struct {
|
|||
|
||||
// https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_field_size
|
||||
// HTTP2MaxFieldSize Limits the maximum size of an HPACK-compressed request header field
|
||||
// NOTE: Deprecated
|
||||
// Deprecated: HTTP2MaxFieldSize is deprecated.
|
||||
HTTP2MaxFieldSize string `json:"http2-max-field-size,omitempty"`
|
||||
|
||||
// https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_header_size
|
||||
// HTTP2MaxHeaderSize Limits the maximum size of the entire request header list after HPACK decompression
|
||||
// NOTE: Deprecated
|
||||
// Deprecated: HTTP2MaxHeaderSize is deprecated.
|
||||
HTTP2MaxHeaderSize string `json:"http2-max-header-size,omitempty"`
|
||||
|
||||
// http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_requests
|
||||
// HTTP2MaxRequests Sets the maximum number of requests (including push requests) that can be served
|
||||
// through one HTTP/2 connection, after which the next client request will lead to connection closing
|
||||
// and the need of establishing a new connection.
|
||||
// NOTE: Deprecated
|
||||
// Deprecated: HTTP2MaxRequests is deprecated.
|
||||
HTTP2MaxRequests int `json:"http2-max-requests,omitempty"`
|
||||
|
||||
// http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_concurrent_streams
|
||||
|
|
@ -552,7 +550,7 @@ type Configuration struct {
|
|||
UseForwardedHeaders bool `json:"use-forwarded-headers"`
|
||||
|
||||
// Sets whether to enable the real ip module
|
||||
EnableRealIp bool `json:"enable-real-ip"`
|
||||
EnableRealIP bool `json:"enable-real-ip"`
|
||||
|
||||
// Sets the header field for identifying the originating IP address of a client
|
||||
// Default is X-Forwarded-For
|
||||
|
|
@ -621,7 +619,7 @@ type Configuration struct {
|
|||
// Default: 0.01
|
||||
OtelSamplerRatio float32 `json:"otel-sampler-ratio"`
|
||||
|
||||
//OtelSamplerParentBased specifies the parent based sampler to be use for any traces created
|
||||
// OtelSamplerParentBased specifies the parent based sampler to be use for any traces created
|
||||
// Default: true
|
||||
OtelSamplerParentBased bool `json:"otel-sampler-parent-based"`
|
||||
|
||||
|
|
@ -891,7 +889,7 @@ func NewDefault() Configuration {
|
|||
EnableUnderscoresInHeaders: false,
|
||||
ErrorLogLevel: errorLevel,
|
||||
UseForwardedHeaders: false,
|
||||
EnableRealIp: false,
|
||||
EnableRealIP: false,
|
||||
ForwardedForHeader: "X-Forwarded-For",
|
||||
ComputeFullForwardedFor: false,
|
||||
ProxyAddOriginalURIHeader: false,
|
||||
|
|
@ -1039,41 +1037,41 @@ func NewDefault() Configuration {
|
|||
|
||||
// TemplateConfig contains the nginx configuration to render the file nginx.conf
|
||||
type TemplateConfig struct {
|
||||
ProxySetHeaders map[string]string
|
||||
AddHeaders map[string]string
|
||||
BacklogSize int
|
||||
Backends []*ingress.Backend
|
||||
PassthroughBackends []*ingress.SSLPassthroughBackend
|
||||
Servers []*ingress.Server
|
||||
TCPBackends []ingress.L4Service
|
||||
UDPBackends []ingress.L4Service
|
||||
HealthzURI string
|
||||
Cfg Configuration
|
||||
IsIPV6Enabled bool
|
||||
IsSSLPassthroughEnabled bool
|
||||
NginxStatusIpv4Whitelist []string
|
||||
NginxStatusIpv6Whitelist []string
|
||||
RedirectServers interface{}
|
||||
ListenPorts *ListenPorts
|
||||
PublishService *apiv1.Service
|
||||
EnableMetrics bool
|
||||
MaxmindEditionFiles *[]string
|
||||
MonitorMaxBatchSize int
|
||||
PID string
|
||||
StatusPath string
|
||||
StatusPort int
|
||||
StreamPort int
|
||||
StreamSnippets []string
|
||||
ProxySetHeaders map[string]string `json:"ProxySetHeaders"`
|
||||
AddHeaders map[string]string `json:"AddHeaders"`
|
||||
BacklogSize int `json:"BacklogSize"`
|
||||
Backends []*ingress.Backend `json:"Backends"`
|
||||
PassthroughBackends []*ingress.SSLPassthroughBackend `json:"PassthroughBackends"`
|
||||
Servers []*ingress.Server `json:"Servers"`
|
||||
TCPBackends []ingress.L4Service `json:"TCPBackends"`
|
||||
UDPBackends []ingress.L4Service `json:"UDPBackends"`
|
||||
HealthzURI string `json:"HealthzURI"`
|
||||
Cfg Configuration `json:"Cfg"`
|
||||
IsIPV6Enabled bool `json:"IsIPV6Enabled"`
|
||||
IsSSLPassthroughEnabled bool `json:"IsSSLPassthroughEnabled"`
|
||||
NginxStatusIpv4Whitelist []string `json:"NginxStatusIpv4Whitelist"`
|
||||
NginxStatusIpv6Whitelist []string `json:"NginxStatusIpv6Whitelist"`
|
||||
RedirectServers interface{} `json:"RedirectServers"`
|
||||
ListenPorts *ListenPorts `json:"ListenPorts"`
|
||||
PublishService *apiv1.Service `json:"PublishService"`
|
||||
EnableMetrics bool `json:"EnableMetrics"`
|
||||
MaxmindEditionFiles *[]string `json:"MaxmindEditionFiles"`
|
||||
MonitorMaxBatchSize int `json:"MonitorMaxBatchSize"`
|
||||
PID string `json:"PID"`
|
||||
StatusPath string `json:"StatusPath"`
|
||||
StatusPort int `json:"StatusPort"`
|
||||
StreamPort int `json:"StreamPort"`
|
||||
StreamSnippets []string `json:"StreamSnippets"`
|
||||
}
|
||||
|
||||
// ListenPorts describe the ports required to run the
|
||||
// NGINX Ingress controller
|
||||
type ListenPorts struct {
|
||||
HTTP int
|
||||
HTTPS int
|
||||
Health int
|
||||
Default int
|
||||
SSLProxy int
|
||||
HTTP int `json:"HTTP"`
|
||||
HTTPS int `json:"HTTPS"`
|
||||
Health int `json:"Health"`
|
||||
Default int `json:"Default"`
|
||||
SSLProxy int `json:"SSLProxy"`
|
||||
}
|
||||
|
||||
// GlobalExternalAuth describe external authentication configuration for the
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ type Configuration struct {
|
|||
|
||||
DisableCatchAll bool
|
||||
|
||||
IngressClassConfiguration *ingressclass.IngressClassConfiguration
|
||||
IngressClassConfiguration *ingressclass.Configuration
|
||||
|
||||
ValidationWebhook string
|
||||
ValidationWebhookCertPath string
|
||||
|
|
@ -143,7 +143,7 @@ type Configuration struct {
|
|||
func getIngressPodZone(svc *apiv1.Service) string {
|
||||
svcKey := k8s.MetaNamespaceKey(svc)
|
||||
if svcZoneAnnotation, ok := svc.ObjectMeta.GetAnnotations()[apiv1.AnnotationTopologyMode]; ok {
|
||||
if strings.ToLower(svcZoneAnnotation) == "auto" {
|
||||
if strings.EqualFold(svcZoneAnnotation, "auto") {
|
||||
if foundZone, ok := k8s.IngressNodeDetails.GetLabels()[apiv1.LabelTopologyZone]; ok {
|
||||
klog.V(3).Infof("Svc has topology aware annotation enabled, try to use zone %q where controller pod is running for Service %q ", foundZone, svcKey)
|
||||
return foundZone
|
||||
|
|
@ -154,7 +154,7 @@ func getIngressPodZone(svc *apiv1.Service) string {
|
|||
}
|
||||
|
||||
// GetPublishService returns the Service used to set the load-balancer status of Ingresses.
|
||||
func (n NGINXController) GetPublishService() *apiv1.Service {
|
||||
func (n *NGINXController) GetPublishService() *apiv1.Service {
|
||||
s, err := n.store.GetService(n.cfg.PublishService)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
|
@ -189,13 +189,16 @@ func (n *NGINXController) syncIngress(interface{}) error {
|
|||
if !utilingress.IsDynamicConfigurationEnough(pcfg, n.runningConfig) {
|
||||
klog.InfoS("Configuration changes detected, backend reload required")
|
||||
|
||||
hash, _ := hashstructure.Hash(pcfg, hashstructure.FormatV1, &hashstructure.HashOptions{
|
||||
hash, err := hashstructure.Hash(pcfg, hashstructure.FormatV1, &hashstructure.HashOptions{
|
||||
TagName: "json",
|
||||
})
|
||||
if err != nil {
|
||||
klog.Errorf("unexpected error hashing configuration: %v", err)
|
||||
}
|
||||
|
||||
pcfg.ConfigurationChecksum = fmt.Sprintf("%v", hash)
|
||||
|
||||
err := n.OnUpdate(*pcfg)
|
||||
err = n.OnUpdate(*pcfg)
|
||||
if err != nil {
|
||||
n.metricCollector.IncReloadErrorCount()
|
||||
n.metricCollector.ConfigSuccess(hash, false)
|
||||
|
|
@ -263,7 +266,7 @@ func (n *NGINXController) syncIngress(interface{}) error {
|
|||
func (n *NGINXController) CheckWarning(ing *networking.Ingress) ([]string, error) {
|
||||
warnings := make([]string, 0)
|
||||
|
||||
var deprecatedAnnotations = sets.NewString()
|
||||
deprecatedAnnotations := sets.NewString()
|
||||
deprecatedAnnotations.Insert(
|
||||
"enable-influxdb",
|
||||
"influxdb-measurement",
|
||||
|
|
@ -335,7 +338,7 @@ func (n *NGINXController) CheckIngress(ing *networking.Ingress) error {
|
|||
}
|
||||
|
||||
if n.cfg.DisableCatchAll && ing.Spec.DefaultBackend != nil {
|
||||
return fmt.Errorf("This deployment is trying to create a catch-all ingress while DisableCatchAll flag is set to true. Remove '.spec.defaultBackend' or set DisableCatchAll flag to false.")
|
||||
return fmt.Errorf("this deployment is trying to create a catch-all ingress while DisableCatchAll flag is set to true. Remove '.spec.defaultBackend' or set DisableCatchAll flag to false")
|
||||
}
|
||||
startRender := time.Now().UnixNano() / 1000000
|
||||
cfg := n.store.GetBackendConfiguration()
|
||||
|
|
@ -355,10 +358,9 @@ func (n *NGINXController) CheckIngress(ing *networking.Ingress) error {
|
|||
}
|
||||
|
||||
for key, value := range ing.ObjectMeta.GetAnnotations() {
|
||||
|
||||
if parser.AnnotationsPrefix != parser.DefaultAnnotationsPrefix {
|
||||
if strings.HasPrefix(key, fmt.Sprintf("%s/", parser.DefaultAnnotationsPrefix)) {
|
||||
return fmt.Errorf("This deployment has a custom annotation prefix defined. Use '%s' instead of '%s'", parser.AnnotationsPrefix, parser.DefaultAnnotationsPrefix)
|
||||
return fmt.Errorf("this deployment has a custom annotation prefix defined. Use '%s' instead of '%s'", parser.AnnotationsPrefix, parser.DefaultAnnotationsPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -374,10 +376,9 @@ func (n *NGINXController) CheckIngress(ing *networking.Ingress) error {
|
|||
return fmt.Errorf("%s annotation cannot be used. Snippet directives are disabled by the Ingress administrator", key)
|
||||
}
|
||||
|
||||
if len(cfg.GlobalRateLimitMemcachedHost) == 0 && strings.HasPrefix(key, fmt.Sprintf("%s/%s", parser.AnnotationsPrefix, "global-rate-limit")) {
|
||||
if cfg.GlobalRateLimitMemcachedHost == "" && strings.HasPrefix(key, fmt.Sprintf("%s/%s", parser.AnnotationsPrefix, "global-rate-limit")) {
|
||||
return fmt.Errorf("'global-rate-limit*' annotations require 'global-rate-limit-memcached-host' settings configured in the global configmap")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
k8s.SetDefaultNGINXPathType(ing)
|
||||
|
|
@ -401,7 +402,7 @@ func (n *NGINXController) CheckIngress(ing *networking.Ingress) error {
|
|||
startTest := time.Now().UnixNano() / 1000000
|
||||
_, servers, pcfg := n.getConfiguration(ings)
|
||||
|
||||
err = checkOverlap(ing, allIngresses, servers)
|
||||
err = checkOverlap(ing, servers)
|
||||
if err != nil {
|
||||
n.metricCollector.IncCheckErrorCount(ing.ObjectMeta.Namespace, ing.Name)
|
||||
return err
|
||||
|
|
@ -452,7 +453,7 @@ func (n *NGINXController) getStreamServices(configmapName string, proto apiv1.Pr
|
|||
return []ingress.L4Service{}
|
||||
}
|
||||
|
||||
var svcs []ingress.L4Service
|
||||
svcs := make([]ingress.L4Service, 0, len(configmap.Data))
|
||||
var svcProxyProtocol ingress.ProxyProtocol
|
||||
|
||||
rp := []int{
|
||||
|
|
@ -489,10 +490,10 @@ func (n *NGINXController) getStreamServices(configmapName string, proto apiv1.Pr
|
|||
svcProxyProtocol.Encode = false
|
||||
// Proxy Protocol is only compatible with TCP Services
|
||||
if len(nsSvcPort) >= 3 && proto == apiv1.ProtocolTCP {
|
||||
if len(nsSvcPort) >= 3 && strings.ToUpper(nsSvcPort[2]) == "PROXY" {
|
||||
if len(nsSvcPort) >= 3 && strings.EqualFold(nsSvcPort[2], "PROXY") {
|
||||
svcProxyProtocol.Decode = true
|
||||
}
|
||||
if len(nsSvcPort) == 4 && strings.ToUpper(nsSvcPort[3]) == "PROXY" {
|
||||
if len(nsSvcPort) == 4 && strings.EqualFold(nsSvcPort[3], "PROXY") {
|
||||
svcProxyProtocol.Encode = true
|
||||
}
|
||||
}
|
||||
|
|
@ -532,6 +533,7 @@ func (n *NGINXController) getStreamServices(configmapName string, proto apiv1.Pr
|
|||
klog.V(3).Infof("Searching Endpoints with %v port number %d for Service %q", proto, targetPort, nsName)
|
||||
for i := range svc.Spec.Ports {
|
||||
sp := svc.Spec.Ports[i]
|
||||
//nolint:gosec // Ignore G109 error
|
||||
if sp.Port == int32(targetPort) {
|
||||
if sp.Protocol == proto {
|
||||
endps = getEndpointsFromSlices(svc, &sp, proto, zone, n.store.GetServiceEndpointsSlices)
|
||||
|
|
@ -574,7 +576,7 @@ func (n *NGINXController) getDefaultUpstream() *ingress.Backend {
|
|||
}
|
||||
svcKey := n.cfg.DefaultService
|
||||
|
||||
if len(svcKey) == 0 {
|
||||
if svcKey == "" {
|
||||
upstream.Endpoints = append(upstream.Endpoints, n.DefaultEndpoint())
|
||||
return upstream
|
||||
}
|
||||
|
|
@ -690,13 +692,14 @@ func dropSnippetDirectives(anns *annotations.Ingress, ingKey string) {
|
|||
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 = ""
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// getBackendServers returns a list of Upstream and Server to be used by the
|
||||
// backend. An upstream can be used in multiple servers if the namespace,
|
||||
// service name and port are the same.
|
||||
//
|
||||
//nolint:gocyclo // Ignore function complexity error
|
||||
func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*ingress.Backend, []*ingress.Server) {
|
||||
du := n.getDefaultUpstream()
|
||||
upstreams := n.createUpstreams(ingresses, du)
|
||||
|
|
@ -1030,7 +1033,7 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B
|
|||
// configure traffic shaping for canary
|
||||
if anns.Canary.Enabled {
|
||||
upstreams[defBackend].NoServer = true
|
||||
upstreams[defBackend].TrafficShapingPolicy = newTrafficShapingPolicy(anns.Canary)
|
||||
upstreams[defBackend].TrafficShapingPolicy = newTrafficShapingPolicy(&anns.Canary)
|
||||
}
|
||||
|
||||
if len(upstreams[defBackend].Endpoints) == 0 {
|
||||
|
|
@ -1095,7 +1098,7 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B
|
|||
// configure traffic shaping for canary
|
||||
if anns.Canary.Enabled {
|
||||
upstreams[name].NoServer = true
|
||||
upstreams[name].TrafficShapingPolicy = newTrafficShapingPolicy(anns.Canary)
|
||||
upstreams[name].TrafficShapingPolicy = newTrafficShapingPolicy(&anns.Canary)
|
||||
}
|
||||
|
||||
if len(upstreams[name].Endpoints) == 0 {
|
||||
|
|
@ -1206,7 +1209,6 @@ func (n *NGINXController) serviceEndpoints(svcKey, backendPort string) ([]ingres
|
|||
if strconv.Itoa(int(servicePort.Port)) == backendPort ||
|
||||
servicePort.TargetPort.String() == backendPort ||
|
||||
servicePort.Name == backendPort {
|
||||
|
||||
endps := getEndpointsFromSlices(svc, &servicePort, apiv1.ProtocolTCP, zone, n.store.GetServiceEndpointsSlices)
|
||||
if len(endps) == 0 {
|
||||
klog.Warningf("Service %q does not have any active Endpoint.", svcKey)
|
||||
|
|
@ -1239,8 +1241,8 @@ func (n *NGINXController) getDefaultSSLCertificate() *ingress.SSLCert {
|
|||
// one root location, which uses a default backend if left unspecified.
|
||||
func (n *NGINXController) createServers(data []*ingress.Ingress,
|
||||
upstreams map[string]*ingress.Backend,
|
||||
du *ingress.Backend) map[string]*ingress.Server {
|
||||
|
||||
du *ingress.Backend,
|
||||
) map[string]*ingress.Server {
|
||||
servers := make(map[string]*ingress.Server, len(data))
|
||||
allAliases := make(map[string][]string, len(data))
|
||||
|
||||
|
|
@ -1282,7 +1284,8 @@ func (n *NGINXController) createServers(data []*ingress.Ingress,
|
|||
Rewrite: false,
|
||||
},
|
||||
},
|
||||
}}
|
||||
},
|
||||
}
|
||||
|
||||
// initialize all other servers
|
||||
for _, ing := range data {
|
||||
|
|
@ -1532,7 +1535,7 @@ func locationApplyAnnotations(loc *ingress.Location, anns *annotations.Ingress)
|
|||
}
|
||||
|
||||
// OK to merge canary ingresses iff there exists one or more ingresses to potentially merge into
|
||||
func nonCanaryIngressExists(ingresses []*ingress.Ingress, canaryIngresses []*ingress.Ingress) bool {
|
||||
func nonCanaryIngressExists(ingresses, canaryIngresses []*ingress.Ingress) bool {
|
||||
return len(ingresses)-len(canaryIngresses) > 0
|
||||
}
|
||||
|
||||
|
|
@ -1540,12 +1543,12 @@ func nonCanaryIngressExists(ingresses []*ingress.Ingress, canaryIngresses []*ing
|
|||
// 1) names of backends do not match and canary doesn't merge into itself
|
||||
// 2) primary name is not the default upstream
|
||||
// 3) the primary has a server
|
||||
func canMergeBackend(primary *ingress.Backend, alternative *ingress.Backend) bool {
|
||||
func canMergeBackend(primary, alternative *ingress.Backend) bool {
|
||||
return alternative != nil && primary.Name != alternative.Name && primary.Name != defUpstreamName && !primary.NoServer
|
||||
}
|
||||
|
||||
// Performs the merge action and checks to ensure that one two alternative backends do not merge into each other
|
||||
func mergeAlternativeBackend(ing *ingress.Ingress, priUps *ingress.Backend, altUps *ingress.Backend) bool {
|
||||
func mergeAlternativeBackend(ing *ingress.Ingress, priUps, altUps *ingress.Backend) bool {
|
||||
if priUps.NoServer {
|
||||
klog.Warningf("unable to merge alternative backend %v into primary backend %v because %v is a primary backend",
|
||||
altUps.Name, priUps.Name, priUps.Name)
|
||||
|
|
@ -1563,8 +1566,7 @@ func mergeAlternativeBackend(ing *ingress.Ingress, priUps *ingress.Backend, altU
|
|||
priUps.SessionAffinity.DeepCopyInto(&altUps.SessionAffinity)
|
||||
}
|
||||
|
||||
priUps.AlternativeBackends =
|
||||
append(priUps.AlternativeBackends, altUps.Name)
|
||||
priUps.AlternativeBackends = append(priUps.AlternativeBackends, altUps.Name)
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -1574,8 +1576,8 @@ func mergeAlternativeBackend(ing *ingress.Ingress, priUps *ingress.Backend, altU
|
|||
// to a backend's alternative list.
|
||||
// If no match is found, then the serverless backend is deleted.
|
||||
func mergeAlternativeBackends(ing *ingress.Ingress, upstreams map[string]*ingress.Backend,
|
||||
servers map[string]*ingress.Server) {
|
||||
|
||||
servers map[string]*ingress.Server,
|
||||
) {
|
||||
// merge catch-all alternative backends
|
||||
if ing.Spec.DefaultBackend != nil {
|
||||
upsName := upstreamName(ing.Namespace, ing.Spec.DefaultBackend.Service)
|
||||
|
|
@ -1585,7 +1587,6 @@ func mergeAlternativeBackends(ing *ingress.Ingress, upstreams map[string]*ingres
|
|||
if altUps == nil {
|
||||
klog.Warningf("alternative backend %s has already been removed", upsName)
|
||||
} else {
|
||||
|
||||
merged := false
|
||||
altEqualsPri := false
|
||||
|
||||
|
|
@ -1676,8 +1677,8 @@ func mergeAlternativeBackends(ing *ingress.Ingress, upstreams map[string]*ingres
|
|||
// extractTLSSecretName returns the name of the Secret containing a SSL
|
||||
// certificate for the given host name, or an empty string.
|
||||
func extractTLSSecretName(host string, ing *ingress.Ingress,
|
||||
getLocalSSLCert func(string) (*ingress.SSLCert, error)) string {
|
||||
|
||||
getLocalSSLCert func(string) (*ingress.SSLCert, error),
|
||||
) string {
|
||||
if ing == nil {
|
||||
return ""
|
||||
}
|
||||
|
|
@ -1694,7 +1695,6 @@ func extractTLSSecretName(host string, ing *ingress.Ingress,
|
|||
|
||||
// no TLS host matching host name, try each TLS host for matching SAN or CN
|
||||
for _, tls := range ing.Spec.TLS {
|
||||
|
||||
if tls.SecretName == "" {
|
||||
// There's no secretName specified, so it will never be available
|
||||
continue
|
||||
|
|
@ -1753,6 +1753,7 @@ func externalNamePorts(name string, svc *apiv1.Service) *apiv1.ServicePort {
|
|||
}
|
||||
|
||||
for _, svcPort := range svc.Spec.Ports {
|
||||
//nolint:gosec // Ignore G109 error
|
||||
if svcPort.Port != int32(port) {
|
||||
continue
|
||||
}
|
||||
|
|
@ -1771,13 +1772,14 @@ func externalNamePorts(name string, svc *apiv1.Service) *apiv1.ServicePort {
|
|||
|
||||
// ExternalName without port
|
||||
return &apiv1.ServicePort{
|
||||
Protocol: "TCP",
|
||||
Protocol: "TCP",
|
||||
//nolint:gosec // Ignore G109 error
|
||||
Port: int32(port),
|
||||
TargetPort: intstr.FromInt(port),
|
||||
}
|
||||
}
|
||||
|
||||
func checkOverlap(ing *networking.Ingress, ingresses []*ingress.Ingress, servers []*ingress.Server) error {
|
||||
func checkOverlap(ing *networking.Ingress, servers []*ingress.Server) error {
|
||||
for _, rule := range ing.Spec.Rules {
|
||||
if rule.HTTP == nil {
|
||||
continue
|
||||
|
|
@ -1870,7 +1872,7 @@ func (n *NGINXController) getStreamSnippets(ingresses []*ingress.Ingress) []stri
|
|||
}
|
||||
|
||||
// newTrafficShapingPolicy creates new ingress.TrafficShapingPolicy instance using canary configuration
|
||||
func newTrafficShapingPolicy(cfg canary.Config) ingress.TrafficShapingPolicy {
|
||||
func newTrafficShapingPolicy(cfg *canary.Config) ingress.TrafficShapingPolicy {
|
||||
return ingress.TrafficShapingPolicy{
|
||||
Weight: cfg.Weight,
|
||||
WeightTotal: cfg.WeightTotal,
|
||||
|
|
|
|||
|
|
@ -60,51 +60,56 @@ import (
|
|||
"k8s.io/ingress-nginx/pkg/util/file"
|
||||
)
|
||||
|
||||
const (
|
||||
exampleBackend = "example-http-svc-1-80"
|
||||
TRUE = "true"
|
||||
)
|
||||
|
||||
type fakeIngressStore struct {
|
||||
ingresses []*ingress.Ingress
|
||||
configuration ngx_config.Configuration
|
||||
}
|
||||
|
||||
func (fakeIngressStore) GetIngressClass(ing *networking.Ingress, icConfig *ingressclass.IngressClassConfiguration) (string, error) {
|
||||
func (fakeIngressStore) GetIngressClass(_ *networking.Ingress, _ *ingressclass.Configuration) (string, error) {
|
||||
return "nginx", nil
|
||||
}
|
||||
|
||||
func (fis fakeIngressStore) GetBackendConfiguration() ngx_config.Configuration {
|
||||
func (fis *fakeIngressStore) GetBackendConfiguration() ngx_config.Configuration {
|
||||
return fis.configuration
|
||||
}
|
||||
|
||||
func (fis fakeIngressStore) GetSecurityConfiguration() defaults.SecurityConfiguration {
|
||||
func (fis *fakeIngressStore) GetSecurityConfiguration() defaults.SecurityConfiguration {
|
||||
return defaults.SecurityConfiguration{
|
||||
AnnotationsRiskLevel: fis.configuration.AnnotationsRiskLevel,
|
||||
AllowCrossNamespaceResources: fis.configuration.AllowCrossNamespaceResources,
|
||||
}
|
||||
}
|
||||
|
||||
func (fakeIngressStore) GetConfigMap(key string) (*corev1.ConfigMap, error) {
|
||||
func (fakeIngressStore) GetConfigMap(_ string) (*corev1.ConfigMap, error) {
|
||||
return nil, fmt.Errorf("test error")
|
||||
}
|
||||
|
||||
func (fakeIngressStore) GetSecret(key string) (*corev1.Secret, error) {
|
||||
func (fakeIngressStore) GetSecret(_ string) (*corev1.Secret, error) {
|
||||
return nil, fmt.Errorf("test error")
|
||||
}
|
||||
|
||||
func (fakeIngressStore) GetService(key string) (*corev1.Service, error) {
|
||||
func (fakeIngressStore) GetService(_ string) (*corev1.Service, error) {
|
||||
return nil, fmt.Errorf("test error")
|
||||
}
|
||||
|
||||
func (fakeIngressStore) GetServiceEndpointsSlices(key string) ([]*discoveryv1.EndpointSlice, error) {
|
||||
func (fakeIngressStore) GetServiceEndpointsSlices(_ string) ([]*discoveryv1.EndpointSlice, error) {
|
||||
return nil, fmt.Errorf("test error")
|
||||
}
|
||||
|
||||
func (fis fakeIngressStore) ListIngresses() []*ingress.Ingress {
|
||||
func (fis *fakeIngressStore) ListIngresses() []*ingress.Ingress {
|
||||
return fis.ingresses
|
||||
}
|
||||
|
||||
func (fis fakeIngressStore) FilterIngresses(ingresses []*ingress.Ingress, filterFunc store.IngressFilterFunc) []*ingress.Ingress {
|
||||
func (fis *fakeIngressStore) FilterIngresses(ingresses []*ingress.Ingress, _ store.IngressFilterFunc) []*ingress.Ingress {
|
||||
return ingresses
|
||||
}
|
||||
|
||||
func (fakeIngressStore) GetLocalSSLCert(name string) (*ingress.SSLCert, error) {
|
||||
func (fakeIngressStore) GetLocalSSLCert(_ string) (*ingress.SSLCert, error) {
|
||||
return nil, fmt.Errorf("test error")
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +125,7 @@ func (fakeIngressStore) GetDefaultBackend() defaults.Backend {
|
|||
return defaults.Backend{}
|
||||
}
|
||||
|
||||
func (fakeIngressStore) Run(stopCh chan struct{}) {}
|
||||
func (fakeIngressStore) Run(_ chan struct{}) {}
|
||||
|
||||
type testNginxTestCommand struct {
|
||||
t *testing.T
|
||||
|
|
@ -129,7 +134,7 @@ type testNginxTestCommand struct {
|
|||
err error
|
||||
}
|
||||
|
||||
func (ntc testNginxTestCommand) ExecCommand(args ...string) *exec.Cmd {
|
||||
func (ntc testNginxTestCommand) ExecCommand(_ ...string) *exec.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -152,7 +157,7 @@ func (ntc testNginxTestCommand) Test(cfg string) ([]byte, error) {
|
|||
|
||||
type fakeTemplate struct{}
|
||||
|
||||
func (fakeTemplate) Write(conf ngx_config.TemplateConfig) ([]byte, error) {
|
||||
func (fakeTemplate) Write(conf *ngx_config.TemplateConfig) ([]byte, error) {
|
||||
r := []byte{}
|
||||
for _, s := range conf.Servers {
|
||||
if len(r) > 0 {
|
||||
|
|
@ -196,7 +201,7 @@ func TestCheckIngress(t *testing.T) {
|
|||
nginx.metricCollector = metric.DummyCollector{}
|
||||
|
||||
nginx.t = fakeTemplate{}
|
||||
nginx.store = fakeIngressStore{
|
||||
nginx.store = &fakeIngressStore{
|
||||
ingresses: []*ingress.Ingress{},
|
||||
}
|
||||
|
||||
|
|
@ -226,7 +231,7 @@ func TestCheckIngress(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("When the hostname is updated", func(t *testing.T) {
|
||||
nginx.store = fakeIngressStore{
|
||||
nginx.store = &fakeIngressStore{
|
||||
ingresses: []*ingress.Ingress{
|
||||
{
|
||||
Ingress: *ing,
|
||||
|
|
@ -273,7 +278,7 @@ func TestCheckIngress(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("When snippets are disabled and user tries to use snippet annotation", func(t *testing.T) {
|
||||
nginx.store = fakeIngressStore{
|
||||
nginx.store = &fakeIngressStore{
|
||||
ingresses: []*ingress.Ingress{},
|
||||
configuration: ngx_config.Configuration{
|
||||
AllowSnippetAnnotations: false,
|
||||
|
|
@ -290,7 +295,7 @@ func TestCheckIngress(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("When invalid directives are used in annotation values", func(t *testing.T) {
|
||||
nginx.store = fakeIngressStore{
|
||||
nginx.store = &fakeIngressStore{
|
||||
ingresses: []*ingress.Ingress{},
|
||||
configuration: ngx_config.Configuration{
|
||||
AnnotationValueWordBlocklist: "invalid_directive, another_directive",
|
||||
|
|
@ -366,12 +371,11 @@ func TestCheckIngress(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCheckWarning(t *testing.T) {
|
||||
|
||||
// Ensure no panic with wrong arguments
|
||||
var nginx = &NGINXController{}
|
||||
nginx := &NGINXController{}
|
||||
|
||||
nginx.t = fakeTemplate{}
|
||||
nginx.store = fakeIngressStore{
|
||||
nginx.store = &fakeIngressStore{
|
||||
ingresses: []*ingress.Ingress{},
|
||||
}
|
||||
|
||||
|
|
@ -390,7 +394,7 @@ func TestCheckWarning(t *testing.T) {
|
|||
},
|
||||
}
|
||||
t.Run("when a deprecated annotation is used a warning should be returned", func(t *testing.T) {
|
||||
ing.ObjectMeta.Annotations[parser.GetAnnotationWithPrefix("enable-influxdb")] = "true"
|
||||
ing.ObjectMeta.Annotations[parser.GetAnnotationWithPrefix("enable-influxdb")] = TRUE
|
||||
defer func() {
|
||||
ing.ObjectMeta.Annotations = map[string]string{}
|
||||
}()
|
||||
|
|
@ -407,7 +411,6 @@ func TestCheckWarning(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("When an invalid pathType is used, a warning should be returned", func(t *testing.T) {
|
||||
|
||||
rules := ing.Spec.DeepCopy().Rules
|
||||
ing.Spec.Rules = []networking.IngressRule{
|
||||
{
|
||||
|
|
@ -443,8 +446,8 @@ func TestCheckWarning(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("adding invalid annotations increases the warning count", func(t *testing.T) {
|
||||
ing.ObjectMeta.Annotations[parser.GetAnnotationWithPrefix("enable-influxdb")] = "true"
|
||||
ing.ObjectMeta.Annotations[parser.GetAnnotationWithPrefix("secure-verify-ca-secret")] = "true"
|
||||
ing.ObjectMeta.Annotations[parser.GetAnnotationWithPrefix("enable-influxdb")] = TRUE
|
||||
ing.ObjectMeta.Annotations[parser.GetAnnotationWithPrefix("secure-verify-ca-secret")] = TRUE
|
||||
ing.ObjectMeta.Annotations[parser.GetAnnotationWithPrefix("influxdb-host")] = "blabla"
|
||||
defer func() {
|
||||
ing.ObjectMeta.Annotations = map[string]string{}
|
||||
|
|
@ -472,6 +475,7 @@ func TestCheckWarning(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
func TestMergeAlternativeBackends(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
ingress *ingress.Ingress
|
||||
|
|
@ -1537,8 +1541,8 @@ func TestExtractTLSSecretName(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
//nolint:gocyclo // Ignore function complexity error
|
||||
func TestGetBackendServers(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
Ingresses []*ingress.Ingress
|
||||
Validate func(ingresses []*ingress.Ingress, upstreams []*ingress.Backend, servers []*ingress.Server)
|
||||
|
|
@ -2078,7 +2082,7 @@ func TestGetBackendServers(t *testing.T) {
|
|||
t.Errorf("server hostname should be 'example.com', got '%s'", s.Hostname)
|
||||
}
|
||||
|
||||
if s.Locations[0].Backend != "example-http-svc-1-80" || s.Locations[1].Backend != "example-http-svc-1-80" || s.Locations[2].Backend != "example-http-svc-1-80" {
|
||||
if s.Locations[0].Backend != exampleBackend || s.Locations[1].Backend != exampleBackend || s.Locations[2].Backend != exampleBackend {
|
||||
t.Errorf("all location backend should be 'example-http-svc-1-80'")
|
||||
}
|
||||
|
||||
|
|
@ -2087,7 +2091,7 @@ func TestGetBackendServers(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
if upstreams[0].Name != "example-http-svc-1-80" {
|
||||
if upstreams[0].Name != exampleBackend {
|
||||
t.Errorf("example-http-svc-1-80 should be first upstream, got %s", upstreams[0].Name)
|
||||
return
|
||||
}
|
||||
|
|
@ -2101,6 +2105,7 @@ func TestGetBackendServers(t *testing.T) {
|
|||
SetConfigMap: testConfigMap,
|
||||
},
|
||||
{
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
Ingresses: []*ingress.Ingress{
|
||||
{
|
||||
Ingress: networking.Ingress{
|
||||
|
|
@ -2208,6 +2213,7 @@ func TestGetBackendServers(t *testing.T) {
|
|||
SetConfigMap: testConfigMap,
|
||||
},
|
||||
{
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
Ingresses: []*ingress.Ingress{
|
||||
{
|
||||
Ingress: networking.Ingress{
|
||||
|
|
@ -2319,7 +2325,7 @@ func TestGetBackendServers(t *testing.T) {
|
|||
SelfLink: fmt.Sprintf("/api/v1/namespaces/%s/configmaps/config", ns),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"proxy-ssl-location-only": "true",
|
||||
"proxy-ssl-location-only": TRUE,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
@ -2380,7 +2386,7 @@ func TestGetBackendServers(t *testing.T) {
|
|||
SelfLink: fmt.Sprintf("/api/v1/namespaces/%s/configmaps/config", ns),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"proxy-ssl-location-only": "true",
|
||||
"proxy-ssl-location-only": TRUE,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
@ -2449,7 +2455,6 @@ func TestGetBackendServers(t *testing.T) {
|
|||
if len(s.Locations[0].Allowlist.CIDR) != 1 || s.Locations[0].Allowlist.CIDR[0] != "10.0.0.0/24" {
|
||||
t.Errorf("allow list was incorrectly dropped, len should be 1 and contain 10.0.0.0/24")
|
||||
}
|
||||
|
||||
},
|
||||
SetConfigMap: func(ns string) *corev1.ConfigMap {
|
||||
return &corev1.ConfigMap{
|
||||
|
|
@ -2520,7 +2525,7 @@ func newNGINXController(t *testing.T) *NGINXController {
|
|||
channels.NewRingChannel(10),
|
||||
false,
|
||||
true,
|
||||
&ingressclass.IngressClassConfiguration{
|
||||
&ingressclass.Configuration{
|
||||
Controller: "k8s.io/ingress-nginx",
|
||||
AnnotationValue: "nginx",
|
||||
},
|
||||
|
|
@ -2586,7 +2591,7 @@ func newDynamicNginxController(t *testing.T, setConfigMap func(string) *corev1.C
|
|||
channels.NewRingChannel(10),
|
||||
false,
|
||||
true,
|
||||
&ingressclass.IngressClassConfiguration{
|
||||
&ingressclass.Configuration{
|
||||
Controller: "k8s.io/ingress-nginx",
|
||||
AnnotationValue: "nginx",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ import (
|
|||
|
||||
// getEndpointsFromSlices returns a list of Endpoint structs for a given service/target port combination.
|
||||
func getEndpointsFromSlices(s *corev1.Service, port *corev1.ServicePort, proto corev1.Protocol, zoneForHints string,
|
||||
getServiceEndpointsSlices func(string) ([]*discoveryv1.EndpointSlice, error)) []ingress.Endpoint {
|
||||
|
||||
getServiceEndpointsSlices func(string) ([]*discoveryv1.EndpointSlice, error),
|
||||
) []ingress.Endpoint {
|
||||
upsServers := []ingress.Endpoint{}
|
||||
|
||||
if s == nil || port == nil {
|
||||
|
|
@ -94,7 +94,7 @@ func getEndpointsFromSlices(s *corev1.Service, port *corev1.ServicePort, proto c
|
|||
if !reflect.DeepEqual(*epPort.Protocol, proto) {
|
||||
continue
|
||||
}
|
||||
var targetPort int32 = 0
|
||||
var targetPort int32
|
||||
if port.Name == "" {
|
||||
// port.Name is optional if there is only one port
|
||||
targetPort = *epPort.Port
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"k8s.io/ingress-nginx/pkg/apis/ingress"
|
||||
)
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
func TestGetEndpointsFromSlices(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ const (
|
|||
DefaultAnnotationValue = "nginx"
|
||||
)
|
||||
|
||||
// IngressClassConfiguration defines the various aspects of IngressClass parsing
|
||||
// Configuration defines the various aspects of IngressClass parsing
|
||||
// and how the controller should behave in each case
|
||||
type IngressClassConfiguration struct {
|
||||
type Configuration struct {
|
||||
// Controller defines the controller value this daemon watch to.
|
||||
// Defaults to "k8s.io/ingress-nginx" defined in flags
|
||||
Controller string
|
||||
|
|
@ -45,7 +45,7 @@ type IngressClassConfiguration struct {
|
|||
// IgnoreIngressClass defines if Controller should ignore the IngressClass Object if no permissions are
|
||||
// granted on IngressClass
|
||||
IgnoreIngressClass bool
|
||||
//IngressClassByName defines if the Controller should watch for Ingress Classes by
|
||||
// IngressClassByName defines if the Controller should watch for Ingress Classes by
|
||||
// .metadata.name together with .spec.Controller
|
||||
IngressClassByName bool
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro
|
|||
if n.cfg.ValidationWebhook != "" {
|
||||
n.validationWebhookServer = &http.Server{
|
||||
Addr: config.ValidationWebhook,
|
||||
//G112 (CWE-400): Potential Slowloris Attack
|
||||
// G112 (CWE-400): Potential Slowloris Attack
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
Handler: adm_controller.NewAdmissionControllerServer(&adm_controller.IngressAdmission{Checker: n}),
|
||||
TLSConfig: ssl.NewTLSListener(n.cfg.ValidationWebhookCertPath, n.cfg.ValidationWebhookKeyPath).TLSConfig(),
|
||||
|
|
@ -429,7 +429,7 @@ func (n *NGINXController) start(cmd *exec.Cmd) {
|
|||
}
|
||||
|
||||
// DefaultEndpoint returns the default endpoint to be use as default server that returns 404.
|
||||
func (n NGINXController) DefaultEndpoint() ingress.Endpoint {
|
||||
func (n *NGINXController) DefaultEndpoint() ingress.Endpoint {
|
||||
return ingress.Endpoint{
|
||||
Address: "127.0.0.1",
|
||||
Port: fmt.Sprintf("%v", n.cfg.ListenPorts.Default),
|
||||
|
|
@ -438,8 +438,9 @@ func (n NGINXController) DefaultEndpoint() ingress.Endpoint {
|
|||
}
|
||||
|
||||
// generateTemplate returns the nginx configuration file content
|
||||
func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressCfg ingress.Configuration) ([]byte, error) {
|
||||
|
||||
//
|
||||
//nolint:gocritic // the cfg shouldn't be changed, and shouldn't be mutated by other processes while being rendered.
|
||||
func (n *NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressCfg ingress.Configuration) ([]byte, error) {
|
||||
if n.cfg.EnableSSLPassthrough {
|
||||
servers := []*tcpproxy.TCPServer{}
|
||||
for _, pb := range ingressCfg.PassthroughBackends {
|
||||
|
|
@ -458,6 +459,7 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC
|
|||
}
|
||||
} else {
|
||||
for _, sp := range svc.Spec.Ports {
|
||||
//nolint:gosec // Ignore G109 error
|
||||
if sp.Port == int32(port) {
|
||||
port = int(sp.Port)
|
||||
break
|
||||
|
|
@ -563,7 +565,7 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC
|
|||
if err != nil {
|
||||
klog.Warningf("Error reading Secret %q from local store: %v", secretName, err)
|
||||
} else {
|
||||
nsSecName := strings.Replace(secretName, "/", "-", -1)
|
||||
nsSecName := strings.ReplaceAll(secretName, "/", "-")
|
||||
dh, ok := secret.Data["dhparam.pem"]
|
||||
if ok {
|
||||
pemFileName, err := ssl.AddOrUpdateDHParam(nsSecName, dh)
|
||||
|
|
@ -589,7 +591,7 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC
|
|||
}
|
||||
}
|
||||
|
||||
tc := ngx_config.TemplateConfig{
|
||||
tc := &ngx_config.TemplateConfig{
|
||||
ProxySetHeaders: setHeaders,
|
||||
AddHeaders: addHeaders,
|
||||
BacklogSize: sysctlSomaxconn(),
|
||||
|
|
@ -623,7 +625,7 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC
|
|||
|
||||
// testTemplate checks if the NGINX configuration inside the byte array is valid
|
||||
// running the command "nginx -t" using a temporal file.
|
||||
func (n NGINXController) testTemplate(cfg []byte) error {
|
||||
func (n *NGINXController) testTemplate(cfg []byte) error {
|
||||
if len(cfg) == 0 {
|
||||
return fmt.Errorf("invalid NGINX configuration (empty)")
|
||||
}
|
||||
|
|
@ -658,6 +660,8 @@ Error: %v
|
|||
// changes were detected. The received backend Configuration is merged with the
|
||||
// configuration ConfigMap before generating the final configuration file.
|
||||
// Returns nil in case the backend was successfully reloaded.
|
||||
//
|
||||
//nolint:gocritic // the cfg shouldn't be changed, and shouldn't be mutated by other processes while being rendered.
|
||||
func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error {
|
||||
cfg := n.store.GetBackendConfiguration()
|
||||
cfg.Resolver = n.resolver
|
||||
|
|
@ -667,12 +671,12 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = createOpentracingCfg(cfg)
|
||||
err = createOpentracingCfg(&cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = createOpentelemetryCfg(cfg)
|
||||
err = createOpentelemetryCfg(&cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -683,7 +687,10 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error {
|
|||
}
|
||||
|
||||
if klog.V(2).Enabled() {
|
||||
src, _ := os.ReadFile(cfgPath)
|
||||
src, err := os.ReadFile(cfgPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !bytes.Equal(src, content) {
|
||||
tmpfile, err := os.CreateTemp("", "new-nginx-cfg")
|
||||
if err != nil {
|
||||
|
|
@ -694,11 +701,14 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//nolint:gosec //Ignore G204 error
|
||||
diffOutput, err := exec.Command("diff", "-I", "'# Configuration.*'", "-u", cfgPath, tmpfile.Name()).CombinedOutput()
|
||||
if err != nil {
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
ws := exitError.Sys().(syscall.WaitStatus)
|
||||
ws, ok := exitError.Sys().(syscall.WaitStatus)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", exitError.Sys())
|
||||
}
|
||||
if ws.ExitStatus() == 2 {
|
||||
klog.Warningf("Failed to executing diff command: %v", err)
|
||||
}
|
||||
|
|
@ -828,9 +838,10 @@ func (n *NGINXController) configureDynamically(pcfg *ingress.Configuration) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
func updateStreamConfiguration(TCPEndpoints []ingress.L4Service, UDPEndpoints []ingress.L4Service) error {
|
||||
func updateStreamConfiguration(tcpEndpoints, udpEndpoints []ingress.L4Service) error {
|
||||
streams := make([]ingress.Backend, 0)
|
||||
for _, ep := range TCPEndpoints {
|
||||
for i := range tcpEndpoints {
|
||||
ep := &tcpEndpoints[i]
|
||||
var service *apiv1.Service
|
||||
if ep.Service != nil {
|
||||
service = &apiv1.Service{Spec: ep.Service.Spec}
|
||||
|
|
@ -844,7 +855,8 @@ func updateStreamConfiguration(TCPEndpoints []ingress.L4Service, UDPEndpoints []
|
|||
Service: service,
|
||||
})
|
||||
}
|
||||
for _, ep := range UDPEndpoints {
|
||||
for i := range udpEndpoints {
|
||||
ep := &udpEndpoints[i]
|
||||
var service *apiv1.Service
|
||||
if ep.Service != nil {
|
||||
service = &apiv1.Service{Spec: ep.Service.Spec}
|
||||
|
|
@ -1034,7 +1046,7 @@ ratio = {{ .OtelSamplerRatio }}
|
|||
parent_based = {{ .OtelSamplerParentBased }}
|
||||
`
|
||||
|
||||
func datadogOpentracingCfg(cfg ngx_config.Configuration) (string, error) {
|
||||
func datadogOpentracingCfg(cfg *ngx_config.Configuration) (string, error) {
|
||||
m := map[string]interface{}{
|
||||
"service": cfg.DatadogServiceName,
|
||||
"agent_host": cfg.DatadogCollectorHost,
|
||||
|
|
@ -1058,7 +1070,7 @@ func datadogOpentracingCfg(cfg ngx_config.Configuration) (string, error) {
|
|||
return string(buf), nil
|
||||
}
|
||||
|
||||
func opentracingCfgFromTemplate(cfg ngx_config.Configuration, tmplName string, tmplText string) (string, error) {
|
||||
func opentracingCfgFromTemplate(cfg *ngx_config.Configuration, tmplName, tmplText string) (string, error) {
|
||||
tmpl, err := template.New(tmplName).Parse(tmplText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -1073,17 +1085,18 @@ func opentracingCfgFromTemplate(cfg ngx_config.Configuration, tmplName string, t
|
|||
return tmplBuf.String(), nil
|
||||
}
|
||||
|
||||
func createOpentracingCfg(cfg ngx_config.Configuration) error {
|
||||
func createOpentracingCfg(cfg *ngx_config.Configuration) error {
|
||||
var configData string
|
||||
var err error
|
||||
|
||||
if cfg.ZipkinCollectorHost != "" {
|
||||
switch {
|
||||
case cfg.ZipkinCollectorHost != "":
|
||||
configData, err = opentracingCfgFromTemplate(cfg, "zipkin", zipkinTmpl)
|
||||
} else if cfg.JaegerCollectorHost != "" || cfg.JaegerEndpoint != "" {
|
||||
case cfg.JaegerCollectorHost != "" || cfg.JaegerEndpoint != "":
|
||||
configData, err = opentracingCfgFromTemplate(cfg, "jaeger", jaegerTmpl)
|
||||
} else if cfg.DatadogCollectorHost != "" {
|
||||
case cfg.DatadogCollectorHost != "":
|
||||
configData, err = datadogOpentracingCfg(cfg)
|
||||
} else {
|
||||
default:
|
||||
configData = "{}"
|
||||
}
|
||||
|
||||
|
|
@ -1097,8 +1110,7 @@ func createOpentracingCfg(cfg ngx_config.Configuration) error {
|
|||
return os.WriteFile("/etc/nginx/opentracing.json", []byte(expanded), file.ReadWriteByUser)
|
||||
}
|
||||
|
||||
func createOpentelemetryCfg(cfg ngx_config.Configuration) error {
|
||||
|
||||
func createOpentelemetryCfg(cfg *ngx_config.Configuration) error {
|
||||
tmpl, err := template.New("otel").Parse(otelTmpl)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -1123,7 +1135,10 @@ func cleanTempNginxCfg() error {
|
|||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
dur, _ := time.ParseDuration("-5m")
|
||||
dur, err := time.ParseDuration("-5m")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fiveMinutesAgo := time.Now().Add(dur)
|
||||
if strings.HasPrefix(info.Name(), tempNginxPattern) && info.ModTime().Before(fiveMinutesAgo) {
|
||||
files = append(files, path)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ func TestConfigureDynamically(t *testing.T) {
|
|||
|
||||
server := &httptest.Server{
|
||||
Listener: listener,
|
||||
//nolint:gosec // Ignore not configured ReadHeaderTimeout in testing
|
||||
Config: &http.Server{
|
||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
|
|
@ -76,23 +77,17 @@ func TestConfigureDynamically(t *testing.T) {
|
|||
|
||||
switch r.URL.Path {
|
||||
case "/configuration/backends":
|
||||
{
|
||||
if strings.Contains(body, "target") {
|
||||
t.Errorf("unexpected target reference in JSON content: %v", body)
|
||||
}
|
||||
if strings.Contains(body, "target") {
|
||||
t.Errorf("unexpected target reference in JSON content: %v", body)
|
||||
}
|
||||
|
||||
if !strings.Contains(body, "service") {
|
||||
t.Errorf("service reference should be present in JSON content: %v", body)
|
||||
}
|
||||
if !strings.Contains(body, "service") {
|
||||
t.Errorf("service reference should be present in JSON content: %v", body)
|
||||
}
|
||||
case "/configuration/general":
|
||||
{
|
||||
}
|
||||
case "/configuration/servers":
|
||||
{
|
||||
if !strings.Contains(body, `{"certificates":{},"servers":{"myapp.fake":"-1"}}`) {
|
||||
t.Errorf("should be present in JSON content: %v", body)
|
||||
}
|
||||
if !strings.Contains(body, `{"certificates":{},"servers":{"myapp.fake":"-1"}}`) {
|
||||
t.Errorf("should be present in JSON content: %v", body)
|
||||
}
|
||||
default:
|
||||
t.Errorf("unknown request to %s", r.URL.Path)
|
||||
|
|
@ -218,6 +213,7 @@ func TestConfigureCertificates(t *testing.T) {
|
|||
|
||||
server := &httptest.Server{
|
||||
Listener: listener,
|
||||
//nolint:gosec // Ignore not configured ReadHeaderTimeout in testing
|
||||
Config: &http.Server{
|
||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
|
|
@ -414,6 +410,7 @@ func TestCleanTempNginxCfg(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
//nolint:unparam // Ingnore `network` always receives `"tcp"` error
|
||||
func tryListen(network, address string) (l net.Listener, err error) {
|
||||
condFunc := func() (bool, error) {
|
||||
l, err = net.Listen(network, address)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,10 @@ func IsRespawnIfRequired(err error) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
waitStatus := exitError.Sys().(syscall.WaitStatus)
|
||||
waitStatus, ok := exitError.Sys().(syscall.WaitStatus)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
klog.Warningf(`
|
||||
-------------------------------------------------------------------------------
|
||||
NGINX master process died (%v): %v
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func setupLeaderElection(config *leaderElectionConfig) {
|
|||
|
||||
var cancelContext context.CancelFunc
|
||||
|
||||
var newLeaderCtx = func(ctx context.Context) context.CancelFunc {
|
||||
newLeaderCtx := func(ctx context.Context) context.CancelFunc {
|
||||
// allow to cancel the context in case we stop being the leader
|
||||
leaderCtx, cancel := context.WithCancel(ctx)
|
||||
go elector.Run(leaderCtx)
|
||||
|
|
@ -86,8 +86,10 @@ func setupLeaderElection(config *leaderElectionConfig) {
|
|||
}
|
||||
|
||||
broadcaster := record.NewBroadcaster()
|
||||
hostname, _ := os.Hostname()
|
||||
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
klog.Errorf("unexpected error getting hostname: %v", err)
|
||||
}
|
||||
recorder := broadcaster.NewRecorder(scheme.Scheme, apiv1.EventSource{
|
||||
Component: "ingress-leader-elector",
|
||||
Host: hostname,
|
||||
|
|
@ -107,7 +109,7 @@ func setupLeaderElection(config *leaderElectionConfig) {
|
|||
|
||||
ttl := 30 * time.Second
|
||||
|
||||
elector, err := leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{
|
||||
elector, err = leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{
|
||||
Lock: lock,
|
||||
LeaseDuration: ttl,
|
||||
RenewDeadline: ttl / 2,
|
||||
|
|
|
|||
|
|
@ -88,10 +88,11 @@ func (s *k8sStore) getPemCertificate(secretName string) (*ingress.SSLCert, error
|
|||
auth := secret.Data["auth"]
|
||||
|
||||
// namespace/secretName -> namespace-secretName
|
||||
nsSecName := strings.Replace(secretName, "/", "-", -1)
|
||||
nsSecName := strings.ReplaceAll(secretName, "/", "-")
|
||||
|
||||
var sslCert *ingress.SSLCert
|
||||
if okcert && okkey {
|
||||
switch {
|
||||
case okcert && okkey:
|
||||
if cert == nil {
|
||||
return nil, fmt.Errorf("key 'tls.crt' missing from Secret %q", secretName)
|
||||
}
|
||||
|
|
@ -144,7 +145,7 @@ func (s *k8sStore) getPemCertificate(secretName string) (*ingress.SSLCert, error
|
|||
}
|
||||
|
||||
klog.V(3).InfoS(msg)
|
||||
} else if len(ca) > 0 {
|
||||
case len(ca) > 0:
|
||||
sslCert, err = ssl.CreateCACert(ca)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected error creating SSL Cert: %v", err)
|
||||
|
|
@ -166,7 +167,7 @@ func (s *k8sStore) getPemCertificate(secretName string) (*ingress.SSLCert, error
|
|||
// makes this secret in 'syncSecret' to be used for Certificate Authentication
|
||||
// this does not enable Certificate Authentication
|
||||
klog.V(3).InfoS("Configuring Secret for TLS authentication", "secret", secretName)
|
||||
} else {
|
||||
default:
|
||||
if auth != nil {
|
||||
return nil, ErrSecretForAuth
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func (s *EndpointSliceLister) MatchByKey(key string) ([]*discoveryv1.EndpointSli
|
|||
keyNsLen = 0
|
||||
} else {
|
||||
// count '/' char
|
||||
keyNsLen += 1
|
||||
keyNsLen++
|
||||
}
|
||||
// filter endpointSlices owned by svc
|
||||
for _, listKey := range s.ListKeys() {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ func TestEndpointSliceLister(t *testing.T) {
|
|||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
eps, err := el.MatchByKey(key)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("unexpeted error %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ type Storer interface {
|
|||
Run(stopCh chan struct{})
|
||||
|
||||
// GetIngressClass validates given ingress against ingress class configuration and returns the ingress class.
|
||||
GetIngressClass(ing *networkingv1.Ingress, icConfig *ingressclass.IngressClassConfiguration) (string, error)
|
||||
GetIngressClass(ing *networkingv1.Ingress, icConfig *ingressclass.Configuration) (string, error)
|
||||
}
|
||||
|
||||
// EventType type of event associated with an informer
|
||||
|
|
@ -242,7 +242,9 @@ type k8sStore struct {
|
|||
defaultSSLCertificate string
|
||||
}
|
||||
|
||||
// New creates a new object store to be used in the ingress controller
|
||||
// New creates a new object store to be used in the ingress controller.
|
||||
//
|
||||
//nolint:gocyclo // Ignore function complexity error.
|
||||
func New(
|
||||
namespace string,
|
||||
namespaceSelector labels.Selector,
|
||||
|
|
@ -252,9 +254,9 @@ func New(
|
|||
updateCh *channels.RingChannel,
|
||||
disableCatchAll bool,
|
||||
deepInspector bool,
|
||||
icConfig *ingressclass.IngressClassConfiguration,
|
||||
disableSyncEvents bool) Storer {
|
||||
|
||||
icConfig *ingressclass.Configuration,
|
||||
disableSyncEvents bool,
|
||||
) Storer {
|
||||
store := &k8sStore{
|
||||
informers: &Informer{},
|
||||
listers: &Lister{},
|
||||
|
|
@ -474,7 +476,8 @@ func New(
|
|||
_, errOld = store.GetIngressClass(oldIng, icConfig)
|
||||
classCur, errCur = store.GetIngressClass(curIng, icConfig)
|
||||
}
|
||||
if errOld != nil && errCur == nil {
|
||||
switch {
|
||||
case errOld != nil && errCur == nil:
|
||||
if hasCatchAllIngressRule(curIng.Spec) && disableCatchAll {
|
||||
klog.InfoS("ignoring update for catch-all ingress because of --disable-catch-all", "ingress", klog.KObj(curIng))
|
||||
return
|
||||
|
|
@ -482,11 +485,11 @@ func New(
|
|||
|
||||
klog.InfoS("creating ingress", "ingress", klog.KObj(curIng), "ingressclass", classCur)
|
||||
recorder.Eventf(curIng, corev1.EventTypeNormal, "Sync", "Scheduled for sync")
|
||||
} else if errOld == nil && errCur != nil {
|
||||
case errOld == nil && errCur != nil:
|
||||
klog.InfoS("removing ingress because of unknown ingressclass", "ingress", klog.KObj(curIng))
|
||||
ingDeleteHandler(old)
|
||||
return
|
||||
} else if errCur == nil && !reflect.DeepEqual(old, cur) {
|
||||
case errCur == nil && !reflect.DeepEqual(old, cur):
|
||||
if hasCatchAllIngressRule(curIng.Spec) && disableCatchAll {
|
||||
klog.InfoS("ignoring update for catch-all ingress and delete old one because of --disable-catch-all", "ingress", klog.KObj(curIng))
|
||||
ingDeleteHandler(old)
|
||||
|
|
@ -494,7 +497,7 @@ func New(
|
|||
}
|
||||
|
||||
recorder.Eventf(curIng, corev1.EventTypeNormal, "Sync", "Scheduled for sync")
|
||||
} else {
|
||||
default:
|
||||
klog.V(3).InfoS("No changes on ingress. Skipping update", "ingress", klog.KObj(curIng))
|
||||
return
|
||||
}
|
||||
|
|
@ -519,7 +522,10 @@ func New(
|
|||
|
||||
ingressClassEventHandler := cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
ingressclass := obj.(*networkingv1.IngressClass)
|
||||
ingressclass, ok := obj.(*networkingv1.IngressClass)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", obj)
|
||||
}
|
||||
foundClassByName := false
|
||||
if icConfig.IngressClassByName && ingressclass.Name == icConfig.AnnotationValue {
|
||||
klog.InfoS("adding ingressclass as ingress-class-by-name is configured", "ingressclass", klog.KObj(ingressclass))
|
||||
|
|
@ -541,7 +547,10 @@ func New(
|
|||
}
|
||||
},
|
||||
DeleteFunc: func(obj interface{}) {
|
||||
ingressclass := obj.(*networkingv1.IngressClass)
|
||||
ingressclass, ok := obj.(*networkingv1.IngressClass)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", obj)
|
||||
}
|
||||
if ingressclass.Spec.Controller != icConfig.Controller {
|
||||
klog.InfoS("ignoring ingressclass as the spec.controller is not the same of this ingress", "ingressclass", klog.KObj(ingressclass))
|
||||
return
|
||||
|
|
@ -557,8 +566,14 @@ func New(
|
|||
}
|
||||
},
|
||||
UpdateFunc: func(old, cur interface{}) {
|
||||
oic := old.(*networkingv1.IngressClass)
|
||||
cic := cur.(*networkingv1.IngressClass)
|
||||
oic, ok := old.(*networkingv1.IngressClass)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", old)
|
||||
}
|
||||
cic, ok := cur.(*networkingv1.IngressClass)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", cur)
|
||||
}
|
||||
if cic.Spec.Controller != icConfig.Controller {
|
||||
klog.InfoS("ignoring ingressclass as the spec.controller is not the same of this ingress", "ingressclass", klog.KObj(cic))
|
||||
return
|
||||
|
|
@ -581,7 +596,10 @@ func New(
|
|||
|
||||
secrEventHandler := cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
sec := obj.(*corev1.Secret)
|
||||
sec, ok := obj.(*corev1.Secret)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", obj)
|
||||
}
|
||||
key := k8s.MetaNamespaceKey(sec)
|
||||
|
||||
if store.defaultSSLCertificate == key {
|
||||
|
|
@ -608,7 +626,10 @@ func New(
|
|||
},
|
||||
UpdateFunc: func(old, cur interface{}) {
|
||||
if !reflect.DeepEqual(old, cur) {
|
||||
sec := cur.(*corev1.Secret)
|
||||
sec, ok := cur.(*corev1.Secret)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", cur)
|
||||
}
|
||||
key := k8s.MetaNamespaceKey(sec)
|
||||
|
||||
if !watchedNamespace(sec.Namespace) {
|
||||
|
|
@ -695,8 +716,14 @@ func New(
|
|||
}
|
||||
},
|
||||
UpdateFunc: func(old, cur interface{}) {
|
||||
oeps := old.(*discoveryv1.EndpointSlice)
|
||||
ceps := cur.(*discoveryv1.EndpointSlice)
|
||||
oeps, ok := old.(*discoveryv1.EndpointSlice)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", old)
|
||||
}
|
||||
ceps, ok := cur.(*discoveryv1.EndpointSlice)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", cur)
|
||||
}
|
||||
if !reflect.DeepEqual(ceps.Endpoints, oeps.Endpoints) {
|
||||
updateCh.In() <- Event{
|
||||
Type: UpdateEvent,
|
||||
|
|
@ -750,7 +777,10 @@ func New(
|
|||
|
||||
cmEventHandler := cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
cfgMap := obj.(*corev1.ConfigMap)
|
||||
cfgMap, ok := obj.(*corev1.ConfigMap)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", obj)
|
||||
}
|
||||
key := k8s.MetaNamespaceKey(cfgMap)
|
||||
handleCfgMapEvent(key, cfgMap, "CREATE")
|
||||
},
|
||||
|
|
@ -759,7 +789,10 @@ func New(
|
|||
return
|
||||
}
|
||||
|
||||
cfgMap := cur.(*corev1.ConfigMap)
|
||||
cfgMap, ok := cur.(*corev1.ConfigMap)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", cur)
|
||||
}
|
||||
key := k8s.MetaNamespaceKey(cfgMap)
|
||||
handleCfgMapEvent(key, cfgMap, "UPDATE")
|
||||
},
|
||||
|
|
@ -767,7 +800,10 @@ func New(
|
|||
|
||||
serviceHandler := cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
svc := obj.(*corev1.Service)
|
||||
svc, ok := obj.(*corev1.Service)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", obj)
|
||||
}
|
||||
if svc.Spec.Type == corev1.ServiceTypeExternalName {
|
||||
updateCh.In() <- Event{
|
||||
Type: CreateEvent,
|
||||
|
|
@ -776,7 +812,10 @@ func New(
|
|||
}
|
||||
},
|
||||
DeleteFunc: func(obj interface{}) {
|
||||
svc := obj.(*corev1.Service)
|
||||
svc, ok := obj.(*corev1.Service)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", obj)
|
||||
}
|
||||
if svc.Spec.Type == corev1.ServiceTypeExternalName {
|
||||
updateCh.In() <- Event{
|
||||
Type: DeleteEvent,
|
||||
|
|
@ -785,8 +824,14 @@ func New(
|
|||
}
|
||||
},
|
||||
UpdateFunc: func(old, cur interface{}) {
|
||||
oldSvc := old.(*corev1.Service)
|
||||
curSvc := cur.(*corev1.Service)
|
||||
oldSvc, ok := old.(*corev1.Service)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", old)
|
||||
}
|
||||
curSvc, ok := cur.(*corev1.Service)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", cur)
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(oldSvc, curSvc) {
|
||||
return
|
||||
|
|
@ -821,7 +866,10 @@ func New(
|
|||
}
|
||||
|
||||
// do not wait for informers to read the configmap configuration
|
||||
ns, name, _ := k8s.ParseNameNS(configmap)
|
||||
ns, name, err := k8s.ParseNameNS(configmap)
|
||||
if err != nil {
|
||||
klog.Errorf("unexpected error parsing name and ns: %v", err)
|
||||
}
|
||||
cm, err := client.CoreV1().ConfigMaps(ns).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
klog.Warningf("Unexpected error reading configuration configmap: %v", err)
|
||||
|
|
@ -837,10 +885,10 @@ func hasCatchAllIngressRule(spec networkingv1.IngressSpec) bool {
|
|||
return spec.DefaultBackend != nil
|
||||
}
|
||||
|
||||
func checkBadAnnotationValue(annotations map[string]string, badwords string) error {
|
||||
func checkBadAnnotationValue(annotationMap map[string]string, badwords string) error {
|
||||
arraybadWords := strings.Split(strings.TrimSpace(badwords), ",")
|
||||
|
||||
for annotation, value := range annotations {
|
||||
for annotation, value := range annotationMap {
|
||||
if strings.HasPrefix(annotation, fmt.Sprintf("%s/", parser.AnnotationsPrefix)) {
|
||||
for _, forbiddenvalue := range arraybadWords {
|
||||
if strings.Contains(value, forbiddenvalue) {
|
||||
|
|
@ -999,7 +1047,7 @@ func (s *k8sStore) GetService(key string) (*corev1.Service, error) {
|
|||
return s.listers.Service.ByKey(key)
|
||||
}
|
||||
|
||||
func (s *k8sStore) GetIngressClass(ing *networkingv1.Ingress, icConfig *ingressclass.IngressClassConfiguration) (string, error) {
|
||||
func (s *k8sStore) GetIngressClass(ing *networkingv1.Ingress, icConfig *ingressclass.Configuration) (string, error) {
|
||||
// First we try ingressClassName
|
||||
if !icConfig.IgnoreIngressClass && ing.Spec.IngressClassName != nil {
|
||||
iclass, err := s.listers.IngressClass.ByKey(*ing.Spec.IngressClassName)
|
||||
|
|
@ -1010,11 +1058,11 @@ func (s *k8sStore) GetIngressClass(ing *networkingv1.Ingress, icConfig *ingressc
|
|||
}
|
||||
|
||||
// Then we try annotation
|
||||
if ingressclass, ok := ing.GetAnnotations()[ingressclass.IngressKey]; ok {
|
||||
if ingressclass != icConfig.AnnotationValue {
|
||||
if class, ok := ing.GetAnnotations()[ingressclass.IngressKey]; ok {
|
||||
if class != icConfig.AnnotationValue {
|
||||
return "", fmt.Errorf("ingress class annotation is not equal to the expected by Ingress Controller")
|
||||
}
|
||||
return ingressclass, nil
|
||||
return class, nil
|
||||
}
|
||||
|
||||
// Then we accept if the WithoutClass is enabled
|
||||
|
|
@ -1055,7 +1103,10 @@ func (s *k8sStore) ListIngresses() []*ingress.Ingress {
|
|||
// filter ingress rules
|
||||
ingresses := make([]*ingress.Ingress, 0)
|
||||
for _, item := range s.listers.IngressWithAnnotation.List() {
|
||||
ing := item.(*ingress.Ingress)
|
||||
ing, ok := item.(*ingress.Ingress)
|
||||
if !ok {
|
||||
klog.Errorf("unexpected type: %T", item)
|
||||
}
|
||||
ingresses = append(ingresses, ing)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,29 +44,27 @@ import (
|
|||
|
||||
var pathPrefix networking.PathType = networking.PathTypePrefix
|
||||
|
||||
var DefaultClassConfig = &ingressclass.IngressClassConfiguration{
|
||||
var DefaultClassConfig = &ingressclass.Configuration{
|
||||
Controller: ingressclass.DefaultControllerName,
|
||||
AnnotationValue: ingressclass.DefaultAnnotationValue,
|
||||
WatchWithoutClass: false,
|
||||
}
|
||||
|
||||
var (
|
||||
commonIngressSpec = networking.IngressSpec{
|
||||
Rules: []networking.IngressRule{
|
||||
{
|
||||
Host: "dummy",
|
||||
IngressRuleValue: networking.IngressRuleValue{
|
||||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
Service: &networking.IngressServiceBackend{
|
||||
Name: "http-svc",
|
||||
Port: networking.ServiceBackendPort{
|
||||
Number: 80,
|
||||
},
|
||||
var commonIngressSpec = networking.IngressSpec{
|
||||
Rules: []networking.IngressRule{
|
||||
{
|
||||
Host: "dummy",
|
||||
IngressRuleValue: networking.IngressRuleValue{
|
||||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
Service: &networking.IngressServiceBackend{
|
||||
Name: "http-svc",
|
||||
Port: networking.ServiceBackendPort{
|
||||
Number: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -75,12 +73,15 @@ var (
|
|||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
const updateDummyHost = "update-dummy"
|
||||
|
||||
//nolint:gocyclo // Ignore function complexity error
|
||||
func TestStore(t *testing.T) {
|
||||
//TODO: move env definition to docker image?
|
||||
os.Setenv("KUBEBUILDER_ASSETS", "/usr/local/bin")
|
||||
// TODO: move env definition to docker image?
|
||||
t.Setenv("KUBEBUILDER_ASSETS", "/usr/local/bin")
|
||||
|
||||
pathPrefix = networking.PathTypePrefix
|
||||
|
||||
|
|
@ -90,9 +91,12 @@ func TestStore(t *testing.T) {
|
|||
t.Fatalf("error: %v", err)
|
||||
}
|
||||
|
||||
emptySelector, _ := labels.Parse("")
|
||||
emptySelector, err := labels.Parse("")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
defer te.Stop() //nolint:errcheck
|
||||
defer te.Stop() //nolint:errcheck // Ignore the error
|
||||
|
||||
clientSet, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
|
|
@ -176,7 +180,11 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -230,7 +238,7 @@ func TestStore(t *testing.T) {
|
|||
time.Sleep(1 * time.Second)
|
||||
|
||||
ni := ing.DeepCopy()
|
||||
ni.Spec.Rules[0].Host = "update-dummy"
|
||||
ni.Spec.Rules[0].Host = updateDummyHost
|
||||
_ = ensureIngress(ni, clientSet, t)
|
||||
if err != nil {
|
||||
t.Errorf("error creating ingress: %v", err)
|
||||
|
|
@ -281,7 +289,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -343,7 +354,7 @@ func TestStore(t *testing.T) {
|
|||
defer deleteIngress(invalidIngress, clientSet, t)
|
||||
|
||||
ni := ing.DeepCopy()
|
||||
ni.Spec.Rules[0].Host = "update-dummy"
|
||||
ni.Spec.Rules[0].Host = updateDummyHost
|
||||
_ = ensureIngress(ni, clientSet, t)
|
||||
if err != nil {
|
||||
t.Errorf("error creating ingress: %v", err)
|
||||
|
|
@ -392,7 +403,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -411,7 +425,7 @@ func TestStore(t *testing.T) {
|
|||
}
|
||||
}(updateCh)
|
||||
|
||||
ingressClassconfig := &ingressclass.IngressClassConfiguration{
|
||||
ingressClassconfig := &ingressclass.Configuration{
|
||||
Controller: ingressclass.DefaultControllerName,
|
||||
AnnotationValue: ingressclass.DefaultAnnotationValue,
|
||||
WatchWithoutClass: true,
|
||||
|
|
@ -463,7 +477,7 @@ func TestStore(t *testing.T) {
|
|||
time.Sleep(1 * time.Second)
|
||||
|
||||
validIngressUpdated := validIngress1.DeepCopy()
|
||||
validIngressUpdated.Spec.Rules[0].Host = "update-dummy"
|
||||
validIngressUpdated.Spec.Rules[0].Host = updateDummyHost
|
||||
_ = ensureIngress(validIngressUpdated, clientSet, t)
|
||||
if err != nil {
|
||||
t.Errorf("error updating ingress: %v", err)
|
||||
|
|
@ -523,7 +537,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -542,7 +559,7 @@ func TestStore(t *testing.T) {
|
|||
}
|
||||
}(updateCh)
|
||||
|
||||
ingressClassconfig := &ingressclass.IngressClassConfiguration{
|
||||
ingressClassconfig := &ingressclass.Configuration{
|
||||
Controller: ingressclass.DefaultControllerName,
|
||||
AnnotationValue: ic,
|
||||
IngressClassByName: true,
|
||||
|
|
@ -581,7 +598,7 @@ func TestStore(t *testing.T) {
|
|||
time.Sleep(1 * time.Second)
|
||||
|
||||
ingressUpdated := ing.DeepCopy()
|
||||
ingressUpdated.Spec.Rules[0].Host = "update-dummy"
|
||||
ingressUpdated.Spec.Rules[0].Host = updateDummyHost
|
||||
_ = ensureIngress(ingressUpdated, clientSet, t)
|
||||
if err != nil {
|
||||
t.Errorf("error updating ingress: %v", err)
|
||||
|
|
@ -630,7 +647,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -684,7 +704,7 @@ func TestStore(t *testing.T) {
|
|||
time.Sleep(1 * time.Second)
|
||||
|
||||
invalidIngressUpdated := invalidIngress.DeepCopy()
|
||||
invalidIngressUpdated.Spec.Rules[0].Host = "update-dummy"
|
||||
invalidIngressUpdated.Spec.Rules[0].Host = updateDummyHost
|
||||
_ = ensureIngress(invalidIngressUpdated, clientSet, t)
|
||||
if err != nil {
|
||||
t.Errorf("error creating ingress: %v", err)
|
||||
|
|
@ -725,7 +745,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -778,7 +801,7 @@ func TestStore(t *testing.T) {
|
|||
time.Sleep(1 * time.Second)
|
||||
|
||||
invalidIngressUpdated := invalidIngress.DeepCopy()
|
||||
invalidIngressUpdated.Spec.Rules[0].Host = "update-dummy"
|
||||
invalidIngressUpdated.Spec.Rules[0].Host = updateDummyHost
|
||||
_ = ensureIngress(invalidIngressUpdated, clientSet, t)
|
||||
if err != nil {
|
||||
t.Errorf("error creating ingress: %v", err)
|
||||
|
|
@ -816,7 +839,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -908,7 +934,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -1008,7 +1037,6 @@ func TestStore(t *testing.T) {
|
|||
if atomic.LoadUint64(&del) != 1 {
|
||||
t.Errorf("expected 1 events of type Delete but %v occurred", del)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
t.Run("should create an ingress with a secret which does not exist", func(t *testing.T) {
|
||||
|
|
@ -1032,7 +1060,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -1159,7 +1190,10 @@ func TestStore(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
e := evt.(Event)
|
||||
e, ok := evt.(Event)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if e.Obj == nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -1174,7 +1208,10 @@ func TestStore(t *testing.T) {
|
|||
}
|
||||
}(updateCh)
|
||||
|
||||
namesapceSelector, _ := labels.Parse("foo=bar")
|
||||
namesapceSelector, err := labels.Parse("foo=bar")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
storer := New(
|
||||
ns,
|
||||
namesapceSelector,
|
||||
|
|
@ -1236,7 +1273,6 @@ func TestStore(t *testing.T) {
|
|||
if atomic.LoadUint64(&del) != 0 {
|
||||
t.Errorf("expected 0 events of type Delete but %v occurred", del)
|
||||
}
|
||||
|
||||
})
|
||||
// test add ingress with secret it doesn't exists and then add secret
|
||||
// check secret is generated on fs
|
||||
|
|
@ -1274,16 +1310,16 @@ func deleteNamespace(ns string, clientSet kubernetes.Interface, t *testing.T) {
|
|||
|
||||
func createIngressClass(clientSet kubernetes.Interface, t *testing.T, controller string) string {
|
||||
t.Helper()
|
||||
ingressclass := &networking.IngressClass{
|
||||
class := &networking.IngressClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("ingress-nginx-%v", time.Now().Unix()),
|
||||
//Namespace: "xpto" // TODO: We don't support namespaced ingress-class yet
|
||||
// Namespace: "xpto" // TODO: We don't support namespaced ingress-class yet
|
||||
},
|
||||
Spec: networking.IngressClassSpec{
|
||||
Controller: controller,
|
||||
},
|
||||
}
|
||||
ic, err := clientSet.NetworkingV1().IngressClasses().Create(context.TODO(), ingressclass, metav1.CreateOptions{})
|
||||
ic, err := clientSet.NetworkingV1().IngressClasses().Create(context.TODO(), class, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error creating ingress class: %v", err)
|
||||
}
|
||||
|
|
@ -1299,7 +1335,7 @@ func deleteIngressClass(ic string, clientSet kubernetes.Interface, t *testing.T)
|
|||
}
|
||||
}
|
||||
|
||||
func createConfigMap(clientSet kubernetes.Interface, ns string, t *testing.T) string {
|
||||
func createConfigMap(clientSet kubernetes.Interface, ns string, t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
configMap := &v1.ConfigMap{
|
||||
|
|
@ -1308,51 +1344,47 @@ func createConfigMap(clientSet kubernetes.Interface, ns string, t *testing.T) st
|
|||
},
|
||||
}
|
||||
|
||||
cm, err := clientSet.CoreV1().ConfigMaps(ns).Create(context.TODO(), configMap, metav1.CreateOptions{})
|
||||
_, err := clientSet.CoreV1().ConfigMaps(ns).Create(context.TODO(), configMap, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error creating the configuration map: %v", err)
|
||||
}
|
||||
|
||||
return cm.Name
|
||||
}
|
||||
|
||||
func ensureIngress(ingress *networking.Ingress, clientSet kubernetes.Interface, t *testing.T) *networking.Ingress {
|
||||
func ensureIngress(ing *networking.Ingress, clientSet kubernetes.Interface, t *testing.T) *networking.Ingress {
|
||||
t.Helper()
|
||||
ing, err := clientSet.NetworkingV1().Ingresses(ingress.Namespace).Update(context.TODO(), ingress, metav1.UpdateOptions{})
|
||||
|
||||
newIngress, err := clientSet.NetworkingV1().Ingresses(ing.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
if k8sErrors.IsNotFound(err) {
|
||||
t.Logf("Ingress %v not found, creating", ingress)
|
||||
t.Logf("Ingress %v not found, creating", ing)
|
||||
|
||||
ing, err = clientSet.NetworkingV1().Ingresses(ingress.Namespace).Create(context.TODO(), ingress, metav1.CreateOptions{})
|
||||
newIngress, err = clientSet.NetworkingV1().Ingresses(ing.Namespace).Create(context.TODO(), ing, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating ingress %+v: %v", ingress, err)
|
||||
t.Fatalf("error creating ingress %+v: %v", ing, err)
|
||||
}
|
||||
|
||||
t.Logf("Ingress %+v created", ingress)
|
||||
return ing
|
||||
t.Logf("Ingress %+v created", ing)
|
||||
return newIngress
|
||||
}
|
||||
|
||||
t.Fatalf("error updating ingress %+v: %v", ingress, err)
|
||||
t.Fatalf("error updating ingress %+v: %v", ing, err)
|
||||
}
|
||||
|
||||
return ing
|
||||
return newIngress
|
||||
}
|
||||
|
||||
func deleteIngress(ingress *networking.Ingress, clientSet kubernetes.Interface, t *testing.T) {
|
||||
func deleteIngress(ing *networking.Ingress, clientSet kubernetes.Interface, t *testing.T) {
|
||||
t.Helper()
|
||||
err := clientSet.NetworkingV1().Ingresses(ingress.Namespace).Delete(context.TODO(), ingress.Name, metav1.DeleteOptions{})
|
||||
|
||||
err := clientSet.NetworkingV1().Ingresses(ing.Namespace).Delete(context.TODO(), ing.Name, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("failed to delete ingress %+v: %v", ingress, err)
|
||||
t.Errorf("failed to delete ingress %+v: %v", ing, err)
|
||||
}
|
||||
|
||||
t.Logf("Ingress %+v deleted", ingress)
|
||||
t.Logf("Ingress %+v deleted", ing)
|
||||
}
|
||||
|
||||
// newStore creates a new mock object store for tests which do not require the
|
||||
// use of Informers.
|
||||
func newStore(t *testing.T) *k8sStore {
|
||||
func newStore() *k8sStore {
|
||||
return &k8sStore{
|
||||
listers: &Lister{
|
||||
// add more listers if needed
|
||||
|
|
@ -1369,7 +1401,7 @@ func newStore(t *testing.T) *k8sStore {
|
|||
}
|
||||
|
||||
func TestUpdateSecretIngressMap(t *testing.T) {
|
||||
s := newStore(t)
|
||||
s := newStore()
|
||||
|
||||
ingTpl := &networking.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -1431,7 +1463,9 @@ func TestUpdateSecretIngressMap(t *testing.T) {
|
|||
ing.ObjectMeta.SetAnnotations(map[string]string{
|
||||
parser.GetAnnotationWithPrefix("auth-secret"): "anotherns/auth",
|
||||
})
|
||||
s.listers.Ingress.Update(ing)
|
||||
if err := s.listers.Ingress.Update(ing); err != nil {
|
||||
t.Errorf("error updating the Ingress: %v", err)
|
||||
}
|
||||
s.updateSecretIngressMap(ing)
|
||||
|
||||
if l := s.secretIngressMap.Len(); l != 0 {
|
||||
|
|
@ -1456,7 +1490,7 @@ func TestUpdateSecretIngressMap(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestListIngresses(t *testing.T) {
|
||||
s := newStore(t)
|
||||
s := newStore()
|
||||
invalidIngressClass := "something"
|
||||
validIngressClass := ingressclass.DefaultControllerName
|
||||
|
||||
|
|
@ -1586,7 +1620,7 @@ func TestWriteSSLSessionTicketKey(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
s := newStore(t)
|
||||
s := newStore()
|
||||
|
||||
cmap := &v1.ConfigMap{
|
||||
Data: map[string]string{
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ const (
|
|||
)
|
||||
|
||||
// ReadConfig obtains the configuration defined by the user merged with the defaults.
|
||||
//
|
||||
//nolint:gocyclo // Ignore function complexity error
|
||||
func ReadConfig(src map[string]string) config.Configuration {
|
||||
conf := map[string]string{}
|
||||
// we need to copy the configmap data because the content is altered
|
||||
|
|
@ -116,12 +118,12 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
luaSharedDicts := make(map[string]int)
|
||||
debugConnectionsList := make([]string, 0)
|
||||
|
||||
//parse lua shared dict values
|
||||
// parse lua shared dict values
|
||||
if val, ok := conf[luaSharedDictsKey]; ok {
|
||||
delete(conf, luaSharedDictsKey)
|
||||
lsd := splitAndTrimSpace(val, ",")
|
||||
for _, v := range lsd {
|
||||
v = strings.Replace(v, " ", "", -1)
|
||||
v = strings.ReplaceAll(v, " ", "")
|
||||
results := strings.SplitN(v, ":", 2)
|
||||
dictName := results[0]
|
||||
size := dictStrToKb(results[1])
|
||||
|
|
@ -196,7 +198,7 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
if ing_net.IsIPV6(ns) {
|
||||
bindAddressIpv6List = append(bindAddressIpv6List, fmt.Sprintf("[%v]", ns))
|
||||
} else {
|
||||
bindAddressIpv4List = append(bindAddressIpv4List, fmt.Sprintf("%v", ns))
|
||||
bindAddressIpv4List = append(bindAddressIpv4List, ns.String())
|
||||
}
|
||||
} else {
|
||||
klog.Warningf("%v is not a valid textual representation of an IP address", i)
|
||||
|
|
@ -250,7 +252,7 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
if val, ok := conf[globalAuthMethod]; ok {
|
||||
delete(conf, globalAuthMethod)
|
||||
|
||||
if len(val) != 0 && !authreq.ValidMethod(val) {
|
||||
if val != "" && !authreq.ValidMethod(val) {
|
||||
klog.Warningf("Global auth location denied - %v.", "invalid HTTP method")
|
||||
} else {
|
||||
to.GlobalExternalAuth.Method = val
|
||||
|
|
@ -261,7 +263,10 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
if val, ok := conf[globalAuthSignin]; ok {
|
||||
delete(conf, globalAuthSignin)
|
||||
|
||||
signinURL, _ := parser.StringToURL(val)
|
||||
signinURL, err := parser.StringToURL(val)
|
||||
if err != nil {
|
||||
klog.Errorf("string to URL conversion failed: %v", err)
|
||||
}
|
||||
if signinURL == nil {
|
||||
klog.Warningf("Global auth location denied - %v.", "global-auth-signin setting is undefined and will not be set")
|
||||
} else {
|
||||
|
|
@ -274,7 +279,10 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
delete(conf, globalAuthSigninRedirectParam)
|
||||
|
||||
redirectParam := strings.TrimSpace(val)
|
||||
dummySigninURL, _ := parser.StringToURL(fmt.Sprintf("%s?%s=dummy", to.GlobalExternalAuth.SigninURL, redirectParam))
|
||||
dummySigninURL, err := parser.StringToURL(fmt.Sprintf("%s?%s=dummy", to.GlobalExternalAuth.SigninURL, redirectParam))
|
||||
if err != nil {
|
||||
klog.Errorf("string to URL conversion failed: %v", err)
|
||||
}
|
||||
if dummySigninURL == nil {
|
||||
klog.Warningf("Global auth redirect parameter denied - %v.", "global-auth-signin-redirect-param setting is invalid and will not be set")
|
||||
} else {
|
||||
|
|
@ -286,7 +294,7 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
if val, ok := conf[globalAuthResponseHeaders]; ok {
|
||||
delete(conf, globalAuthResponseHeaders)
|
||||
|
||||
if len(val) != 0 {
|
||||
if val != "" {
|
||||
harr := splitAndTrimSpace(val, ",")
|
||||
for _, header := range harr {
|
||||
if !authreq.ValidHeader(header) {
|
||||
|
|
@ -385,8 +393,8 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
if val, ok := conf[debugConnections]; ok {
|
||||
delete(conf, debugConnections)
|
||||
for _, i := range splitAndTrimSpace(val, ",") {
|
||||
validIp := net.ParseIP(i)
|
||||
if validIp != nil {
|
||||
validIP := net.ParseIP(i)
|
||||
if validIP != nil {
|
||||
debugConnectionsList = append(debugConnectionsList, i)
|
||||
} else {
|
||||
_, _, err := net.ParseCIDR(i)
|
||||
|
|
@ -415,14 +423,14 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
to.DisableIpv6DNS = !ing_net.IsIPv6Enabled()
|
||||
to.LuaSharedDicts = luaSharedDicts
|
||||
|
||||
config := &mapstructure.DecoderConfig{
|
||||
decoderConfig := &mapstructure.DecoderConfig{
|
||||
Metadata: nil,
|
||||
WeaklyTypedInput: true,
|
||||
Result: &to,
|
||||
TagName: "json",
|
||||
}
|
||||
|
||||
decoder, err := mapstructure.NewDecoder(config)
|
||||
decoder, err := mapstructure.NewDecoder(decoderConfig)
|
||||
if err != nil {
|
||||
klog.Warningf("unexpected error merging defaults: %v", err)
|
||||
}
|
||||
|
|
@ -456,6 +464,7 @@ func filterErrors(codes []int) []int {
|
|||
return fa
|
||||
}
|
||||
|
||||
//nolint:unparam // Ignore `sep` always receives `,` error
|
||||
func splitAndTrimSpace(s, sep string) []string {
|
||||
f := func(c rune) bool {
|
||||
return strings.EqualFold(string(c), sep)
|
||||
|
|
@ -474,8 +483,11 @@ func dictStrToKb(sizeStr string) int {
|
|||
if sizeMatch == nil {
|
||||
return -1
|
||||
}
|
||||
size, _ := strconv.Atoi(sizeMatch[1]) // validated already with regex
|
||||
if sizeMatch[2] == "" || strings.ToLower(sizeMatch[2]) == "m" {
|
||||
size, err := strconv.Atoi(sizeMatch[1]) // validated already with regex
|
||||
if err != nil {
|
||||
klog.Errorf("unexpected error converting size string %s to int: %v", sizeStr, err)
|
||||
}
|
||||
if sizeMatch[2] == "" || strings.EqualFold(sizeMatch[2], "m") {
|
||||
size *= 1024
|
||||
}
|
||||
return size
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ const (
|
|||
nonIdempotent = "non_idempotent"
|
||||
defBufferSize = 65535
|
||||
writeIndentOnEmptyLines = true // backward-compatibility
|
||||
httpProtocol = "HTTP"
|
||||
autoHTTPProtocol = "AUTO_HTTP"
|
||||
httpsProtocol = "HTTPS"
|
||||
grpcProtocol = "GRPC"
|
||||
grpcsProtocol = "GRPCS"
|
||||
fcgiProtocol = "FCGI"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -64,13 +70,13 @@ type Writer interface {
|
|||
// Write renders the template.
|
||||
// NOTE: Implementors must ensure that the content of the returned slice is not modified by the implementation
|
||||
// after the return of this function.
|
||||
Write(conf config.TemplateConfig) ([]byte, error)
|
||||
Write(conf *config.TemplateConfig) ([]byte, error)
|
||||
}
|
||||
|
||||
// Template ...
|
||||
// Template ingress template
|
||||
type Template struct {
|
||||
tmpl *text_template.Template
|
||||
//fw watch.FileWatcher
|
||||
|
||||
bp *BufferPool
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +103,7 @@ func NewTemplate(file string) (*Template, error) {
|
|||
// 2. Collapses multiple empty lines to single one
|
||||
// 3. Re-indent
|
||||
// (ATW: always returns nil)
|
||||
func cleanConf(in *bytes.Buffer, out *bytes.Buffer) error {
|
||||
func cleanConf(in, out *bytes.Buffer) error {
|
||||
depth := 0
|
||||
lineStarted := false
|
||||
emptyLineWritten := false
|
||||
|
|
@ -176,7 +182,7 @@ func cleanConf(in *bytes.Buffer, out *bytes.Buffer) error {
|
|||
|
||||
// Write populates a buffer using a template with NGINX configuration
|
||||
// and the servers and upstreams created by Ingress rules
|
||||
func (t *Template) Write(conf config.TemplateConfig) ([]byte, error) {
|
||||
func (t *Template) Write(conf *config.TemplateConfig) ([]byte, error) {
|
||||
tmplBuf := t.bp.Get()
|
||||
defer t.bp.Put(tmplBuf)
|
||||
|
||||
|
|
@ -184,14 +190,14 @@ func (t *Template) Write(conf config.TemplateConfig) ([]byte, error) {
|
|||
defer t.bp.Put(outCmdBuf)
|
||||
|
||||
if klog.V(3).Enabled() {
|
||||
b, err := json.Marshal(conf)
|
||||
b, err := json.Marshal(*conf)
|
||||
if err != nil {
|
||||
klog.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
klog.InfoS("NGINX", "configuration", string(b))
|
||||
}
|
||||
|
||||
err := t.tmpl.Execute(tmplBuf, conf)
|
||||
err := t.tmpl.Execute(tmplBuf, *conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -211,78 +217,76 @@ func (t *Template) Write(conf config.TemplateConfig) ([]byte, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
var (
|
||||
funcMap = text_template.FuncMap{
|
||||
"empty": func(input interface{}) bool {
|
||||
check, ok := input.(string)
|
||||
if ok {
|
||||
return len(check) == 0
|
||||
}
|
||||
return true
|
||||
},
|
||||
"escapeLiteralDollar": escapeLiteralDollar,
|
||||
"buildLuaSharedDictionaries": buildLuaSharedDictionaries,
|
||||
"luaConfigurationRequestBodySize": luaConfigurationRequestBodySize,
|
||||
"buildLocation": buildLocation,
|
||||
"buildAuthLocation": buildAuthLocation,
|
||||
"shouldApplyGlobalAuth": shouldApplyGlobalAuth,
|
||||
"buildAuthResponseHeaders": buildAuthResponseHeaders,
|
||||
"buildAuthUpstreamLuaHeaders": buildAuthUpstreamLuaHeaders,
|
||||
"buildAuthProxySetHeaders": buildAuthProxySetHeaders,
|
||||
"buildAuthUpstreamName": buildAuthUpstreamName,
|
||||
"shouldApplyAuthUpstream": shouldApplyAuthUpstream,
|
||||
"extractHostPort": extractHostPort,
|
||||
"changeHostPort": changeHostPort,
|
||||
"buildProxyPass": buildProxyPass,
|
||||
"filterRateLimits": filterRateLimits,
|
||||
"buildRateLimitZones": buildRateLimitZones,
|
||||
"buildRateLimit": buildRateLimit,
|
||||
"configForLua": configForLua,
|
||||
"locationConfigForLua": locationConfigForLua,
|
||||
"buildResolvers": buildResolvers,
|
||||
"buildUpstreamName": buildUpstreamName,
|
||||
"isLocationInLocationList": isLocationInLocationList,
|
||||
"isLocationAllowed": isLocationAllowed,
|
||||
"buildDenyVariable": buildDenyVariable,
|
||||
"getenv": os.Getenv,
|
||||
"contains": strings.Contains,
|
||||
"split": strings.Split,
|
||||
"hasPrefix": strings.HasPrefix,
|
||||
"hasSuffix": strings.HasSuffix,
|
||||
"trimSpace": strings.TrimSpace,
|
||||
"toUpper": strings.ToUpper,
|
||||
"toLower": strings.ToLower,
|
||||
"formatIP": formatIP,
|
||||
"quote": quote,
|
||||
"buildNextUpstream": buildNextUpstream,
|
||||
"getIngressInformation": getIngressInformation,
|
||||
"serverConfig": func(all config.TemplateConfig, server *ingress.Server) interface{} {
|
||||
return struct{ First, Second interface{} }{all, server}
|
||||
},
|
||||
"isValidByteSize": isValidByteSize,
|
||||
"buildForwardedFor": buildForwardedFor,
|
||||
"buildAuthSignURL": buildAuthSignURL,
|
||||
"buildAuthSignURLLocation": buildAuthSignURLLocation,
|
||||
"buildOpentracing": buildOpentracing,
|
||||
"buildOpentelemetry": buildOpentelemetry,
|
||||
"proxySetHeader": proxySetHeader,
|
||||
"enforceRegexModifier": enforceRegexModifier,
|
||||
"buildCustomErrorDeps": buildCustomErrorDeps,
|
||||
"buildCustomErrorLocationsPerServer": buildCustomErrorLocationsPerServer,
|
||||
"shouldLoadModSecurityModule": shouldLoadModSecurityModule,
|
||||
"buildHTTPListener": buildHTTPListener,
|
||||
"buildHTTPSListener": buildHTTPSListener,
|
||||
"buildOpentracingForLocation": buildOpentracingForLocation,
|
||||
"buildOpentelemetryForLocation": buildOpentelemetryForLocation,
|
||||
"shouldLoadOpentracingModule": shouldLoadOpentracingModule,
|
||||
"shouldLoadOpentelemetryModule": shouldLoadOpentelemetryModule,
|
||||
"buildModSecurityForLocation": buildModSecurityForLocation,
|
||||
"buildMirrorLocations": buildMirrorLocations,
|
||||
"shouldLoadAuthDigestModule": shouldLoadAuthDigestModule,
|
||||
"buildServerName": buildServerName,
|
||||
"buildCorsOriginRegex": buildCorsOriginRegex,
|
||||
}
|
||||
)
|
||||
var funcMap = text_template.FuncMap{
|
||||
"empty": func(input interface{}) bool {
|
||||
check, ok := input.(string)
|
||||
if ok {
|
||||
return check == ""
|
||||
}
|
||||
return true
|
||||
},
|
||||
"escapeLiteralDollar": escapeLiteralDollar,
|
||||
"buildLuaSharedDictionaries": buildLuaSharedDictionaries,
|
||||
"luaConfigurationRequestBodySize": luaConfigurationRequestBodySize,
|
||||
"buildLocation": buildLocation,
|
||||
"buildAuthLocation": buildAuthLocation,
|
||||
"shouldApplyGlobalAuth": shouldApplyGlobalAuth,
|
||||
"buildAuthResponseHeaders": buildAuthResponseHeaders,
|
||||
"buildAuthUpstreamLuaHeaders": buildAuthUpstreamLuaHeaders,
|
||||
"buildAuthProxySetHeaders": buildAuthProxySetHeaders,
|
||||
"buildAuthUpstreamName": buildAuthUpstreamName,
|
||||
"shouldApplyAuthUpstream": shouldApplyAuthUpstream,
|
||||
"extractHostPort": extractHostPort,
|
||||
"changeHostPort": changeHostPort,
|
||||
"buildProxyPass": buildProxyPass,
|
||||
"filterRateLimits": filterRateLimits,
|
||||
"buildRateLimitZones": buildRateLimitZones,
|
||||
"buildRateLimit": buildRateLimit,
|
||||
"configForLua": configForLua,
|
||||
"locationConfigForLua": locationConfigForLua,
|
||||
"buildResolvers": buildResolvers,
|
||||
"buildUpstreamName": buildUpstreamName,
|
||||
"isLocationInLocationList": isLocationInLocationList,
|
||||
"isLocationAllowed": isLocationAllowed,
|
||||
"buildDenyVariable": buildDenyVariable,
|
||||
"getenv": os.Getenv,
|
||||
"contains": strings.Contains,
|
||||
"split": strings.Split,
|
||||
"hasPrefix": strings.HasPrefix,
|
||||
"hasSuffix": strings.HasSuffix,
|
||||
"trimSpace": strings.TrimSpace,
|
||||
"toUpper": strings.ToUpper,
|
||||
"toLower": strings.ToLower,
|
||||
"formatIP": formatIP,
|
||||
"quote": quote,
|
||||
"buildNextUpstream": buildNextUpstream,
|
||||
"getIngressInformation": getIngressInformation,
|
||||
"serverConfig": func(all config.TemplateConfig, server *ingress.Server) interface{} {
|
||||
return struct{ First, Second interface{} }{all, server}
|
||||
},
|
||||
"isValidByteSize": isValidByteSize,
|
||||
"buildForwardedFor": buildForwardedFor,
|
||||
"buildAuthSignURL": buildAuthSignURL,
|
||||
"buildAuthSignURLLocation": buildAuthSignURLLocation,
|
||||
"buildOpentracing": buildOpentracing,
|
||||
"buildOpentelemetry": buildOpentelemetry,
|
||||
"proxySetHeader": proxySetHeader,
|
||||
"enforceRegexModifier": enforceRegexModifier,
|
||||
"buildCustomErrorDeps": buildCustomErrorDeps,
|
||||
"buildCustomErrorLocationsPerServer": buildCustomErrorLocationsPerServer,
|
||||
"shouldLoadModSecurityModule": shouldLoadModSecurityModule,
|
||||
"buildHTTPListener": buildHTTPListener,
|
||||
"buildHTTPSListener": buildHTTPSListener,
|
||||
"buildOpentracingForLocation": buildOpentracingForLocation,
|
||||
"buildOpentelemetryForLocation": buildOpentelemetryForLocation,
|
||||
"shouldLoadOpentracingModule": shouldLoadOpentracingModule,
|
||||
"shouldLoadOpentelemetryModule": shouldLoadOpentelemetryModule,
|
||||
"buildModSecurityForLocation": buildModSecurityForLocation,
|
||||
"buildMirrorLocations": buildMirrorLocations,
|
||||
"shouldLoadAuthDigestModule": shouldLoadAuthDigestModule,
|
||||
"buildServerName": buildServerName,
|
||||
"buildCorsOriginRegex": buildCorsOriginRegex,
|
||||
}
|
||||
|
||||
// escapeLiteralDollar will replace the $ character with ${literal_dollar}
|
||||
// which is made to work via the following configuration in the http section of
|
||||
|
|
@ -296,7 +300,7 @@ func escapeLiteralDollar(input interface{}) string {
|
|||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return strings.Replace(inputStr, `$`, `${literal_dollar}`, -1)
|
||||
return strings.ReplaceAll(inputStr, `$`, `${literal_dollar}`)
|
||||
}
|
||||
|
||||
// formatIP will wrap IPv6 addresses in [] and return IPv4 addresses
|
||||
|
|
@ -328,9 +332,7 @@ func quote(input interface{}) string {
|
|||
return fmt.Sprintf("%q", inputStr)
|
||||
}
|
||||
|
||||
func buildLuaSharedDictionaries(c interface{}, s interface{}) string {
|
||||
var out []string
|
||||
|
||||
func buildLuaSharedDictionaries(c, s interface{}) string {
|
||||
cfg, ok := c.(config.Configuration)
|
||||
if !ok {
|
||||
klog.Errorf("expected a 'config.Configuration' type but %T was returned", c)
|
||||
|
|
@ -343,6 +345,7 @@ func buildLuaSharedDictionaries(c interface{}, s interface{}) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
out := make([]string, 0, len(cfg.LuaSharedDicts))
|
||||
for name, size := range cfg.LuaSharedDicts {
|
||||
sizeStr := dictKbToStr(size)
|
||||
out = append(out, fmt.Sprintf("lua_shared_dict %s %s", name, sizeStr))
|
||||
|
|
@ -364,7 +367,7 @@ func luaConfigurationRequestBodySize(c interface{}) string {
|
|||
if size < cfg.LuaSharedDicts["certificate_data"] {
|
||||
size = cfg.LuaSharedDicts["certificate_data"]
|
||||
}
|
||||
size = size + 1024
|
||||
size += 1024
|
||||
|
||||
return dictKbToStr(size)
|
||||
}
|
||||
|
|
@ -418,7 +421,7 @@ func configForLua(input interface{}) string {
|
|||
}
|
||||
|
||||
// locationConfigForLua formats some location specific configuration into Lua table represented as string
|
||||
func locationConfigForLua(l interface{}, a interface{}) string {
|
||||
func locationConfigForLua(l, a interface{}) string {
|
||||
location, ok := l.(*ingress.Location)
|
||||
if !ok {
|
||||
klog.Errorf("expected an '*ingress.Location' type but %T was given", l)
|
||||
|
|
@ -459,7 +462,7 @@ func locationConfigForLua(l interface{}, a interface{}) string {
|
|||
}
|
||||
|
||||
// buildResolvers returns the resolvers reading the /etc/resolv.conf file
|
||||
func buildResolvers(res interface{}, disableIpv6 interface{}) string {
|
||||
func buildResolvers(res, disableIpv6 interface{}) string {
|
||||
// NGINX need IPV6 addresses to be surrounded by brackets
|
||||
nss, ok := res.([]net.IP)
|
||||
if !ok {
|
||||
|
|
@ -484,7 +487,7 @@ func buildResolvers(res interface{}, disableIpv6 interface{}) string {
|
|||
}
|
||||
r = append(r, fmt.Sprintf("[%v]", ns))
|
||||
} else {
|
||||
r = append(r, fmt.Sprintf("%v", ns))
|
||||
r = append(r, ns.String())
|
||||
}
|
||||
}
|
||||
r = append(r, "valid=30s")
|
||||
|
|
@ -554,7 +557,7 @@ func buildAuthLocation(input interface{}, globalExternalAuthURL string) string {
|
|||
|
||||
str := base64.URLEncoding.EncodeToString([]byte(location.Path))
|
||||
// removes "=" after encoding
|
||||
str = strings.Replace(str, "=", "", -1)
|
||||
str = strings.ReplaceAll(str, "=", "")
|
||||
|
||||
pathType := "default"
|
||||
if location.PathType != nil {
|
||||
|
|
@ -644,7 +647,7 @@ func buildAuthUpstreamName(input interface{}, host string) string {
|
|||
|
||||
// shouldApplyAuthUpstream returns true only in case when ExternalAuth.URL and
|
||||
// ExternalAuth.KeepaliveConnections are all set
|
||||
func shouldApplyAuthUpstream(l interface{}, c interface{}) bool {
|
||||
func shouldApplyAuthUpstream(l, c interface{}) bool {
|
||||
location, ok := l.(*ingress.Location)
|
||||
if !ok {
|
||||
klog.Errorf("expected an '*ingress.Location' type but %T was returned", l)
|
||||
|
|
@ -672,14 +675,14 @@ func shouldApplyAuthUpstream(l interface{}, c interface{}) bool {
|
|||
}
|
||||
|
||||
// extractHostPort will extract the host:port part from the URL specified by url
|
||||
func extractHostPort(url string) string {
|
||||
if url == "" {
|
||||
func extractHostPort(newURL string) string {
|
||||
if newURL == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
authURL, err := parser.StringToURL(url)
|
||||
authURL, err := parser.StringToURL(newURL)
|
||||
if err != nil {
|
||||
klog.Errorf("expected a valid URL but %s was returned", url)
|
||||
klog.Errorf("expected a valid URL but %s was returned", newURL)
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
@ -687,14 +690,14 @@ func extractHostPort(url string) string {
|
|||
}
|
||||
|
||||
// changeHostPort will change the host:port part of the url to value
|
||||
func changeHostPort(url string, value string) string {
|
||||
if url == "" {
|
||||
func changeHostPort(newURL, value string) string {
|
||||
if newURL == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
authURL, err := parser.StringToURL(url)
|
||||
authURL, err := parser.StringToURL(newURL)
|
||||
if err != nil {
|
||||
klog.Errorf("expected a valid URL but %s was returned", url)
|
||||
klog.Errorf("expected a valid URL but %s was returned", newURL)
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
@ -707,7 +710,7 @@ func changeHostPort(url string, value string) string {
|
|||
// (specified through the nginx.ingress.kubernetes.io/rewrite-target annotation)
|
||||
// If the annotation nginx.ingress.kubernetes.io/add-base-url:"true" is specified it will
|
||||
// add a base tag in the head of the response from the service
|
||||
func buildProxyPass(host string, b interface{}, loc interface{}) string {
|
||||
func buildProxyPass(_ string, b, loc interface{}) string {
|
||||
backends, ok := b.([]*ingress.Backend)
|
||||
if !ok {
|
||||
klog.Errorf("expected an '[]*ingress.Backend' type but %T was returned", b)
|
||||
|
|
@ -726,17 +729,17 @@ func buildProxyPass(host string, b interface{}, loc interface{}) string {
|
|||
proxyPass := "proxy_pass"
|
||||
|
||||
switch location.BackendProtocol {
|
||||
case "AUTO_HTTP":
|
||||
case autoHTTPProtocol:
|
||||
proto = "$scheme://"
|
||||
case "HTTPS":
|
||||
case httpsProtocol:
|
||||
proto = "https://"
|
||||
case "GRPC":
|
||||
case grpcProtocol:
|
||||
proto = "grpc://"
|
||||
proxyPass = "grpc_pass"
|
||||
case "GRPCS":
|
||||
case grpcsProtocol:
|
||||
proto = "grpcs://"
|
||||
proxyPass = "grpc_pass"
|
||||
case "FCGI":
|
||||
case fcgiProtocol:
|
||||
proto = ""
|
||||
proxyPass = "fastcgi_pass"
|
||||
}
|
||||
|
|
@ -748,7 +751,7 @@ func buildProxyPass(host string, b interface{}, loc interface{}) string {
|
|||
if backend.SSLPassthrough {
|
||||
proto = "https://"
|
||||
|
||||
if location.BackendProtocol == "GRPCS" {
|
||||
if location.BackendProtocol == grpcsProtocol {
|
||||
proto = "grpcs://"
|
||||
}
|
||||
}
|
||||
|
|
@ -775,7 +778,7 @@ func buildProxyPass(host string, b interface{}, loc interface{}) string {
|
|||
var xForwardedPrefix string
|
||||
|
||||
if len(location.XForwardedPrefix) > 0 {
|
||||
xForwardedPrefix = fmt.Sprintf("%s X-Forwarded-Prefix \"%s\";\n", proxySetHeader(location), location.XForwardedPrefix)
|
||||
xForwardedPrefix = fmt.Sprintf("%s X-Forwarded-Prefix %q;\n", proxySetHeader(location), location.XForwardedPrefix)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`
|
||||
|
|
@ -935,9 +938,7 @@ func isLocationAllowed(input interface{}) bool {
|
|||
return loc.Denied == nil
|
||||
}
|
||||
|
||||
var (
|
||||
denyPathSlugMap = map[string]string{}
|
||||
)
|
||||
var denyPathSlugMap = map[string]string{}
|
||||
|
||||
// buildDenyVariable returns a nginx variable for a location in a
|
||||
// server to be used in the whitelist check
|
||||
|
|
@ -977,7 +978,11 @@ func buildNextUpstream(i, r interface{}) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
retryNonIdempotent := r.(bool)
|
||||
retryNonIdempotent, ok := r.(bool)
|
||||
if !ok {
|
||||
klog.Errorf("expected a 'bool' type but %T was returned", i)
|
||||
return ""
|
||||
}
|
||||
|
||||
parts := strings.Split(nextUpstream, " ")
|
||||
|
||||
|
|
@ -1002,8 +1007,10 @@ func buildNextUpstream(i, r interface{}) string {
|
|||
// refer to http://nginx.org/en/docs/syntax.html
|
||||
// Nginx differentiates between size and offset
|
||||
// offset directives support gigabytes in addition
|
||||
var nginxSizeRegex = regexp.MustCompile("^[0-9]+[kKmM]{0,1}$")
|
||||
var nginxOffsetRegex = regexp.MustCompile("^[0-9]+[kKmMgG]{0,1}$")
|
||||
var (
|
||||
nginxSizeRegex = regexp.MustCompile(`^\d+[kKmM]?$`)
|
||||
nginxOffsetRegex = regexp.MustCompile(`^\d+[kKmMgG]?$`)
|
||||
)
|
||||
|
||||
// isValidByteSize validates size units valid in nginx
|
||||
// http://nginx.org/en/docs/syntax.html
|
||||
|
|
@ -1153,13 +1160,17 @@ func buildForwardedFor(input interface{}) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
ffh := strings.Replace(s, "-", "_", -1)
|
||||
ffh := strings.ReplaceAll(s, "-", "_")
|
||||
ffh = strings.ToLower(ffh)
|
||||
return fmt.Sprintf("$http_%v", ffh)
|
||||
}
|
||||
|
||||
func buildAuthSignURL(authSignURL, authRedirectParam string) string {
|
||||
u, _ := url.Parse(authSignURL)
|
||||
u, err := url.Parse(authSignURL)
|
||||
if err != nil {
|
||||
klog.Errorf("error parsing authSignURL: %v", err)
|
||||
return ""
|
||||
}
|
||||
q := u.Query()
|
||||
if authRedirectParam == "" {
|
||||
authRedirectParam = defaultGlobalAuthRedirectParam
|
||||
|
|
@ -1198,7 +1209,7 @@ func randomString() string {
|
|||
return string(b)
|
||||
}
|
||||
|
||||
func buildOpentracing(c interface{}, s interface{}) string {
|
||||
func buildOpentracing(c, s interface{}) string {
|
||||
cfg, ok := c.(config.Configuration)
|
||||
if !ok {
|
||||
klog.Errorf("expected a 'config.Configuration' type but %T was returned", c)
|
||||
|
|
@ -1217,6 +1228,7 @@ func buildOpentracing(c interface{}, s interface{}) string {
|
|||
|
||||
buf := bytes.NewBufferString("")
|
||||
|
||||
//nolint:gocritic // rewriting if-else to switch statement is not more readable
|
||||
if cfg.DatadogCollectorHost != "" {
|
||||
buf.WriteString("opentracing_load_tracer /usr/local/lib/libdd_opentracing.so /etc/nginx/opentracing.json;")
|
||||
} else if cfg.ZipkinCollectorHost != "" {
|
||||
|
|
@ -1228,16 +1240,16 @@ func buildOpentracing(c interface{}, s interface{}) string {
|
|||
buf.WriteString("\r\n")
|
||||
|
||||
if cfg.OpentracingOperationName != "" {
|
||||
buf.WriteString(fmt.Sprintf("opentracing_operation_name \"%s\";\n", cfg.OpentracingOperationName))
|
||||
fmt.Fprintf(buf, "opentracing_operation_name \"%s\";\n", cfg.OpentracingOperationName)
|
||||
}
|
||||
if cfg.OpentracingLocationOperationName != "" {
|
||||
buf.WriteString(fmt.Sprintf("opentracing_location_operation_name \"%s\";\n", cfg.OpentracingLocationOperationName))
|
||||
fmt.Fprintf(buf, "opentracing_location_operation_name \"%s\";\n", cfg.OpentracingLocationOperationName)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func buildOpentelemetry(c interface{}, s interface{}) string {
|
||||
func buildOpentelemetry(c, s interface{}) string {
|
||||
cfg, ok := c.(config.Configuration)
|
||||
if !ok {
|
||||
klog.Errorf("expected a 'config.Configuration' type but %T was returned", c)
|
||||
|
|
@ -1259,7 +1271,7 @@ func buildOpentelemetry(c interface{}, s interface{}) string {
|
|||
buf.WriteString("\r\n")
|
||||
|
||||
if cfg.OpentelemetryOperationName != "" {
|
||||
buf.WriteString(fmt.Sprintf("opentelemetry_operation_name \"%s\";\n", cfg.OpentelemetryOperationName))
|
||||
fmt.Fprintf(buf, "opentelemetry_operation_name \"%s\";\n", cfg.OpentelemetryOperationName)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
|
@ -1271,7 +1283,7 @@ func proxySetHeader(loc interface{}) string {
|
|||
return "proxy_set_header"
|
||||
}
|
||||
|
||||
if location.BackendProtocol == "GRPC" || location.BackendProtocol == "GRPCS" {
|
||||
if location.BackendProtocol == grpcProtocol || location.BackendProtocol == grpcsProtocol {
|
||||
return "grpc_set_header"
|
||||
}
|
||||
|
||||
|
|
@ -1280,7 +1292,7 @@ func proxySetHeader(loc interface{}) string {
|
|||
|
||||
// buildCustomErrorDeps is a utility function returning a struct wrapper with
|
||||
// the data required to build the 'CUSTOM_ERRORS' template
|
||||
func buildCustomErrorDeps(upstreamName string, errorCodes []int, enableMetrics bool, modsecurityEnabled bool) interface{} {
|
||||
func buildCustomErrorDeps(upstreamName string, errorCodes []int, enableMetrics, modsecurityEnabled bool) interface{} {
|
||||
return struct {
|
||||
UpstreamName string
|
||||
ErrorCodes []int
|
||||
|
|
@ -1355,7 +1367,7 @@ func opentracingPropagateContext(location *ingress.Location) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
if location.BackendProtocol == "GRPC" || location.BackendProtocol == "GRPCS" {
|
||||
if location.BackendProtocol == grpcProtocol || location.BackendProtocol == grpcsProtocol {
|
||||
return "opentracing_grpc_propagate_context;"
|
||||
}
|
||||
|
||||
|
|
@ -1372,7 +1384,7 @@ func opentelemetryPropagateContext(location *ingress.Location) string {
|
|||
// shouldLoadModSecurityModule determines whether or not the ModSecurity module needs to be loaded.
|
||||
// First, it checks if `enable-modsecurity` is set in the ConfigMap. If it is not, it iterates over all locations to
|
||||
// check if ModSecurity is enabled by the annotation `nginx.ingress.kubernetes.io/enable-modsecurity`.
|
||||
func shouldLoadModSecurityModule(c interface{}, s interface{}) bool {
|
||||
func shouldLoadModSecurityModule(c, s interface{}) bool {
|
||||
cfg, ok := c.(config.Configuration)
|
||||
if !ok {
|
||||
klog.Errorf("expected a 'config.Configuration' type but %T was returned", c)
|
||||
|
|
@ -1403,7 +1415,7 @@ func shouldLoadModSecurityModule(c interface{}, s interface{}) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func buildHTTPListener(t interface{}, s interface{}) string {
|
||||
func buildHTTPListener(t, s interface{}) string {
|
||||
var out []string
|
||||
|
||||
tc, ok := t.(config.TemplateConfig)
|
||||
|
|
@ -1423,9 +1435,9 @@ func buildHTTPListener(t interface{}, s interface{}) string {
|
|||
addrV4 = tc.Cfg.BindAddressIpv4
|
||||
}
|
||||
|
||||
co := commonListenOptions(tc, hostname)
|
||||
co := commonListenOptions(&tc, hostname)
|
||||
|
||||
out = append(out, httpListener(addrV4, co, tc)...)
|
||||
out = append(out, httpListener(addrV4, co, &tc)...)
|
||||
|
||||
if !tc.IsIPV6Enabled {
|
||||
return strings.Join(out, "\n")
|
||||
|
|
@ -1436,12 +1448,12 @@ func buildHTTPListener(t interface{}, s interface{}) string {
|
|||
addrV6 = tc.Cfg.BindAddressIpv6
|
||||
}
|
||||
|
||||
out = append(out, httpListener(addrV6, co, tc)...)
|
||||
out = append(out, httpListener(addrV6, co, &tc)...)
|
||||
|
||||
return strings.Join(out, "\n")
|
||||
}
|
||||
|
||||
func buildHTTPSListener(t interface{}, s interface{}) string {
|
||||
func buildHTTPSListener(t, s interface{}) string {
|
||||
var out []string
|
||||
|
||||
tc, ok := t.(config.TemplateConfig)
|
||||
|
|
@ -1456,14 +1468,14 @@ func buildHTTPSListener(t interface{}, s interface{}) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
co := commonListenOptions(tc, hostname)
|
||||
co := commonListenOptions(&tc, hostname)
|
||||
|
||||
addrV4 := []string{""}
|
||||
if len(tc.Cfg.BindAddressIpv4) > 0 {
|
||||
addrV4 = tc.Cfg.BindAddressIpv4
|
||||
}
|
||||
|
||||
out = append(out, httpsListener(addrV4, co, tc)...)
|
||||
out = append(out, httpsListener(addrV4, co, &tc)...)
|
||||
|
||||
if !tc.IsIPV6Enabled {
|
||||
return strings.Join(out, "\n")
|
||||
|
|
@ -1474,12 +1486,12 @@ func buildHTTPSListener(t interface{}, s interface{}) string {
|
|||
addrV6 = tc.Cfg.BindAddressIpv6
|
||||
}
|
||||
|
||||
out = append(out, httpsListener(addrV6, co, tc)...)
|
||||
out = append(out, httpsListener(addrV6, co, &tc)...)
|
||||
|
||||
return strings.Join(out, "\n")
|
||||
}
|
||||
|
||||
func commonListenOptions(template config.TemplateConfig, hostname string) string {
|
||||
func commonListenOptions(template *config.TemplateConfig, hostname string) string {
|
||||
var out []string
|
||||
|
||||
if template.Cfg.UseProxyProtocol {
|
||||
|
|
@ -1503,7 +1515,7 @@ func commonListenOptions(template config.TemplateConfig, hostname string) string
|
|||
return strings.Join(out, " ")
|
||||
}
|
||||
|
||||
func httpListener(addresses []string, co string, tc config.TemplateConfig) []string {
|
||||
func httpListener(addresses []string, co string, tc *config.TemplateConfig) []string {
|
||||
out := make([]string, 0)
|
||||
for _, address := range addresses {
|
||||
lo := []string{"listen"}
|
||||
|
|
@ -1514,15 +1526,14 @@ func httpListener(addresses []string, co string, tc config.TemplateConfig) []str
|
|||
lo = append(lo, fmt.Sprintf("%v:%v", address, tc.ListenPorts.HTTP))
|
||||
}
|
||||
|
||||
lo = append(lo, co)
|
||||
lo = append(lo, ";")
|
||||
lo = append(lo, co, ";")
|
||||
out = append(out, strings.Join(lo, " "))
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func httpsListener(addresses []string, co string, tc config.TemplateConfig) []string {
|
||||
func httpsListener(addresses []string, co string, tc *config.TemplateConfig) []string {
|
||||
out := make([]string, 0)
|
||||
for _, address := range addresses {
|
||||
lo := []string{"listen"}
|
||||
|
|
@ -1545,8 +1556,7 @@ func httpsListener(addresses []string, co string, tc config.TemplateConfig) []st
|
|||
}
|
||||
}
|
||||
|
||||
lo = append(lo, co)
|
||||
lo = append(lo, "ssl")
|
||||
lo = append(lo, co, "ssl")
|
||||
|
||||
if tc.Cfg.UseHTTP2 {
|
||||
lo = append(lo, "http2")
|
||||
|
|
@ -1559,7 +1569,7 @@ func httpsListener(addresses []string, co string, tc config.TemplateConfig) []st
|
|||
return out
|
||||
}
|
||||
|
||||
func buildOpentracingForLocation(isOTEnabled bool, isOTTrustSet bool, location *ingress.Location) string {
|
||||
func buildOpentracingForLocation(isOTEnabled, isOTTrustSet bool, location *ingress.Location) string {
|
||||
isOTEnabledInLoc := location.Opentracing.Enabled
|
||||
isOTSetInLoc := location.Opentracing.Set
|
||||
|
||||
|
|
@ -1578,13 +1588,13 @@ func buildOpentracingForLocation(isOTEnabled bool, isOTTrustSet bool, location *
|
|||
|
||||
if (!isOTTrustSet && !location.Opentracing.TrustSet) ||
|
||||
(location.Opentracing.TrustSet && !location.Opentracing.TrustEnabled) {
|
||||
opc = opc + "\nopentracing_trust_incoming_span off;"
|
||||
opc += "\nopentracing_trust_incoming_span off;"
|
||||
}
|
||||
|
||||
return opc
|
||||
}
|
||||
|
||||
func buildOpentelemetryForLocation(isOTEnabled bool, isOTTrustSet bool, location *ingress.Location) string {
|
||||
func buildOpentelemetryForLocation(isOTEnabled, isOTTrustSet bool, location *ingress.Location) string {
|
||||
isOTEnabledInLoc := location.Opentelemetry.Enabled
|
||||
isOTSetInLoc := location.Opentelemetry.Set
|
||||
|
||||
|
|
@ -1602,14 +1612,14 @@ func buildOpentelemetryForLocation(isOTEnabled bool, isOTTrustSet bool, location
|
|||
}
|
||||
|
||||
if location.Opentelemetry.OperationName != "" {
|
||||
opc = opc + "\nopentelemetry_operation_name " + location.Opentelemetry.OperationName + ";"
|
||||
opc += "\nopentelemetry_operation_name " + location.Opentelemetry.OperationName + ";"
|
||||
}
|
||||
|
||||
if (!isOTTrustSet && !location.Opentelemetry.TrustSet) ||
|
||||
(location.Opentelemetry.TrustSet && !location.Opentelemetry.TrustEnabled) {
|
||||
opc = opc + "\nopentelemetry_trust_incoming_spans off;"
|
||||
opc += "\nopentelemetry_trust_incoming_spans off;"
|
||||
} else {
|
||||
opc = opc + "\nopentelemetry_trust_incoming_spans on;"
|
||||
opc += "\nopentelemetry_trust_incoming_spans on;"
|
||||
}
|
||||
return opc
|
||||
}
|
||||
|
|
@ -1617,7 +1627,7 @@ func buildOpentelemetryForLocation(isOTEnabled bool, isOTTrustSet bool, location
|
|||
// shouldLoadOpentracingModule determines whether or not the Opentracing module needs to be loaded.
|
||||
// First, it checks if `enable-opentracing` is set in the ConfigMap. If it is not, it iterates over all locations to
|
||||
// check if Opentracing is enabled by the annotation `nginx.ingress.kubernetes.io/enable-opentracing`.
|
||||
func shouldLoadOpentracingModule(c interface{}, s interface{}) bool {
|
||||
func shouldLoadOpentracingModule(c, s interface{}) bool {
|
||||
cfg, ok := c.(config.Configuration)
|
||||
if !ok {
|
||||
klog.Errorf("expected a 'config.Configuration' type but %T was returned", c)
|
||||
|
|
@ -1647,7 +1657,7 @@ func shouldLoadOpentracingModule(c interface{}, s interface{}) bool {
|
|||
|
||||
// shouldLoadOpentelemetryModule determines whether or not the Opentelemetry module needs to be loaded.
|
||||
// It checks if `enable-opentelemetry` is set in the ConfigMap.
|
||||
func shouldLoadOpentelemetryModule(c interface{}, s interface{}) bool {
|
||||
func shouldLoadOpentelemetryModule(c, s interface{}) bool {
|
||||
cfg, ok := c.(config.Configuration)
|
||||
if !ok {
|
||||
klog.Errorf("expected a 'config.Configuration' type but %T was returned", c)
|
||||
|
|
@ -1674,6 +1684,7 @@ func shouldLoadOpentelemetryModule(c interface{}, s interface{}) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
//nolint:gocritic // Ignore passing cfg by pointer error
|
||||
func buildModSecurityForLocation(cfg config.Configuration, location *ingress.Location) string {
|
||||
isMSEnabledInLoc := location.ModSecurity.Enable
|
||||
isMSEnableSetInLoc := location.ModSecurity.EnableSet
|
||||
|
|
@ -1807,7 +1818,7 @@ func convertGoSliceIntoLuaTable(goSliceInterface interface{}, emptyStringAsNil b
|
|||
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
if emptyStringAsNil && len(goSlice.Interface().(string)) == 0 {
|
||||
if emptyStringAsNil && goSlice.Interface().(string) == "" {
|
||||
return "nil", nil
|
||||
}
|
||||
return fmt.Sprintf(`"%v"`, goSlice.Interface()), nil
|
||||
|
|
@ -1840,17 +1851,17 @@ func buildCorsOriginRegex(corsOrigins []string) string {
|
|||
return "set $http_origin *;\nset $cors 'true';"
|
||||
}
|
||||
|
||||
var originsRegex string = "if ($http_origin ~* ("
|
||||
originsRegex := "if ($http_origin ~* ("
|
||||
for i, origin := range corsOrigins {
|
||||
originTrimmed := strings.TrimSpace(origin)
|
||||
if len(originTrimmed) > 0 {
|
||||
builtOrigin := buildOriginRegex(originTrimmed)
|
||||
originsRegex += builtOrigin
|
||||
if i != len(corsOrigins)-1 {
|
||||
originsRegex = originsRegex + "|"
|
||||
originsRegex += "|"
|
||||
}
|
||||
}
|
||||
}
|
||||
originsRegex = originsRegex + ")$ ) { set $cors 'true'; }"
|
||||
originsRegex += ")$ ) { set $cors 'true'; }"
|
||||
return originsRegex
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@ import (
|
|||
func init() {
|
||||
// the default value of nginx.TemplatePath assumes the template exists in
|
||||
// the root filesystem and not in the rootfs directory
|
||||
path, err := filepath.Abs(filepath.Join("../../../../rootfs/", nginx.TemplatePath))
|
||||
absPath, err := filepath.Abs(filepath.Join("..", "..", "..", "..", "rootfs", nginx.TemplatePath))
|
||||
if err == nil {
|
||||
nginx.TemplatePath = path
|
||||
nginx.TemplatePath = absPath
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ var (
|
|||
Target string
|
||||
Location string
|
||||
ProxyPass string
|
||||
AutoHttpProxyPass string
|
||||
AutoHTTPProxyPass string
|
||||
Sticky bool
|
||||
XForwardedPrefix string
|
||||
SecureBackend bool
|
||||
|
|
@ -200,6 +200,12 @@ proxy_pass $scheme://upstream_balancer;`,
|
|||
}
|
||||
)
|
||||
|
||||
const (
|
||||
defaultBackend = "upstream-name"
|
||||
defaultHost = "example.com"
|
||||
fooAuthHost = "foo.com/auth"
|
||||
)
|
||||
|
||||
func getTestDataDir() (string, error) {
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
|
|
@ -326,9 +332,6 @@ func TestBuildLocation(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBuildProxyPass(t *testing.T) {
|
||||
defaultBackend := "upstream-name"
|
||||
defaultHost := "example.com"
|
||||
|
||||
for k, tc := range tmplFuncTestcases {
|
||||
loc := &ingress.Location{
|
||||
Path: tc.Path,
|
||||
|
|
@ -339,7 +342,7 @@ func TestBuildProxyPass(t *testing.T) {
|
|||
}
|
||||
|
||||
if tc.SecureBackend {
|
||||
loc.BackendProtocol = "HTTPS"
|
||||
loc.BackendProtocol = httpsProtocol
|
||||
}
|
||||
|
||||
backend := &ingress.Backend{
|
||||
|
|
@ -367,9 +370,6 @@ func TestBuildProxyPass(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBuildProxyPassAutoHttp(t *testing.T) {
|
||||
defaultBackend := "upstream-name"
|
||||
defaultHost := "example.com"
|
||||
|
||||
for k, tc := range tmplFuncTestcases {
|
||||
loc := &ingress.Location{
|
||||
Path: tc.Path,
|
||||
|
|
@ -379,9 +379,9 @@ func TestBuildProxyPassAutoHttp(t *testing.T) {
|
|||
}
|
||||
|
||||
if tc.SecureBackend {
|
||||
loc.BackendProtocol = "HTTPS"
|
||||
loc.BackendProtocol = httpsProtocol
|
||||
} else {
|
||||
loc.BackendProtocol = "AUTO_HTTP"
|
||||
loc.BackendProtocol = autoHTTPProtocol
|
||||
}
|
||||
|
||||
backend := &ingress.Backend{
|
||||
|
|
@ -402,7 +402,7 @@ func TestBuildProxyPassAutoHttp(t *testing.T) {
|
|||
backends := []*ingress.Backend{backend}
|
||||
|
||||
pp := buildProxyPass(defaultHost, backends, loc)
|
||||
if !strings.EqualFold(tc.AutoHttpProxyPass, pp) {
|
||||
if !strings.EqualFold(tc.AutoHTTPProxyPass, pp) {
|
||||
t.Errorf("%s: expected \n'%v'\nbut returned \n'%v'", k, tc.ProxyPass, pp)
|
||||
}
|
||||
}
|
||||
|
|
@ -417,7 +417,7 @@ func TestBuildAuthLocation(t *testing.T) {
|
|||
t.Errorf("Expected '%v' but returned '%v'", expected, actual)
|
||||
}
|
||||
|
||||
authURL := "foo.com/auth"
|
||||
authURL := fooAuthHost
|
||||
globalAuthURL := "foo.com/global-auth"
|
||||
|
||||
loc := &ingress.Location{
|
||||
|
|
@ -428,7 +428,7 @@ func TestBuildAuthLocation(t *testing.T) {
|
|||
EnableGlobalAuth: true,
|
||||
}
|
||||
|
||||
encodedAuthURL := strings.Replace(base64.URLEncoding.EncodeToString([]byte(loc.Path)), "=", "", -1)
|
||||
encodedAuthURL := strings.ReplaceAll(base64.URLEncoding.EncodeToString([]byte(loc.Path)), "=", "")
|
||||
externalAuthPath := fmt.Sprintf("/_external-auth-%v-default", encodedAuthURL)
|
||||
|
||||
testCases := []struct {
|
||||
|
|
@ -460,8 +460,7 @@ func TestBuildAuthLocation(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestShouldApplyGlobalAuth(t *testing.T) {
|
||||
|
||||
authURL := "foo.com/auth"
|
||||
authURL := fooAuthHost
|
||||
globalAuthURL := "foo.com/global-auth"
|
||||
|
||||
loc := &ingress.Location{
|
||||
|
|
@ -579,12 +578,12 @@ func TestBuildAuthUpstreamName(t *testing.T) {
|
|||
|
||||
loc := &ingress.Location{
|
||||
ExternalAuth: authreq.Config{
|
||||
URL: "foo.com/auth",
|
||||
URL: fooAuthHost,
|
||||
},
|
||||
Path: "/cat",
|
||||
}
|
||||
|
||||
encodedAuthURL := strings.Replace(base64.URLEncoding.EncodeToString([]byte(loc.Path)), "=", "", -1)
|
||||
encodedAuthURL := strings.ReplaceAll(base64.URLEncoding.EncodeToString([]byte(loc.Path)), "=", "")
|
||||
externalAuthPath := fmt.Sprintf("external-auth-%v-default", encodedAuthURL)
|
||||
|
||||
testCases := []struct {
|
||||
|
|
@ -606,7 +605,7 @@ func TestBuildAuthUpstreamName(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestShouldApplyAuthUpstream(t *testing.T) {
|
||||
authURL := "foo.com/auth"
|
||||
authURL := fooAuthHost
|
||||
|
||||
loc := &ingress.Location{
|
||||
ExternalAuth: authreq.Config{
|
||||
|
|
@ -702,7 +701,10 @@ func TestChangeHostPort(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTemplateWithData(t *testing.T) {
|
||||
pwd, _ := os.Getwd()
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
f, err := os.Open(path.Join(pwd, "../../../../test/data/config.json"))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error reading json file: %v", err)
|
||||
|
|
@ -727,7 +729,7 @@ func TestTemplateWithData(t *testing.T) {
|
|||
|
||||
dat.Cfg.DefaultSSLCertificate = &ingress.SSLCert{}
|
||||
|
||||
rt, err := ngxTpl.Write(dat)
|
||||
rt, err := ngxTpl.Write(&dat)
|
||||
if err != nil {
|
||||
t.Errorf("invalid NGINX template: %v", err)
|
||||
}
|
||||
|
|
@ -746,7 +748,10 @@ func TestTemplateWithData(t *testing.T) {
|
|||
}
|
||||
|
||||
func BenchmarkTemplateWithData(b *testing.B) {
|
||||
pwd, _ := os.Getwd()
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
b.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
f, err := os.Open(path.Join(pwd, "../../../../test/data/config.json"))
|
||||
if err != nil {
|
||||
b.Errorf("unexpected error reading json file: %v", err)
|
||||
|
|
@ -767,7 +772,7 @@ func BenchmarkTemplateWithData(b *testing.B) {
|
|||
}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := ngxTpl.Write(dat); err != nil {
|
||||
if _, err := ngxTpl.Write(&dat); err != nil {
|
||||
b.Errorf("unexpected error writing template: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -1066,9 +1071,6 @@ func TestBuildUpstreamName(t *testing.T) {
|
|||
t.Errorf("Expected '%v' but returned '%v'", expected, actual)
|
||||
}
|
||||
|
||||
defaultBackend := "upstream-name"
|
||||
defaultHost := "example.com"
|
||||
|
||||
for k, tc := range tmplFuncTestcases {
|
||||
loc := &ingress.Location{
|
||||
Path: tc.Path,
|
||||
|
|
@ -1079,7 +1081,7 @@ func TestBuildUpstreamName(t *testing.T) {
|
|||
}
|
||||
|
||||
if tc.SecureBackend {
|
||||
loc.BackendProtocol = "HTTPS"
|
||||
loc.BackendProtocol = httpsProtocol
|
||||
}
|
||||
|
||||
backend := &ingress.Backend{
|
||||
|
|
@ -1134,13 +1136,13 @@ func TestEscapeLiteralDollar(t *testing.T) {
|
|||
|
||||
func TestOpentracingPropagateContext(t *testing.T) {
|
||||
tests := map[*ingress.Location]string{
|
||||
{BackendProtocol: "HTTP"}: "opentracing_propagate_context;",
|
||||
{BackendProtocol: "HTTPS"}: "opentracing_propagate_context;",
|
||||
{BackendProtocol: "AUTO_HTTP"}: "opentracing_propagate_context;",
|
||||
{BackendProtocol: "GRPC"}: "opentracing_grpc_propagate_context;",
|
||||
{BackendProtocol: "GRPCS"}: "opentracing_grpc_propagate_context;",
|
||||
{BackendProtocol: "FCGI"}: "opentracing_propagate_context;",
|
||||
nil: "",
|
||||
{BackendProtocol: httpProtocol}: "opentracing_propagate_context;",
|
||||
{BackendProtocol: httpsProtocol}: "opentracing_propagate_context;",
|
||||
{BackendProtocol: autoHTTPProtocol}: "opentracing_propagate_context;",
|
||||
{BackendProtocol: grpcProtocol}: "opentracing_grpc_propagate_context;",
|
||||
{BackendProtocol: grpcsProtocol}: "opentracing_grpc_propagate_context;",
|
||||
{BackendProtocol: fcgiProtocol}: "opentracing_propagate_context;",
|
||||
nil: "",
|
||||
}
|
||||
|
||||
for loc, expectedDirective := range tests {
|
||||
|
|
@ -1153,13 +1155,13 @@ func TestOpentracingPropagateContext(t *testing.T) {
|
|||
|
||||
func TestOpentelemetryPropagateContext(t *testing.T) {
|
||||
tests := map[*ingress.Location]string{
|
||||
{BackendProtocol: "HTTP"}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: "HTTPS"}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: "AUTO_HTTP"}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: "GRPC"}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: "GRPCS"}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: "FCGI"}: "opentelemetry_propagate;",
|
||||
nil: "",
|
||||
{BackendProtocol: httpProtocol}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: httpsProtocol}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: autoHTTPProtocol}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: grpcProtocol}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: grpcsProtocol}: "opentelemetry_propagate;",
|
||||
{BackendProtocol: fcgiProtocol}: "opentelemetry_propagate;",
|
||||
nil: "",
|
||||
}
|
||||
|
||||
for loc, expectedDirective := range tests {
|
||||
|
|
@ -1171,7 +1173,6 @@ func TestOpentelemetryPropagateContext(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetIngressInformation(t *testing.T) {
|
||||
|
||||
testcases := map[string]struct {
|
||||
Ingress interface{}
|
||||
Host string
|
||||
|
|
@ -1625,7 +1626,7 @@ func TestProxySetHeader(t *testing.T) {
|
|||
{
|
||||
name: "gRPC backend",
|
||||
loc: &ingress.Location{
|
||||
BackendProtocol: "GRPC",
|
||||
BackendProtocol: grpcProtocol,
|
||||
},
|
||||
expected: "grpc_set_header",
|
||||
},
|
||||
|
|
@ -1716,7 +1717,6 @@ func TestBuildOpenTracing(t *testing.T) {
|
|||
if expected != actual {
|
||||
t.Errorf("Expected '%v' but returned '%v'", expected, actual)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestBuildOpenTelemetry(t *testing.T) {
|
||||
|
|
@ -1777,6 +1777,7 @@ func TestEnforceRegexModifier(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
func TestShouldLoadModSecurityModule(t *testing.T) {
|
||||
// ### Invalid argument type tests ###
|
||||
// The first tests should return false.
|
||||
|
|
@ -1877,6 +1878,7 @@ opentracing_trust_incoming_span off;`
|
|||
}
|
||||
}
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
func TestShouldLoadOpentracingModule(t *testing.T) {
|
||||
// ### Invalid argument type tests ###
|
||||
// The first tests should return false.
|
||||
|
|
@ -1978,6 +1980,7 @@ opentelemetry_trust_incoming_spans off;`
|
|||
}
|
||||
}
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
func TestShouldLoadOpentelemetryModule(t *testing.T) {
|
||||
// ### Invalid argument type tests ###
|
||||
// The first tests should return false.
|
||||
|
|
@ -2104,7 +2107,6 @@ func TestModSecurityForLocation(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBuildServerName(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
title string
|
||||
hostname string
|
||||
|
|
|
|||
|
|
@ -135,11 +135,13 @@ func (nc NginxCommand) ExecCommand(args ...string) *exec.Cmd {
|
|||
|
||||
cmdArgs = append(cmdArgs, "-c", cfgPath)
|
||||
cmdArgs = append(cmdArgs, args...)
|
||||
//nolint:gosec // Ignore G204 error
|
||||
return exec.Command(nc.Binary, cmdArgs...)
|
||||
}
|
||||
|
||||
// Test checks if config file is a syntax valid nginx configuration
|
||||
func (nc NginxCommand) Test(cfg string) ([]byte, error) {
|
||||
//nolint:gosec // Ignore G204 error
|
||||
return exec.Command(nc.Binary, "-c", cfg, "-t").CombinedOutput()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue