From 3fe85243182a5ae4c0714015e8e7e094463179bf Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sat, 13 Jan 2018 15:48:23 -0300 Subject: [PATCH] Cleanup --- cmd/nginx/main.go | 2 +- internal/ingress/controller/backend_ssl.go | 197 --------------- .../ingress/controller/backend_ssl_test.go | 234 ------------------ internal/ingress/controller/controller.go | 108 ++------ internal/ingress/controller/nginx.go | 162 +++--------- .../ingress/controller/store/backend_ssl.go | 4 +- internal/ingress/controller/store/store.go | 63 +++-- internal/ingress/store/main.go | 113 --------- 8 files changed, 100 insertions(+), 783 deletions(-) delete mode 100644 internal/ingress/controller/backend_ssl.go delete mode 100644 internal/ingress/controller/backend_ssl_test.go delete mode 100644 internal/ingress/store/main.go diff --git a/cmd/nginx/main.go b/cmd/nginx/main.go index a34bfb51c..a645c317a 100644 --- a/cmd/nginx/main.go +++ b/cmd/nginx/main.go @@ -189,7 +189,7 @@ func setupSSLProxy(sslPort, proxyPort int, n *controller.NGINXController) { var conn net.Conn var err error - if n.IsProxyProtocolEnabled { + if n.IsProxyProtocolEnabled() { // we need to wrap the listener in order to decode // proxy protocol before handling the connection conn, err = proxyList.Accept() diff --git a/internal/ingress/controller/backend_ssl.go b/internal/ingress/controller/backend_ssl.go deleted file mode 100644 index ee5cbd241..000000000 --- a/internal/ingress/controller/backend_ssl.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright 2015 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 controller - -import ( - "fmt" - "io/ioutil" - "strings" - - "github.com/golang/glog" - "github.com/imdario/mergo" - - apiv1 "k8s.io/api/core/v1" - extensions "k8s.io/api/extensions/v1beta1" - - "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" - "k8s.io/ingress-nginx/internal/net/ssl" -) - -// syncSecret keeps in sync Secrets used by Ingress rules with the files on -// disk to allow copy of the content of the secret to disk to be used -// by external processes. -func (ic *NGINXController) syncSecret(key string) { - glog.V(3).Infof("starting syncing of secret %v", key) - - cert, err := ic.getPemCertificate(key) - if err != nil { - glog.Warningf("error obtaining PEM from secret %v: %v", key, err) - return - } - - // create certificates and add or update the item in the store - cur, exists := ic.sslCertTracker.Get(key) - if exists { - s := cur.(*ingress.SSLCert) - if s.Equal(cert) { - // no need to update - return - } - glog.Infof("updating secret %v in the local store", key) - ic.sslCertTracker.Update(key, cert) - // this update must trigger an update - // (like an update event from a change in Ingress) - ic.syncQueue.Enqueue(&extensions.Ingress{}) - return - } - - glog.Infof("adding secret %v to the local store", key) - ic.sslCertTracker.Add(key, cert) - // this update must trigger an update - // (like an update event from a change in Ingress) - ic.syncQueue.Enqueue(&extensions.Ingress{}) -} - -// getPemCertificate receives a secret, and creates a ingress.SSLCert as return. -// It parses the secret and verifies if it's a keypair, or a 'ca.crt' secret only. -func (ic *NGINXController) getPemCertificate(secretName string) (*ingress.SSLCert, error) { - secret, err := ic.store.GetSecret(secretName) - if err != nil { - return nil, fmt.Errorf("error retrieving secret %v: %v", secretName, err) - } - - cert, okcert := secret.Data[apiv1.TLSCertKey] - key, okkey := secret.Data[apiv1.TLSPrivateKeyKey] - ca := secret.Data["ca.crt"] - - // namespace/secretName -> namespace-secretName - nsSecName := strings.Replace(secretName, "/", "-", -1) - - var s *ingress.SSLCert - if okcert && okkey { - if cert == nil { - return nil, fmt.Errorf("secret %v has no 'tls.crt'", secretName) - } - if key == nil { - return nil, fmt.Errorf("secret %v has no 'tls.key'", secretName) - } - - // If 'ca.crt' is also present, it will allow this secret to be used in the - // 'nginx.ingress.kubernetes.io/auth-tls-secret' annotation - s, err = ssl.AddOrUpdateCertAndKey(nsSecName, cert, key, ca, ic.fileSystem) - if err != nil { - return nil, fmt.Errorf("unexpected error creating pem file: %v", err) - } - - glog.V(3).Infof("found 'tls.crt' and 'tls.key', configuring %v as a TLS Secret (CN: %v)", secretName, s.CN) - if ca != nil { - glog.V(3).Infof("found 'ca.crt', secret %v can also be used for Certificate Authentication", secretName) - } - - } else if ca != nil { - s, err = ssl.AddCertAuth(nsSecName, ca, ic.fileSystem) - - if err != nil { - return nil, fmt.Errorf("unexpected error creating pem file: %v", err) - } - - // makes this secret in 'syncSecret' to be used for Certificate Authentication - // this does not enable Certificate Authentication - glog.V(3).Infof("found only 'ca.crt', configuring %v as an Certificate Authentication Secret", secretName) - - } else { - return nil, fmt.Errorf("no keypair or CA cert could be found in %v", secretName) - } - - s.Name = secret.Name - s.Namespace = secret.Namespace - return s, nil -} - -func (ic *NGINXController) checkSSLChainIssues() { - for _, secretName := range ic.sslCertTracker.ListKeys() { - s, _ := ic.sslCertTracker.Get(secretName) - secret := s.(*ingress.SSLCert) - - if secret.FullChainPemFileName != "" { - // chain already checked - continue - } - - data, err := ssl.FullChainCert(secret.PemFileName, ic.fileSystem) - if err != nil { - glog.Errorf("unexpected error generating SSL certificate with full intermediate chain CA certs: %v", err) - continue - } - - fullChainPemFileName := fmt.Sprintf("%v/%v-%v-full-chain.pem", ingress.DefaultSSLDirectory, secret.Namespace, secret.Name) - err = ioutil.WriteFile(fullChainPemFileName, data, 0655) - if err != nil { - glog.Errorf("unexpected error creating SSL certificate: %v", err) - continue - } - - dst := &ingress.SSLCert{} - - err = mergo.MergeWithOverwrite(dst, secret) - if err != nil { - glog.Errorf("unexpected error creating SSL certificate: %v", err) - continue - } - - dst.FullChainPemFileName = fullChainPemFileName - - glog.Infof("updating local copy of ssl certificate %v with missing intermediate CA certs", secretName) - ic.sslCertTracker.Update(secretName, dst) - // this update must trigger an update - // (like an update event from a change in Ingress) - ic.syncQueue.Enqueue(&extensions.Ingress{}) - } -} - -// checkMissingSecrets verify if one or more ingress rules contains a reference -// to a secret that is not present in the local secret store. -// In this case we call syncSecret. -func (ic *NGINXController) checkMissingSecrets() { - for _, ing := range ic.store.ListIngresses() { - if !class.IsValid(ing) { - continue - } - - for _, tls := range ing.Spec.TLS { - if tls.SecretName == "" { - continue - } - - key := fmt.Sprintf("%v/%v", ing.Namespace, tls.SecretName) - if _, ok := ic.sslCertTracker.Get(key); !ok { - ic.syncSecret(key) - } - } - - key, _ := parser.GetStringAnnotation("auth-tls-secret", ing) - if key == "" { - continue - } - - if _, ok := ic.sslCertTracker.Get(key); !ok { - ic.syncSecret(key) - } - } -} diff --git a/internal/ingress/controller/backend_ssl_test.go b/internal/ingress/controller/backend_ssl_test.go deleted file mode 100644 index 42763bba1..000000000 --- a/internal/ingress/controller/backend_ssl_test.go +++ /dev/null @@ -1,234 +0,0 @@ -/* -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 controller - -import ( - "encoding/base64" - "fmt" - "io/ioutil" - - apiv1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - testclient "k8s.io/client-go/kubernetes/fake" - cache_client "k8s.io/client-go/tools/cache" - - "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/ingress-nginx/internal/ingress/store" -) - -const ( - // openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc" - tlsCrt = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIekNDQWdlZ0F3SUJBZ0lKQU1KZld6Mm81cWVnTUEwR0NTcUdTSWIzRFFFQkN3VUFNQ1l4RVRBUEJnTlYKQkFNTUNHNW5hVzU0YzNaak1SRXdEd1lEVlFRS0RBaHVaMmx1ZUhOMll6QWVGdzB4TnpBME1URXdNakF3TlRCYQpGdzB5TnpBME1Ea3dNakF3TlRCYU1DWXhFVEFQQmdOVkJBTU1DRzVuYVc1NGMzWmpNUkV3RHdZRFZRUUtEQWh1CloybHVlSE4yWXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUgzVTYvY3ArODAKU3hJRjltSnlUcGI5RzBodnhsM0JMaGdQWDBTWjZ3d1lISGJXeTh2dmlCZjVwWTdvVHd0b2FPaTN1VFNsL2RtVwpvUi9XNm9GVWM5a2l6NlNXc3p6YWRXL2l2Q21LMmxOZUFVc2gvaXY0aTAvNXlreDJRNXZUT2tVL1dra2JPOW1OCjdSVTF0QW1KT3M0T1BVc3hZZkw2cnJJUzZPYktHS2UvYUVkek9QS2NPMDJ5NUxDeHM0TFhhWDIzU1l6TG1XYVAKYVZBallrN1NRZm1xUm5mYlF4RWlpaDFQWTFRRXgxWWs0RzA0VmtHUitrSVVMaWF0L291ZjQxY0dXRTZHMTF4NQpkV1BHeS9XcGtqRGlaM0UwekdNZnJBVUZibnErN1dhRTJCRzVoUVV3ZG9SQUtWTnMzaVhLRlRkT3hoRll5bnBwCjA3cDJVNS96ZHRrQ0F3RUFBYU5RTUU0d0hRWURWUjBPQkJZRUZCL2U5UnVna0Mwc0VNTTZ6enRCSjI1U1JxalMKTUI4R0ExVWRJd1FZTUJhQUZCL2U5UnVna0Mwc0VNTTZ6enRCSjI1U1JxalNNQXdHQTFVZEV3UUZNQU1CQWY4dwpEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRys4MXdaSXRuMmFWSlFnejNkNmJvZW1nUXhSSHpaZDhNc1IrdFRvCnpJLy9ac1Nwc2FDR3F0TkdTaHVGKzB3TVZ4NjlpQ3lJTnJJb2J4K29NTHBsQzFQSk9uektSUUdvZEhYNFZaSUwKVlhxSFd2VStjK3ZtT0QxUEt3UjcwRi9rTXk2Yk4xMVI2amhIZ3RPZGdLKzdRczhRMVlUSC9RS2dMd3RJTFRHRwpTZlYxWFlmbnF1TXlZKzFzck00U3ZRSmRzdmFUQmJkZHE2RllpdjhXZFpIaG51ZGlSODdZcFgzOUlTSlFkOXF2CnR6OGthZTVqQVFEUWFiZnFsVWZNT1hmUnhyei96S2NvN3dMeWFMWTh1eVhEWUVIZmlHRWdablV0RjgxVlhDZUIKeU80UERBR0FuVmlXTndFM0NZcGI4RkNGelMyaVVVMDJaQWJRajlvUnYyUWNON1E9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" - tlsKey = "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRREI5MU92M0tmdk5Fc1MKQmZaaWNrNlcvUnRJYjhaZHdTNFlEMTlFbWVzTUdCeDIxc3ZMNzRnWCthV082RThMYUdqb3Q3azBwZjNabHFFZgoxdXFCVkhQWklzK2tsck04Mm5WdjRyd3BpdHBUWGdGTElmNHIrSXRQK2NwTWRrT2IwenBGUDFwSkd6dlpqZTBWCk5iUUppVHJPRGoxTE1XSHkrcTZ5RXVqbXloaW52MmhIY3pqeW5EdE5zdVN3c2JPQzEybDl0MG1NeTVsbWoybFEKSTJKTzBrSDVxa1ozMjBNUklvb2RUMk5VQk1kV0pPQnRPRlpCa2ZwQ0ZDNG1yZjZMbitOWEJsaE9odGRjZVhWagp4c3YxcVpJdzRtZHhOTXhqSDZ3RkJXNTZ2dTFtaE5nUnVZVUZNSGFFUUNsVGJONGx5aFUzVHNZUldNcDZhZE82CmRsT2Y4M2JaQWdNQkFBRUNnZ0VBRGU1WW1XSHN3ZFpzcWQrNXdYcGFRS2Z2SkxXNmRwTmdYeVFEZ0tiWlplWDUKYldPaUFZU3pycDBra2U0SGQxZEphYVdBYk5LYk45eUV1QWUwa2hOaHVxK3dZQzdlc3JreUJCWXgwMzRBamtwTApKMzFLaHhmejBZdXNSdStialg2UFNkZnlBUnd1b1VKN1M3R3V1NXlhbDZBWU1PVmNGcHFBbjVPU0hMbFpLZnNLClN3NXZyM3NKUjNyOENNWVZoUmQ0citGam9lMXlaczJhUHl2bno5c0U3T0ZCSVRGSVBKcE4veG53VUNpWW5vSEMKV2F2TzB5RCtPeTUyN2hBQ1FwaFVMVjRaZXV2bEZwd2ZlWkZveUhnc2YrM1FxeGhpdGtJb3NGakx2Y0xlL2xjZwpSVHNRUnU5OGJNUTdSakJpYU5kaURadjBaWEMvUUMvS054SEw0bXgxTFFLQmdRRHVDY0pUM2JBZmJRY2YvSGh3CjNxRzliNE9QTXpwOTl2ajUzWU1hZHo5Vlk1dm9RR3RGeFlwbTBRVm9MR1lkQ3BHK0lXaDdVVHBMV0JUeGtMSkYKd3EwcEFmRVhmdHB0anhmcyt0OExWVUFtSXJiM2hwUjZDUjJmYjFJWVZRWUJ4dUdzN0hWMmY3NnRZMVAzSEFnNwpGTDJNTnF3ZDd5VmlsVXdSTVptcmJKV3Qwd0tCZ1FEUW1qZlgzc1NWSWZtN1FQaVQvclhSOGJMM1B3V0lNa3NOCldJTVRYeDJmaG0vd0hOL0pNdCtEK2VWbGxjSXhLMmxSYlNTQ1NwU2hzRUVsMHNxWHZUa1FFQnJxN3RFZndRWU0KbGxNbDJQb0ovV2E5c2VYSTAzWWRNeC94Vm5sbzNaUG9MUGg4UmtKekJTWkhnMlB6cCs0VmlnUklBcGdYMXo3TwpMbHg0SEVtaEl3S0JnUURES1RVdVZYL2xCQnJuV3JQVXRuT2RRU1IzNytSeENtQXZYREgxTFBlOEpxTFkxSmdlCjZFc0U2VEtwcWwwK1NrQWJ4b0JIT3QyMGtFNzdqMHJhYnpaUmZNb1NIV3N3a0RWcGtuWDBjTHpiaDNMRGxvOTkKVHFQKzUrSkRHTktIK210a3Y2bStzaFcvU3NTNHdUN3VVWjdtcXB5TEhsdGtiRXVsZlNra3B5NUJDUUtCZ0RmUwpyVk1GZUZINGI1NGV1dWJQNk5Rdi9CYVNOT2JIbnJJSmw3b2RZQTRLcWZYMXBDVnhpY01Gb3MvV2pjc2V0T1puCmNMZTFRYVVyUjZQWmp3R2dUNTd1MEdWQ1Y1QkoxVmFVKzlkTEEwNmRFMXQ4T2VQT1F2TjVkUGplalVyMDBObjIKL3VBeTVTRm1wV0hKMVh1azJ0L0V1WFNUelNQRUpEaUV5NVlRNjl0RkFvR0JBT2tDcW1jVGZGYlpPTjJRK2JqdgpvVmQvSFpLR3YrbEhqcm5maVlhODVxcUszdWJmb0FSNGppR3V3TThqc3hZZW8vb0hQdHJDTkxINndsYlZNTUFGCmlRZG80ZUF3S0xxRHo1MUx4U2hMckwzUUtNQ1FuZVhkT0VjaEdqSW9zRG5Zekd5RTBpSzJGbWNvWHVSQU1QOHgKWDFreUlkazdENDFxSjQ5WlM1OEdBbXlLCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K" - tlscaName = "ca.crt" -) - -type MockQueue struct { - cache_client.Store - Synced bool -} - -func (f *MockQueue) HasSynced() bool { - return f.Synced -} - -func (f *MockQueue) AddIfNotPresent(obj interface{}) error { - return nil -} - -func (f *MockQueue) Pop(process cache_client.PopProcessFunc) (interface{}, error) { - return nil, nil -} - -func (f *MockQueue) Close() { - // just mock -} - -func buildSimpleClientSetForBackendSSL() *testclient.Clientset { - return testclient.NewSimpleClientset() -} - -func buildIngListenerForBackendSSL() store.IngressLister { - ingLister := store.IngressLister{} - ingLister.Store = cache_client.NewStore(cache_client.DeletionHandlingMetaNamespaceKeyFunc) - return ingLister -} - -func buildSecretForBackendSSL() *apiv1.Secret { - return &apiv1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo_secret", - Namespace: metav1.NamespaceDefault, - }, - } -} - -func buildSecrListerForBackendSSL() store.SecretLister { - secrLister := store.SecretLister{} - secrLister.Store = cache_client.NewStore(cache_client.DeletionHandlingMetaNamespaceKeyFunc) - - return secrLister -} - -/* -func buildListers() *ingress.StoreLister { - sl := &ingress.StoreLister{} - sl.Ingress.Store = buildIngListenerForBackendSSL() - sl.Secret.Store = buildSecrListerForBackendSSL() - return sl -} -*/ -func buildControllerForBackendSSL() cache_client.Controller { - cfg := &cache_client.Config{ - Queue: &MockQueue{Synced: true}, - } - - return cache_client.New(cfg) -} - -/* -func buildGenericControllerForBackendSSL() *NGINXController { - gc := &NGINXController{ - syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(0.3, 1), - cfg: &Configuration{ - Client: buildSimpleClientSetForBackendSSL(), - }, - listers: buildListers(), - } - - gc.syncQueue = task.NewTaskQueue(gc.syncIngress) - return gc -} -*/ - -func buildCrtKeyAndCA() ([]byte, []byte, []byte, error) { - // prepare - td, err := ioutil.TempDir("", "ssl") - if err != nil { - return nil, nil, nil, fmt.Errorf("error occurs while creating temp directory: %v", err) - } - ingress.DefaultSSLDirectory = td - - dCrt, err := base64.StdEncoding.DecodeString(tlsCrt) - if err != nil { - return nil, nil, nil, err - } - - dKey, err := base64.StdEncoding.DecodeString(tlsKey) - if err != nil { - return nil, nil, nil, err - } - - dCa := dCrt - - return dCrt, dKey, dCa, nil -} - -/* -func TestSyncSecret(t *testing.T) { - // prepare for test - dCrt, dKey, dCa, err := buildCrtKeyAndCA() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - foos := []struct { - tn string - secretName string - Data map[string][]byte - expectSuccess bool - }{ - {"getPemCertificate_error", "default/foo_secret", map[string][]byte{apiv1.TLSPrivateKeyKey: dKey}, false}, - {"normal_test", "default/foo_secret", map[string][]byte{apiv1.TLSCertKey: dCrt, apiv1.TLSPrivateKeyKey: dKey, tlscaName: dCa}, true}, - } - - for _, foo := range foos { - t.Run(foo.tn, func(t *testing.T) { - ic := buildGenericControllerForBackendSSL() - - // init secret for getPemCertificate - secret := buildSecretForBackendSSL() - secret.SetNamespace("default") - secret.SetName("foo_secret") - secret.Data = foo.Data - ic.store..Secret.Add(secret) - - key := "default/foo_secret" - // for add - ic.syncSecret(key) - if foo.expectSuccess { - // validate - _, exist := ic.sslCertTracker.Get(key) - if !exist { - t.Errorf("Failed to sync secret: %s", foo.secretName) - } else { - // for update - ic.syncSecret(key) - } - } - }) - } -} - -func TestGetPemCertificate(t *testing.T) { - // prepare - dCrt, dKey, dCa, err := buildCrtKeyAndCA() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - foos := []struct { - tn string - secretName string - Data map[string][]byte - eErr bool - }{ - {"sceret_not_exist", "default/foo_secret_not_exist", nil, true}, - {"data_not_complete_all_not_exist", "default/foo_secret", map[string][]byte{}, true}, - {"data_not_complete_TLSCertKey_not_exist", "default/foo_secret", map[string][]byte{apiv1.TLSPrivateKeyKey: dKey, tlscaName: dCa}, false}, - {"data_not_complete_TLSCertKeyAndCA_not_exist", "default/foo_secret", map[string][]byte{apiv1.TLSPrivateKeyKey: dKey}, true}, - {"data_not_complete_TLSPrivateKeyKey_not_exist", "default/foo_secret", map[string][]byte{apiv1.TLSCertKey: dCrt, tlscaName: dCa}, false}, - {"data_not_complete_TLSPrivateKeyKeyAndCA_not_exist", "default/foo_secret", map[string][]byte{apiv1.TLSCertKey: dCrt}, true}, - {"data_not_complete_CA_not_exist", "default/foo_secret", map[string][]byte{apiv1.TLSCertKey: dCrt, apiv1.TLSPrivateKeyKey: dKey}, false}, - {"normal_test", "default/foo_secret", map[string][]byte{apiv1.TLSCertKey: dCrt, apiv1.TLSPrivateKeyKey: dKey, tlscaName: dCa}, false}, - } - - for _, foo := range foos { - t.Run(foo.tn, func(t *testing.T) { - ic := buildGenericControllerForBackendSSL() - secret := buildSecretForBackendSSL() - secret.Data = foo.Data - ic.listers.Secret.Add(secret) - sslCert, err := ic.getPemCertificate(foo.secretName) - - if foo.eErr { - if err == nil { - t.Fatal("Expected error") - } - } else { - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - if sslCert == nil { - t.Error("Expected an ingress.SSLCert") - } - } - }) - } -} -*/ diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index 71f382116..1ed532772 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -36,13 +36,9 @@ import ( clientset "k8s.io/client-go/kubernetes" "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/ingress-nginx/internal/ingress/annotations" "k8s.io/ingress-nginx/internal/ingress/annotations/healthcheck" - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/annotations/proxy" ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config" - "k8s.io/ingress-nginx/internal/ingress/defaults" - "k8s.io/ingress-nginx/internal/ingress/resolver" "k8s.io/ingress-nginx/internal/k8s" "k8s.io/ingress-nginx/internal/task" ) @@ -100,11 +96,6 @@ type Configuration struct { SyncRateLimit float32 } -// GetDefaultBackend returns the default backend -func (n NGINXController) GetDefaultBackend() defaults.Backend { - return n.backendDefaults -} - // GetPublishService returns the configured service used to set ingress status func (n NGINXController) GetPublishService() *apiv1.Service { s, err := n.store.GetService(n.cfg.PublishService) @@ -115,16 +106,6 @@ func (n NGINXController) GetPublishService() *apiv1.Service { return s } -// GetSecret searches for a secret in the local secrets Store -func (n NGINXController) GetSecret(name string) (*apiv1.Secret, error) { - return n.store.GetSecret(name) -} - -// GetService searches for a service in the local secrets Store -func (n NGINXController) GetService(name string) (*apiv1.Service, error) { - return n.store.GetService(name) -} - // sync collects all the pieces required to assemble the configuration file and // then sends the content to the backend (OnUpdate) receiving the populated // template as response reloading the backend if is required. @@ -138,7 +119,7 @@ func (n *NGINXController) syncIngress(item interface{}) error { if element, ok := item.(task.Element); ok { if name, ok := element.Key.(string); ok { if ing, err := n.store.GetIngress(name); err == nil { - n.readSecrets(ing) + n.store.ReadSecrets(ing) } } } @@ -368,7 +349,6 @@ func (n *NGINXController) getBackendServers(ingresses []*extensions.Ingress) ([] anns, err := n.store.GetIngressAnnotations(ing) if err != nil { glog.Errorf("unexpected error reading ingress annotations: %v", err) - anns = &annotations.Ingress{} } for _, rule := range ing.Spec.Rules { @@ -580,29 +560,6 @@ func (n *NGINXController) getBackendServers(ingresses []*extensions.Ingress) ([] return aUpstreams, aServers } -// GetAuthCertificate is used by the auth-tls annotations to get a cert from a secret -func (n NGINXController) GetAuthCertificate(name string) (*resolver.AuthSSLCert, error) { - if _, exists := n.sslCertTracker.Get(name); !exists { - n.syncSecret(name) - } - - _, err := n.store.GetSecret(name) - if err != nil { - return &resolver.AuthSSLCert{}, fmt.Errorf("unexpected error: %v", err) - } - - bc, exists := n.sslCertTracker.Get(name) - if !exists { - return &resolver.AuthSSLCert{}, fmt.Errorf("secret %v does not exist", name) - } - cert := bc.(*ingress.SSLCert) - return &resolver.AuthSSLCert{ - Secret: name, - CAFileName: cert.CAFileName, - PemSHA: cert.PemSHA, - }, nil -} - // createUpstreams creates the NGINX upstreams for each service referenced in // Ingress rules. The servers inside the upstream are endpoints. func (n *NGINXController) createUpstreams(data []*extensions.Ingress, du *ingress.Backend) map[string]*ingress.Backend { @@ -610,7 +567,10 @@ func (n *NGINXController) createUpstreams(data []*extensions.Ingress, du *ingres upstreams[defUpstreamName] = du for _, ing := range data { - anns := n.getIngressAnnotations(ing) + anns, err := n.store.GetIngressAnnotations(ing) + if err != nil { + glog.Errorf("unexpected error reading ingress annotations: %v", err) + } var defBackend string if ing.Spec.Backend != nil { @@ -840,7 +800,7 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, // remove the alias to avoid conflicts. aliases := make(map[string]string, len(data)) - bdef := n.GetDefaultBackend() + bdef := n.store.GetDefaultBackend() ngxProxy := proxy.Config{ BodySize: bdef.ProxyBodySize, ConnectTimeout: bdef.ProxyConnectTimeout, @@ -860,7 +820,7 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, // Tries to fetch the default Certificate from nginx configuration. // If it does not exists, use the ones generated on Start() - defaultCertificate, err := n.getPemCertificate(n.cfg.DefaultSSLCertificate) + defaultCertificate, err := n.store.GetLocalSecret(n.cfg.DefaultSSLCertificate) if err == nil { defaultPemFileName = defaultCertificate.PemFileName defaultPemSHA = defaultCertificate.PemSHA @@ -883,7 +843,10 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, // initialize all the servers for _, ing := range data { - anns := n.getIngressAnnotations(ing) + anns, err := n.store.GetIngressAnnotations(ing) + if err != nil { + glog.Errorf("unexpected error reading ingress annotations: %v", err) + } // default upstream server un := du.Name @@ -951,7 +914,10 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, // configure default location, alias, and SSL for _, ing := range data { - anns := n.getIngressAnnotations(ing) + anns, err := n.store.GetIngressAnnotations(ing) + if err != nil { + glog.Errorf("unexpected error reading ingress annotations: %v", err) + } for _, rule := range ing.Spec.Rules { host := rule.Host @@ -1016,13 +982,12 @@ func (n *NGINXController) createServers(data []*extensions.Ingress, } key := fmt.Sprintf("%v/%v", ing.Namespace, tlsSecretName) - bc, exists := n.sslCertTracker.Get(key) - if !exists { + cert, err := n.store.GetLocalSecret(key) + if err != nil { glog.Warningf("ssl certificate \"%v\" does not exist in local store", key) continue } - cert := bc.(*ingress.SSLCert) err = cert.Certificate.VerifyHostname(host) if err != nil { glog.Warningf("unexpected error validating SSL certificate %v for host %v. Reason: %v", key, host, err) @@ -1148,24 +1113,6 @@ func (n *NGINXController) getEndpoints( return upsServers } -// readSecrets extracts information about secrets from an Ingress rule -func (n *NGINXController) readSecrets(ing *extensions.Ingress) { - for _, tls := range ing.Spec.TLS { - if tls.SecretName == "" { - continue - } - - key := fmt.Sprintf("%v/%v", ing.Namespace, tls.SecretName) - n.syncSecret(key) - } - - key, _ := parser.GetStringAnnotation("auth-tls-secret", ing) - if key == "" { - return - } - n.syncSecret(key) -} - func (n *NGINXController) isForceReload() bool { return atomic.LoadInt32(&n.forceReload) != 0 } @@ -1179,24 +1126,3 @@ func (n *NGINXController) SetForceReload(shouldReload bool) { atomic.StoreInt32(&n.forceReload, 0) } } - -func (n *NGINXController) extractAnnotations(ing *extensions.Ingress) { - glog.V(3).Infof("updating annotations information for ingress %v/%v", ing.Namespace, ing.Name) - anns := n.annotations.Extract(ing) - err := n.store.UpdateIngressAnnotation(anns) - if err != nil { - glog.Errorf("unexpected error updating annotations information for ingress %v/%v: %v", anns.Namespace, anns.Name, err) - } -} - -// getByIngress returns the parsed annotations from an Ingress -func (n *NGINXController) getIngressAnnotations(ing *extensions.Ingress) *annotations.Ingress { - key := fmt.Sprintf("%v/%v", ing.Namespace, ing.Name) - item, err := n.store.GetIngressAnnotations(ing) - if err != nil { - glog.Errorf("unexpected error getting ingress annotation %v: %v", key, err) - return &annotations.Ingress{} - } - - return item -} diff --git a/internal/ingress/controller/nginx.go b/internal/ingress/controller/nginx.go index 174cfe0e2..1d5e1ba83 100644 --- a/internal/ingress/controller/nginx.go +++ b/internal/ingress/controller/nginx.go @@ -18,7 +18,6 @@ package controller import ( "bytes" - "encoding/base64" "errors" "fmt" "io/ioutil" @@ -35,7 +34,6 @@ import ( apiv1 "k8s.io/api/core/v1" extensions "k8s.io/api/extensions/v1beta1" - "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes/scheme" v1core "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/tools/record" @@ -50,7 +48,6 @@ import ( "k8s.io/ingress-nginx/internal/ingress/controller/process" "k8s.io/ingress-nginx/internal/ingress/controller/store" ngx_template "k8s.io/ingress-nginx/internal/ingress/controller/template" - "k8s.io/ingress-nginx/internal/ingress/defaults" "k8s.io/ingress-nginx/internal/ingress/status" ing_net "k8s.io/ingress-nginx/internal/net" "k8s.io/ingress-nginx/internal/net/dns" @@ -95,16 +92,12 @@ func NewNGINXController(config *Configuration, fs file.Filesystem) *NGINXControl } n := &NGINXController{ - backendDefaults: ngx_config.NewDefault().Backend, - binary: ngx, - - configmap: &apiv1.ConfigMap{}, + binary: ngx, isIPV6Enabled: ing_net.IsIPv6Enabled(), resolver: h, cfg: config, - sslCertTracker: store.NewSSLCertTracker(), syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(config.SyncRateLimit, 1), recorder: eventBroadcaster.NewRecorder(scheme.Scheme, apiv1.EventSource{ @@ -112,7 +105,7 @@ func NewNGINXController(config *Configuration, fs file.Filesystem) *NGINXControl }), stopCh: make(chan struct{}), - updateCh: make(chan store.Event), + updateCh: make(chan store.Event, 1024), stopLock: &sync.Mutex{}, @@ -136,7 +129,7 @@ func NewNGINXController(config *Configuration, fs file.Filesystem) *NGINXControl n.syncQueue = task.NewTaskQueue(n.syncIngress) - n.annotations = annotations.NewAnnotationExtractor(n) + n.annotations = annotations.NewAnnotationExtractor(n.store) if config.UpdateStatus { n.syncStatus = status.NewStatusSyncer(status.Config{ @@ -203,10 +196,6 @@ type NGINXController struct { syncStatus status.Sync - // local store of SSL certificates - // (only certificates used in ingress) - sslCertTracker *store.SSLCertTracker - syncRateLimiter flowcontrol.RateLimiter // stopLock is used to enforce only a single call to Stop is active. @@ -227,8 +216,6 @@ type NGINXController struct { t *ngx_template.Template - configmap *apiv1.ConfigMap - binary string resolver []net.IP @@ -238,15 +225,8 @@ type NGINXController struct { // returns true if IPV6 is enabled in the pod isIPV6Enabled bool - // returns true if proxy protocol es enabled - IsProxyProtocolEnabled bool - isShuttingDown bool - Proxy *TCPProxy - - backendDefaults defaults.Backend - store store.Storer fileSystem filesystem.Filesystem @@ -258,28 +238,10 @@ func (n *NGINXController) Start() { n.store.Run(n.stopCh) - // initial sync of secrets to avoid unnecessary reloads - glog.Info("running initial sync of secrets") - for _, ing := range n.store.ListIngresses() { - if !class.IsValid(ing) { - a := ing.GetAnnotations()[class.IngressKey] - glog.Infof("ignoring add for ingress %v based on annotation %v with value %v", ing.Name, class.IngressKey, a) - continue - } - - n.readSecrets(ing) - } - - if n.cfg.EnableSSLChainCompletion { - go wait.Until(n.checkSSLChainIssues, 60*time.Second, n.stopCh) - } - if n.syncStatus != nil { go n.syncStatus.Run() } - go wait.Until(n.checkMissingSecrets, 30*time.Second, n.stopCh) - done := make(chan error, 1) cmd := exec.Command(n.binary, "-c", cfgPath) @@ -293,21 +255,6 @@ func (n *NGINXController) Start() { glog.Info("starting NGINX process...") n.start(cmd) - go func() { - for { - select { - case evt := <-n.updateCh: - if n.isShuttingDown { - break - } - glog.Infof("Event %v received - object %v", evt.Type, evt.Obj) - n.syncQueue.Enqueue(evt.Obj) - case <-n.stopCh: - break - } - } - }() - go n.syncQueue.Run(time.Second, n.stopCh) // force initial sync n.syncQueue.Enqueue(&extensions.Ingress{}) @@ -332,6 +279,12 @@ func (n *NGINXController) Start() { // start a new nginx master process if the controller is not being stopped n.start(cmd) } + case evt := <-n.updateCh: + if n.isShuttingDown { + break + } + glog.V(3).Infof("Event %v received - object %v", evt.Type, evt.Obj) + n.syncQueue.Enqueue(evt.Obj) case <-n.stopCh: break } @@ -434,37 +387,6 @@ Error: %v return nil } -// SetConfig sets the configured configmap -func (n *NGINXController) SetConfig(cmap *apiv1.ConfigMap) { - n.configmap = cmap - n.IsProxyProtocolEnabled = false - - m := map[string]string{} - if cmap != nil { - m = cmap.Data - } - - val, ok := m["use-proxy-protocol"] - if ok { - b, err := strconv.ParseBool(val) - if err == nil { - n.IsProxyProtocolEnabled = b - } - } - - c := ngx_template.ReadConfig(m) - if c.SSLSessionTicketKey != "" { - d, err := base64.StdEncoding.DecodeString(c.SSLSessionTicketKey) - if err != nil { - glog.Warningf("unexpected error decoding key ssl-session-ticket-key: %v", err) - c.SSLSessionTicketKey = "" - } - ioutil.WriteFile("/etc/nginx/tickets.key", d, 0644) - } - - n.backendDefaults = c.Backend -} - // OnUpdate is called periodically by syncQueue to keep the configuration in sync. // // 1. converts configmap configuration to custom configuration object @@ -474,45 +396,43 @@ func (n *NGINXController) SetConfig(cmap *apiv1.ConfigMap) { // returning nill implies the backend will be reloaded. // if an error is returned means requeue the update func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error { - cfg := ngx_template.ReadConfig(n.configmap.Data) + cfg := n.store.GetBackendConfiguration() cfg.Resolver = n.resolver - servers := []*TCPServer{} - for _, pb := range ingressCfg.PassthroughBackends { - svc := pb.Service - if svc == nil { - glog.Warningf("missing service for PassthroughBackends %v", pb.Backend) - continue - } - port, err := strconv.Atoi(pb.Port.String()) - if err != nil { - for _, sp := range svc.Spec.Ports { - if sp.Name == pb.Port.String() { - port = int(sp.Port) - break - } - } - } else { - for _, sp := range svc.Spec.Ports { - if sp.Port == int32(port) { - port = int(sp.Port) - break + /* + servers := []*TCPServer{} + for _, pb := range ingressCfg.PassthroughBackends { + svc := pb.Service + if svc == nil { + glog.Warningf("missing service for PassthroughBackends %v", pb.Backend) + continue + } + port, err := strconv.Atoi(pb.Port.String()) + if err != nil { + for _, sp := range svc.Spec.Ports { + if sp.Name == pb.Port.String() { + port = int(sp.Port) + break + } + } + } else { + for _, sp := range svc.Spec.Ports { + if sp.Port == int32(port) { + port = int(sp.Port) + break + } } } + + //TODO: Allow PassthroughBackends to specify they support proxy-protocol + servers = append(servers, &TCPServer{ + Hostname: pb.Hostname, + IP: svc.Spec.ClusterIP, + Port: port, + ProxyProtocol: false, + }) } - - //TODO: Allow PassthroughBackends to specify they support proxy-protocol - servers = append(servers, &TCPServer{ - Hostname: pb.Hostname, - IP: svc.Spec.ClusterIP, - Port: port, - ProxyProtocol: false, - }) - } - - if n.cfg.EnableSSLPassthrough { - n.Proxy.ServerList = servers - } + */ // we need to check if the status module configuration changed if cfg.EnableVtsStatus { diff --git a/internal/ingress/controller/store/backend_ssl.go b/internal/ingress/controller/store/backend_ssl.go index 8d674d3bd..6f9a6d099 100644 --- a/internal/ingress/controller/store/backend_ssl.go +++ b/internal/ingress/controller/store/backend_ssl.go @@ -201,8 +201,8 @@ func (s k8sStore) checkMissingSecrets() { } } -// readSecrets extracts information about secrets from an Ingress rule -func (s k8sStore) readSecrets(ing *extensions.Ingress) { +// ReadSecrets extracts information about secrets from an Ingress rule +func (s k8sStore) ReadSecrets(ing *extensions.Ingress) { for _, tls := range ing.Spec.TLS { if tls.SecretName == "" { continue diff --git a/internal/ingress/controller/store/store.go b/internal/ingress/controller/store/store.go index 86111eab5..711018c74 100644 --- a/internal/ingress/controller/store/store.go +++ b/internal/ingress/controller/store/store.go @@ -17,7 +17,9 @@ limitations under the License. package store import ( + "encoding/base64" "fmt" + "io/ioutil" "reflect" "time" @@ -41,6 +43,8 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations" "k8s.io/ingress-nginx/internal/ingress/annotations/class" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" + ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config" + ngx_template "k8s.io/ingress-nginx/internal/ingress/controller/template" "k8s.io/ingress-nginx/internal/ingress/defaults" "k8s.io/ingress-nginx/internal/ingress/resolver" "k8s.io/ingress-nginx/internal/k8s" @@ -49,6 +53,9 @@ import ( // Storer is the interface that wraps the required methods to gather information // about ingresses, services, secrets and ingress annotations. type Storer interface { + // GetBackendConfiguration returns the nginx configuration stored in a configmap + GetBackendConfiguration() ngx_config.Configuration + // GetConfigMap returns a ConfigmMap using the namespace and name as key GetConfigMap(key string) (*apiv1.ConfigMap, error) @@ -69,9 +76,6 @@ type Storer interface { // GetIngressAnnotations returns the annotations associated to an Ingress GetIngressAnnotations(ing *extensions.Ingress) (*annotations.Ingress, error) - // UpdateIngressAnnotation updates the annotations associated to an Ingress - UpdateIngressAnnotation(ing *annotations.Ingress) error - // GetLocalSecret returns the local copy of a Secret GetLocalSecret(name string) (*ingress.SSLCert, error) @@ -86,11 +90,11 @@ type Storer interface { // GetDefaultBackend returns the default backend configuration GetDefaultBackend() defaults.Backend - // SetDefaultBackend sets the default backend configuration - SetDefaultBackend(defaults.Backend) - // Run initiates the synchronization of the controllers Run(stopCh chan struct{}) + + // ReadSecrets extracts information about secrets from an Ingress rule + ReadSecrets(*extensions.Ingress) } // EventType type of event associated with an informer @@ -162,7 +166,7 @@ func (c *Controller) Run(stopCh chan struct{}) { type k8sStore struct { isOCSPCheckEnabled bool - backendDefaults defaults.Backend + backendConfig ngx_config.Configuration cache *Controller // listers @@ -195,6 +199,7 @@ func New(checkOCSP bool, sslStore: NewSSLCertTracker(), filesystem: fs, updateCh: updateCh, + backendConfig: ngx_config.NewDefault(), } eventBroadcaster := record.NewBroadcaster() @@ -337,10 +342,11 @@ func New(checkOCSP bool, mapEventHandler := cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { - upCmap := obj.(*apiv1.ConfigMap) - mapKey := fmt.Sprintf("%s/%s", upCmap.Namespace, upCmap.Name) + m := obj.(*apiv1.ConfigMap) + mapKey := fmt.Sprintf("%s/%s", m.Namespace, m.Name) if mapKey == configmap { glog.V(2).Infof("adding configmap %v to backend", mapKey) + store.setConfig(m) updateCh <- Event{ Type: CreateEvent, Obj: obj, @@ -349,10 +355,11 @@ func New(checkOCSP bool, }, UpdateFunc: func(old, cur interface{}) { if !reflect.DeepEqual(old, cur) { - upCmap := cur.(*apiv1.ConfigMap) - mapKey := fmt.Sprintf("%s/%s", upCmap.Namespace, upCmap.Name) + m := cur.(*apiv1.ConfigMap) + mapKey := fmt.Sprintf("%s/%s", m.Namespace, m.Name) if mapKey == configmap { glog.V(2).Infof("updating configmap backend (%v)", mapKey) + store.setConfig(m) updateCh <- Event{ Type: UpdateEvent, Obj: cur, @@ -360,7 +367,7 @@ func New(checkOCSP bool, } // updates to configuration configmaps can trigger an update if mapKey == configmap || mapKey == tcp || mapKey == udp { - recorder.Eventf(upCmap, apiv1.EventTypeNormal, "UPDATE", fmt.Sprintf("ConfigMap %v", mapKey)) + recorder.Eventf(m, apiv1.EventTypeNormal, "UPDATE", fmt.Sprintf("ConfigMap %v", mapKey)) updateCh <- Event{ Type: UpdateEvent, Obj: cur, @@ -452,20 +459,14 @@ func (s k8sStore) GetIngressAnnotations(ing *extensions.Ingress) (*annotations.I key := fmt.Sprintf("%v/%v", ing.Namespace, ing.Name) item, exists, err := s.listers.IngressAnnotation.GetByKey(key) if err != nil { - return nil, fmt.Errorf("unexpected error getting ingress annotation %v: %v", key, err) + return &annotations.Ingress{}, fmt.Errorf("unexpected error getting ingress annotation %v: %v", key, err) } if !exists { - return nil, fmt.Errorf("ingress annotation %v was not found", key) + return &annotations.Ingress{}, fmt.Errorf("ingress annotations %v was not found", key) } return item.(*annotations.Ingress), nil } -// UpdateIngressAnnotation updates the annotations associated to an Ingress -func (s k8sStore) UpdateIngressAnnotation(ing *annotations.Ingress) error { - key := fmt.Sprintf("%v/%v", ing.Namespace, ing.Name) - return s.listers.IngressAnnotation.Update(key) -} - // GetLocalSecret returns the local copy of a Secret func (s k8sStore) GetLocalSecret(key string) (*ingress.SSLCert, error) { return s.sslStore.ByKey(key) @@ -499,11 +500,25 @@ func (s k8sStore) GetAuthCertificate(name string) (*resolver.AuthSSLCert, error) // GetDefaultBackend returns the default backend func (s k8sStore) GetDefaultBackend() defaults.Backend { - return s.backendDefaults + return s.backendConfig.Backend } -func (s *k8sStore) SetDefaultBackend(bd defaults.Backend) { - s.backendDefaults = bd +func (s k8sStore) GetBackendConfiguration() ngx_config.Configuration { + return s.backendConfig +} + +func (s *k8sStore) setConfig(cmap *apiv1.ConfigMap) { + s.backendConfig = ngx_template.ReadConfig(cmap.Data) + + // TODO: this should not be done here + if s.backendConfig.SSLSessionTicketKey != "" { + d, err := base64.StdEncoding.DecodeString(s.backendConfig.SSLSessionTicketKey) + if err != nil { + glog.Warningf("unexpected error decoding key ssl-session-ticket-key: %v", err) + s.backendConfig.SSLSessionTicketKey = "" + } + ioutil.WriteFile("/etc/nginx/tickets.key", d, 0644) + } } // Run initiates the synchronization of the controllers @@ -515,7 +530,7 @@ func (s k8sStore) Run(stopCh chan struct{}) { // initial sync of secrets to avoid unnecessary reloads glog.Info("running initial sync of secrets") for _, ing := range s.ListIngresses() { - s.readSecrets(ing) + s.ReadSecrets(ing) } // start goroutine to check for missing local secrets diff --git a/internal/ingress/store/main.go b/internal/ingress/store/main.go deleted file mode 100644 index 299f54c0b..000000000 --- a/internal/ingress/store/main.go +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 2015 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 store - -import ( - "fmt" - - apiv1 "k8s.io/api/core/v1" - "k8s.io/client-go/tools/cache" -) - -// IngressLister makes a Store that lists Ingress. -type IngressLister struct { - cache.Store -} - -// IngressAnnotationsLister makes a Store that lists annotations in Ingress rules. -type IngressAnnotationsLister struct { - cache.Store -} - -// SecretLister makes a Store that lists Secrets. -type SecretLister struct { - cache.Store -} - -// GetByName searches for a secret in the local secrets Store -func (sl *SecretLister) GetByName(name string) (*apiv1.Secret, error) { - s, exists, err := sl.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, fmt.Errorf("secret %v was not found", name) - } - return s.(*apiv1.Secret), nil -} - -// ConfigMapLister makes a Store that lists Configmaps. -type ConfigMapLister struct { - cache.Store -} - -// GetByName searches for a configmap in the local configmaps Store -func (cml *ConfigMapLister) GetByName(name string) (*apiv1.ConfigMap, error) { - s, exists, err := cml.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, fmt.Errorf("configmap %v was not found", name) - } - return s.(*apiv1.ConfigMap), nil -} - -// ServiceLister makes a Store that lists Services. -type ServiceLister struct { - cache.Store -} - -// GetByName searches for a service in the local secrets Store -func (sl *ServiceLister) GetByName(name string) (*apiv1.Service, error) { - s, exists, err := sl.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, fmt.Errorf("service %v was not found", name) - } - return s.(*apiv1.Service), nil -} - -// EndpointLister makes a Store that lists Endpoints. -type EndpointLister struct { - cache.Store -} - -// GetServiceEndpoints returns the endpoints of a service, matched on service name. -func (s *EndpointLister) GetServiceEndpoints(svc *apiv1.Service) (*apiv1.Endpoints, error) { - for _, m := range s.Store.List() { - ep := m.(*apiv1.Endpoints) - if svc.Name == ep.Name && svc.Namespace == ep.Namespace { - return ep, nil - } - } - return nil, fmt.Errorf("could not find endpoints for service: %v", svc.Name) -} - -// SSLCertTracker holds a store of referenced Secrets in Ingress rules -type SSLCertTracker struct { - cache.ThreadSafeStore -} - -// NewSSLCertTracker creates a new SSLCertTracker store -func NewSSLCertTracker() *SSLCertTracker { - return &SSLCertTracker{ - cache.NewThreadSafeStore(cache.Indexers{}, cache.Indices{}), - } -}