-
Couldn't load subscription status.
- Fork 110
Allow to remap key name when mirroring secret #475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -149,6 +149,19 @@ public async Task Handle(WatcherEvent notification, CancellationToken cancellati | |
| } | ||
| } | ||
|
|
||
| protected IDictionary<string, T> MappedData<T>(IDictionary<string, T>? data, Dictionary<string, string>? mapping = null) | ||
| { | ||
| mapping ??= new Dictionary<string, string>(); | ||
| IDictionary<string, T> newData = new Dictionary<string, T>(); | ||
| if (data != null) | ||
| { | ||
| foreach (var (key, value) in data) | ||
| { | ||
| newData.Add(mapping.GetValueOrDefault(key, key), value); | ||
| } | ||
| } | ||
| return newData; | ||
| } | ||
|
|
||
| private async Task HandleUpsert(TResource resource, WatchEventType eventType, CancellationToken cancellationToken) | ||
| { | ||
|
|
@@ -428,25 +441,38 @@ private async Task ResourceReflect(KubeRef sourceId, KubeRef targetId, TResource | |
| [Annotations.Reflection.MetaReflectedVersion] = source.Metadata.ResourceVersion, | ||
| [Annotations.Reflection.MetaReflectedAt] = JsonConvert.SerializeObject(DateTimeOffset.UtcNow) | ||
| }; | ||
| patchAnnotations[Annotations.Reflection.KeyMapping] = ""; | ||
| if (autoReflection) | ||
| { | ||
| patchAnnotations[Annotations.Reflection.KeyMapping] = autoReflection ? source.GetReflectionProperties().AutoKeyMapping : string.Empty; | ||
| } else if (targetResource is not null) | ||
| { | ||
| patchAnnotations[Annotations.Reflection.KeyMapping] = | ||
| targetResource.Metadata.Annotations.TryGetValue(Annotations.Reflection.KeyMapping, out var keyMapping) ? keyMapping : string.Empty; | ||
| } | ||
|
|
||
| Dictionary<string, string> mapping = new Dictionary<string, string>(); | ||
| try | ||
| { | ||
| mapping = Mapping(patchAnnotations[Annotations.Reflection.KeyMapping]); | ||
| } | ||
| catch (FormatException e) | ||
| { | ||
| Logger.LogError(e, e.Message); | ||
| } | ||
|
|
||
| try | ||
| { | ||
| if (targetResource is null) | ||
| { | ||
| var newResource = await OnResourceClone(source); | ||
| var newResource = await OnResourceClone(source, mapping); | ||
| newResource.Metadata ??= new V1ObjectMeta(); | ||
| newResource.Metadata.Name = targetId.Name; | ||
| newResource.Metadata.NamespaceProperty = targetId.Namespace; | ||
| newResource.Metadata.Annotations ??= new Dictionary<string, string>(); | ||
| var newResourceAnnotations = newResource.Metadata.Annotations; | ||
| foreach (var patchAnnotation in patchAnnotations) | ||
| newResourceAnnotations[patchAnnotation.Key] = patchAnnotation.Value; | ||
| newResourceAnnotations[Annotations.Reflection.MetaAutoReflects] = autoReflection.ToString(); | ||
|
||
| newResourceAnnotations[Annotations.Reflection.Reflects] = sourceId.ToString(); | ||
| newResourceAnnotations[Annotations.Reflection.MetaReflectedVersion] = source.Metadata.ResourceVersion; | ||
| newResourceAnnotations[Annotations.Reflection.MetaReflectedAt] = | ||
| JsonConvert.SerializeObject(DateTimeOffset.UtcNow); | ||
|
|
||
| try | ||
| { | ||
|
|
@@ -476,7 +502,7 @@ private async Task ResourceReflect(KubeRef sourceId, KubeRef targetId, TResource | |
| annotations[patchAnnotation.Key] = patchAnnotation.Value; | ||
| patchDoc.Replace(e => e.Metadata.Annotations, annotations); | ||
|
|
||
| await OnResourceConfigurePatch(source, patchDoc); | ||
| await OnResourceConfigurePatch(source, patchDoc, mapping); | ||
|
|
||
| var patch = JsonConvert.SerializeObject(patchDoc, Formatting.Indented); | ||
| await OnResourceApplyPatch(new V1Patch(patch, V1Patch.PatchType.JsonPatch), targetId); | ||
|
|
@@ -488,11 +514,31 @@ private async Task ResourceReflect(KubeRef sourceId, KubeRef targetId, TResource | |
| } | ||
| } | ||
|
|
||
| private Dictionary<string, string> Mapping(string? keyMapping) | ||
| { | ||
| var mappings = new Dictionary<string, string>(); | ||
| if (string.IsNullOrEmpty(keyMapping)) return mappings; | ||
|
|
||
| foreach (var definition in keyMapping.Split(",")) | ||
| { | ||
| var definitionDetail = definition.Split(":"); | ||
| if (definitionDetail.Length == 2) | ||
| { | ||
| mappings.Add(definitionDetail[0], definitionDetail[1]); | ||
| } | ||
| else | ||
| { | ||
| throw new FormatException("Invalid key mapping, format is src_key:dst_key,src_other:dst_other. Received: " + definition); | ||
| } | ||
| } | ||
| return mappings; | ||
| } | ||
|
|
||
|
|
||
| protected abstract Task OnResourceApplyPatch(V1Patch source, KubeRef refId); | ||
| protected abstract Task OnResourceConfigurePatch(TResource source, JsonPatchDocument<TResource> patchDoc); | ||
| protected abstract Task OnResourceConfigurePatch(TResource source, JsonPatchDocument<TResource> patchDoc, Dictionary<string, string> mapping); | ||
| protected abstract Task OnResourceCreate(TResource item, string ns); | ||
| protected abstract Task<TResource> OnResourceClone(TResource sourceResource); | ||
| protected abstract Task<TResource> OnResourceClone(TResource sourceResource, Dictionary<string, string> mapping); | ||
| protected abstract Task OnResourceDelete(KubeRef resourceId); | ||
|
|
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mapping.GetValueOrDefault(key, key)could easily be an empty string - which is fine. But in this case you should not copy the data over.Example: mapping 'tls.key:' would NOT copy over the private key.
Use case: I have a secret created by the cert manager and I want to copy it over to another namespace. But I only want the public key! Private key must stay with the source...since this is kind of the point of certificates :D
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not necessary true, I have a use case where two signer need the same key, I want to copy the key too.
Nevertheless I understand what you mean.
Currently you cannot copy partially, the idea was to improve the functionality, not necessary to add a comprehensive behaviour.
To do something more complex (i.e. what you suggest), a combination reflector + external-secret can do the job at the moment (technically even what I added, but it can be useful for small problems).