Skip to content

Commit 4bc5868

Browse files
authoredMar 1, 2023
feat: Adds the ability to replace webhooks on startup and configure the webhooks when creating (#538)
Fixes #525 and #532
1 parent 0d9e504 commit 4bc5868

File tree

5 files changed

+95
-6
lines changed

5 files changed

+95
-6
lines changed
 

‎src/KubeOps/Operator/Commands/Management/Webhooks/Install.cs

+47-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ public Install(
4343
LongName = "ca-certs")]
4444
public string CaCertificatesPath { get; set; } = "/ca";
4545

46+
[Option(
47+
Description =
48+
"If specified and set to true it will replace already existing webhooks",
49+
ShortName = "r",
50+
LongName = "replace-existing")]
51+
public bool ReplaceExistingWebhooks { get; set; }
52+
4653
public async Task<int> OnExecuteAsync(CommandLineApplication app)
4754
{
4855
var client = app.GetRequiredService<IKubernetesClient>();
@@ -116,7 +123,27 @@ await client.Create(
116123
validatorConfig.Metadata.OwnerReferences = new List<V1OwnerReference> { deployment.MakeOwnerReference(), };
117124
}
118125

119-
await client.Save(validatorConfig);
126+
if (ReplaceExistingWebhooks)
127+
{
128+
// var existingItems = await client.List<V1ValidatingWebhookConfiguration>();
129+
// var existingItem = existingItems.FirstOrDefault(item => item.Name() == validatorConfig.Name());
130+
var existingItem = await client.Get<V1ValidatingWebhookConfiguration>(validatorConfig.Name());
131+
if (existingItem != null)
132+
{
133+
await app.Out.WriteLineAsync("Validator existed, updating.");
134+
await client.Update(existingItem);
135+
}
136+
else
137+
{
138+
await app.Out.WriteLineAsync("Validator didn't exist, creating.");
139+
await client.Save(validatorConfig);
140+
}
141+
}
142+
else
143+
{
144+
await app.Out.WriteLineAsync("Not updating validator, attempting to save.");
145+
await client.Save(validatorConfig);
146+
}
120147

121148
await app.Out.WriteLineAsync("Create mutator definition.");
122149
var mutatorConfig = _mutatingWebhookConfigurationBuilder.BuildWebhookConfiguration(webhookConfig);
@@ -125,7 +152,25 @@ await client.Create(
125152
mutatorConfig.Metadata.OwnerReferences = new List<V1OwnerReference> { deployment.MakeOwnerReference(), };
126153
}
127154

128-
await client.Save(mutatorConfig);
155+
if (ReplaceExistingWebhooks)
156+
{
157+
var existingItem = await client.Get<V1MutatingWebhookConfiguration>(mutatorConfig.Name());
158+
if (existingItem != null)
159+
{
160+
await app.Out.WriteLineAsync("Mutator existed, updating.");
161+
await client.Update(existingItem);
162+
}
163+
else
164+
{
165+
await app.Out.WriteLineAsync("Mutator didn't exist, creating.");
166+
await client.Save(mutatorConfig);
167+
}
168+
}
169+
else
170+
{
171+
await app.Out.WriteLineAsync("Not updating mutator, attempting to save.");
172+
await client.Save(mutatorConfig);
173+
}
129174

130175
await app.Out.WriteLineAsync("Installed webhook service and admission configurations.");
131176

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using k8s.Models;
2+
3+
namespace KubeOps.Operator.Webhooks;
4+
5+
/// <summary>
6+
/// Implement this interface to configure the MutatingWebhook object before it is applied to Kubernetes.
7+
/// </summary>
8+
public interface IConfigurableMutationWebhook
9+
{
10+
/// <summary>
11+
/// Called when building the MutatingWebhook to allow further customizations before it is applied.
12+
/// </summary>
13+
/// <param name="webhook">The MutatingWebhook that will be applied.</param>
14+
void Configure(V1MutatingWebhook webhook);
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using k8s.Models;
2+
3+
namespace KubeOps.Operator.Webhooks;
4+
5+
/// <summary>
6+
/// Implement this interface to configure the ValidatingWebhook object before it is applied to Kubernetes.
7+
/// </summary>
8+
public interface IConfigurableValidationWebhook
9+
{
10+
/// <summary>
11+
/// Called when building the ValidatingWebhook to allow further customizations before it is applied.
12+
/// </summary>
13+
/// <param name="webhook">The ValidatingWebhook that will be applied.</param>
14+
void Configure(V1ValidatingWebhook webhook);
15+
}

‎src/KubeOps/Operator/Webhooks/MutatingWebhookBuilder.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Reflection;
1+
using System.Reflection;
22
using k8s.Models;
33
using KubeOps.KubernetesClient.Entities;
44
using KubeOps.Operator.Builder;
@@ -60,7 +60,7 @@ public List<V1MutatingWebhook> BuildWebhooks(WebhookConfig webhookConfig)
6060

6161
var crd = entityType.ToEntityDefinition();
6262

63-
return new V1MutatingWebhook
63+
var webhook = new V1MutatingWebhook
6464
{
6565
Name = name.TrimWebhookName(),
6666
AdmissionReviewVersions = new[] { "v1" },
@@ -79,6 +79,13 @@ public List<V1MutatingWebhook> BuildWebhooks(WebhookConfig webhookConfig)
7979
},
8080
ClientConfig = clientConfig,
8181
};
82+
83+
if (instance is IConfigurableMutationWebhook configurable)
84+
{
85+
configurable.Configure(webhook);
86+
}
87+
88+
return webhook;
8289
})
8390
.ToList();
8491
}

‎src/KubeOps/Operator/Webhooks/ValidatingWebhookBuilder.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Reflection;
1+
using System.Reflection;
22
using k8s.Models;
33
using KubeOps.KubernetesClient.Entities;
44
using KubeOps.Operator.Builder;
@@ -60,7 +60,7 @@ public List<V1ValidatingWebhook> BuildWebhooks(WebhookConfig webhookConfig)
6060

6161
var crd = entityType.ToEntityDefinition();
6262

63-
return new V1ValidatingWebhook
63+
var webhook = new V1ValidatingWebhook
6464
{
6565
Name = name.TrimWebhookName(),
6666
AdmissionReviewVersions = new[] { "v1" },
@@ -79,6 +79,13 @@ public List<V1ValidatingWebhook> BuildWebhooks(WebhookConfig webhookConfig)
7979
},
8080
ClientConfig = clientConfig,
8181
};
82+
83+
if (instance is IConfigurableValidationWebhook configurable)
84+
{
85+
configurable.Configure(webhook);
86+
}
87+
88+
return webhook;
8289
})
8390
.ToList();
8491
}

0 commit comments

Comments
 (0)
Please sign in to comment.