@@ -12,10 +12,25 @@ import (
12
12
routeapi "github.com/openshift/origin/pkg/route/apis/route"
13
13
)
14
14
15
+ // certificateFile represents a certificate file.
16
+ type certificateFile struct {
17
+ CertDir string
18
+ ID string
19
+ Contents []byte
20
+ }
21
+
22
+ // certificateFileTag generates a certificate file tag/name. This is used to
23
+ // index into the map of deleted certificates.
24
+ func (cf certificateFile ) Tag () string {
25
+ return filepath .Join (cf .CertDir , cf .ID + ".pem" )
26
+ }
27
+
15
28
// simpleCertificateManager is the default implementation of a certificateManager
16
29
type simpleCertificateManager struct {
17
30
cfg * certificateManagerConfig
18
31
w certificateWriter
32
+
33
+ deletedCertificates map [string ]certificateFile
19
34
}
20
35
21
36
// newSimpleCertificateManager should be used to create a new cert manager. It will return an error
@@ -27,7 +42,7 @@ func newSimpleCertificateManager(cfg *certificateManagerConfig, w certificateWri
27
42
if w == nil {
28
43
return nil , fmt .Errorf ("certificate manager requires a certificate writer" )
29
44
}
30
- return & simpleCertificateManager {cfg , w }, nil
45
+ return & simpleCertificateManager {cfg , w , make ( map [ string ] certificateFile , 0 ) }, nil
31
46
}
32
47
33
48
// validateCertManagerConfig ensures that the key functions and directories are set as well as
@@ -81,6 +96,8 @@ func (cm *simpleCertificateManager) WriteCertificatesForConfig(config *ServiceAl
81
96
buffer .Write ([]byte (caCertObj .Contents ))
82
97
}
83
98
99
+ certFile := certificateFile {CertDir : cm .cfg .certDir , ID : certObj .ID }
100
+ delete (cm .deletedCertificates , certFile .Tag ())
84
101
if err := cm .w .WriteCertificate (cm .cfg .certDir , certObj .ID , buffer .Bytes ()); err != nil {
85
102
return err
86
103
}
@@ -92,6 +109,8 @@ func (cm *simpleCertificateManager) WriteCertificatesForConfig(config *ServiceAl
92
109
destCert , ok := config .Certificates [destCertKey ]
93
110
94
111
if ok {
112
+ destCertFile := certificateFile {CertDir : cm .cfg .caCertDir , ID : destCert .ID }
113
+ delete (cm .deletedCertificates , destCertFile .Tag ())
95
114
if err := cm .w .WriteCertificate (cm .cfg .caCertDir , destCert .ID , []byte (destCert .Contents )); err != nil {
96
115
return err
97
116
}
@@ -101,7 +120,7 @@ func (cm *simpleCertificateManager) WriteCertificatesForConfig(config *ServiceAl
101
120
return nil
102
121
}
103
122
104
- // deleteCertificatesForConfig will delete all certificates for the ServiceAliasConfig
123
+ // DeleteCertificatesForConfig will delete all certificates for the ServiceAliasConfig
105
124
func (cm * simpleCertificateManager ) DeleteCertificatesForConfig (config * ServiceAliasConfig ) error {
106
125
if config == nil {
107
126
return nil
@@ -112,10 +131,8 @@ func (cm *simpleCertificateManager) DeleteCertificatesForConfig(config *ServiceA
112
131
certObj , ok := config .Certificates [certKey ]
113
132
114
133
if ok {
115
- err := cm .w .DeleteCertificate (cm .cfg .certDir , certObj .ID )
116
- if err != nil {
117
- return err
118
- }
134
+ certFile := certificateFile {CertDir : cm .cfg .certDir , ID : certObj .ID }
135
+ cm .deletedCertificates [certFile .Tag ()] = certFile
119
136
}
120
137
}
121
138
@@ -124,16 +141,41 @@ func (cm *simpleCertificateManager) DeleteCertificatesForConfig(config *ServiceA
124
141
destCert , ok := config .Certificates [destCertKey ]
125
142
126
143
if ok {
127
- err := cm .w .DeleteCertificate (cm .cfg .caCertDir , destCert .ID )
128
- if err != nil {
129
- return err
130
- }
144
+
145
+ destCertFile := certificateFile {CertDir : cm .cfg .caCertDir , ID : destCert .ID }
146
+ cm .deletedCertificates [destCertFile .Tag ()] = destCertFile
131
147
}
132
148
}
133
149
}
134
150
return nil
135
151
}
136
152
153
+ // Commit applies any pending changes made to the certificateManager.
154
+ func (cm * simpleCertificateManager ) Commit () error {
155
+ // Deletion of certificates that are being referenced in backends or
156
+ // config is problematic in that the template router will not
157
+ // reload because the config is invalid, so we _do_ need to "stage"
158
+ // or commit the removals. Remove all the deleted certificates.
159
+ for _ , certFile := range cm .deletedCertificates {
160
+ err := cm .w .DeleteCertificate (certFile .CertDir , certFile .ID )
161
+ if err != nil {
162
+ // TODO: Do we care if a file deletion failed?
163
+ // Otherwise we will keep hitting this error on
164
+ // every commit. Should we just ignore errors here?
165
+ // Clean this up based on review comments.
166
+ // FIXME: return err
167
+ }
168
+ }
169
+
170
+ cm .deletedCertificates = make (map [string ]certificateFile , 0 )
171
+
172
+ // If we decide to stage the certificate writes, we can flush the
173
+ // write to the disk here. The tradeoff is storing a copy in memory
174
+ // until we commit.
175
+
176
+ return nil
177
+ }
178
+
137
179
// simpleCertificateWriter is the default implementation of a certificateWriter
138
180
type simpleCertificateWriter struct {}
139
181
0 commit comments