Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions src/KubeOps/Operator/Commands/Management/Webhooks/Install.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ public Install(
LongName = "ca-certs")]
public string CaCertificatesPath { get; set; } = "/ca";

[Option(
Description =
"If specified and set to true it will replace already existing webhooks",
ShortName = "r",
LongName = "replace-existing")]
public bool ReplaceExistingWebhooks { get; set; }

public async Task<int> OnExecuteAsync(CommandLineApplication app)
{
var client = app.GetRequiredService<IKubernetesClient>();
Expand Down Expand Up @@ -116,7 +123,27 @@ await client.Create(
validatorConfig.Metadata.OwnerReferences = new List<V1OwnerReference> { deployment.MakeOwnerReference(), };
}

await client.Save(validatorConfig);
if (ReplaceExistingWebhooks)
{
// var existingItems = await client.List<V1ValidatingWebhookConfiguration>();
// var existingItem = existingItems.FirstOrDefault(item => item.Name() == validatorConfig.Name());
var existingItem = await client.Get<V1ValidatingWebhookConfiguration>(validatorConfig.Name());
if (existingItem != null)
{
await app.Out.WriteLineAsync("Validator existed, updating.");
await client.Update(existingItem);
}
else
{
await app.Out.WriteLineAsync("Validator didn't exist, creating.");
await client.Save(validatorConfig);
}
}
else
{
await app.Out.WriteLineAsync("Not updating validator, attempting to save.");
await client.Save(validatorConfig);
}

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

await client.Save(mutatorConfig);
if (ReplaceExistingWebhooks)
{
var existingItem = await client.Get<V1MutatingWebhookConfiguration>(mutatorConfig.Name());
if (existingItem != null)
{
await app.Out.WriteLineAsync("Mutator existed, updating.");
await client.Update(existingItem);
}
else
{
await app.Out.WriteLineAsync("Mutator didn't exist, creating.");
await client.Save(mutatorConfig);
}
}
else
{
await app.Out.WriteLineAsync("Not updating mutator, attempting to save.");
await client.Save(mutatorConfig);
}

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

Expand Down
15 changes: 15 additions & 0 deletions src/KubeOps/Operator/Webhooks/IConfigurableMutationWebhook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using k8s.Models;

namespace KubeOps.Operator.Webhooks;

/// <summary>
/// Implement this interface to configure the MutatingWebhook object before it is applied to Kubernetes.
/// </summary>
public interface IConfigurableMutationWebhook
{
/// <summary>
/// Called when building the MutatingWebhook to allow further customizations before it is applied.
/// </summary>
/// <param name="webhook">The MutatingWebhook that will be applied.</param>
void Configure(V1MutatingWebhook webhook);
}
15 changes: 15 additions & 0 deletions src/KubeOps/Operator/Webhooks/IConfigurableValidationWebhook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using k8s.Models;

namespace KubeOps.Operator.Webhooks;

/// <summary>
/// Implement this interface to configure the ValidatingWebhook object before it is applied to Kubernetes.
/// </summary>
public interface IConfigurableValidationWebhook
{
/// <summary>
/// Called when building the ValidatingWebhook to allow further customizations before it is applied.
/// </summary>
/// <param name="webhook">The ValidatingWebhook that will be applied.</param>
void Configure(V1ValidatingWebhook webhook);
}
11 changes: 9 additions & 2 deletions src/KubeOps/Operator/Webhooks/MutatingWebhookBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Reflection;
using System.Reflection;
using k8s.Models;
using KubeOps.KubernetesClient.Entities;
using KubeOps.Operator.Builder;
Expand Down Expand Up @@ -60,7 +60,7 @@ public List<V1MutatingWebhook> BuildWebhooks(WebhookConfig webhookConfig)

var crd = entityType.ToEntityDefinition();

return new V1MutatingWebhook
var webhook = new V1MutatingWebhook
{
Name = name.TrimWebhookName(),
AdmissionReviewVersions = new[] { "v1" },
Expand All @@ -79,6 +79,13 @@ public List<V1MutatingWebhook> BuildWebhooks(WebhookConfig webhookConfig)
},
ClientConfig = clientConfig,
};

if (instance is IConfigurableMutationWebhook configurable)
{
configurable.Configure(webhook);
}

return webhook;
})
.ToList();
}
Expand Down
11 changes: 9 additions & 2 deletions src/KubeOps/Operator/Webhooks/ValidatingWebhookBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Reflection;
using System.Reflection;
using k8s.Models;
using KubeOps.KubernetesClient.Entities;
using KubeOps.Operator.Builder;
Expand Down Expand Up @@ -60,7 +60,7 @@ public List<V1ValidatingWebhook> BuildWebhooks(WebhookConfig webhookConfig)

var crd = entityType.ToEntityDefinition();

return new V1ValidatingWebhook
var webhook = new V1ValidatingWebhook
{
Name = name.TrimWebhookName(),
AdmissionReviewVersions = new[] { "v1" },
Expand All @@ -79,6 +79,13 @@ public List<V1ValidatingWebhook> BuildWebhooks(WebhookConfig webhookConfig)
},
ClientConfig = clientConfig,
};

if (instance is IConfigurableValidationWebhook configurable)
{
configurable.Configure(webhook);
}

return webhook;
})
.ToList();
}
Expand Down