1
16
17 package writer
18
19 import (
20 "context"
21 "errors"
22
23 corev1 "k8s.io/api/core/v1"
24 apierrors "k8s.io/apimachinery/pkg/api/errors"
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 "k8s.io/apimachinery/pkg/types"
27 "sigs.k8s.io/controller-runtime/pkg/client"
28
29 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/webhook/cert/generator"
30 )
31
32
33 type secretCertWriter struct {
34 *SecretCertWriterOptions
35
36
37 dnsName string
38 }
39
40
41 type SecretCertWriterOptions struct {
42
43 Client client.Client
44
45 CertGenerator generator.CertGenerator
46
47 Secret *types.NamespacedName
48 }
49
50 var _ CertWriter = &secretCertWriter{}
51
52 func (ops *SecretCertWriterOptions) setDefaults() {
53 if ops.CertGenerator == nil {
54 ops.CertGenerator = &generator.SelfSignedCertGenerator{}
55 }
56 }
57
58 func (ops *SecretCertWriterOptions) validate() error {
59 if ops.Client == nil {
60 return errors.New("client must be set in SecretCertWriterOptions")
61 }
62 if ops.Secret == nil {
63 return errors.New("secret must be set in SecretCertWriterOptions")
64 }
65 return nil
66 }
67
68
69 func NewSecretCertWriter(ops SecretCertWriterOptions) (CertWriter, error) {
70 ops.setDefaults()
71 err := ops.validate()
72 if err != nil {
73 return nil, err
74 }
75 return &secretCertWriter{
76 SecretCertWriterOptions: &ops,
77 }, nil
78 }
79
80
81 func (s *secretCertWriter) EnsureCert(dnsName string) (*generator.Artifacts, bool, error) {
82
83 s.dnsName = dnsName
84 return handleCommon(s.dnsName, s)
85 }
86
87 var _ certReadWriter = &secretCertWriter{}
88
89 func (s *secretCertWriter) buildSecret() (*corev1.Secret, *generator.Artifacts, error) {
90 certs, err := s.CertGenerator.Generate(s.dnsName)
91 if err != nil {
92 return nil, nil, err
93 }
94 secret := certsToSecret(certs, *s.Secret)
95 return secret, certs, err
96 }
97
98 func (s *secretCertWriter) write() (*generator.Artifacts, error) {
99 secret, certs, err := s.buildSecret()
100 if err != nil {
101 return nil, err
102 }
103 err = s.Client.Create(context.Background(), secret)
104 if apierrors.IsAlreadyExists(err) {
105 return nil, alreadyExistError{err}
106 }
107 return certs, err
108 }
109
110 func (s *secretCertWriter) overwrite() (
111 *generator.Artifacts, error) {
112 secret, certs, err := s.buildSecret()
113 if err != nil {
114 return nil, err
115 }
116 err = s.Client.Update(context.Background(), secret)
117 return certs, err
118 }
119
120 func (s *secretCertWriter) read() (*generator.Artifacts, error) {
121 secret := &corev1.Secret{
122 TypeMeta: metav1.TypeMeta{
123 APIVersion: "v1",
124 Kind: "Secret",
125 },
126 }
127 err := s.Client.Get(context.Background(), *s.Secret, secret)
128 if apierrors.IsNotFound(err) {
129 return nil, notFoundError{err}
130 }
131 certs := secretToCerts(secret)
132 if certs != nil {
133
134 s.CertGenerator.SetCA(certs.CAKey, certs.CACert)
135 }
136 return certs, nil
137 }
138
139 func secretToCerts(secret *corev1.Secret) *generator.Artifacts {
140 if secret.Data == nil {
141 return nil
142 }
143 return &generator.Artifacts{
144 CAKey: secret.Data[CAKeyName],
145 CACert: secret.Data[CACertName],
146 Cert: secret.Data[ServerCertName],
147 Key: secret.Data[ServerKeyName],
148 }
149 }
150
151 func certsToSecret(certs *generator.Artifacts, sec types.NamespacedName) *corev1.Secret {
152 return &corev1.Secret{
153 TypeMeta: metav1.TypeMeta{
154 APIVersion: "v1",
155 Kind: "Secret",
156 },
157 ObjectMeta: metav1.ObjectMeta{
158 Namespace: sec.Namespace,
159 Name: sec.Name,
160 },
161 Data: map[string][]byte{
162 CAKeyName: certs.CAKey,
163 CACertName: certs.CACert,
164 ServerKeyName: certs.Key,
165 ServerCertName: certs.Cert,
166 },
167 }
168 }
169
170
171 func (s *secretCertWriter) Inject(objs ...client.Object) error {
172
173
174
175
176
177
178
179
180
181
182
183
184 return nil
185 }
186
View as plain text