Implement Equaler

This commit is contained in:
Manuel de Brito Fontes 2017-06-14 19:40:25 -04:00
parent 75a4a61254
commit 92eeb7828b
12 changed files with 560 additions and 31 deletions

View file

@ -44,7 +44,7 @@ type External struct {
SigninURL string `json:"signinUrl"`
Method string `json:"method"`
SendBody bool `json:"sendBody"`
ResponseHeaders []string `json:"responseHeaders"`
ResponseHeaders []string `json:"responseHeaders,omitEmpty"`
}
func (e1 *External) Equal(e2 *External) bool {

View file

@ -36,8 +36,8 @@ const (
// AuthSSLConfig contains the AuthSSLCert used for muthual autentication
// and the configured ValidationDepth
type AuthSSLConfig struct {
AuthSSLCert resolver.AuthSSLCert
ValidationDepth int `json:"validationDepth"`
AuthSSLCert resolver.AuthSSLCert `json:"authSSLCert"`
ValidationDepth int `json:"validationDepth"`
}
func (assl1 *AuthSSLConfig) Equal(assl2 *AuthSSLConfig) bool {
@ -47,7 +47,7 @@ func (assl1 *AuthSSLConfig) Equal(assl2 *AuthSSLConfig) bool {
if assl1 == nil || assl2 == nil {
return false
}
if (&assl1.AuthSSLCert).Equal(&assl2.AuthSSLCert) {
if !(&assl1.AuthSSLCert).Equal(&assl2.AuthSSLCert) {
return false
}
if assl1.ValidationDepth != assl2.ValidationDepth {

View file

@ -36,7 +36,7 @@ const (
// SourceRange returns the CIDR
type SourceRange struct {
CIDR []string `json:"cidr"`
CIDR []string `json:"cidr,omitEmpty"`
}
func (sr1 *SourceRange) Equal(sr2 *SourceRange) bool {
@ -47,6 +47,10 @@ func (sr1 *SourceRange) Equal(sr2 *SourceRange) bool {
return false
}
if len(sr1.CIDR) != len(sr2.CIDR) {
return false
}
for _, s1l := range sr1.CIDR {
found := false
for _, sl2 := range sr2.CIDR {

View file

@ -54,10 +54,10 @@ func (rt1 *RateLimit) Equal(rt2 *RateLimit) bool {
if rt1 == nil || rt2 == nil {
return false
}
if (&rt1.Connections).Equal(&rt2.Connections) {
if !(&rt1.Connections).Equal(&rt2.Connections) {
return false
}
if (&rt1.RPS).Equal(&rt2.RPS) {
if !(&rt1.RPS).Equal(&rt2.RPS) {
return false
}

View file

@ -18,6 +18,7 @@ package secureupstream
import (
"fmt"
"github.com/pkg/errors"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
@ -32,8 +33,8 @@ const (
// Secure describes SSL backend configuration
type Secure struct {
Secure bool
CACert resolver.AuthSSLCert
Secure bool `json:"secure"`
CACert resolver.AuthSSLCert `json:"caCert"`
}
type su struct {

View file

@ -412,7 +412,7 @@ func (ic *GenericController) syncIngress(key interface{}) error {
}
if ic.runningConfig != nil && ic.runningConfig.Equal(&pcfg) {
glog.Infof("skipping backend reload (no changes detected)")
glog.V(3).Infof("skipping backend reload (no changes detected)")
return nil
}

View file

@ -0,0 +1,74 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ingress
import (
"encoding/json"
"os"
"path/filepath"
"testing"
)
func TestEqualConfiguration(t *testing.T) {
ap, _ := filepath.Abs("../../../tests/manifests/configuration-a.json")
a, err := readJSON(ap)
if err != nil {
t.Errorf("unexpected error reading JSON file: %v", err)
}
bp, _ := filepath.Abs("../../../tests/manifests/configuration-b.json")
b, err := readJSON(bp)
if err != nil {
t.Errorf("unexpected error reading JSON file: %v", err)
}
cp, _ := filepath.Abs("../../../tests/manifests/configuration-c.json")
c, err := readJSON(cp)
if err != nil {
t.Errorf("unexpected error reading JSON file: %v", err)
}
if !a.Equal(b) {
t.Errorf("expected equal configurations (configuration-a.json and configuration-b.json)")
}
if !b.Equal(a) {
t.Errorf("expected equal configurations (configuration-a.json and configuration-b.json)")
}
if a.Equal(c) {
t.Errorf("expected equal configurations (configuration-a.json and configuration-c.json)")
}
}
func readJSON(p string) (*Configuration, error) {
f, err := os.Open(p)
if err != nil {
return nil, err
}
var c Configuration
d := json.NewDecoder(f)
err = d.Decode(&c)
if err != nil {
return nil, err
}
return &c, nil
}

View file

@ -124,9 +124,9 @@ type BackendInfo struct {
type Configuration struct {
// Backends are a list of backends used by all the Ingress rules in the
// ingress controller. This list includes the default backend
Backends []*Backend `json:"namespace"`
Backends []*Backend `json:"backends,omitEmpty"`
// Servers
Servers []*Server `json:"servers"`
Servers []*Server `json:"servers,omitEmpty"`
// TCPEndpoints contain endpoints for tcp streams handled by this backend
// +optional
TCPEndpoints []L4Service `json:"tcpEndpoints,omitempty"`
@ -143,7 +143,7 @@ type Configuration struct {
type Backend struct {
// Name represents an unique api.Service name formatted as <namespace>-<name>-<port>
Name string `json:"name"`
Service *api.Service `json:"service"`
Service *api.Service `json:"service,omitempty"`
Port intstr.IntOrString `json:"port"`
// This indicates if the communication protocol between the backend and the endpoint is HTTP or HTTPS
// Allowing the use of HTTPS
@ -156,9 +156,9 @@ type Backend struct {
// SSLPassthrough indicates that Ingress controller will delegate TLS termination to the endpoints.
SSLPassthrough bool `json:"sslPassthrough"`
// Endpoints contains the list of endpoints currently running
Endpoints []Endpoint `json:"endpoints"`
Endpoints []Endpoint `json:"endpoints,omitempty"`
// StickySessionAffinitySession contains the StickyConfig object with stickness configuration
SessionAffinity SessionAffinityConfig
SessionAffinity SessionAffinityConfig `json:"sessionAffinityConfig"`
}
// SessionAffinityConfig describes different affinity configurations for new sessions.
@ -168,8 +168,8 @@ type Backend struct {
// affinity values are incompatible. Once set, the backend makes no guarantees
// about honoring updates.
type SessionAffinityConfig struct {
AffinityType string `json:"name"`
CookieSessionAffinity CookieSessionAffinity
AffinityType string `json:"name"`
CookieSessionAffinity CookieSessionAffinity `json:"cookieSessionAffinity"`
}
// CookieSessionAffinity defines the structure used in Affinity configured by Cookies.
@ -253,7 +253,7 @@ type Location struct {
BasicDigestAuth auth.BasicDigest `json:"basicDigestAuth,omitempty"`
// Denied returns an error when this location cannot not be allowed
// Requesting a denied location should return HTTP code 403.
Denied error
Denied error `json:"denied,omitempty"`
// EnableCORS indicates if path must support CORS
// +optional
EnableCORS bool `json:"enableCors,omitempty"`
@ -294,7 +294,7 @@ type Location struct {
// The endpoints must provide the TLS termination exposing the required SSL certificate.
// The ingress controller only pipes the underlying TCP connection
type SSLPassthroughBackend struct {
Service *api.Service `json:"service"`
Service *api.Service `json:"service,omitEmpty"`
Port intstr.IntOrString `json:"port"`
// Backend describes the endpoints to use.
Backend string `json:"namespace,omitempty"`
@ -309,7 +309,7 @@ type L4Service struct {
// Backend of the service
Backend L4Backend `json:"backend"`
// Endpoints active endpoints of the service
Endpoints []Endpoint `json:"endpoins"`
Endpoints []Endpoint `json:"endpoins,omitEmpty"`
}
// L4Backend describes the kubernetes service behind L4 Ingress service

View file

@ -54,7 +54,7 @@ func (c1 *Configuration) Equal(c2 *Configuration) bool {
for _, c1b := range c1.Backends {
found := false
for _, c2b := range c2.Backends {
if (c1b).Equal(c2b) {
if c1b.Equal(c2b) {
found = true
break
}
@ -67,7 +67,7 @@ func (c1 *Configuration) Equal(c2 *Configuration) bool {
for _, c1s := range c1.Servers {
found := false
for _, c2s := range c2.Servers {
if (c1s).Equal(c2s) {
if c1s.Equal(c2s) {
found = true
break
}
@ -272,6 +272,7 @@ func (s1 *Server) Equal(s2 *Server) bool {
if s1.SSLPemChecksum != s2.SSLPemChecksum {
return false
}
if len(s1.Locations) != len(s2.Locations) {
return false
}
@ -279,7 +280,7 @@ func (s1 *Server) Equal(s2 *Server) bool {
for _, s1l := range s1.Locations {
found := false
for _, sl2 := range s2.Locations {
if (s1l).Equal(sl2) {
if s1l.Equal(sl2) {
found = true
break
}
@ -308,6 +309,7 @@ func (l1 *Location) Equal(l2 *Location) bool {
if l1.Backend != l2.Backend {
return false
}
if (l1.Service == nil && l2.Service != nil) ||
(l1.Service != nil && l2.Service == nil) {
return false
@ -325,10 +327,10 @@ func (l1 *Location) Equal(l2 *Location) bool {
}
}
if l1.Port != l2.Port {
if l1.Port.StrVal != l2.Port.StrVal {
return false
}
if (&l1.BasicDigestAuth).Equal(&l2.BasicDigestAuth) {
if !(&l1.BasicDigestAuth).Equal(&l2.BasicDigestAuth) {
return false
}
if l1.Denied != l2.Denied {
@ -337,22 +339,22 @@ func (l1 *Location) Equal(l2 *Location) bool {
if l1.EnableCORS != l2.EnableCORS {
return false
}
if (&l1.ExternalAuth).Equal(&l2.ExternalAuth) {
if !(&l1.ExternalAuth).Equal(&l2.ExternalAuth) {
return false
}
if (&l1.RateLimit).Equal(&l2.RateLimit) {
if !(&l1.RateLimit).Equal(&l2.RateLimit) {
return false
}
if (&l1.Redirect).Equal(&l2.Redirect) {
if !(&l1.Redirect).Equal(&l2.Redirect) {
return false
}
if (&l1.Whitelist).Equal(&l2.Whitelist) {
if !(&l1.Whitelist).Equal(&l2.Whitelist) {
return false
}
if (&l1.Proxy).Equal(&l2.Proxy) {
if !(&l1.Proxy).Equal(&l2.Proxy) {
return false
}
if (&l1.CertificateAuth).Equal(&l2.CertificateAuth) {
if !(&l1.CertificateAuth).Equal(&l2.CertificateAuth) {
return false
}
if l1.UsePortInRedirects != l2.UsePortInRedirects {

View file

@ -0,0 +1,97 @@
{
"backends": [{
"name": "upstream-default-backend",
"port": 0,
"secure": false,
"secureCert": {
"secret": "",
"caFilename": "",
"pemSha": ""
},
"sslPassthrough": false,
"endpoints": [{
"address": "172.17.0.5",
"port": "8080",
"maxFails": 0,
"failTimeout": 0
}],
"sessionAffinityConfig": {
"name": "",
"cookieSessionAffinity": {
"name": "",
"hash": ""
}
}
}],
"servers": [{
"hostname": "_",
"sslPassthrough": false,
"sslCertificate": "/ingress-controller/ssl/default-fake-certificate.pem",
"sslExpireTime": "0001-01-01T00:00:00Z",
"sslPemChecksum": "4302f26460e2c49c9a69229449efefb30dc42a9a",
"locations": [{
"path": "/",
"isDefBackend": true,
"backend": "upstream-default-backend",
"service": null,
"port": 0,
"basicDigestAuth": {
"type": "",
"realm": "",
"file": "",
"secured": false
},
"externalAuth": {
"url": "",
"host": "",
"signinUrl": "",
"method": "",
"sendBody": false,
"responseHeaders": null
},
"rateLimit": {
"connections": {
"name": "",
"limit": 0,
"burst": 0,
"sharedSize": 0
},
"rps": {
"name": "",
"limit": 0,
"burst": 0,
"sharedSize": 0
}
},
"redirect": {
"target": "",
"addBaseUrl": false,
"sslRedirect": false,
"forceSSLRedirect": false,
"appRoot": ""
},
"whitelist": {
"cidr": null
},
"proxy": {
"bodySize": "1m",
"conectTimeout": 5,
"sendTimeout": 60,
"readTimeout": 60,
"bufferSize": "4k",
"cookieDomain": "off",
"cookiePath": "off"
},
"certificateAuth": {
"authSSLCert": {
"secret": "",
"caFilename": "",
"pemSha": ""
},
"validationDepth": 0
},
"use-port-in-redirects": false,
"configuration-snippet": ""
}]
}]
}

View file

@ -0,0 +1,97 @@
{
"backends": [{
"name": "upstream-default-backend",
"port": 0,
"secure": false,
"secureCert": {
"secret": "",
"caFilename": "",
"pemSha": ""
},
"sslPassthrough": false,
"endpoints": [{
"address": "172.17.0.5",
"port": "8080",
"maxFails": 0,
"failTimeout": 0
}],
"sessionAffinityConfig": {
"name": "",
"cookieSessionAffinity": {
"name": "",
"hash": ""
}
}
}],
"servers": [{
"hostname": "_",
"sslPassthrough": false,
"sslCertificate": "/ingress-controller/ssl/default-fake-certificate.pem",
"sslExpireTime": "0001-01-01T00:00:00Z",
"sslPemChecksum": "4302f26460e2c49c9a69229449efefb30dc42a9a",
"locations": [{
"path": "/",
"isDefBackend": true,
"backend": "upstream-default-backend",
"service": null,
"port": 0,
"basicDigestAuth": {
"type": "",
"realm": "",
"file": "",
"secured": false
},
"externalAuth": {
"url": "",
"host": "",
"signinUrl": "",
"method": "",
"sendBody": false,
"responseHeaders": null
},
"rateLimit": {
"connections": {
"name": "",
"limit": 0,
"burst": 0,
"sharedSize": 0
},
"rps": {
"name": "",
"limit": 0,
"burst": 0,
"sharedSize": 0
}
},
"redirect": {
"target": "",
"addBaseUrl": false,
"sslRedirect": false,
"forceSSLRedirect": false,
"appRoot": ""
},
"whitelist": {
"cidr": null
},
"proxy": {
"bodySize": "1m",
"conectTimeout": 5,
"sendTimeout": 60,
"readTimeout": 60,
"bufferSize": "4k",
"cookieDomain": "off",
"cookiePath": "off"
},
"certificateAuth": {
"authSSLCert": {
"secret": "",
"caFilename": "",
"pemSha": ""
},
"validationDepth": 0
},
"use-port-in-redirects": false,
"configuration-snippet": ""
}]
}]
}

View file

@ -0,0 +1,254 @@
{
"backends": [{
"name": "upstream-default-backend",
"service": null,
"port": 0,
"secure": false,
"secureCert": {
"secret": "",
"caFilename": "",
"pemSha": ""
},
"sslPassthrough": false,
"endpoints": [{
"address": "172.17.0.8",
"port": "8080",
"maxFails": 0,
"failTimeout": 0
}],
"SessionAffinity": {
"name": "",
"CookieSessionAffinity": {
"name": "",
"hash": ""
}
}
}, {
"name": "deis-deis-controller-8000",
"service": {
"metadata": {
"name": "deis-controller",
"namespace": "deis",
"selfLink": "/api/v1/namespaces/deis/services/deis-controller",
"uid": "1cba01a8-50b0-11e7-a384-0800270f5693",
"resourceVersion": "532",
"creationTimestamp": "2017-06-14T03:18:18Z",
"labels": {
"heritage": "deis"
}
},
"spec": {
"ports": [{
"name": "http",
"protocol": "TCP",
"port": 8000,
"targetPort": 8000,
"nodePort": 30171
}],
"selector": {
"app": "deis-controller"
},
"clusterIP": "10.0.0.198",
"type": "NodePort",
"sessionAffinity": "None"
},
"status": {
"loadBalancer": {}
}
},
"port": 8000,
"secure": false,
"secureCert": {
"secret": "",
"caFilename": "",
"pemSha": ""
},
"sslPassthrough": false,
"endpoints": [{
"address": "172.17.0.7",
"port": "8000",
"maxFails": 0,
"failTimeout": 0
}],
"SessionAffinity": {
"name": "",
"CookieSessionAffinity": {
"name": "",
"hash": ""
}
}
}],
"servers": [{
"hostname": "_",
"sslPassthrough": false,
"sslCertificate": "/ingress-controller/ssl/default-fake-certificate.pem",
"sslExpireTime": "0001-01-01T00:00:00Z",
"sslPemChecksum": "123b44425920a2e4825ae779fba0e6e07fbac03d",
"locations": [{
"path": "/",
"isDefBackend": true,
"backend": "upstream-default-backend",
"service": null,
"port": 0,
"basicDigestAuth": {
"type": "",
"realm": "",
"file": "",
"secured": false
},
"Denied": null,
"externalAuth": {
"url": "",
"host": "",
"signinUrl": "",
"method": "",
"sendBody": false,
"responseHeaders": null
},
"rateLimit": {
"connections": {
"name": "",
"limit": 0,
"burst": 0,
"sharedSize": 0
},
"rps": {
"name": "",
"limit": 0,
"burst": 0,
"sharedSize": 0
}
},
"redirect": {
"target": "",
"addBaseUrl": false,
"sslRedirect": false,
"forceSSLRedirect": false,
"appRoot": ""
},
"whitelist": {
"cidr": null
},
"proxy": {
"bodySize": "1g",
"conectTimeout": 5,
"sendTimeout": 60,
"readTimeout": 60,
"bufferSize": "4k",
"cookieDomain": "off",
"cookiePath": "off"
},
"certificateAuth": {
"AuthSSLCert": {
"secret": "",
"caFilename": "",
"pemSha": ""
},
"validationDepth": 0
},
"use-port-in-redirects": false,
"configuration-snippet": ""
}]
}, {
"hostname": "deis.minikube",
"sslPassthrough": false,
"sslCertificate": "",
"sslExpireTime": "0001-01-01T00:00:00Z",
"sslPemChecksum": "",
"locations": [{
"path": "/",
"isDefBackend": false,
"backend": "deis-deis-controller-8000",
"service": {
"metadata": {
"name": "deis-controller",
"namespace": "deis",
"selfLink": "/api/v1/namespaces/deis/services/deis-controller",
"uid": "1cba01a8-50b0-11e7-a384-0800270f5693",
"resourceVersion": "532",
"creationTimestamp": "2017-06-14T03:18:18Z",
"labels": {
"heritage": "deis"
}
},
"spec": {
"ports": [{
"name": "http",
"protocol": "TCP",
"port": 8000,
"targetPort": 8000,
"nodePort": 30171
}],
"selector": {
"app": "deis-controller"
},
"clusterIP": "10.0.0.198",
"type": "NodePort",
"sessionAffinity": "None"
},
"status": {
"loadBalancer": {}
}
},
"port": 8000,
"basicDigestAuth": {
"type": "",
"realm": "",
"file": "",
"secured": false
},
"Denied": null,
"externalAuth": {
"url": "",
"host": "",
"signinUrl": "",
"method": "",
"sendBody": false,
"responseHeaders": null
},
"rateLimit": {
"connections": {
"name": "",
"limit": 0,
"burst": 0,
"sharedSize": 0
},
"rps": {
"name": "",
"limit": 0,
"burst": 0,
"sharedSize": 0
}
},
"redirect": {
"target": "",
"addBaseUrl": false,
"sslRedirect": true,
"forceSSLRedirect": false,
"appRoot": ""
},
"whitelist": {
"cidr": null
},
"proxy": {
"bodySize": "1g",
"conectTimeout": 5,
"sendTimeout": 60,
"readTimeout": 60,
"bufferSize": "4k",
"cookieDomain": "off",
"cookiePath": "off"
},
"certificateAuth": {
"AuthSSLCert": {
"secret": "",
"caFilename": "",
"pemSha": ""
},
"validationDepth": 0
},
"use-port-in-redirects": false,
"configuration-snippet": ""
}]
}]
}