@@ -16,125 +16,175 @@ limitations under the License.
16
16
17
17
package writer
18
18
19
- //import (
20
- // "fmt"
21
- // "strings"
22
- //
23
- // admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
24
- // "k8s.io/apimachinery/pkg/api/meta"
25
- // "k8s.io/apimachinery/pkg/runtime"
26
- // "sigs.k8s.io/controller-runtime/pkg/admission/certgenerator"
27
- //)
28
- //
29
- //const (
30
- // // FSCertProvisionAnnotationKeyPrefix should be used in an annotation in the following format:
31
- // // fs.certprovisioner.kubernetes.io/<webhook-name>: path/to/certs/
32
- // // the webhook cert manager library will provision the certificate for the webhook by
33
- // // storing it under the specified path.
34
- // // format: local.certprovisioner.kubernetes.io/webhookName: path/to/certs/
35
- // FSCertProvisionAnnotationKeyPrefix = "fs.certprovisioner.kubernetes.io/"
36
- //)
37
- //
38
- //// FSCertWriterProvider deals with writing to the local filesystem.
39
- //type FSCertWriterProvider struct {
40
- // CertGenerator certgenerator.CertGenerator
41
- //}
42
- //
43
- //var _ CertWriter = &FSCertWriterProvider{}
44
- //
45
- //// Provide creates a new CertWriter and initialized with the passed-in webhookConfig.
46
- //func (s *FSCertWriterProvider) Provide(webhookConfig runtime.Object) (CertWriter, error) {
47
- // fsWebhookMap := map[string]*webhookAndPath{}
48
- //
49
- // accessor, err := meta.Accessor(webhookConfig)
50
- // if err != nil {
51
- // return nil, err
52
- // }
53
- // annotations := accessor.GetAnnotations()
54
- // if annotations == nil {
55
- // return nil, nil
56
- // }
57
- //
58
- // // Parse the annotations to extract info
59
- // for k, v := range annotations {
60
- // // an example annotation: local.certprovisioner.kubernetes.io/webhookName: path/to/certs/
61
- // if strings.HasPrefix(k, FSCertProvisionAnnotationKeyPrefix) {
62
- // webhookName := strings.TrimPrefix(k, FSCertProvisionAnnotationKeyPrefix)
63
- // fsWebhookMap[webhookName] = &webhookAndPath{
64
- // path: v,
65
- // }
66
- // }
67
- // }
68
- //
69
- // webhooks, err := getWebhooksFromObject(webhookConfig)
70
- // if err != nil {
71
- // return nil, err
72
- // }
73
- // for i, webhook := range webhooks {
74
- // if p, found := fsWebhookMap[webhook.Name]; found {
75
- // p.webhook = &webhooks[i]
76
- // }
77
- // }
78
- //
79
- // // validation
80
- // for k, v := range fsWebhookMap {
81
- // if v.webhook == nil {
82
- // return nil, fmt.Errorf("expecting a webhook named %q", k)
83
- // }
84
- // }
85
- //
86
- // generator := s.CertGenerator
87
- // if s.CertGenerator == nil {
88
- // generator = &certgenerator.SelfSignedCertGenerator{}
89
- // }
90
- //
91
- // return &fsCertWriter{
92
- // CertGenerator: generator,
93
- // webhookConfig: webhookConfig,
94
- // webhookToPath: fsWebhookMap,
95
- // }, nil
96
- //}
97
- //
98
- //// fsCertWriter deals with writing to the local filesystem.
99
- //type fsCertWriter struct {
100
- // CertGenerator certgenerator.CertGenerator
101
- //
102
- // webhookConfig runtime.Object
103
- // webhookToPath map[string]*webhookAndPath
104
- //}
105
- //
106
- //type webhookAndPath struct {
107
- // webhook *admissionregistrationv1beta1.Webhook
108
- // path string
109
- //}
110
- //
111
- //var _ certReadWriter = &fsCertWriter{}
112
- //
113
- //// EnsureCert processes the webhooks managed by this CertWriter.
114
- //// It provisions the certificate and update the CA in the webhook.
115
- //// It will write the certificate to the filesystem.
116
- //func (s *fsCertWriter) EnsureCert() error {
117
- // var err error
118
- // for _, v := range s.webhookToPath {
119
- // err = handleCommon(v.webhook, s)
120
- // if err != nil {
121
- // return err
122
- // }
123
- // }
124
- // return nil
125
- //}
126
- //
127
- //func (s *fsCertWriter) write(webhookName string) (*certgenerator.CertArtifacts, error) {
128
- // // TODO: implement this
129
- // return nil, nil
130
- //}
131
- //
132
- //func (s *fsCertWriter) overwrite(webhookName string) (*certgenerator.CertArtifacts, error) {
133
- // // TODO: implement this
134
- // return nil, nil
135
- //}
136
- //
137
- //func (s *fsCertWriter) read(webhookName string) (*certgenerator.CertArtifacts, error) {
138
- // // TODO: implement this
139
- // return nil, nil
140
- //}
19
+ import (
20
+ "fmt"
21
+ "io/ioutil"
22
+ "path"
23
+ "strings"
24
+
25
+ admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
26
+ "k8s.io/apimachinery/pkg/api/meta"
27
+ "k8s.io/apimachinery/pkg/runtime"
28
+ certgenerator "sigs.k8s.io/controller-runtime/pkg/admission/cert/generator"
29
+ "sigs.k8s.io/controller-runtime/pkg/admission/cert/writer/internal/atomic"
30
+ )
31
+
32
+ const (
33
+ // FSCertProvisionAnnotationKeyPrefix should be used in an annotation in the following format:
34
+ // fs.certprovisioner.kubernetes.io/<webhook-name>: path/to/certs/
35
+ // the webhook cert manager library will provision the certificate for the webhook by
36
+ // storing it under the specified path.
37
+ // format: fs.certprovisioner.kubernetes.io/webhookName: path/to/certs/
38
+ FSCertProvisionAnnotationKeyPrefix = "fs.certprovisioner.kubernetes.io/"
39
+ )
40
+
41
+ // FSCertWriter provisions the certificate by reading and writing to the filesystem.
42
+ type FSCertWriter struct {
43
+ CertGenerator certgenerator.CertGenerator
44
+ }
45
+
46
+ var _ CertWriter = & FSCertWriter {}
47
+
48
+ // EnsureCerts provisions certificates for a webhook configuration by writing them in the filesystem.
49
+ func (s * FSCertWriter ) EnsureCerts (webhookConfig runtime.Object ) error {
50
+ webhookMap := map [string ]* webhookAndPath {}
51
+
52
+ accessor , err := meta .Accessor (webhookConfig )
53
+ if err != nil {
54
+ return err
55
+ }
56
+ annotations := accessor .GetAnnotations ()
57
+ if annotations == nil {
58
+ return nil
59
+ }
60
+
61
+ // Parse the annotations to extract info
62
+ for k , v := range annotations {
63
+ // an example annotation: fs.certprovisioner.kubernetes.io/webhookName: path/to/certs/
64
+ if strings .HasPrefix (k , FSCertProvisionAnnotationKeyPrefix ) {
65
+ webhookName := strings .TrimPrefix (k , FSCertProvisionAnnotationKeyPrefix )
66
+ webhookMap [webhookName ] = & webhookAndPath {
67
+ path : v ,
68
+ }
69
+ }
70
+ }
71
+
72
+ webhooks , err := getWebhooksFromObject (webhookConfig )
73
+ if err != nil {
74
+ return err
75
+ }
76
+ for i , webhook := range webhooks {
77
+ if p , found := webhookMap [webhook .Name ]; found {
78
+ p .webhook = & webhooks [i ]
79
+ }
80
+ }
81
+
82
+ // validation
83
+ for k , v := range webhookMap {
84
+ if v .webhook == nil {
85
+ return fmt .Errorf ("expecting a webhook named %q" , k )
86
+ }
87
+ }
88
+
89
+ generator := s .CertGenerator
90
+ if s .CertGenerator == nil {
91
+ generator = & certgenerator.SelfSignedCertGenerator {}
92
+ }
93
+
94
+ cw := & fsCertWriter {
95
+ certGenerator : generator ,
96
+ webhookConfig : webhookConfig ,
97
+ webhookMap : webhookMap ,
98
+ }
99
+ return cw .ensureCert ()
100
+ }
101
+
102
+ // fsCertWriter deals with writing to the local filesystem.
103
+ type fsCertWriter struct {
104
+ certGenerator certgenerator.CertGenerator
105
+
106
+ webhookConfig runtime.Object
107
+ webhookMap map [string ]* webhookAndPath
108
+ }
109
+
110
+ type webhookAndPath struct {
111
+ webhook * admissionregistrationv1beta1.Webhook
112
+ path string
113
+ }
114
+
115
+ var _ certReadWriter = & fsCertWriter {}
116
+
117
+ func (s * fsCertWriter ) ensureCert () error {
118
+ var err error
119
+ for _ , v := range s .webhookMap {
120
+ err = handleCommon (v .webhook , s )
121
+ if err != nil {
122
+ return err
123
+ }
124
+ }
125
+ return nil
126
+ }
127
+
128
+ func (f * fsCertWriter ) write (webhookName string ) (* certgenerator.Artifacts , error ) {
129
+ return f .doWrite (webhookName )
130
+ }
131
+
132
+ func (f * fsCertWriter ) overwrite (webhookName string ) (* certgenerator.Artifacts , error ) {
133
+ return f .doWrite (webhookName )
134
+ }
135
+
136
+ func (f * fsCertWriter ) doWrite (webhookName string ) (* certgenerator.Artifacts , error ) {
137
+ v := f .webhookMap [webhookName ]
138
+ commonName , err := dnsNameForWebhook (& v .webhook .ClientConfig )
139
+ if err != nil {
140
+ return nil , err
141
+ }
142
+ certs , err := f .certGenerator .Generate (commonName )
143
+ if err != nil {
144
+ return nil , err
145
+ }
146
+ aw , err := atomic .NewAtomicWriter (v .path , fmt .Sprintf ("processing webhook %q" , webhookName ))
147
+ if err != nil {
148
+ return nil , err
149
+ }
150
+ err = aw .Write (certToProjectionMap (certs ))
151
+ return certs , err
152
+ }
153
+
154
+ func (f * fsCertWriter ) read (webhookName string ) (* certgenerator.Artifacts , error ) {
155
+ dir := f .webhookMap [webhookName ].path
156
+ caBytes , err := ioutil .ReadFile (path .Join (dir , CACertName ))
157
+ if err != nil {
158
+ return nil , err
159
+ }
160
+ certBytes , err := ioutil .ReadFile (path .Join (dir , ServerCertName ))
161
+ if err != nil {
162
+ return nil , err
163
+ }
164
+ keyBytes , err := ioutil .ReadFile (path .Join (dir , ServerKeyName ))
165
+ if err != nil {
166
+ return nil , err
167
+ }
168
+ return & certgenerator.Artifacts {
169
+ CACert : caBytes ,
170
+ Cert : certBytes ,
171
+ Key : keyBytes ,
172
+ }, nil
173
+ }
174
+
175
+ func certToProjectionMap (cert * certgenerator.Artifacts ) map [string ]atomic.FileProjection {
176
+ return map [string ]atomic.FileProjection {
177
+ CACertName : {
178
+ Data : cert .CACert ,
179
+ Mode : 0666 ,
180
+ },
181
+ ServerCertName : {
182
+ Data : cert .Cert ,
183
+ Mode : 0666 ,
184
+ },
185
+ ServerKeyName : {
186
+ Data : cert .Key ,
187
+ Mode : 0666 ,
188
+ },
189
+ }
190
+ }
0 commit comments