Skip to content

Commit 81b9fa7

Browse files
author
Mengqi Yu
committed
fs cert writer
1 parent 12d5374 commit 81b9fa7

File tree

3 files changed

+177
-127
lines changed

3 files changed

+177
-127
lines changed

pkg/admission/cert/writer/certwriter.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ func NewCertWriter(ops Options) (CertWriter, error) {
6666
Client: ops.Client,
6767
CertGenerator: ops.CertGenerator,
6868
}
69-
//f := &FSCertWriter{
70-
// CertGenerator: ops.CertGenerator,
71-
//}
69+
f := &FSCertWriter{
70+
CertGenerator: ops.CertGenerator,
71+
}
7272
return &MultiCertWriter{
7373
CertWriters: []CertWriter{
7474
s,
75-
//f,
75+
f,
7676
},
7777
}, nil
7878
}

pkg/admission/cert/writer/certwriter_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ var _ = Describe("NewProvider", func() {
5757
Client: cl,
5858
CertGenerator: &generator.SelfSignedCertGenerator{},
5959
},
60-
//&FSCertWriterProvider{
60+
//&FSCertWriter{
6161
// CertGenerator: &certgenerator.SelfSignedCertGenerator{},
6262
//},
6363
},

pkg/admission/cert/writer/fs.go

Lines changed: 172 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -16,125 +16,175 @@ limitations under the License.
1616

1717
package writer
1818

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

Comments
 (0)