istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/keycertbundle/watcher.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package keycertbundle 16 17 import ( 18 "os" 19 "sync" 20 ) 21 22 // KeyCertBundle stores the cert, private key and root cert for istiod. 23 type KeyCertBundle struct { 24 CertPem []byte 25 KeyPem []byte 26 CABundle []byte 27 } 28 29 type Watcher struct { 30 mutex sync.RWMutex 31 bundle KeyCertBundle 32 watcherID int32 33 watchers map[int32]chan struct{} 34 } 35 36 func NewWatcher() *Watcher { 37 return &Watcher{ 38 watchers: make(map[int32]chan struct{}), 39 } 40 } 41 42 // AddWatcher returns channel to receive the updated items. 43 func (w *Watcher) AddWatcher() (int32, chan struct{}) { 44 ch := make(chan struct{}, 1) 45 w.mutex.Lock() 46 defer w.mutex.Unlock() 47 id := w.watcherID 48 w.watchers[id] = ch 49 w.watcherID++ 50 51 return id, ch 52 } 53 54 // RemoveWatcher removes the given watcher. 55 func (w *Watcher) RemoveWatcher(id int32) { 56 w.mutex.Lock() 57 defer w.mutex.Unlock() 58 ch := w.watchers[id] 59 if ch != nil { 60 close(ch) 61 } 62 delete(w.watchers, id) 63 } 64 65 // SetAndNotify sets the key cert and root cert and notify the watchers. 66 func (w *Watcher) SetAndNotify(key, cert, caBundle []byte) { 67 w.mutex.Lock() 68 defer w.mutex.Unlock() 69 if len(key) != 0 { 70 w.bundle.KeyPem = key 71 } 72 if len(cert) != 0 { 73 w.bundle.CertPem = cert 74 } 75 if len(caBundle) != 0 { 76 w.bundle.CABundle = caBundle 77 } 78 for _, ch := range w.watchers { 79 select { 80 case ch <- struct{}{}: 81 default: 82 } 83 } 84 } 85 86 // SetFromFilesAndNotify sets the key cert and root cert from files and notify the watchers. 87 func (w *Watcher) SetFromFilesAndNotify(keyFile, certFile, rootCert string) error { 88 cert, err := os.ReadFile(certFile) 89 if err != nil { 90 return err 91 } 92 key, err := os.ReadFile(keyFile) 93 if err != nil { 94 return err 95 } 96 caBundle, err := os.ReadFile(rootCert) 97 if err != nil { 98 return err 99 } 100 w.SetAndNotify(key, cert, caBundle) 101 return nil 102 } 103 104 // GetCABundle returns the CABundle. 105 func (w *Watcher) GetCABundle() []byte { 106 w.mutex.RLock() 107 defer w.mutex.RUnlock() 108 return w.bundle.CABundle 109 } 110 111 // GetKeyCertBundle returns the bundle. 112 func (w *Watcher) GetKeyCertBundle() KeyCertBundle { 113 w.mutex.RLock() 114 defer w.mutex.RUnlock() 115 return w.bundle 116 }