Skip to content

[bug]: Cannot create mutation webhook with built-in resources #713

@stevefan1999-personal

Description

@stevefan1999-personal

Describe the bug

Ditto to title

To reproduce

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <InvariantGlobalization>true</InvariantGlobalization>
    <PublishAot>true</PublishAot>
    <EnablePreviewFeatures>true</EnablePreviewFeatures>
    <JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
    <TrimMode>copy</TrimMode>
    <EnableTrimAnalyzer>true</EnableTrimAnalyzer>
    <IlcGenerateCompleteTypeMetadata>true</IlcGenerateCompleteTypeMetadata>

  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="KubeOps.Generator" Version="8.0.1-pre.6" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
    <PackageReference Include="KubeOps.Operator.Web" Version="8.0.1-pre.6" />
  </ItemGroup>

</Project>
using k8s.Models;
using KubeOps.Abstractions.Controller;
using KubeOps.Abstractions.Entities;
using KubeOps.Abstractions.Rbac;
using KubeOps.Operator;
using KubeOps.Operator.Web.Builder;
using KubeOps.Operator.Web.Webhooks.Admission.Mutation;
var builder = WebApplication.CreateSlimBuilder(args);

builder.Services
    .AddKubernetesOperator()
    .RegisterComponents()
#if DEBUG
    .AddDevelopmentTunnel(5000)
#endif
    ;
builder.Services
    .AddControllers();

var app = builder.Build();

app.UseRouting();
app.UseDeveloperExceptionPage();
app.MapControllers();

app.MapGet("/", () => "Hello World!");

await app.RunAsync();

[MutationWebhook(typeof(V1Service))]
public class ServiceMutationWebhook(ILogger<ServiceMutationWebhook> logger) : MutationWebhook<V1Service>
{
    public override MutationResult<V1Service> Create(V1Service entity, bool dryRun)
    {
        logger.LogInformation("{}", entity);

        return NoChanges();
    }
}

Expected behavior

It works

Screenshots

fail: Microsoft.Extensions.Hosting.Internal.Host[11]
      Hosting failed to start
      k8s.Autorest.HttpOperationException: Operation returned an invalid status code 'UnprocessableEntity', response body {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"MutatingWebhookConfiguration.admissionregistration.k8s.io \"dev-mutators\" is invalid: webhooks[1].name: Invalid value: \"mutate.service..v1\": a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')","reason":"Invalid","details":{"name":"dev-mutators","group":"admissionregistration.k8s.io","kind":"MutatingWebhookConfiguration","causes":[{"reason":"FieldValueInvalid","message":"Invalid value: \"mutate.service..v1\": a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')","field":"webhooks[1].name"}]},"code":422}

         at k8s.Kubernetes.SendRequestRaw(String requestContent, HttpRequestMessage httpRequest, CancellationToken cancellationToken)
         at k8s.AbstractKubernetes.ICustomObjectsOperations_ReplaceClusterCustomObjectWithHttpMessagesAsync[T](Object body, String group, String version, String plural, String name, String dryRun, String fieldManager, IReadOnlyDictionary`2 customHeaders, CancellationToken cancellationToken)
         at k8s.AbstractKubernetes.k8s.ICustomObjectsOperations.ReplaceClusterCustomObjectWithHttpMessagesAsync[T](Object body, String group, String version, String plural, String name, String dryRun, String fieldManager, IReadOnlyDictionary`2 customHeaders, CancellationToken cancellationToken)
         at k8s.GenericClient.ReplaceAsync[T](T obj, String name, CancellationToken cancel)
         at KubeOps.KubernetesClient.KubernetesClient.UpdateAsync[TEntity](TEntity entity)
         at KubeOps.KubernetesClient.IKubernetesClient.SaveAsync[TEntity](TEntity entity)
         at KubeOps.Operator.Web.LocalTunnel.DevelopmentTunnelService.RegisterMutators(Uri uri)
         at KubeOps.Operator.Web.LocalTunnel.DevelopmentTunnelService.StartAsync(CancellationToken cancellationToken)
         at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
         at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
Unhandled exception. k8s.Autorest.HttpOperationException: Operation returned an invalid status code 'UnprocessableEntity', response body {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"MutatingWebhookConfiguration.admissionregistration.k8s.io \"dev-mutators\" is invalid: webhooks[1].name: Invalid value: \"mutate.service..v1\": a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')","reason":"Invalid","details":{"name":"dev-mutators","group":"admissionregistration.k8s.io","kind":"MutatingWebhookConfiguration","causes":[{"reason":"FieldValueInvalid","message":"Invalid value: \"mutate.service..v1\": a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')","field":"webhooks[1].name"}]},"code":422}

   at k8s.Kubernetes.SendRequestRaw(String requestContent, HttpRequestMessage httpRequest, CancellationToken cancellationToken)
   at k8s.AbstractKubernetes.ICustomObjectsOperations_ReplaceClusterCustomObjectWithHttpMessagesAsync[T](Object body, String group, String version, String plural, String name, String dryRun, String fieldManager, IReadOnlyDictionary`2 customHeaders, CancellationToken cancellationToken)    
   at k8s.AbstractKubernetes.k8s.ICustomObjectsOperations.ReplaceClusterCustomObjectWithHttpMessagesAsync[T](Object body, String group, String version, String plural, String name, String dryRun, String fieldManager, IReadOnlyDictionary`2 customHeaders, CancellationToken cancellationToken)
   at k8s.GenericClient.ReplaceAsync[T](T obj, String name, CancellationToken cancel)
   at KubeOps.KubernetesClient.KubernetesClient.UpdateAsync[TEntity](TEntity entity)
   at KubeOps.KubernetesClient.IKubernetesClient.SaveAsync[TEntity](TEntity entity)
   at KubeOps.Operator.Web.LocalTunnel.DevelopmentTunnelService.RegisterMutators(Uri uri)
   at KubeOps.Operator.Web.LocalTunnel.DevelopmentTunnelService.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
   at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Program.<Main>$(String[] args) in F:\csharp\SteamGsltOperator\SteamGsltOperator.Operator\Program.cs:line 29
   at Program.<Main>(String[] args)

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions