Merge remote-tracking branch 'upstream/master' into fix/collect-metrics-if-metrics-per-host-false
This commit is contained in:
commit
ef75a2d6fc
1311 changed files with 40786 additions and 85757 deletions
|
|
@ -17,9 +17,8 @@ limitations under the License.
|
|||
package class
|
||||
|
||||
import (
|
||||
"k8s.io/klog"
|
||||
|
||||
networking "k8s.io/api/networking/v1beta1"
|
||||
"k8s.io/ingress-nginx/internal/k8s"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -39,25 +38,30 @@ var (
|
|||
IngressClass = "nginx"
|
||||
)
|
||||
|
||||
// IsValid returns true if the given Ingress either doesn't specify
|
||||
// the ingress.class annotation, or it's set to the configured in the
|
||||
// ingress controller.
|
||||
// IsValid returns true if the given Ingress specify the ingress.class
|
||||
// annotation or IngressClassName resource for Kubernetes >= v1.18
|
||||
func IsValid(ing *networking.Ingress) bool {
|
||||
// 1. with annotation
|
||||
ingress, ok := ing.GetAnnotations()[IngressKey]
|
||||
if !ok {
|
||||
klog.V(3).Infof("annotation %v is not present in ingress %v/%v", IngressKey, ing.Namespace, ing.Name)
|
||||
if ok {
|
||||
// empty annotation and same annotation on ingress
|
||||
if ingress == "" && IngressClass == DefaultClass {
|
||||
return true
|
||||
}
|
||||
|
||||
return ingress == IngressClass
|
||||
}
|
||||
|
||||
// we have 2 valid combinations
|
||||
// 1 - ingress with default class | blank annotation on ingress
|
||||
// 2 - ingress with specific class | same annotation on ingress
|
||||
//
|
||||
// and 2 invalid combinations
|
||||
// 3 - ingress with default class | fixed annotation on ingress
|
||||
// 4 - ingress with specific class | different annotation on ingress
|
||||
if ingress == "" && IngressClass == DefaultClass {
|
||||
return true
|
||||
// 2. k8s < v1.18. Check default annotation
|
||||
if !k8s.IsIngressV1Ready {
|
||||
return IngressClass == DefaultClass
|
||||
}
|
||||
|
||||
return ingress == IngressClass
|
||||
// 3. without annotation and IngressClass. Check default annotation
|
||||
if k8s.IngressClass == nil {
|
||||
return IngressClass == DefaultClass
|
||||
}
|
||||
|
||||
// 4. with IngressClass
|
||||
return k8s.IngressClass.Name == *ing.Spec.IngressClassName
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
// Config contains ModSecurity Configuration items
|
||||
type Config struct {
|
||||
Enable bool `json:"enable-modsecurity"`
|
||||
EnableSet bool `json:"enable-modsecurity-set"`
|
||||
OWASPRules bool `json:"enable-owasp-core-rules"`
|
||||
TransactionID string `json:"modsecurity-transaction-id"`
|
||||
Snippet string `json:"modsecurity-snippet"`
|
||||
|
|
@ -41,6 +42,9 @@ func (modsec1 *Config) Equal(modsec2 *Config) bool {
|
|||
if modsec1.Enable != modsec2.Enable {
|
||||
return false
|
||||
}
|
||||
if modsec1.EnableSet != modsec2.EnableSet {
|
||||
return false
|
||||
}
|
||||
if modsec1.OWASPRules != modsec2.OWASPRules {
|
||||
return false
|
||||
}
|
||||
|
|
@ -69,9 +73,11 @@ func (a modSecurity) Parse(ing *networking.Ingress) (interface{}, error) {
|
|||
var err error
|
||||
config := &Config{}
|
||||
|
||||
config.EnableSet = true
|
||||
config.Enable, err = parser.GetBoolAnnotation("enable-modsecurity", ing)
|
||||
if err != nil {
|
||||
config.Enable = false
|
||||
config.EnableSet = false
|
||||
}
|
||||
|
||||
config.OWASPRules, err = parser.GetBoolAnnotation("enable-owasp-core-rules", ing)
|
||||
|
|
|
|||
|
|
@ -41,22 +41,22 @@ func TestParse(t *testing.T) {
|
|||
annotations map[string]string
|
||||
expected Config
|
||||
}{
|
||||
{map[string]string{enable: "true"}, Config{true, false, "", ""}},
|
||||
{map[string]string{enable: "false"}, Config{false, false, "", ""}},
|
||||
{map[string]string{enable: ""}, Config{false, false, "", ""}},
|
||||
{map[string]string{enable: "true"}, Config{true, true, false, "", ""}},
|
||||
{map[string]string{enable: "false"}, Config{false, true, false, "", ""}},
|
||||
{map[string]string{enable: ""}, Config{false, false, false, "", ""}},
|
||||
|
||||
{map[string]string{owasp: "true"}, Config{false, true, "", ""}},
|
||||
{map[string]string{owasp: "false"}, Config{false, false, "", ""}},
|
||||
{map[string]string{owasp: ""}, Config{false, false, "", ""}},
|
||||
{map[string]string{owasp: "true"}, Config{false, false, true, "", ""}},
|
||||
{map[string]string{owasp: "false"}, Config{false, false, false, "", ""}},
|
||||
{map[string]string{owasp: ""}, Config{false, false, false, "", ""}},
|
||||
|
||||
{map[string]string{transID: "ok"}, Config{false, false, "ok", ""}},
|
||||
{map[string]string{transID: ""}, Config{false, false, "", ""}},
|
||||
{map[string]string{transID: "ok"}, Config{false, false, false, "ok", ""}},
|
||||
{map[string]string{transID: ""}, Config{false, false, false, "", ""}},
|
||||
|
||||
{map[string]string{snippet: "ModSecurity Rule"}, Config{false, false, "", "ModSecurity Rule"}},
|
||||
{map[string]string{snippet: ""}, Config{false, false, "", ""}},
|
||||
{map[string]string{snippet: "ModSecurity Rule"}, Config{false, false, false, "", "ModSecurity Rule"}},
|
||||
{map[string]string{snippet: ""}, Config{false, false, false, "", ""}},
|
||||
|
||||
{map[string]string{}, Config{false, false, "", ""}},
|
||||
{nil, Config{false, false, "", ""}},
|
||||
{map[string]string{}, Config{false, false, false, "", ""}},
|
||||
{nil, Config{false, false, false, "", ""}},
|
||||
}
|
||||
|
||||
ing := &networking.Ingress{
|
||||
|
|
|
|||
|
|
@ -17,9 +17,13 @@ limitations under the License.
|
|||
package rewrite
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
networking "k8s.io/api/networking/v1beta1"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||
"k8s.io/ingress-nginx/internal/ingress/errors"
|
||||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||
)
|
||||
|
||||
|
|
@ -90,8 +94,29 @@ func (a rewrite) Parse(ing *networking.Ingress) (interface{}, error) {
|
|||
config.ForceSSLRedirect = a.r.GetDefaultBackend().ForceSSLRedirect
|
||||
}
|
||||
|
||||
config.AppRoot, _ = parser.GetStringAnnotation("app-root", ing)
|
||||
config.UseRegex, _ = parser.GetBoolAnnotation("use-regex", ing)
|
||||
|
||||
config.AppRoot, err = parser.GetStringAnnotation("app-root", ing)
|
||||
if err != nil {
|
||||
if !errors.IsMissingAnnotations(err) && !errors.IsInvalidContent(err) {
|
||||
klog.Warningf("Annotation app-root contains an invalid value: %v", err)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
u, err := url.ParseRequestURI(config.AppRoot)
|
||||
if err != nil {
|
||||
klog.Warningf("Annotation app-root contains an invalid value: %v", err)
|
||||
config.AppRoot = ""
|
||||
return config, nil
|
||||
}
|
||||
|
||||
if u.IsAbs() {
|
||||
klog.Warningf("Annotation app-root only allows absolute paths (%v)", config.AppRoot)
|
||||
config.AppRoot = ""
|
||||
return config, nil
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,9 @@ func buildIngress() *networking.Ingress {
|
|||
|
||||
return &networking.Ingress{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Annotations: map[string]string{},
|
||||
},
|
||||
Spec: networking.IngressSpec{
|
||||
Backend: &networking.IngressBackend{
|
||||
|
|
@ -163,19 +164,42 @@ func TestForceSSLRedirect(t *testing.T) {
|
|||
}
|
||||
}
|
||||
func TestAppRoot(t *testing.T) {
|
||||
ing := buildIngress()
|
||||
ap := NewParser(mockBackend{redirect: true})
|
||||
|
||||
data := map[string]string{}
|
||||
data[parser.GetAnnotationWithPrefix("app-root")] = "/app1"
|
||||
ing.SetAnnotations(data)
|
||||
|
||||
i, _ := NewParser(mockBackend{redirect: true}).Parse(ing)
|
||||
redirect, ok := i.(*Config)
|
||||
if !ok {
|
||||
t.Errorf("expected a App Context")
|
||||
testCases := []struct {
|
||||
title string
|
||||
path string
|
||||
expected string
|
||||
errExpected bool
|
||||
}{
|
||||
{"Empty path should return an error", "", "", true},
|
||||
{"Relative paths are not allowed", "demo", "", true},
|
||||
{"Path / should pass", "/", "/", false},
|
||||
{"Path /demo should pass", "/demo", "/demo", false},
|
||||
}
|
||||
if redirect.AppRoot != "/app1" {
|
||||
t.Errorf("Unexpected value got in AppRoot")
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.title, func(t *testing.T) {
|
||||
ing := buildIngress()
|
||||
ing.Annotations[parser.GetAnnotationWithPrefix("app-root")] = testCase.path
|
||||
i, err := ap.Parse(ing)
|
||||
if err != nil {
|
||||
if testCase.errExpected {
|
||||
return
|
||||
}
|
||||
|
||||
t.Fatalf("%v: unexpected error obtaining running address/es: %v", testCase.title, err)
|
||||
}
|
||||
|
||||
rewrite, ok := i.(*Config)
|
||||
if !ok {
|
||||
t.Fatalf("expected a rewrite Config")
|
||||
}
|
||||
|
||||
if testCase.expected != rewrite.AppRoot {
|
||||
t.Fatalf("%v: expected AppRoot with value %v but was returned: %v", testCase.title, testCase.expected, rewrite.AppRoot)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,10 @@ type Configuration struct {
|
|||
// By default this is disabled
|
||||
EnableModsecurity bool `json:"enable-modsecurity"`
|
||||
|
||||
// EnableOCSP enables the OCSP support in SSL connections
|
||||
// By default this is disabled
|
||||
EnableOCSP bool `json:"enable-ocsp"`
|
||||
|
||||
// EnableOWASPCoreRules enables the OWASP ModSecurity Core Rule Set (CRS)
|
||||
// By default this is disabled
|
||||
EnableOWASPCoreRules bool `json:"enable-owasp-modsecurity-crs"`
|
||||
|
|
@ -268,6 +272,11 @@ type Configuration struct {
|
|||
NginxStatusIpv4Whitelist []string `json:"nginx-status-ipv4-whitelist,omitempty"`
|
||||
NginxStatusIpv6Whitelist []string `json:"nginx-status-ipv6-whitelist,omitempty"`
|
||||
|
||||
// Plugins configures plugins to use placed in the directory /etc/nginx/lua/plugins.
|
||||
// Every plugin has to have main.lua in the root. Every plugin has to bundle all of its dependencies.
|
||||
// The execution order follows the definition.
|
||||
Plugins []string `json:"plugins,omitempty"`
|
||||
|
||||
// If UseProxyProtocol is enabled ProxyRealIPCIDR defines the default the IP/network address
|
||||
// of your external load balancer
|
||||
ProxyRealIPCIDR []string `json:"proxy-real-ip-cidr,omitempty"`
|
||||
|
|
@ -826,6 +835,7 @@ type TemplateConfig struct {
|
|||
ListenPorts *ListenPorts
|
||||
PublishService *apiv1.Service
|
||||
EnableMetrics bool
|
||||
MaxmindEditionFiles []string
|
||||
|
||||
PID string
|
||||
StatusPath string
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/mitchellh/hashstructure"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
networking "k8s.io/api/networking/v1beta1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
|
@ -98,7 +99,8 @@ type Configuration struct {
|
|||
ValidationWebhookCertPath string
|
||||
ValidationWebhookKeyPath string
|
||||
|
||||
GlobalExternalAuth *ngx_config.GlobalExternalAuth
|
||||
GlobalExternalAuth *ngx_config.GlobalExternalAuth
|
||||
MaxmindEditionFiles []string
|
||||
}
|
||||
|
||||
// GetPublishService returns the Service used to set the load-balancer status of Ingresses.
|
||||
|
|
@ -197,23 +199,18 @@ func (n *NGINXController) syncIngress(interface{}) error {
|
|||
// CheckIngress returns an error in case the provided ingress, when added
|
||||
// to the current configuration, generates an invalid configuration
|
||||
func (n *NGINXController) CheckIngress(ing *networking.Ingress) error {
|
||||
//TODO: this is wrong
|
||||
if n == nil {
|
||||
return fmt.Errorf("cannot check ingress on a nil ingress controller")
|
||||
}
|
||||
|
||||
if ing == nil {
|
||||
// no ingress to add, no state change
|
||||
return nil
|
||||
}
|
||||
|
||||
if !class.IsValid(ing) {
|
||||
klog.Infof("ignoring ingress %v in %v based on annotation %v", ing.Name, ing.ObjectMeta.Namespace, class.IngressKey)
|
||||
klog.Warningf("ignoring ingress %v in %v based on annotation %v", ing.Name, ing.ObjectMeta.Namespace, class.IngressKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
if n.cfg.Namespace != "" && ing.ObjectMeta.Namespace != n.cfg.Namespace {
|
||||
klog.Infof("ignoring ingress %v in namespace %v different from the namespace watched %s", ing.Name, ing.ObjectMeta.Namespace, n.cfg.Namespace)
|
||||
klog.Warningf("ignoring ingress %v in namespace %v different from the namespace watched %s", ing.Name, ing.ObjectMeta.Namespace, n.cfg.Namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -222,6 +219,8 @@ func (n *NGINXController) CheckIngress(ing *networking.Ingress) error {
|
|||
toCheck.ObjectMeta.Name == ing.ObjectMeta.Name
|
||||
}
|
||||
|
||||
k8s.SetDefaultNGINXPathType(ing)
|
||||
|
||||
ings := n.store.ListIngresses(filter)
|
||||
ings = append(ings, &ingress.Ingress{
|
||||
Ingress: *ing,
|
||||
|
|
@ -530,6 +529,12 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in
|
|||
addLoc := true
|
||||
for _, loc := range server.Locations {
|
||||
if loc.Path == nginxPath {
|
||||
// Same paths but different types are allowed
|
||||
// (same type means overlap in the path definition)
|
||||
if !apiequality.Semantic.DeepEqual(loc.PathType, path.PathType) {
|
||||
break
|
||||
}
|
||||
|
||||
addLoc = false
|
||||
|
||||
if !loc.IsDefBackend {
|
||||
|
|
@ -546,6 +551,7 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in
|
|||
loc.Port = ups.Port
|
||||
loc.Service = ups.Service
|
||||
loc.Ingress = ing
|
||||
|
||||
locationApplyAnnotations(loc, anns)
|
||||
|
||||
if loc.Redirect.FromToWWW {
|
||||
|
|
@ -559,9 +565,9 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in
|
|||
if addLoc {
|
||||
klog.V(3).Infof("Adding location %q for server %q with upstream %q (Ingress %q)",
|
||||
nginxPath, server.Hostname, ups.Name, ingKey)
|
||||
|
||||
loc := &ingress.Location{
|
||||
Path: nginxPath,
|
||||
PathType: path.PathType,
|
||||
Backend: ups.Name,
|
||||
IsDefBackend: false,
|
||||
Service: ups.Service,
|
||||
|
|
@ -956,12 +962,14 @@ func (n *NGINXController) createServers(data []*ingress.Ingress,
|
|||
}
|
||||
|
||||
// initialize default server and root location
|
||||
pathTypePrefix := networking.PathTypePrefix
|
||||
servers[defServerName] = &ingress.Server{
|
||||
Hostname: defServerName,
|
||||
SSLCert: n.getDefaultSSLCertificate(),
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: rootLocation,
|
||||
PathType: &pathTypePrefix,
|
||||
IsDefBackend: true,
|
||||
Backend: du.Name,
|
||||
Proxy: ngxProxy,
|
||||
|
|
@ -1028,8 +1036,10 @@ func (n *NGINXController) createServers(data []*ingress.Ingress,
|
|||
continue
|
||||
}
|
||||
|
||||
pathTypePrefix := networking.PathTypePrefix
|
||||
loc := &ingress.Location{
|
||||
Path: rootLocation,
|
||||
PathType: &pathTypePrefix,
|
||||
IsDefBackend: true,
|
||||
Backend: un,
|
||||
Service: &apiv1.Service{},
|
||||
|
|
@ -1065,7 +1075,7 @@ func (n *NGINXController) createServers(data []*ingress.Ingress,
|
|||
|
||||
if len(servers[host].Aliases) == 0 {
|
||||
servers[host].Aliases = anns.Aliases
|
||||
if _, ok := allAliases[host]; !ok {
|
||||
if aliases := allAliases[host]; len(aliases) == 0 {
|
||||
allAliases[host] = anns.Aliases
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1314,7 +1324,7 @@ func mergeAlternativeBackends(ing *ingress.Ingress, upstreams map[string]*ingres
|
|||
break
|
||||
}
|
||||
|
||||
if canMergeBackend(priUps, altUps) && loc.Path == path.Path {
|
||||
if canMergeBackend(priUps, altUps) && loc.Path == path.Path && *loc.PathType == *path.PathType {
|
||||
klog.V(2).Infof("matching backend %v found for alternative backend %v",
|
||||
priUps.Name, altUps.Name)
|
||||
|
||||
|
|
@ -1340,9 +1350,12 @@ func extractTLSSecretName(host string, ing *ingress.Ingress,
|
|||
}
|
||||
|
||||
// naively return Secret name from TLS spec if host name matches
|
||||
lowercaseHost := toLowerCaseASCII(host)
|
||||
for _, tls := range ing.Spec.TLS {
|
||||
if sets.NewString(tls.Hosts...).Has(host) {
|
||||
return tls.SecretName
|
||||
for _, tlsHost := range tls.Hosts {
|
||||
if toLowerCaseASCII(tlsHost) == lowercaseHost {
|
||||
return tls.SecretName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
|
|
@ -256,6 +257,8 @@ func TestCheckIngress(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
var pathPrefix = networking.PathTypePrefix
|
||||
|
||||
func TestMergeAlternativeBackends(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
ingress *ingress.Ingress
|
||||
|
|
@ -278,7 +281,8 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-canary",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -313,8 +317,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "example.com",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "example-http-svc-80",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "example-http-svc-80",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -338,8 +343,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "example.com",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "example-http-svc-80",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "example-http-svc-80",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -359,7 +365,8 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "foo-http-svc-canary",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -378,7 +385,8 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-canary",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -425,8 +433,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "foo.bar",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "example-foo-http-svc-80",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "example-foo-http-svc-80",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -434,8 +443,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "example.com",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "example-http-svc-80",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "example-http-svc-80",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -471,8 +481,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "example.com",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "example-http-svc-80",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "example-http-svc-80",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -492,7 +503,8 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-canary",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -556,8 +568,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "_",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "example-http-svc-80",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "example-http-svc-80",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -581,8 +594,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "_",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "example-http-svc-80",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "example-http-svc-80",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -622,8 +636,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "_",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "upstream-default-backend",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "upstream-default-backend",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -634,8 +649,9 @@ func TestMergeAlternativeBackends(t *testing.T) {
|
|||
Hostname: "_",
|
||||
Locations: []*ingress.Location{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: "upstream-default-backend",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: "upstream-default-backend",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -802,6 +818,33 @@ func TestExtractTLSSecretName(t *testing.T) {
|
|||
},
|
||||
"demo",
|
||||
},
|
||||
"ingress tls, hosts, matching cert cn, uppercase host": {
|
||||
"FOO.BAR",
|
||||
&ingress.Ingress{
|
||||
Ingress: networking.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
},
|
||||
Spec: networking.IngressSpec{
|
||||
TLS: []networking.IngressTLS{
|
||||
{
|
||||
Hosts: []string{"foo.bar", "example.com"},
|
||||
SecretName: "demo",
|
||||
},
|
||||
},
|
||||
Rules: []networking.IngressRule{
|
||||
{
|
||||
Host: "foo.bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
func(string) (*ingress.SSLCert, error) {
|
||||
return nil, nil
|
||||
},
|
||||
"demo",
|
||||
},
|
||||
}
|
||||
|
||||
for title, tc := range testCases {
|
||||
|
|
@ -942,7 +985,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-canary",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1001,7 +1045,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1037,7 +1082,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Path: "/",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-canary",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1105,7 +1151,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/a",
|
||||
Path: "/a",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-1",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1141,7 +1188,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/a",
|
||||
Path: "/a",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-2",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1177,7 +1225,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/b",
|
||||
Path: "/b",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-2",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1213,7 +1262,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/b",
|
||||
Path: "/b",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-1",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1249,7 +1299,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/c",
|
||||
Path: "/c",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-1",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1285,7 +1336,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/c",
|
||||
Path: "/c",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "http-svc-2",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1369,7 +1421,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/path1",
|
||||
Path: "/path1",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "path1-svc",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1408,7 +1461,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/path2",
|
||||
Path: "/path2",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "path2-svc",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1472,7 +1526,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/path1",
|
||||
Path: "/path1",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "path1-svc",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1511,7 +1566,8 @@ func TestGetBackendServers(t *testing.T) {
|
|||
HTTP: &networking.HTTPIngressRuleValue{
|
||||
Paths: []networking.HTTPIngressPath{
|
||||
{
|
||||
Path: "/path2",
|
||||
Path: "/path2",
|
||||
PathType: &pathPrefix,
|
||||
Backend: networking.IngressBackend{
|
||||
ServiceName: "path2-svc",
|
||||
ServicePort: intstr.IntOrString{
|
||||
|
|
@ -1606,7 +1662,7 @@ func newNGINXController(t *testing.T) *NGINXController {
|
|||
},
|
||||
}
|
||||
|
||||
_, err := clientSet.CoreV1().ConfigMaps(ns).Create(configMap)
|
||||
_, err := clientSet.CoreV1().ConfigMaps(ns).Create(context.TODO(), configMap, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating the configuration map: %v", err)
|
||||
}
|
||||
|
|
@ -1662,7 +1718,7 @@ func newDynamicNginxController(t *testing.T, setConfigMap func(string) *v1.Confi
|
|||
clientSet := fake.NewSimpleClientset()
|
||||
configMap := setConfigMap(ns)
|
||||
|
||||
_, err := clientSet.CoreV1().ConfigMaps(ns).Create(configMap)
|
||||
_, err := clientSet.CoreV1().ConfigMaps(ns).Create(context.TODO(), configMap, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating the configuration map: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -615,12 +615,12 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC
|
|||
ListenPorts: n.cfg.ListenPorts,
|
||||
PublishService: n.GetPublishService(),
|
||||
EnableMetrics: n.cfg.EnableMetrics,
|
||||
|
||||
HealthzURI: nginx.HealthPath,
|
||||
PID: nginx.PID,
|
||||
StatusPath: nginx.StatusPath,
|
||||
StatusPort: nginx.StatusPort,
|
||||
StreamPort: nginx.StreamPort,
|
||||
MaxmindEditionFiles: n.cfg.MaxmindEditionFiles,
|
||||
HealthzURI: nginx.HealthPath,
|
||||
PID: nginx.PID,
|
||||
StatusPath: nginx.StatusPath,
|
||||
StatusPort: nginx.StatusPort,
|
||||
StreamPort: nginx.StreamPort,
|
||||
}
|
||||
|
||||
tc.Cfg.Checksum = ingressCfg.ConfigurationChecksum
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
|
@ -25,8 +26,6 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
"github.com/eapache/channels"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
|
|
@ -35,6 +34,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
k8sruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/informers"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
|
|
@ -42,6 +42,7 @@ import (
|
|||
clientcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/file"
|
||||
"k8s.io/ingress-nginx/internal/ingress"
|
||||
|
|
@ -290,11 +291,11 @@ func New(
|
|||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (k8sruntime.Object, error) {
|
||||
options.LabelSelector = labelSelector.String()
|
||||
return client.CoreV1().Pods(store.pod.Namespace).List(options)
|
||||
return client.CoreV1().Pods(store.pod.Namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
options.LabelSelector = labelSelector.String()
|
||||
return client.CoreV1().Pods(store.pod.Namespace).Watch(options)
|
||||
return client.CoreV1().Pods(store.pod.Namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&corev1.Pod{},
|
||||
|
|
@ -614,16 +615,32 @@ func New(
|
|||
},
|
||||
}
|
||||
|
||||
serviceHandler := cache.ResourceEventHandlerFuncs{
|
||||
UpdateFunc: func(old, cur interface{}) {
|
||||
oldSvc := old.(*corev1.Service)
|
||||
curSvc := cur.(*corev1.Service)
|
||||
|
||||
if reflect.DeepEqual(oldSvc, curSvc) {
|
||||
return
|
||||
}
|
||||
|
||||
updateCh.In() <- Event{
|
||||
Type: UpdateEvent,
|
||||
Obj: cur,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
store.informers.Ingress.AddEventHandler(ingEventHandler)
|
||||
store.informers.Endpoint.AddEventHandler(epEventHandler)
|
||||
store.informers.Secret.AddEventHandler(secrEventHandler)
|
||||
store.informers.ConfigMap.AddEventHandler(cmEventHandler)
|
||||
store.informers.Service.AddEventHandler(cache.ResourceEventHandlerFuncs{})
|
||||
store.informers.Service.AddEventHandler(serviceHandler)
|
||||
store.informers.Pod.AddEventHandler(podEventHandler)
|
||||
|
||||
// do not wait for informers to read the configmap configuration
|
||||
ns, name, _ := k8s.ParseNameNS(configmap)
|
||||
cm, err := client.CoreV1().ConfigMaps(ns).Get(name, metav1.GetOptions{})
|
||||
cm, err := client.CoreV1().ConfigMaps(ns).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
klog.Warningf("Unexpected error reading configuration configmap: %v", err)
|
||||
}
|
||||
|
|
@ -638,6 +655,9 @@ func isCatchAllIngress(spec networkingv1beta1.IngressSpec) bool {
|
|||
return spec.Backend != nil && len(spec.Rules) == 0
|
||||
}
|
||||
|
||||
// Default path type is Prefix to not break existing definitions
|
||||
var defaultPathType = networkingv1beta1.PathTypePrefix
|
||||
|
||||
// syncIngress parses ingress annotations converting the value of the
|
||||
// annotation to a go struct
|
||||
func (s *k8sStore) syncIngress(ing *networkingv1beta1.Ingress) {
|
||||
|
|
@ -661,6 +681,8 @@ func (s *k8sStore) syncIngress(ing *networkingv1beta1.Ingress) {
|
|||
}
|
||||
}
|
||||
|
||||
k8s.SetDefaultNGINXPathType(copyIng)
|
||||
|
||||
err := s.listers.IngressWithAnnotation.Update(&ingress.Ingress{
|
||||
Ingress: *copyIng,
|
||||
ParsedAnnotations: s.annotations.Extract(ing),
|
||||
|
|
@ -924,8 +946,8 @@ func (s k8sStore) GetRunningControllerPodsCount() int {
|
|||
var runtimeScheme = k8sruntime.NewScheme()
|
||||
|
||||
func init() {
|
||||
extensionsv1beta1.AddToScheme(runtimeScheme)
|
||||
networkingv1beta1.AddToScheme(runtimeScheme)
|
||||
utilruntime.Must(extensionsv1beta1.AddToScheme(runtimeScheme))
|
||||
utilruntime.Must(networkingv1beta1.AddToScheme(runtimeScheme))
|
||||
}
|
||||
|
||||
func fromExtensions(old *extensionsv1beta1.Ingress) (*networkingv1beta1.Ingress, error) {
|
||||
|
|
@ -948,10 +970,12 @@ func toIngress(obj interface{}) (*networkingv1beta1.Ingress, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
k8s.SetDefaultNGINXPathType(ing)
|
||||
return ing, true
|
||||
}
|
||||
|
||||
if ing, ok := obj.(*networkingv1beta1.Ingress); ok {
|
||||
k8s.SetDefaultNGINXPathType(ing)
|
||||
return ing, true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package store
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
|
@ -252,7 +253,7 @@ func TestStore(t *testing.T) {
|
|||
// Secret takes a bit to update
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
err = clientSet.NetworkingV1beta1().Ingresses(ni.Namespace).Delete(ni.Name, &metav1.DeleteOptions{})
|
||||
err = clientSet.NetworkingV1beta1().Ingresses(ni.Namespace).Delete(context.TODO(), ni.Name, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error creating ingress: %v", err)
|
||||
}
|
||||
|
|
@ -451,7 +452,7 @@ func TestStore(t *testing.T) {
|
|||
t.Errorf("expected 0 events of type Delete but %v occurred", del)
|
||||
}
|
||||
|
||||
err = clientSet.CoreV1().Secrets(ns).Delete(secretName, &metav1.DeleteOptions{})
|
||||
err = clientSet.CoreV1().Secrets(ns).Delete(context.TODO(), secretName, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error deleting secret: %v", err)
|
||||
}
|
||||
|
|
@ -565,7 +566,7 @@ func TestStore(t *testing.T) {
|
|||
t.Errorf("expected 1 events of type Update but %v occurred", upd)
|
||||
}
|
||||
|
||||
err = clientSet.CoreV1().Secrets(ns).Delete(secretName, &metav1.DeleteOptions{})
|
||||
err = clientSet.CoreV1().Secrets(ns).Delete(context.TODO(), secretName, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error deleting secret: %v", err)
|
||||
}
|
||||
|
|
@ -707,7 +708,7 @@ func createNamespace(clientSet kubernetes.Interface, t *testing.T) string {
|
|||
},
|
||||
}
|
||||
|
||||
ns, err := clientSet.CoreV1().Namespaces().Create(namespace)
|
||||
ns, err := clientSet.CoreV1().Namespaces().Create(context.TODO(), namespace, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error creating the namespace: %v", err)
|
||||
}
|
||||
|
|
@ -718,7 +719,7 @@ func createNamespace(clientSet kubernetes.Interface, t *testing.T) string {
|
|||
func deleteNamespace(ns string, clientSet kubernetes.Interface, t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
err := clientSet.CoreV1().Namespaces().Delete(ns, &metav1.DeleteOptions{})
|
||||
err := clientSet.CoreV1().Namespaces().Delete(context.TODO(), ns, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error deleting the namespace: %v", err)
|
||||
}
|
||||
|
|
@ -733,7 +734,7 @@ func createConfigMap(clientSet kubernetes.Interface, ns string, t *testing.T) st
|
|||
},
|
||||
}
|
||||
|
||||
cm, err := clientSet.CoreV1().ConfigMaps(ns).Create(configMap)
|
||||
cm, err := clientSet.CoreV1().ConfigMaps(ns).Create(context.TODO(), configMap, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("error creating the configuration map: %v", err)
|
||||
}
|
||||
|
|
@ -743,13 +744,13 @@ func createConfigMap(clientSet kubernetes.Interface, ns string, t *testing.T) st
|
|||
|
||||
func ensureIngress(ingress *networking.Ingress, clientSet kubernetes.Interface, t *testing.T) *networking.Ingress {
|
||||
t.Helper()
|
||||
ing, err := clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Update(ingress)
|
||||
ing, err := clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Update(context.TODO(), ingress, metav1.UpdateOptions{})
|
||||
|
||||
if err != nil {
|
||||
if k8sErrors.IsNotFound(err) {
|
||||
t.Logf("Ingress %v not found, creating", ingress)
|
||||
|
||||
ing, err = clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Create(ingress)
|
||||
ing, err = clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Create(context.TODO(), ingress, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating ingress %+v: %v", ingress, err)
|
||||
}
|
||||
|
|
@ -766,7 +767,7 @@ func ensureIngress(ingress *networking.Ingress, clientSet kubernetes.Interface,
|
|||
|
||||
func deleteIngress(ingress *networking.Ingress, clientSet kubernetes.Interface, t *testing.T) {
|
||||
t.Helper()
|
||||
err := clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Delete(ingress.Name, &metav1.DeleteOptions{})
|
||||
err := clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Delete(context.TODO(), ingress.Name, metav1.DeleteOptions{})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("failed to delete ingress %+v: %v", ingress, err)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ const (
|
|||
globalAuthCacheKey = "global-auth-cache-key"
|
||||
globalAuthCacheDuration = "global-auth-cache-duration"
|
||||
luaSharedDictsKey = "lua-shared-dicts"
|
||||
plugins = "plugins"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -72,6 +73,7 @@ var (
|
|||
"balancer_ewma_last_touched_at": 10,
|
||||
"balancer_ewma_locks": 1,
|
||||
"certificate_servers": 5,
|
||||
"ocsp_response_cache": 5, // keep this same as certificate_servers
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -107,7 +109,7 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
//parse lua shared dict values
|
||||
if val, ok := conf[luaSharedDictsKey]; ok {
|
||||
delete(conf, luaSharedDictsKey)
|
||||
lsd := strings.Split(val, ",")
|
||||
lsd := splitAndTrimSpace(val, ",")
|
||||
for _, v := range lsd {
|
||||
v = strings.Replace(v, " ", "", -1)
|
||||
results := strings.SplitN(v, ":", 2)
|
||||
|
|
@ -136,9 +138,10 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
luaSharedDicts[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := conf[customHTTPErrors]; ok {
|
||||
delete(conf, customHTTPErrors)
|
||||
for _, i := range strings.Split(val, ",") {
|
||||
for _, i := range splitAndTrimSpace(val, ",") {
|
||||
j, err := strconv.Atoi(i)
|
||||
if err != nil {
|
||||
klog.Warningf("%v is not a valid http code: %v", i, err)
|
||||
|
|
@ -147,27 +150,32 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := conf[hideHeaders]; ok {
|
||||
delete(conf, hideHeaders)
|
||||
hideHeadersList = strings.Split(val, ",")
|
||||
hideHeadersList = splitAndTrimSpace(val, ",")
|
||||
}
|
||||
|
||||
if val, ok := conf[skipAccessLogUrls]; ok {
|
||||
delete(conf, skipAccessLogUrls)
|
||||
skipUrls = strings.Split(val, ",")
|
||||
skipUrls = splitAndTrimSpace(val, ",")
|
||||
}
|
||||
|
||||
if val, ok := conf[whitelistSourceRange]; ok {
|
||||
delete(conf, whitelistSourceRange)
|
||||
whiteList = append(whiteList, strings.Split(val, ",")...)
|
||||
whiteList = append(whiteList, splitAndTrimSpace(val, ",")...)
|
||||
}
|
||||
|
||||
if val, ok := conf[proxyRealIPCIDR]; ok {
|
||||
delete(conf, proxyRealIPCIDR)
|
||||
proxyList = append(proxyList, strings.Split(val, ",")...)
|
||||
proxyList = append(proxyList, splitAndTrimSpace(val, ",")...)
|
||||
} else {
|
||||
proxyList = append(proxyList, "0.0.0.0/0")
|
||||
}
|
||||
|
||||
if val, ok := conf[bindAddress]; ok {
|
||||
delete(conf, bindAddress)
|
||||
for _, i := range strings.Split(val, ",") {
|
||||
for _, i := range splitAndTrimSpace(val, ",") {
|
||||
ns := net.ParseIP(i)
|
||||
if ns != nil {
|
||||
if ing_net.IsIPV6(ns) {
|
||||
|
|
@ -183,15 +191,17 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
|
||||
if val, ok := conf[blockCIDRs]; ok {
|
||||
delete(conf, blockCIDRs)
|
||||
blockCIDRList = strings.Split(val, ",")
|
||||
blockCIDRList = splitAndTrimSpace(val, ",")
|
||||
}
|
||||
|
||||
if val, ok := conf[blockUserAgents]; ok {
|
||||
delete(conf, blockUserAgents)
|
||||
blockUserAgentList = strings.Split(val, ",")
|
||||
blockUserAgentList = splitAndTrimSpace(val, ",")
|
||||
}
|
||||
|
||||
if val, ok := conf[blockReferers]; ok {
|
||||
delete(conf, blockReferers)
|
||||
blockRefererList = strings.Split(val, ",")
|
||||
blockRefererList = splitAndTrimSpace(val, ",")
|
||||
}
|
||||
|
||||
if val, ok := conf[httpRedirectCode]; ok {
|
||||
|
|
@ -249,15 +259,12 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
delete(conf, globalAuthResponseHeaders)
|
||||
|
||||
if len(val) != 0 {
|
||||
harr := strings.Split(val, ",")
|
||||
harr := splitAndTrimSpace(val, ",")
|
||||
for _, header := range harr {
|
||||
header = strings.TrimSpace(header)
|
||||
if len(header) > 0 {
|
||||
if !authreq.ValidHeader(header) {
|
||||
klog.Warningf("Global auth location denied - %v.", "invalid headers list")
|
||||
} else {
|
||||
responseHeaders = append(responseHeaders, header)
|
||||
}
|
||||
if !authreq.ValidHeader(header) {
|
||||
klog.Warningf("Global auth location denied - %v.", "invalid headers list")
|
||||
} else {
|
||||
responseHeaders = append(responseHeaders, header)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -266,19 +273,16 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
|
||||
if val, ok := conf[globalAuthRequestRedirect]; ok {
|
||||
delete(conf, globalAuthRequestRedirect)
|
||||
|
||||
to.GlobalExternalAuth.RequestRedirect = val
|
||||
}
|
||||
|
||||
if val, ok := conf[globalAuthSnippet]; ok {
|
||||
delete(conf, globalAuthSnippet)
|
||||
|
||||
to.GlobalExternalAuth.AuthSnippet = val
|
||||
}
|
||||
|
||||
if val, ok := conf[globalAuthCacheKey]; ok {
|
||||
delete(conf, globalAuthCacheKey)
|
||||
|
||||
to.GlobalExternalAuth.AuthCacheKey = val
|
||||
}
|
||||
|
||||
|
|
@ -317,23 +321,17 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
|
||||
// Nginx Status whitelist
|
||||
if val, ok := conf[nginxStatusIpv4Whitelist]; ok {
|
||||
whitelist := make([]string, 0)
|
||||
whitelist = append(whitelist, strings.Split(val, ",")...)
|
||||
to.NginxStatusIpv4Whitelist = whitelist
|
||||
|
||||
to.NginxStatusIpv4Whitelist = splitAndTrimSpace(val, ",")
|
||||
delete(conf, nginxStatusIpv4Whitelist)
|
||||
}
|
||||
if val, ok := conf[nginxStatusIpv6Whitelist]; ok {
|
||||
whitelist := make([]string, 0)
|
||||
whitelist = append(whitelist, strings.Split(val, ",")...)
|
||||
to.NginxStatusIpv6Whitelist = whitelist
|
||||
|
||||
if val, ok := conf[nginxStatusIpv6Whitelist]; ok {
|
||||
to.NginxStatusIpv6Whitelist = splitAndTrimSpace(val, ",")
|
||||
delete(conf, nginxStatusIpv6Whitelist)
|
||||
}
|
||||
|
||||
if val, ok := conf[workerProcesses]; ok {
|
||||
to.WorkerProcesses = val
|
||||
|
||||
if val == "auto" {
|
||||
to.WorkerProcesses = strconv.Itoa(runtime.NumCPU())
|
||||
}
|
||||
|
|
@ -341,6 +339,11 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
delete(conf, workerProcesses)
|
||||
}
|
||||
|
||||
if val, ok := conf[plugins]; ok {
|
||||
to.Plugins = splitAndTrimSpace(val, ",")
|
||||
delete(conf, plugins)
|
||||
}
|
||||
|
||||
to.CustomHTTPErrors = filterErrors(errors)
|
||||
to.SkipAccessLogURLs = skipUrls
|
||||
to.WhitelistSourceRange = whiteList
|
||||
|
|
@ -395,3 +398,16 @@ func filterErrors(codes []int) []int {
|
|||
|
||||
return fa
|
||||
}
|
||||
|
||||
func splitAndTrimSpace(s, sep string) []string {
|
||||
f := func(c rune) bool {
|
||||
return strings.EqualFold(string(c), sep)
|
||||
}
|
||||
|
||||
values := strings.FieldsFunc(s, f)
|
||||
for i := range values {
|
||||
values[i] = strings.TrimSpace(values[i])
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
|
|
|||
|
|
@ -358,3 +358,39 @@ func TestLuaSharedDictsParsing(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitAndTrimSpace(t *testing.T) {
|
||||
testsCases := []struct {
|
||||
name string
|
||||
input string
|
||||
expect []string
|
||||
}{
|
||||
{
|
||||
name: "empty string",
|
||||
input: "",
|
||||
expect: []string{},
|
||||
},
|
||||
{
|
||||
name: "two elements",
|
||||
input: "el1,el2",
|
||||
expect: []string{"el1", "el2"},
|
||||
},
|
||||
{
|
||||
name: "two elements with spaces",
|
||||
input: " el1, el2",
|
||||
expect: []string{"el1", "el2"},
|
||||
},
|
||||
{
|
||||
name: "empty elements with spaces",
|
||||
input: " el1, el2,el3,,",
|
||||
expect: []string{"el1", "el2", "el3"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testsCases {
|
||||
data := splitAndTrimSpace(tc.input, ",")
|
||||
if !reflect.DeepEqual(data, tc.expect) {
|
||||
t.Errorf("Testing %v. Expected \"%v\" but \"%v\" was returned", tc.name, tc.expect, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import (
|
|||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/klog"
|
||||
|
||||
|
|
@ -171,7 +172,6 @@ var (
|
|||
"proxySetHeader": proxySetHeader,
|
||||
"buildInfluxDB": buildInfluxDB,
|
||||
"enforceRegexModifier": enforceRegexModifier,
|
||||
"stripLocationModifer": stripLocationModifer,
|
||||
"buildCustomErrorDeps": buildCustomErrorDeps,
|
||||
"buildCustomErrorLocationsPerServer": buildCustomErrorLocationsPerServer,
|
||||
"shouldLoadModSecurityModule": shouldLoadModSecurityModule,
|
||||
|
|
@ -373,10 +373,6 @@ func needsRewrite(location *ingress.Location) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func stripLocationModifer(path string) string {
|
||||
return strings.TrimLeft(path, "~* ")
|
||||
}
|
||||
|
||||
// enforceRegexModifier checks if the "rewrite-target" or "use-regex" annotation
|
||||
// is used on any location path within a server
|
||||
func enforceRegexModifier(input interface{}) bool {
|
||||
|
|
@ -407,6 +403,11 @@ func buildLocation(input interface{}, enforceRegex bool) string {
|
|||
if enforceRegex {
|
||||
return fmt.Sprintf(`~* "^%s"`, path)
|
||||
}
|
||||
|
||||
if location.PathType != nil && *location.PathType == networkingv1beta1.PathTypeExact {
|
||||
return fmt.Sprintf(`= %s`, path)
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
|
|
@ -557,7 +558,6 @@ rewrite "(?i)%s" %s break;
|
|||
return defProxyPass
|
||||
}
|
||||
|
||||
// TODO: Needs Unit Tests
|
||||
func filterRateLimits(input interface{}) []ratelimit.Config {
|
||||
ratelimits := []ratelimit.Config{}
|
||||
found := sets.String{}
|
||||
|
|
@ -578,7 +578,6 @@ func filterRateLimits(input interface{}) []ratelimit.Config {
|
|||
return ratelimits
|
||||
}
|
||||
|
||||
// TODO: Needs Unit Tests
|
||||
// buildRateLimitZones produces an array of limit_conn_zone in order to allow
|
||||
// rate limiting of request. Each Ingress rule could have up to three zones, one
|
||||
// for connection limit by IP address, one for limiting requests per minute, and
|
||||
|
|
@ -1345,26 +1344,21 @@ func shouldLoadOpentracingModule(c interface{}, s interface{}) bool {
|
|||
|
||||
func buildModSecurityForLocation(cfg config.Configuration, location *ingress.Location) string {
|
||||
isMSEnabledInLoc := location.ModSecurity.Enable
|
||||
isMSEnableSetInLoc := location.ModSecurity.EnableSet
|
||||
isMSEnabled := cfg.EnableModsecurity
|
||||
|
||||
if !isMSEnabled && !isMSEnabledInLoc {
|
||||
return ""
|
||||
}
|
||||
|
||||
if !isMSEnabledInLoc {
|
||||
return ""
|
||||
if isMSEnableSetInLoc && !isMSEnabledInLoc {
|
||||
return "modsecurity off;"
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
|
||||
if !isMSEnabled {
|
||||
buffer.WriteString(`modsecurity on;
|
||||
modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
|
||||
`)
|
||||
}
|
||||
|
||||
if !cfg.EnableOWASPCoreRules && location.ModSecurity.OWASPRules {
|
||||
buffer.WriteString(`modsecurity_rules_file /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf;
|
||||
`)
|
||||
}
|
||||
|
||||
|
|
@ -1380,6 +1374,16 @@ modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
|
|||
`, location.ModSecurity.TransactionID))
|
||||
}
|
||||
|
||||
if !isMSEnabled {
|
||||
buffer.WriteString(`modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
|
||||
`)
|
||||
}
|
||||
|
||||
if !cfg.EnableOWASPCoreRules && location.ModSecurity.OWASPRules {
|
||||
buffer.WriteString(`modsecurity_rules_file /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf;
|
||||
`)
|
||||
}
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1221,15 +1221,6 @@ func TestEnforceRegexModifier(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestStripLocationModifer(t *testing.T) {
|
||||
expected := "ok.com"
|
||||
actual := stripLocationModifer("~*ok.com")
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("Expected '%v' but returned '%v'", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldLoadModSecurityModule(t *testing.T) {
|
||||
// ### Invalid argument type tests ###
|
||||
// The first tests should return false.
|
||||
|
|
@ -1373,9 +1364,13 @@ func TestShouldLoadOpentracingModule(t *testing.T) {
|
|||
|
||||
func TestModSecurityForLocation(t *testing.T) {
|
||||
loadModule := `modsecurity on;
|
||||
modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
|
||||
`
|
||||
|
||||
modSecCfg := `modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
|
||||
`
|
||||
|
||||
modsecOff := "modsecurity off;"
|
||||
|
||||
modsecRule := `modsecurity_rules '
|
||||
#RULE#
|
||||
';
|
||||
|
|
@ -1394,30 +1389,34 @@ modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
|
|||
isEnabledInCM bool
|
||||
isOwaspEnabledInCM bool
|
||||
isEnabledInLoc bool
|
||||
isEnableSetInLoc bool
|
||||
isOwaspEnabledInLoc bool
|
||||
snippet string
|
||||
transactionID string
|
||||
expected string
|
||||
}{
|
||||
{"configmap enabled, configmap OWASP disabled, without annotation, snippet or transaction ID", true, false, false, false, "", "", ""},
|
||||
{"configmap enabled, configmap OWASP disabled, without annotation, snippet and with transaction ID", true, false, false, false, "", transactionID, ""},
|
||||
{"configmap enabled, configmap OWASP enabled, without annotation, OWASP enabled", true, true, false, false, "", "", ""},
|
||||
{"configmap enabled, configmap OWASP enabled, without annotation, OWASP disabled, with snippet and no transaction ID", true, true, true, false, testRule, "", modsecRule},
|
||||
{"configmap enabled, configmap OWASP enabled, without annotation, OWASP disabled, with snippet and transaction ID", true, true, true, false, testRule, transactionID, fmt.Sprintf("%v%v", modsecRule, transactionCfg)},
|
||||
{"configmap enabled, with annotation, OWASP disabled", true, false, true, false, "", "", ""},
|
||||
{"configmap enabled, configmap OWASP disabled, with annotation, OWASP enabled, no snippet and no transaction ID", true, false, true, true, "", "", owaspRules},
|
||||
{"configmap enabled, configmap OWASP disabled, with annotation, OWASP enabled, with snippet and no transaction ID", true, false, true, true, "", "", owaspRules},
|
||||
{"configmap enabled, configmap OWASP disabled, with annotation, OWASP enabled, with snippet and transaction ID", true, false, true, true, "", transactionID, fmt.Sprintf("%v%v", owaspRules, transactionCfg)},
|
||||
{"configmap enabled, OWASP configmap enabled, with annotation, OWASP disabled", true, true, true, false, "", "", ""},
|
||||
{"configmap disabled, with annotation, OWASP disabled", false, false, true, false, "", "", loadModule},
|
||||
{"configmap disabled, with annotation, OWASP disabled", false, false, true, false, testRule, "", fmt.Sprintf("%v%v", loadModule, modsecRule)},
|
||||
{"configmap disabled, with annotation, OWASP enabled", false, false, true, false, testRule, "", fmt.Sprintf("%v%v", loadModule, modsecRule)},
|
||||
{"configmap enabled, configmap OWASP disabled, without annotation, snippet or transaction ID", true, false, false, false, false, "", "", ""},
|
||||
{"configmap enabled, configmap OWASP disabled, without annotation, snippet and with transaction ID", true, false, false, false, false, "", transactionID, transactionCfg},
|
||||
{"configmap enabled, configmap OWASP enabled, without annotation, OWASP enabled", true, true, false, false, false, "", "", ""},
|
||||
{"configmap enabled, configmap OWASP enabled, without annotation, OWASP disabled, with snippet and no transaction ID", true, true, false, false, false, testRule, "", modsecRule},
|
||||
{"configmap enabled, configmap OWASP enabled, without annotation, OWASP disabled, with snippet and transaction ID", true, true, false, false, false, testRule, transactionID, fmt.Sprintf("%v%v", modsecRule, transactionCfg)},
|
||||
{"configmap enabled, configmap OWASP disabled, annotation enabled, OWASP disabled", true, false, true, true, false, "", "", ""},
|
||||
{"configmap enabled, configmap OWASP disabled, annotation enabled, OWASP enabled, no snippet and no transaction ID", true, false, true, true, true, "", "", owaspRules},
|
||||
{"configmap enabled, configmap OWASP disabled, annotation disabled, OWASP disabled, no snippet and no transaction ID", true, false, false, true, false, "", "", modsecOff},
|
||||
{"configmap enabled, configmap OWASP disabled, annotation enabled, OWASP enabled, with snippet and no transaction ID", true, false, true, true, true, "", "", owaspRules},
|
||||
{"configmap enabled, configmap OWASP disabled, annotation enabled, OWASP enabled, with snippet and transaction ID", true, false, true, true, true, "", transactionID, fmt.Sprintf("%v%v", transactionCfg, owaspRules)},
|
||||
{"configmap enabled, configmap OWASP enabled, annotation enabled, OWASP disabled", true, true, true, true, false, "", "", ""},
|
||||
{"configmap disabled, annotation enabled, OWASP disabled", false, false, true, true, false, "", "", fmt.Sprintf("%v%v", loadModule, modSecCfg)},
|
||||
{"configmap disabled, annotation disabled, OWASP disabled", false, false, false, true, false, "", "", ""},
|
||||
{"configmap disabled, annotation enabled, OWASP disabled", false, false, true, true, false, testRule, "", fmt.Sprintf("%v%v%v", loadModule, modsecRule, modSecCfg)},
|
||||
{"configmap disabled, annotation enabled, OWASP enabled", false, false, true, true, false, testRule, "", fmt.Sprintf("%v%v%v", loadModule, modsecRule, modSecCfg)},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
il := &ingress.Location{
|
||||
ModSecurity: modsecurity.Config{
|
||||
Enable: testCase.isEnabledInLoc,
|
||||
EnableSet: testCase.isEnableSetInLoc,
|
||||
OWASPRules: testCase.isOwaspEnabledInLoc,
|
||||
Snippet: testCase.snippet,
|
||||
TransactionID: testCase.transactionID,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package status
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"sort"
|
||||
|
|
@ -180,7 +181,7 @@ func (s *statusSync) runningAddresses() ([]string, error) {
|
|||
}
|
||||
|
||||
// get information about all the pods running the ingress controller
|
||||
pods, err := s.Client.CoreV1().Pods(s.pod.Namespace).List(metav1.ListOptions{
|
||||
pods, err := s.Client.CoreV1().Pods(s.pod.Namespace).List(context.TODO(), metav1.ListOptions{
|
||||
LabelSelector: labels.SelectorFromSet(s.pod.Labels).String(),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -204,7 +205,7 @@ func (s *statusSync) runningAddresses() ([]string, error) {
|
|||
}
|
||||
|
||||
func (s *statusSync) isRunningMultiplePods() bool {
|
||||
pods, err := s.Client.CoreV1().Pods(s.pod.Namespace).List(metav1.ListOptions{
|
||||
pods, err := s.Client.CoreV1().Pods(s.pod.Namespace).List(context.TODO(), metav1.ListOptions{
|
||||
LabelSelector: labels.SelectorFromSet(s.pod.Labels).String(),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -266,27 +267,27 @@ func runUpdate(ing *ingress.Ingress, status []apiv1.LoadBalancerIngress,
|
|||
|
||||
if k8s.IsNetworkingIngressAvailable {
|
||||
ingClient := client.NetworkingV1beta1().Ingresses(ing.Namespace)
|
||||
currIng, err := ingClient.Get(ing.Name, metav1.GetOptions{})
|
||||
currIng, err := ingClient.Get(context.TODO(), ing.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("unexpected error searching Ingress %v/%v", ing.Namespace, ing.Name))
|
||||
}
|
||||
|
||||
klog.Infof("updating Ingress %v/%v status from %v to %v", currIng.Namespace, currIng.Name, currIng.Status.LoadBalancer.Ingress, status)
|
||||
currIng.Status.LoadBalancer.Ingress = status
|
||||
_, err = ingClient.UpdateStatus(currIng)
|
||||
_, err = ingClient.UpdateStatus(context.TODO(), currIng, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
klog.Warningf("error updating ingress rule: %v", err)
|
||||
}
|
||||
} else {
|
||||
ingClient := client.ExtensionsV1beta1().Ingresses(ing.Namespace)
|
||||
currIng, err := ingClient.Get(ing.Name, metav1.GetOptions{})
|
||||
currIng, err := ingClient.Get(context.TODO(), ing.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("unexpected error searching Ingress %v/%v", ing.Namespace, ing.Name))
|
||||
}
|
||||
|
||||
klog.Infof("updating Ingress %v/%v status from %v to %v", currIng.Namespace, currIng.Name, currIng.Status.LoadBalancer.Ingress, status)
|
||||
currIng.Status.LoadBalancer.Ingress = status
|
||||
_, err = ingClient.UpdateStatus(currIng)
|
||||
_, err = ingClient.UpdateStatus(context.TODO(), currIng, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
klog.Warningf("error updating ingress rule: %v", err)
|
||||
}
|
||||
|
|
@ -327,7 +328,7 @@ func ingressSliceEqual(lhs, rhs []apiv1.LoadBalancerIngress) bool {
|
|||
|
||||
func statusAddressFromService(service string, kubeClient clientset.Interface) ([]string, error) {
|
||||
ns, name, _ := k8s.ParseNameNS(service)
|
||||
svc, err := kubeClient.CoreV1().Services(ns).Get(name, metav1.GetOptions{})
|
||||
svc, err := kubeClient.CoreV1().Services(ns).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package status
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
|
@ -322,7 +323,7 @@ func TestStatusActions(t *testing.T) {
|
|||
newIPs := []apiv1.LoadBalancerIngress{{
|
||||
IP: "11.0.0.2",
|
||||
}}
|
||||
fooIngress1, err1 := fk.Client.NetworkingV1beta1().Ingresses(apiv1.NamespaceDefault).Get("foo_ingress_1", metav1.GetOptions{})
|
||||
fooIngress1, err1 := fk.Client.NetworkingV1beta1().Ingresses(apiv1.NamespaceDefault).Get(context.TODO(), "foo_ingress_1", metav1.GetOptions{})
|
||||
if err1 != nil {
|
||||
t.Fatalf("unexpected error")
|
||||
}
|
||||
|
|
@ -337,7 +338,7 @@ func TestStatusActions(t *testing.T) {
|
|||
fk.Shutdown()
|
||||
// ingress should be empty
|
||||
newIPs2 := []apiv1.LoadBalancerIngress{}
|
||||
fooIngress2, err2 := fk.Client.NetworkingV1beta1().Ingresses(apiv1.NamespaceDefault).Get("foo_ingress_1", metav1.GetOptions{})
|
||||
fooIngress2, err2 := fk.Client.NetworkingV1beta1().Ingresses(apiv1.NamespaceDefault).Get(context.TODO(), "foo_ingress_1", metav1.GetOptions{})
|
||||
if err2 != nil {
|
||||
t.Fatalf("unexpected error")
|
||||
}
|
||||
|
|
@ -346,7 +347,7 @@ func TestStatusActions(t *testing.T) {
|
|||
t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, newIPs2)
|
||||
}
|
||||
|
||||
oic, err := fk.Client.NetworkingV1beta1().Ingresses(metav1.NamespaceDefault).Get("foo_ingress_different_class", metav1.GetOptions{})
|
||||
oic, err := fk.Client.NetworkingV1beta1().Ingresses(metav1.NamespaceDefault).Get(context.TODO(), "foo_ingress_different_class", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,6 +224,8 @@ type Location struct {
|
|||
// a '/'. If unspecified, the path defaults to a catch all sending
|
||||
// traffic to the backend.
|
||||
Path string `json:"path"`
|
||||
// PathType represents the type of path referred to by a HTTPIngressPath.
|
||||
PathType *networking.PathType `json:"pathType"`
|
||||
// IsDefBackend indicates if service specified in the Ingress
|
||||
// contains active endpoints or not. Returning true means the location
|
||||
// uses the default backend.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue