Merge branch 'kubernetes:main' into main

This commit is contained in:
Nicholas Orlowsky 2024-05-18 02:10:37 +02:00 committed by GitHub
commit 9e79a36020
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
664 changed files with 19886 additions and 10226 deletions

View file

@ -66,12 +66,12 @@ type SSLCert struct {
}
// GetObjectKind implements the ObjectKind interface as a noop
func (s SSLCert) GetObjectKind() schema.ObjectKind {
func (s *SSLCert) GetObjectKind() schema.ObjectKind {
return schema.EmptyObjectKind
}
// Identifier returns a the couple issuer / serial number if they both exist, an empty string otherwise
func (s SSLCert) Identifier() string {
func (s *SSLCert) Identifier() string {
if s.Certificate != nil {
if s.Certificate.SerialNumber != nil {
return fmt.Sprintf("%s-%s", s.Certificate.Issuer.SerialNumber, s.Certificate.SerialNumber.String())
@ -81,7 +81,7 @@ func (s SSLCert) Identifier() string {
}
// HashInclude defines if a field should be used or not to calculate the hash
func (s SSLCert) HashInclude(field string, v interface{}) (bool, error) {
func (s *SSLCert) HashInclude(field string, _ interface{}) (bool, error) {
switch field {
case "PemSHA", "CASHA", "ExpireTime":
return true, nil

View file

@ -27,15 +27,15 @@ import (
"k8s.io/ingress-nginx/internal/ingress/annotations/authtls"
"k8s.io/ingress-nginx/internal/ingress/annotations/connection"
"k8s.io/ingress-nginx/internal/ingress/annotations/cors"
"k8s.io/ingress-nginx/internal/ingress/annotations/customheaders"
"k8s.io/ingress-nginx/internal/ingress/annotations/fastcgi"
"k8s.io/ingress-nginx/internal/ingress/annotations/globalratelimit"
"k8s.io/ingress-nginx/internal/ingress/annotations/ipallowlist"
"k8s.io/ingress-nginx/internal/ingress/annotations/ipdenylist"
"k8s.io/ingress-nginx/internal/ingress/annotations/ipwhitelist"
"k8s.io/ingress-nginx/internal/ingress/annotations/log"
"k8s.io/ingress-nginx/internal/ingress/annotations/mirror"
"k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity"
"k8s.io/ingress-nginx/internal/ingress/annotations/opentelemetry"
"k8s.io/ingress-nginx/internal/ingress/annotations/opentracing"
"k8s.io/ingress-nginx/internal/ingress/annotations/proxy"
"k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl"
"k8s.io/ingress-nginx/internal/ingress/annotations/ratelimit"
@ -73,7 +73,7 @@ type Configuration struct {
DefaultSSLCertificate *SSLCert `json:"-"`
StreamSnippets []string
StreamSnippets []string `json:"StreamSnippets"`
}
// Backend describes one or more remote server/s (endpoints) associated with a service
@ -129,7 +129,7 @@ type TrafficShapingPolicy struct {
}
// HashInclude defines if a field should be used or not to calculate the hash
func (s Backend) HashInclude(field string, v interface{}) (bool, error) {
func (b *Backend) HashInclude(field string, _ interface{}) (bool, error) {
switch field {
case "Endpoints":
return false, nil
@ -224,7 +224,7 @@ type Server struct {
// is required.
// The chain in the execution order of annotations should be:
// - Denylist
// - Whitelist
// - Allowlist
// - RateLimit
// - BasicDigestAuth
// - ExternalAuth
@ -264,7 +264,8 @@ type Location struct {
BasicDigestAuth auth.Config `json:"basicDigestAuth,omitempty"`
// Denied returns an error when this location cannot not be allowed
// Requesting a denied location should return HTTP code 403.
Denied *string `json:"denied,omitempty"`
Denied *string `json:"denied,omitempty"`
CustomHeaders customheaders.Config `json:"customHeaders,omitempty"`
// CorsConfig returns the Cors Configuration for the ingress rule
// +optional
CorsConfig cors.Config `json:"corsConfig,omitempty"`
@ -298,10 +299,10 @@ type Location struct {
// addresses or networks are allowed.
// +optional
Denylist ipdenylist.SourceRange `json:"denylist,omitempty"`
// Whitelist indicates only connections from certain client
// Allowlist indicates only connections from certain client
// addresses or networks are allowed.
// +optional
Whitelist ipwhitelist.SourceRange `json:"whitelist,omitempty"`
Allowlist ipallowlist.SourceRange `json:"allowlist,omitempty"`
// Proxy contains information about timeouts and buffer sizes
// to be used in connections against endpoints
// +optional
@ -346,6 +347,11 @@ type Location struct {
// CustomHTTPErrors specifies the error codes that should be intercepted.
// +optional
CustomHTTPErrors []int `json:"custom-http-errors"`
// ProxyInterceptErrors disables error intecepting when using CustomHTTPErrors
// e.g. custom 404 and 503 when service-a does not exist or is not available
// but service-a can return 404 and 503 error codes without intercept
// +optional
DisableProxyInterceptErrors bool `json:"disable-proxy-intercept-errors"`
// ModSecurity allows to enable and configure modsecurity
// +optional
ModSecurity modsecurity.Config `json:"modsecurity"`
@ -354,9 +360,6 @@ type Location struct {
// Mirror allows you to mirror traffic to a "test" backend
// +optional
Mirror mirror.Config `json:"mirror,omitempty"`
// Opentracing allows the global opentracing setting to be overridden for a location
// +optional
Opentracing opentracing.Config `json:"opentracing"`
// Opentelemetry allows the global opentelemetry setting to be overridden for a location
// +optional
Opentelemetry opentelemetry.Config `json:"opentelemetry"`
@ -410,5 +413,4 @@ type Ingress struct {
}
// GeneralConfig holds the definition of lua general configuration data
type GeneralConfig struct {
}
type GeneralConfig struct{}

View file

@ -80,58 +80,58 @@ func (c1 *Configuration) Equal(c2 *Configuration) bool {
}
// Equal tests for equality between two Backend types
func (b1 *Backend) Equal(b2 *Backend) bool {
if b1 == b2 {
func (b *Backend) Equal(newB *Backend) bool {
if b == newB {
return true
}
if b1 == nil || b2 == nil {
if b == nil || newB == nil {
return false
}
if b1.Name != b2.Name {
if b.Name != newB.Name {
return false
}
if b1.NoServer != b2.NoServer {
if b.NoServer != newB.NoServer {
return false
}
if b1.Service != b2.Service {
if b1.Service == nil || b2.Service == nil {
if b.Service != newB.Service {
if b.Service == nil || newB.Service == nil {
return false
}
if b1.Service.GetNamespace() != b2.Service.GetNamespace() {
if b.Service.GetNamespace() != newB.Service.GetNamespace() {
return false
}
if b1.Service.GetName() != b2.Service.GetName() {
if b.Service.GetName() != newB.Service.GetName() {
return false
}
}
if b1.Port != b2.Port {
if b.Port != newB.Port {
return false
}
if b1.SSLPassthrough != b2.SSLPassthrough {
if b.SSLPassthrough != newB.SSLPassthrough {
return false
}
if !(&b1.SessionAffinity).Equal(&b2.SessionAffinity) {
if !(&b.SessionAffinity).Equal(&newB.SessionAffinity) {
return false
}
if b1.UpstreamHashBy != b2.UpstreamHashBy {
if b.UpstreamHashBy != newB.UpstreamHashBy {
return false
}
if b1.LoadBalancing != b2.LoadBalancing {
if b.LoadBalancing != newB.LoadBalancing {
return false
}
match := compareEndpoints(b1.Endpoints, b2.Endpoints)
match := compareEndpoints(b.Endpoints, newB.Endpoints)
if !match {
return false
}
if !b1.TrafficShapingPolicy.Equal(b2.TrafficShapingPolicy) {
if !b.TrafficShapingPolicy.Equal(&newB.TrafficShapingPolicy) {
return false
}
return sets.StringElementsMatch(b1.AlternativeBackends, b2.AlternativeBackends)
return sets.StringElementsMatch(b.AlternativeBackends, newB.AlternativeBackends)
}
// Equal tests for equality between two SessionAffinityConfig types
@ -243,7 +243,7 @@ func (e1 *Endpoint) Equal(e2 *Endpoint) bool {
}
// Equal checks for equality between two TrafficShapingPolicies
func (tsp1 TrafficShapingPolicy) Equal(tsp2 TrafficShapingPolicy) bool {
func (tsp1 *TrafficShapingPolicy) Equal(tsp2 *TrafficShapingPolicy) bool {
if tsp1.Weight != tsp2.Weight {
return false
}
@ -335,6 +335,8 @@ func (s1 *Server) Equal(s2 *Server) bool {
}
// Equal tests for equality between two Location types
//
//nolint:gocyclo // Ignore function complexity error
func (l1 *Location) Equal(l2 *Location) bool {
if l1 == l2 {
return true
@ -400,7 +402,7 @@ func (l1 *Location) Equal(l2 *Location) bool {
if !(&l1.Denylist).Equal(&l2.Denylist) {
return false
}
if !(&l1.Whitelist).Equal(&l2.Whitelist) {
if !(&l1.Allowlist).Equal(&l2.Allowlist) {
return false
}
if !(&l1.Proxy).Equal(&l2.Proxy) {
@ -456,10 +458,6 @@ func (l1 *Location) Equal(l2 *Location) bool {
return false
}
if !l1.Opentracing.Equal(&l2.Opentracing) {
return false
}
if !l1.Opentelemetry.Equal(&l2.Opentelemetry) {
return false
}
@ -468,6 +466,10 @@ func (l1 *Location) Equal(l2 *Location) bool {
return false
}
if l1.DisableProxyInterceptErrors != l2.DisableProxyInterceptErrors {
return false
}
return true
}
@ -550,39 +552,39 @@ func (l4b1 *L4Backend) Equal(l4b2 *L4Backend) bool {
}
// Equal tests for equality between two SSLCert types
func (s1 *SSLCert) Equal(s2 *SSLCert) bool {
if s1 == s2 {
func (s *SSLCert) Equal(newS *SSLCert) bool {
if s == newS {
return true
}
if s1 == nil || s2 == nil {
if s == nil || newS == nil {
return false
}
if s1.CASHA != s2.CASHA {
if s.CASHA != newS.CASHA {
return false
}
if s1.CRLSHA != s2.CRLSHA {
if s.CRLSHA != newS.CRLSHA {
return false
}
if s1.PemSHA != s2.PemSHA {
if s.PemSHA != newS.PemSHA {
return false
}
if s1.CAFileName != s2.CAFileName {
if s.CAFileName != newS.CAFileName {
return false
}
if s1.CRLFileName != s2.CRLFileName {
if s.CRLFileName != newS.CRLFileName {
return false
}
if !s1.ExpireTime.Equal(s2.ExpireTime) {
if !s.ExpireTime.Equal(newS.ExpireTime) {
return false
}
if s1.PemCertKey != s2.PemCertKey {
if s.PemCertKey != newS.PemCertKey {
return false
}
if s1.UID != s2.UID {
if s.UID != newS.UID {
return false
}
return sets.StringElementsMatch(s1.CN, s2.CN)
return sets.StringElementsMatch(s.CN, newS.CN)
}
var compareEndpointsFunc = func(e1, e2 interface{}) bool {

View file

@ -25,19 +25,29 @@ import (
)
func TestEqualConfiguration(t *testing.T) {
ap, _ := filepath.Abs("../../../test/manifests/configuration-a.json")
ap, err := filepath.Abs("../../../test/manifests/configuration-a.json")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
a, err := readJSON(ap)
if err != nil {
t.Errorf("unexpected error reading JSON file: %v", err)
}
bp, _ := filepath.Abs("../../../test/manifests/configuration-b.json")
bp, err := filepath.Abs("../../../test/manifests/configuration-b.json")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
b, err := readJSON(bp)
if err != nil {
t.Errorf("unexpected error reading JSON file: %v", err)
}
cp, _ := filepath.Abs("../../../test/manifests/configuration-c.json")
cp, err := filepath.Abs("../../../test/manifests/configuration-c.json")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
c, err := readJSON(cp)
if err != nil {
t.Errorf("unexpected error reading JSON file: %v", err)
@ -84,15 +94,18 @@ func TestL4ServiceElementsMatch(t *testing.T) {
{[]L4Service{{Port: 80}}, []L4Service{{Port: 80}}, true},
{
[]L4Service{
{Port: 80, Endpoints: []Endpoint{{Address: "1.1.1.1"}}}},
{Port: 80, Endpoints: []Endpoint{{Address: "1.1.1.1"}}},
},
[]L4Service{{Port: 80}},
false,
},
{
[]L4Service{
{Port: 80, Endpoints: []Endpoint{{Address: "1.1.1.1"}, {Address: "1.1.1.2"}}}},
{Port: 80, Endpoints: []Endpoint{{Address: "1.1.1.1"}, {Address: "1.1.1.2"}}},
},
[]L4Service{
{Port: 80, Endpoints: []Endpoint{{Address: "1.1.1.2"}, {Address: "1.1.1.1"}}}},
{Port: 80, Endpoints: []Endpoint{{Address: "1.1.1.2"}, {Address: "1.1.1.1"}}},
},
true,
},
{

View file

@ -132,6 +132,9 @@ Requires setting the publish-service parameter to a valid Service reference.`)
electionID = flags.String("election-id", "ingress-controller-leader",
`Election id to use for Ingress status updates.`)
electionTTL = flags.Duration("election-ttl", 30*time.Second,
`Duration a leader election is valid before it's getting re-elected`)
updateStatusOnShutdown = flags.Bool("update-status-on-shutdown", true,
`Update the load-balancer status of Ingress objects when the controller shuts down.
Requires the update-status parameter.`)
@ -146,12 +149,18 @@ Requires the update-status parameter.`)
enableSSLPassthrough = flags.Bool("enable-ssl-passthrough", false,
`Enable SSL Passthrough.`)
disableLeaderElection = flags.Bool("disable-leader-election", false,
`Disable Leader Election on NGINX Controller.`)
disableServiceExternalName = flags.Bool("disable-svc-external-name", false,
`Disable support for Services of type ExternalName.`)
annotationsPrefix = flags.String("annotations-prefix", parser.DefaultAnnotationsPrefix,
`Prefix of the Ingress annotations specific to the NGINX controller.`)
enableAnnotationValidation = flags.Bool("enable-annotation-validation", false,
`If true, will enable the annotation validation feature. This value will be defaulted to true on a future release`)
enableSSLChainCompletion = flags.Bool("enable-ssl-chain-completion", false,
`Autocomplete SSL certificate chains with missing intermediate CA certificates.
Certificates uploaded to Kubernetes must have the "Authority Information Access" X.509 v3
@ -218,7 +227,7 @@ Takes the form "<host>:port". If not provided, no admission controller is starte
disableSyncEvents = flags.Bool("disable-sync-events", false, "Disables the creation of 'Sync' event resources")
enableTopologyAwareRouting = flags.Bool("enable-topology-aware-routing", false, "Enable topology aware hints feature, needs service object annotation service.kubernetes.io/topology-aware-hints sets to auto.")
enableTopologyAwareRouting = flags.Bool("enable-topology-aware-routing", false, "Enable topology aware routing feature, needs service object annotation service.kubernetes.io/topology-mode sets to auto.")
)
flags.StringVar(&nginx.MaxmindMirror, "maxmind-mirror", "", `Maxmind mirror url (example: http://geoip.local/databases.`)
@ -249,6 +258,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g
}
parser.AnnotationsPrefix = *annotationsPrefix
parser.EnableAnnotationValidation = *enableAnnotationValidation
// check port collisions
if !ing_net.IsPortAvailable(*httpPort) {
@ -294,12 +304,12 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g
nginx.HealthCheckTimeout = time.Duration(*defHealthCheckTimeout) * time.Second
}
if len(*watchNamespace) != 0 && len(*watchNamespaceSelector) != 0 {
if *watchNamespace != "" && *watchNamespaceSelector != "" {
return false, nil, fmt.Errorf("flags --watch-namespace and --watch-namespace-selector are mutually exclusive")
}
var namespaceSelector labels.Selector
if len(*watchNamespaceSelector) != 0 {
if *watchNamespaceSelector != "" {
var err error
namespaceSelector, err = labels.Parse(*watchNamespaceSelector)
if err != nil {
@ -307,7 +317,11 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g
}
}
var histogramBuckets = &collectors.HistogramBuckets{
if *electionTTL <= 0 {
*electionTTL = 30 * time.Second
}
histogramBuckets := &collectors.HistogramBuckets{
TimeBuckets: *timeBuckets,
LengthBuckets: *lengthBuckets,
SizeBuckets: *sizeBuckets,
@ -320,6 +334,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g
KubeConfigFile: *kubeConfigFile,
UpdateStatus: *updateStatus,
ElectionID: *electionID,
ElectionTTL: *electionTTL,
EnableProfiling: *profiling,
EnableMetrics: *enableMetrics,
MetricsPerHost: *metricsPerHost,
@ -329,6 +344,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g
MonitorMaxBatchSize: *monitorMaxBatchSize,
DisableServiceExternalName: *disableServiceExternalName,
EnableSSLPassthrough: *enableSSLPassthrough,
DisableLeaderElection: *disableLeaderElection,
ResyncPeriod: *resyncPeriod,
DefaultService: *defaultSvc,
Namespace: *watchNamespace,
@ -356,7 +372,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g
HTTPS: *httpsPort,
SSLProxy: *sslProxyPort,
},
IngressClassConfiguration: &ingressclass.IngressClassConfiguration{
IngressClassConfiguration: &ingressclass.Configuration{
Controller: *ingressClassController,
AnnotationValue: *ingressClassAnnotation,
WatchWithoutClass: *watchWithoutClass,
@ -376,7 +392,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g
var err error
if nginx.MaxmindEditionIDs != "" {
if err = nginx.ValidateGeoLite2DBEditions(); err != nil {
if err := nginx.ValidateGeoLite2DBEditions(); err != nil {
return false, nil, err
}
if nginx.MaxmindLicenseKey != "" || nginx.MaxmindMirror != "" {

View file

@ -19,6 +19,7 @@ package flags
import (
"os"
"testing"
"time"
)
func TestNoMandatoryFlag(t *testing.T) {
@ -33,7 +34,8 @@ func TestDefaults(t *testing.T) {
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = []string{"cmd",
os.Args = []string{
"cmd",
"--default-backend-service", "namespace/test",
"--http-port", "0",
"--https-port", "0",
@ -53,8 +55,8 @@ func TestDefaults(t *testing.T) {
}
}
func TestSetupSSLProxy(t *testing.T) {
// TODO
func TestSetupSSLProxy(_ *testing.T) {
// TODO TestSetupSSLProxy
}
func TestFlagConflict(t *testing.T) {
@ -108,3 +110,105 @@ func TestMaxmindRetryDownload(t *testing.T) {
t.Fatalf("Expected an error parsing flags but none returned")
}
}
func TestDisableLeaderElectionFlag(t *testing.T) {
ResetForTesting(func() { t.Fatal("Parsing failed") })
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = []string{"cmd", "--disable-leader-election", "--http-port", "80", "--https-port", "443"}
_, conf, err := ParseFlags()
if err != nil {
t.Fatalf("Unexpected error parsing default flags: %v", err)
}
if !conf.DisableLeaderElection {
t.Fatalf("Expected --disable-leader-election and conf.DisableLeaderElection as true, but found: %v", conf.DisableLeaderElection)
}
}
func TestIfLeaderElectionDisabledFlagIsFalse(t *testing.T) {
ResetForTesting(func() { t.Fatal("Parsing failed") })
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443"}
_, conf, err := ParseFlags()
if err != nil {
t.Fatalf("Unexpected error parsing default flags: %v", err)
}
if conf.DisableLeaderElection {
t.Fatalf("Expected --disable-leader-election and conf.DisableLeaderElection as false, but found: %v", conf.DisableLeaderElection)
}
}
func TestLeaderElectionTTLDefaultValue(t *testing.T) {
ResetForTesting(func() { t.Fatal("Parsing failed") })
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443"}
_, conf, err := ParseFlags()
if err != nil {
t.Fatalf("Unexpected error parsing default flags: %v", err)
}
if conf.ElectionTTL != 30*time.Second {
t.Fatalf("Expected --election-ttl and conf.ElectionTTL as 30s, but found: %v", conf.ElectionTTL)
}
}
func TestLeaderElectionTTLParseValueInSeconds(t *testing.T) {
ResetForTesting(func() { t.Fatal("Parsing failed") })
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443", "--election-ttl", "10s"}
_, conf, err := ParseFlags()
if err != nil {
t.Fatalf("Unexpected error parsing default flags: %v", err)
}
if conf.ElectionTTL != 10*time.Second {
t.Fatalf("Expected --election-ttl and conf.ElectionTTL as 10s, but found: %v", conf.ElectionTTL)
}
}
func TestLeaderElectionTTLParseValueInMinutes(t *testing.T) {
ResetForTesting(func() { t.Fatal("Parsing failed") })
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443", "--election-ttl", "10m"}
_, conf, err := ParseFlags()
if err != nil {
t.Fatalf("Unexpected error parsing default flags: %v", err)
}
if conf.ElectionTTL != 10*time.Minute {
t.Fatalf("Expected --election-ttl and conf.ElectionTTL as 10m, but found: %v", conf.ElectionTTL)
}
}
func TestLeaderElectionTTLParseValueInHours(t *testing.T) {
ResetForTesting(func() { t.Fatal("Parsing failed") })
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
os.Args = []string{"cmd", "--http-port", "80", "--https-port", "443", "--election-ttl", "1h"}
_, conf, err := ParseFlags()
if err != nil {
t.Fatalf("Unexpected error parsing default flags: %v", err)
}
if conf.ElectionTTL != 1*time.Hour {
t.Fatalf("Expected --election-ttl and conf.ElectionTTL as 1h, but found: %v", conf.ElectionTTL)
}
}

View file

@ -29,7 +29,6 @@ import (
)
func RegisterHealthz(healthPath string, mux *http.ServeMux, checks ...healthz.HealthChecker) {
healthCheck := []healthz.HealthChecker{healthz.PingHealthz}
if len(checks) > 0 {
healthCheck = append(healthCheck, checks...)
@ -67,7 +66,7 @@ func RegisterProfiler(host string, port int) {
server := &http.Server{
Addr: fmt.Sprintf("%s:%d", host, port),
//G112 (CWE-400): Potential Slowloris Attack
// G112 (CWE-400): Potential Slowloris Attack
ReadHeaderTimeout: 10 * time.Second,
Handler: mux,
}

View file

@ -69,7 +69,7 @@ func (p *TCPProxy) Handle(conn net.Conn) {
}
proxy := p.Default
hostname, err := parser.GetHostname(data[:])
hostname, err := parser.GetHostname(data)
if err == nil {
klog.V(4).InfoS("TLS Client Hello", "host", hostname)
proxy = p.Get(hostname)
@ -91,8 +91,14 @@ func (p *TCPProxy) Handle(conn net.Conn) {
if proxy.ProxyProtocol {
// write out the Proxy Protocol header
localAddr := conn.LocalAddr().(*net.TCPAddr)
remoteAddr := conn.RemoteAddr().(*net.TCPAddr)
localAddr, ok := conn.LocalAddr().(*net.TCPAddr)
if !ok {
klog.Errorf("unexpected type: %T", conn.LocalAddr())
}
remoteAddr, ok := conn.RemoteAddr().(*net.TCPAddr)
if !ok {
klog.Errorf("unexpected type: %T", conn.RemoteAddr())
}
protocol := "UNKNOWN"
if remoteAddr.IP.To4() != nil {
protocol = "TCP4"
@ -119,9 +125,8 @@ func (p *TCPProxy) Handle(conn net.Conn) {
func pipe(client, server net.Conn) {
doCopy := func(s, c net.Conn, cancel chan<- bool) {
if _, err := io.Copy(s, c); err != nil {
klog.Errorf("Error copying data: %v", err)
}
//nolint:errcheck // No need to catch these errors
io.Copy(s, c)
cancel <- true
}

View file

@ -26,8 +26,8 @@ import (
"github.com/fsnotify/fsnotify"
)
// FileWatcher is an interface we use to watch changes in files
type FileWatcher interface {
// Watcher is an interface we use to watch changes in files
type Watcher interface {
Close() error
}
@ -40,7 +40,7 @@ type OSFileWatcher struct {
}
// NewFileWatcher creates a new FileWatcher
func NewFileWatcher(file string, onEvent func()) (FileWatcher, error) {
func NewFileWatcher(file string, onEvent func()) (Watcher, error) {
fw := OSFileWatcher{
file: file,
onEvent: onEvent,

View file

@ -17,4 +17,4 @@ limitations under the License.
package file
// ReadWriteByUser defines linux permission to read and write files for the owner user
const ReadWriteByUser = 0700
const ReadWriteByUser = 0o700

View file

@ -33,12 +33,10 @@ const (
DefaultSSLDirectory = "/etc/ingress-controller/ssl"
)
var (
directories = []string{
DefaultSSLDirectory,
AuthDirectory,
}
)
var directories = []string{
DefaultSSLDirectory,
AuthDirectory,
}
// CreateRequiredDirectories verifies if the required directories to
// start the ingress controller exist and creates the missing ones.

View file

@ -114,7 +114,7 @@ func GetRemovedIngresses(rucfg, newcfg *ingress.Configuration) []string {
// IsDynamicConfigurationEnough returns whether a Configuration can be
// dynamically applied, without reloading the backend.
func IsDynamicConfigurationEnough(newcfg *ingress.Configuration, oldcfg *ingress.Configuration) bool {
func IsDynamicConfigurationEnough(newcfg, oldcfg *ingress.Configuration) bool {
copyOfRunningConfig := *oldcfg
copyOfPcfg := *newcfg
@ -133,21 +133,21 @@ func IsDynamicConfigurationEnough(newcfg *ingress.Configuration, oldcfg *ingress
// clearL4serviceEndpoints is a helper function to clear endpoints from the ingress configuration since they should be ignored when
// checking if the new configuration changes can be applied dynamically.
func clearL4serviceEndpoints(config *ingress.Configuration) {
var clearedTCPL4Services []ingress.L4Service
var clearedUDPL4Services []ingress.L4Service
for _, service := range config.TCPEndpoints {
clearedTCPL4Services := make([]ingress.L4Service, 0, len(config.TCPEndpoints))
clearedUDPL4Services := make([]ingress.L4Service, 0, len(config.UDPEndpoints))
for i := range config.TCPEndpoints {
copyofService := ingress.L4Service{
Port: service.Port,
Backend: service.Backend,
Port: config.TCPEndpoints[i].Port,
Backend: config.TCPEndpoints[i].Backend,
Endpoints: []ingress.Endpoint{},
Service: nil,
}
clearedTCPL4Services = append(clearedTCPL4Services, copyofService)
}
for _, service := range config.UDPEndpoints {
for i := range config.UDPEndpoints {
copyofService := ingress.L4Service{
Port: service.Port,
Backend: service.Backend,
Port: config.UDPEndpoints[i].Port,
Backend: config.UDPEndpoints[i].Backend,
Endpoints: []ingress.Endpoint{},
Service: nil,
}
@ -160,7 +160,7 @@ func clearL4serviceEndpoints(config *ingress.Configuration) {
// clearCertificates is a helper function to clear Certificates from the ingress configuration since they should be ignored when
// checking if the new configuration changes can be applied dynamically if dynamic certificates is on
func clearCertificates(config *ingress.Configuration) {
var clearedServers []*ingress.Server
clearedServers := make([]*ingress.Server, 0, len(config.Servers))
for _, server := range config.Servers {
copyOfServer := *server
copyOfServer.SSLCert = nil
@ -169,16 +169,16 @@ func clearCertificates(config *ingress.Configuration) {
config.Servers = clearedServers
}
type redirect struct {
type Redirect struct {
From string
To string
SSLCert *ingress.SSLCert
}
// BuildRedirects build the redirects of servers based on configurations and certificates
func BuildRedirects(servers []*ingress.Server) []*redirect {
func BuildRedirects(servers []*ingress.Server) []*Redirect {
names := sets.Set[string]{}
redirectServers := make([]*redirect, 0)
redirectServers := make([]*Redirect, 0)
for _, srv := range servers {
if !srv.RedirectFromToWWW {
@ -212,7 +212,7 @@ func BuildRedirects(servers []*ingress.Server) []*redirect {
continue
}
r := &redirect{
r := &Redirect{
From: from,
To: to,
}

View file

@ -16,9 +16,9 @@ limitations under the License.
package process
// ProcessController defines a common interface for a process to be controlled,
// Controller defines a common interface for a process to be controlled,
// like the configurer, the webhook or the proper ingress controller
type ProcessController interface {
type Controller interface {
Start()
Stop() error
}

View file

@ -29,7 +29,7 @@ type exiter func(code int)
// HandleSigterm receives a ProcessController interface and deals with
// the graceful shutdown
func HandleSigterm(ngx ProcessController, delay int, exit exiter) {
func HandleSigterm(ngx Controller, delay int, exit exiter) {
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGTERM)
<-signalChan

View file

@ -43,7 +43,7 @@ func (f *FakeProcess) exiterFunc(code int) {
}
func sendDelayedSignal(delay time.Duration) error {
time.Sleep(delay * time.Second)
time.Sleep(delay)
return syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
}
@ -67,7 +67,7 @@ func TestHandleSigterm(t *testing.T) {
process := &FakeProcess{shouldError: tt.shouldError}
t.Run(tt.name, func(t *testing.T) {
go func() {
err := sendDelayedSignal(2) // Send a signal after 2 seconds
err := sendDelayedSignal(2 * time.Second) // Send a signal after 2 seconds
if err != nil {
t.Errorf("error sending delayed signal: %v", err)
}

View file

@ -23,7 +23,7 @@ import (
"runtime"
)
// NumCPU ...
// NumCPU returns the number of logical CPUs usable by the current process.
func NumCPU() int {
return runtime.NumCPU()
}

View file

@ -20,23 +20,20 @@ import (
"testing"
)
var (
testCasesElementMatch = []struct {
listA []string
listB []string
expected bool
}{
{nil, nil, true},
{[]string{"1"}, nil, false},
{[]string{"1"}, []string{"1"}, true},
{[]string{"1", "2", "1"}, []string{"1", "1", "2"}, true},
{[]string{"1", "3", "1"}, []string{"1", "1", "2"}, false},
{[]string{"1", "1"}, []string{"1", "2"}, false},
}
)
var testCasesElementMatch = []struct {
listA []string
listB []string
expected bool
}{
{nil, nil, true},
{[]string{"1"}, nil, false},
{[]string{"1"}, []string{"1"}, true},
{[]string{"1", "2", "1"}, []string{"1", "1", "2"}, true},
{[]string{"1", "3", "1"}, []string{"1", "1", "2"}, false},
{[]string{"1", "1"}, []string{"1", "2"}, false},
}
func TestElementsMatch(t *testing.T) {
for _, testCase := range testCasesElementMatch {
result := StringElementsMatch(testCase.listA, testCase.listB)
if result != testCase.expected {