1
0
Fork 0
mirror of https://github.com/external-secrets/external-secrets.git synced 2024-12-14 11:57:59 +00:00

Set metadata to external secrets managed by cluster external secrets (#2413)

Signed-off-by: shuheiktgw <s-kitagawa@mercari.com>
This commit is contained in:
Shuhei Kitagawa 2023-06-15 06:23:04 +09:00 committed by GitHub
parent c9d09546c1
commit 9dd4186df1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 154 additions and 8 deletions

View file

@ -28,6 +28,10 @@ type ClusterExternalSecretSpec struct {
// +optional
ExternalSecretName string `json:"externalSecretName"`
// The metadata of the external secrets to be created
// +optional
ExternalSecretMetadata ExternalSecretMetadata `json:"externalSecretMetadata"`
// The labels to select by to find the Namespaces to create the ExternalSecrets in.
NamespaceSelector metav1.LabelSelector `json:"namespaceSelector"`
@ -35,6 +39,15 @@ type ClusterExternalSecretSpec struct {
RefreshInterval *metav1.Duration `json:"refreshTime,omitempty"`
}
// ExternalSecretMetadata defines metadata fields for the ExternalSecret generated by the ClusterExternalSecret.
type ExternalSecretMetadata struct {
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// +optional
Labels map[string]string `json:"labels,omitempty"`
}
type ClusterExternalSecretConditionType string
const (

View file

@ -492,6 +492,7 @@ func (in *ClusterExternalSecretNamespaceFailure) DeepCopy() *ClusterExternalSecr
func (in *ClusterExternalSecretSpec) DeepCopyInto(out *ClusterExternalSecretSpec) {
*out = *in
in.ExternalSecretSpec.DeepCopyInto(&out.ExternalSecretSpec)
in.ExternalSecretMetadata.DeepCopyInto(&out.ExternalSecretMetadata)
in.NamespaceSelector.DeepCopyInto(&out.NamespaceSelector)
if in.RefreshInterval != nil {
in, out := &in.RefreshInterval, &out.RefreshInterval
@ -855,6 +856,35 @@ func (in *ExternalSecretList) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalSecretMetadata) DeepCopyInto(out *ExternalSecretMetadata) {
*out = *in
if in.Annotations != nil {
in, out := &in.Annotations, &out.Annotations
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.Labels != nil {
in, out := &in.Labels, &out.Labels
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretMetadata.
func (in *ExternalSecretMetadata) DeepCopy() *ExternalSecretMetadata {
if in == nil {
return nil
}
out := new(ExternalSecretMetadata)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExternalSecretRewrite) DeepCopyInto(out *ExternalSecretRewrite) {
*out = *in

View file

@ -51,6 +51,18 @@ spec:
spec:
description: ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.
properties:
externalSecretMetadata:
description: The metadata of the external secrets to be created
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
externalSecretName:
description: The name of the external secrets to be created defaults
to the name of the ClusterExternalSecret

View file

@ -46,6 +46,18 @@ spec:
spec:
description: ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.
properties:
externalSecretMetadata:
description: The metadata of the external secrets to be created
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
externalSecretName:
description: The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
type: string

View file

@ -1160,6 +1160,20 @@ string
</tr>
<tr>
<td>
<code>externalSecretMetadata</code></br>
<em>
<a href="#external-secrets.io/v1beta1.ExternalSecretMetadata">
ExternalSecretMetadata
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>The metadata of the external secrets to be created</p>
</td>
</tr>
<tr>
<td>
<code>namespaceSelector</code></br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#labelselector-v1-meta">
@ -1310,6 +1324,20 @@ string
</tr>
<tr>
<td>
<code>externalSecretMetadata</code></br>
<em>
<a href="#external-secrets.io/v1beta1.ExternalSecretMetadata">
ExternalSecretMetadata
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>The metadata of the external secrets to be created</p>
</td>
</tr>
<tr>
<td>
<code>namespaceSelector</code></br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#labelselector-v1-meta">
@ -2342,6 +2370,47 @@ ExternalSecretDecodingStrategy
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1beta1.ExternalSecretMetadata">ExternalSecretMetadata
</h3>
<p>
(<em>Appears on:</em>
<a href="#external-secrets.io/v1beta1.ClusterExternalSecretSpec">ClusterExternalSecretSpec</a>)
</p>
<p>
<p>ExternalSecretMetadata defines metadata fields for the ExternalSecret generated by the ClusterExternalSecret.</p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>annotations</code></br>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
</td>
</tr>
<tr>
<td>
<code>labels</code></br>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
</td>
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1beta1.ExternalSecretMetadataPolicy">ExternalSecretMetadataPolicy
(<code>string</code> alias)</p></h3>
<p>

View file

@ -118,7 +118,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
continue
}
if result, err := r.resolveExternalSecret(ctx, &clusterExternalSecret, &existingES, namespace, esName); err != nil {
if result, err := r.resolveExternalSecret(ctx, &clusterExternalSecret, &existingES, namespace, esName, clusterExternalSecret.Spec.ExternalSecretMetadata); err != nil {
log.Error(err, result)
failedNamespaces[namespace.Name] = result
continue
@ -139,7 +139,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
return ctrl.Result{RequeueAfter: refreshInt}, nil
}
func (r *Reconciler) resolveExternalSecret(ctx context.Context, clusterExternalSecret *esv1beta1.ClusterExternalSecret, existingES *esv1beta1.ExternalSecret, namespace v1.Namespace, esName string) (string, error) {
func (r *Reconciler) resolveExternalSecret(ctx context.Context, clusterExternalSecret *esv1beta1.ClusterExternalSecret, existingES *esv1beta1.ExternalSecret, namespace v1.Namespace, esName string, esMetadata esv1beta1.ExternalSecretMetadata) (string, error) {
// this means the existing ES does not belong to us
if err := controllerutil.SetControllerReference(clusterExternalSecret, existingES, r.Scheme); err != nil {
return errSetCtrlReference, err
@ -147,8 +147,10 @@ func (r *Reconciler) resolveExternalSecret(ctx context.Context, clusterExternalS
externalSecret := esv1beta1.ExternalSecret{
ObjectMeta: metav1.ObjectMeta{
Name: esName,
Namespace: namespace.Name,
Name: esName,
Namespace: namespace.Name,
Labels: esMetadata.Labels,
Annotations: esMetadata.Annotations,
},
Spec: clusterExternalSecret.Spec.ExternalSecretSpec,
}

View file

@ -94,10 +94,6 @@ var _ = Describe("ClusterExternalSecret controller", func() {
ExternalSecretName = "test-es"
ExternalSecretStore = "test-store"
ExternalSecretTargetSecretName = "test-secret"
ClusterSecretStoreNamespace = "css-test-ns"
FakeManager = "fake.manager"
FooValue = "map-foo-value"
BarValue = "map-bar-value"
)
var ExternalSecretNamespaceTargets = []testNamespace{
@ -203,6 +199,17 @@ var _ = Describe("ClusterExternalSecret controller", func() {
}
}
syncWithESMetadata := func(tc *testCase) {
tc.clusterExternalSecret.Spec.ExternalSecretMetadata = esv1beta1.ExternalSecretMetadata{
Labels: map[string]string{"test-label-key1": "test-label-value1", "test-label-key2": "test-label-value2"},
Annotations: map[string]string{"test-annotation-key1": "test-annotation-value1", "test-annotation-key2": "test-annotation-value2"},
}
tc.checkExternalSecret = func(ces *esv1beta1.ClusterExternalSecret, es *esv1beta1.ExternalSecret) {
Expect(es.ObjectMeta.Labels).To(Equal(map[string]string{"test-label-key1": "test-label-value1", "test-label-key2": "test-label-value2"}))
Expect(es.ObjectMeta.Annotations).To(Equal(map[string]string{"test-annotation-key1": "test-annotation-value1", "test-annotation-key2": "test-annotation-value2"}))
}
}
doNotOverwriteExistingES := func(tc *testCase) {
tc.preTest = func() {
es := &esv1beta1.ExternalSecret{
@ -366,6 +373,7 @@ var _ = Describe("ClusterExternalSecret controller", func() {
},
Entry("Should use cluster external secret name if external secret name isn't defined", syncWithoutESName),
Entry("Should set external secret metadata if the field is set", syncWithESMetadata),
Entry("Should not overwrite existing external secrets and error out if one is present", doNotOverwriteExistingES),
Entry("Should have list of all provisioned namespaces", populatedProvisionedNamespaces),
Entry("Should delete external secrets when namespaces no longer match", deleteESInNonMatchingNS),