Check and complete intermediate SSL certificates
This commit is contained in:
parent
edf2b03c22
commit
8807db9748
13 changed files with 132 additions and 214 deletions
|
|
@ -20,16 +20,14 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/imdario/mergo"
|
||||
"k8s.io/klog"
|
||||
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
networking "k8s.io/api/networking/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/file"
|
||||
"k8s.io/ingress-nginx/internal/ingress"
|
||||
"k8s.io/ingress-nginx/internal/k8s"
|
||||
ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
|
||||
"k8s.io/ingress-nginx/internal/net/ssl"
|
||||
)
|
||||
|
||||
|
|
@ -103,7 +101,7 @@ func (s *k8sStore) getPemCertificate(secretName string) (*ingress.SSLCert, error
|
|||
return nil, fmt.Errorf("unexpected error creating SSL Cert: %v", err)
|
||||
}
|
||||
|
||||
if !s.isDynamicCertificatesEnabled || len(ca) > 0 {
|
||||
if !ngx_config.EnableDynamicCertificates || len(ca) > 0 {
|
||||
err = ssl.StoreSSLCertOnDisk(s.filesystem, nsSecName, sslCert)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while storing certificate and key: %v", err)
|
||||
|
|
@ -152,57 +150,6 @@ func (s *k8sStore) getPemCertificate(secretName string) (*ingress.SSLCert, error
|
|||
return sslCert, nil
|
||||
}
|
||||
|
||||
func (s *k8sStore) checkSSLChainIssues() {
|
||||
for _, item := range s.ListLocalSSLCerts() {
|
||||
secrKey := k8s.MetaNamespaceKey(item)
|
||||
secret, err := s.GetLocalSSLCert(secrKey)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if secret.FullChainPemFileName != "" {
|
||||
// chain already checked
|
||||
continue
|
||||
}
|
||||
|
||||
data, err := ssl.FullChainCert(secret.PemFileName, s.filesystem)
|
||||
if err != nil {
|
||||
klog.Errorf("Error generating CA certificate chain for Secret %q: %v", secrKey, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fullChainPemFileName := fmt.Sprintf("%v/%v-%v-full-chain.pem", file.DefaultSSLDirectory, secret.Namespace, secret.Name)
|
||||
|
||||
file, err := s.filesystem.Create(fullChainPemFileName)
|
||||
if err != nil {
|
||||
klog.Errorf("Error creating SSL certificate file for Secret %q: %v", secrKey, err)
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = file.Write(data)
|
||||
if err != nil {
|
||||
klog.Errorf("Error creating SSL certificate for Secret %q: %v", secrKey, err)
|
||||
continue
|
||||
}
|
||||
|
||||
dst := &ingress.SSLCert{}
|
||||
|
||||
err = mergo.MergeWithOverwrite(dst, secret)
|
||||
if err != nil {
|
||||
klog.Errorf("Error creating SSL certificate for Secret %q: %v", secrKey, err)
|
||||
continue
|
||||
}
|
||||
|
||||
dst.FullChainPemFileName = fullChainPemFileName
|
||||
|
||||
klog.Infof("Updating local copy of SSL certificate %q with missing intermediate CA certs", secrKey)
|
||||
s.sslStore.Update(secrKey, dst)
|
||||
// this update must trigger an update
|
||||
// (like an update event from a change in Ingress)
|
||||
s.sendDummyEvent()
|
||||
}
|
||||
}
|
||||
|
||||
// sendDummyEvent sends a dummy event to trigger an update
|
||||
// This is used in when a secret change
|
||||
func (s *k8sStore) sendDummyEvent() {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
k8sruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/informers"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
|
|
@ -187,8 +186,6 @@ func (i *Informer) Run(stopCh chan struct{}) {
|
|||
|
||||
// k8sStore internal Storer implementation using informers and thread safe stores
|
||||
type k8sStore struct {
|
||||
isOCSPCheckEnabled bool
|
||||
|
||||
// backendConfig contains the running configuration from the configmap
|
||||
// this is required because this rarely changes but is a very expensive
|
||||
// operation to execute in each OnUpdate invocation
|
||||
|
|
@ -224,36 +221,31 @@ type k8sStore struct {
|
|||
|
||||
defaultSSLCertificate string
|
||||
|
||||
isDynamicCertificatesEnabled bool
|
||||
|
||||
pod *k8s.PodInfo
|
||||
}
|
||||
|
||||
// New creates a new object store to be used in the ingress controller
|
||||
func New(checkOCSP bool,
|
||||
func New(
|
||||
namespace, configmap, tcp, udp, defaultSSLCertificate string,
|
||||
resyncPeriod time.Duration,
|
||||
client clientset.Interface,
|
||||
fs file.Filesystem,
|
||||
updateCh *channels.RingChannel,
|
||||
isDynamicCertificatesEnabled bool,
|
||||
pod *k8s.PodInfo,
|
||||
disableCatchAll bool) Storer {
|
||||
|
||||
store := &k8sStore{
|
||||
isOCSPCheckEnabled: checkOCSP,
|
||||
informers: &Informer{},
|
||||
listers: &Lister{},
|
||||
sslStore: NewSSLCertTracker(),
|
||||
filesystem: fs,
|
||||
updateCh: updateCh,
|
||||
backendConfig: ngx_config.NewDefault(),
|
||||
syncSecretMu: &sync.Mutex{},
|
||||
backendConfigMu: &sync.RWMutex{},
|
||||
secretIngressMap: NewObjectRefMap(),
|
||||
defaultSSLCertificate: defaultSSLCertificate,
|
||||
isDynamicCertificatesEnabled: isDynamicCertificatesEnabled,
|
||||
pod: pod,
|
||||
informers: &Informer{},
|
||||
listers: &Lister{},
|
||||
sslStore: NewSSLCertTracker(),
|
||||
filesystem: fs,
|
||||
updateCh: updateCh,
|
||||
backendConfig: ngx_config.NewDefault(),
|
||||
syncSecretMu: &sync.Mutex{},
|
||||
backendConfigMu: &sync.RWMutex{},
|
||||
secretIngressMap: NewObjectRefMap(),
|
||||
defaultSSLCertificate: defaultSSLCertificate,
|
||||
pod: pod,
|
||||
}
|
||||
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
|
|
@ -878,10 +870,6 @@ func (s *k8sStore) setConfig(cmap *corev1.ConfigMap) {
|
|||
func (s *k8sStore) Run(stopCh chan struct{}) {
|
||||
// start informers
|
||||
s.informers.Run(stopCh)
|
||||
|
||||
if s.isOCSPCheckEnabled {
|
||||
go wait.Until(s.checkSSLChainIssues, 60*time.Second, stopCh)
|
||||
}
|
||||
}
|
||||
|
||||
// GetRunningControllerPodsCount returns the number of Running ingress-nginx controller Pods
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import (
|
|||
"k8s.io/ingress-nginx/internal/file"
|
||||
"k8s.io/ingress-nginx/internal/ingress"
|
||||
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
|
||||
ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
|
||||
"k8s.io/ingress-nginx/internal/k8s"
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
|
@ -87,7 +88,7 @@ func TestStore(t *testing.T) {
|
|||
}(updateCh)
|
||||
|
||||
fs := newFS(t)
|
||||
storer := New(true,
|
||||
storer := New(
|
||||
ns,
|
||||
fmt.Sprintf("%v/config", ns),
|
||||
fmt.Sprintf("%v/tcp", ns),
|
||||
|
|
@ -97,7 +98,6 @@ func TestStore(t *testing.T) {
|
|||
clientSet,
|
||||
fs,
|
||||
updateCh,
|
||||
false,
|
||||
pod,
|
||||
false)
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ func TestStore(t *testing.T) {
|
|||
}(updateCh)
|
||||
|
||||
fs := newFS(t)
|
||||
storer := New(true,
|
||||
storer := New(
|
||||
ns,
|
||||
fmt.Sprintf("%v/config", ns),
|
||||
fmt.Sprintf("%v/tcp", ns),
|
||||
|
|
@ -178,7 +178,6 @@ func TestStore(t *testing.T) {
|
|||
clientSet,
|
||||
fs,
|
||||
updateCh,
|
||||
false,
|
||||
pod,
|
||||
false)
|
||||
|
||||
|
|
@ -319,7 +318,7 @@ func TestStore(t *testing.T) {
|
|||
}(updateCh)
|
||||
|
||||
fs := newFS(t)
|
||||
storer := New(true,
|
||||
storer := New(
|
||||
ns,
|
||||
fmt.Sprintf("%v/config", ns),
|
||||
fmt.Sprintf("%v/tcp", ns),
|
||||
|
|
@ -329,7 +328,6 @@ func TestStore(t *testing.T) {
|
|||
clientSet,
|
||||
fs,
|
||||
updateCh,
|
||||
false,
|
||||
pod,
|
||||
false)
|
||||
|
||||
|
|
@ -426,7 +424,7 @@ func TestStore(t *testing.T) {
|
|||
}(updateCh)
|
||||
|
||||
fs := newFS(t)
|
||||
storer := New(true,
|
||||
storer := New(
|
||||
ns,
|
||||
fmt.Sprintf("%v/config", ns),
|
||||
fmt.Sprintf("%v/tcp", ns),
|
||||
|
|
@ -436,7 +434,6 @@ func TestStore(t *testing.T) {
|
|||
clientSet,
|
||||
fs,
|
||||
updateCh,
|
||||
false,
|
||||
pod,
|
||||
false)
|
||||
|
||||
|
|
@ -516,7 +513,7 @@ func TestStore(t *testing.T) {
|
|||
}(updateCh)
|
||||
|
||||
fs := newFS(t)
|
||||
storer := New(true,
|
||||
storer := New(
|
||||
ns,
|
||||
fmt.Sprintf("%v/config", ns),
|
||||
fmt.Sprintf("%v/tcp", ns),
|
||||
|
|
@ -526,7 +523,6 @@ func TestStore(t *testing.T) {
|
|||
clientSet,
|
||||
fs,
|
||||
updateCh,
|
||||
false,
|
||||
pod,
|
||||
false)
|
||||
|
||||
|
|
@ -628,7 +624,7 @@ func TestStore(t *testing.T) {
|
|||
}(updateCh)
|
||||
|
||||
fs := newFS(t)
|
||||
storer := New(true,
|
||||
storer := New(
|
||||
ns,
|
||||
fmt.Sprintf("%v/config", ns),
|
||||
fmt.Sprintf("%v/tcp", ns),
|
||||
|
|
@ -638,7 +634,6 @@ func TestStore(t *testing.T) {
|
|||
clientSet,
|
||||
fs,
|
||||
updateCh,
|
||||
false,
|
||||
pod,
|
||||
false)
|
||||
|
||||
|
|
@ -708,6 +703,9 @@ func TestStore(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("should exists a secret in the local store and filesystem", func(t *testing.T) {
|
||||
ngx_config.EnableDynamicCertificates = false
|
||||
defer func() { ngx_config.EnableDynamicCertificates = true }()
|
||||
|
||||
err := framework.WaitForSecretInNamespace(clientSet, ns, name)
|
||||
if err != nil {
|
||||
t.Errorf("error waiting for secret: %v", err)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue