Skip to content

Commit 0bd3dad

Browse files
committed
Use x-kubernetes-action instead of operationId to generate method names
1 parent 2cf1a53 commit 0bd3dad

File tree

11 files changed

+189
-315
lines changed

11 files changed

+189
-315
lines changed

Directory.Packages.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
3434
</ItemGroup>
3535
<ItemGroup>
36+
<PackageVersion Include="Humanizer.Core" Version="2.14.1" />
3637
<PackageVersion Include="Autofac" Version="8.2.1" />
3738
<PackageVersion Include="CaseExtensions" Version="1.1.0" />
3839
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.13.0" />
@@ -50,4 +51,4 @@
5051
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.7.112" />
5152
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
5253
</ItemGroup>
53-
</Project>
54+
</Project>

examples/clientset/Program.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@ internal class Program
99
{
1010
private static async Task Main(string[] args)
1111
{
12+
1213
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
1314
IKubernetes client = new Kubernetes(config);
1415

1516
ClientSet clientSet = new ClientSet(client);
16-
var list = await clientSet.CoreV1.Pod.ListNamespacedPodAsync("default").ConfigureAwait(false);
17+
var list = await clientSet.CoreV1.Pods.ListAsync("default").ConfigureAwait(false);
1718
foreach (var item in list)
1819
{
1920
System.Console.WriteLine(item.Metadata.Name);
2021
}
22+
23+
var pod = await clientSet.CoreV1.Pods.GetAsync("test","default").ConfigureAwait(false);
24+
System.Console.WriteLine(pod?.Metadata?.Name);
2125
}
2226
}
2327

src/KubernetesClient/AbstractKubernetes.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace k8s;
55

66
public abstract partial class AbstractKubernetes
77
{
8-
internal static class HttpMethods
8+
private static class HttpMethods
99
{
1010
public static readonly HttpMethod Delete = HttpMethod.Delete;
1111
public static readonly HttpMethod Get = HttpMethod.Get;
@@ -23,7 +23,7 @@ internal static class HttpMethods
2323

2424
}
2525

26-
internal sealed class QueryBuilder
26+
private sealed class QueryBuilder
2727
{
2828
private readonly List<string> parameters = new List<string>();
2929

@@ -99,7 +99,7 @@ private MediaTypeHeaderValue GetHeader(V1Patch body)
9999
}
100100
}
101101

102-
internal abstract Task<HttpOperationResponse<T>> CreateResultAsync<T>(HttpRequestMessage httpRequest, HttpResponseMessage httpResponse, bool? watch, CancellationToken cancellationToken);
102+
protected abstract Task<HttpOperationResponse<T>> CreateResultAsync<T>(HttpRequestMessage httpRequest, HttpResponseMessage httpResponse, bool? watch, CancellationToken cancellationToken);
103103

104-
internal abstract Task<HttpResponseMessage> SendRequest<T>(string relativeUri, HttpMethod method, IReadOnlyDictionary<string, IReadOnlyList<string>> customHeaders, T body, CancellationToken cancellationToken);
104+
protected abstract Task<HttpResponseMessage> SendRequest<T>(string relativeUri, HttpMethod method, IReadOnlyDictionary<string, IReadOnlyList<string>> customHeaders, T body, CancellationToken cancellationToken);
105105
}

src/KubernetesClient/GenericClient.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ public GenericClient(IKubernetes kubernetes, string group, string version, strin
3131
public async Task<T> CreateAsync<T>(T obj, CancellationToken cancel = default)
3232
where T : IKubernetesObject
3333
{
34-
3534
var resp = await kubernetes.CustomObjects.CreateClusterCustomObjectWithHttpMessagesAsync<T>(obj, group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
3635
return resp.Body;
3736
}

src/KubernetesClient/Kubernetes.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private void Initialize()
5656
BaseUri = new Uri("http://localhost");
5757
}
5858

59-
internal override async Task<HttpOperationResponse<T>> CreateResultAsync<T>(HttpRequestMessage httpRequest, HttpResponseMessage httpResponse, bool? watch, CancellationToken cancellationToken)
59+
protected override async Task<HttpOperationResponse<T>> CreateResultAsync<T>(HttpRequestMessage httpRequest, HttpResponseMessage httpResponse, bool? watch, CancellationToken cancellationToken)
6060
{
6161
if (httpRequest == null)
6262
{
@@ -96,7 +96,7 @@ internal override async Task<HttpOperationResponse<T>> CreateResultAsync<T>(Http
9696
return result;
9797
}
9898

99-
internal override Task<HttpResponseMessage> SendRequest<T>(string relativeUri, HttpMethod method, IReadOnlyDictionary<string, IReadOnlyList<string>> customHeaders, T body, CancellationToken cancellationToken)
99+
protected override Task<HttpResponseMessage> SendRequest<T>(string relativeUri, HttpMethod method, IReadOnlyDictionary<string, IReadOnlyList<string>> customHeaders, T body, CancellationToken cancellationToken)
100100
{
101101
var httpRequest = new HttpRequestMessage
102102
{

src/LibKubernetesGenerator/ClientSetGenerator.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using NSwag;
44
using System.Collections.Generic;
55
using System.Linq;
6+
using Humanizer;
67

78
namespace LibKubernetesGenerator
89
{
@@ -65,13 +66,12 @@ public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializa
6566
var groupVersionKindElements = x.Operation?.ExtensionData?["x-kubernetes-group-version-kind"];
6667
var groupVersionKind = (Dictionary<string, object>)groupVersionKindElements;
6768

68-
return new { Kind = groupVersionKind?["kind"], Api = x };
69-
69+
return new { Kind = groupVersionKind?["kind"] as string, Api = x };
7070
});
7171

7272
foreach (var item in apis.GroupBy(x => x.Kind))
7373
{
74-
var kind = item.Key as string;
74+
var kind = item.Key.Pluralize();
7575
apiGroups[kind] = item.Select(x => x.Api).ToArray();
7676
clients.Add(kind);
7777
}
@@ -85,11 +85,11 @@ public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializa
8585
{
8686
var name = apiGroup.Key;
8787
var apis = apiGroup.Value.ToArray();
88-
88+
var group = apis.Select(x => x.Operation.Tags[0]).First();
8989
sc.SetValue("apis", apis, true);
9090
sc.SetValue("name", name, true);
91+
sc.SetValue("group", group.ToPascalCase(), true);
9192
context.RenderToContext("Client.cs.template", sc, $"{name}Client.g.cs");
92-
context.RenderToContext("ClientExtensions.cs.template", sc, $"{name}ClientExtensions.g.cs");
9393
}
9494

9595
sc = _scriptObjectFactory.CreateScriptObject();

src/LibKubernetesGenerator/GeneralNameHelper.cs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ public void RegisterHelper(ScriptObject scriptObject)
2222
{
2323
scriptObject.Import(nameof(GetInterfaceName), new Func<JsonSchema, string>(GetInterfaceName));
2424
scriptObject.Import(nameof(GetMethodName), new Func<OpenApiOperation, string, string>(GetMethodName));
25+
scriptObject.Import(nameof(GetActionName),
26+
new Func<OpenApiOperationDescription, string, string, string>(GetActionName));
2527
scriptObject.Import(nameof(GetDotNetName), new Func<string, string, string>(GetDotNetName));
26-
scriptObject.Import(nameof(GetDotNetNameOpenApiParameter), new Func<OpenApiParameter, string, string>(GetDotNetNameOpenApiParameter));
28+
scriptObject.Import(nameof(GetDotNetNameOpenApiParameter),
29+
new Func<OpenApiParameter, string, string>(GetDotNetNameOpenApiParameter));
2730
}
2831

2932
private string GetInterfaceName(JsonSchema definition)
@@ -162,5 +165,60 @@ public static string GetMethodName(OpenApiOperation watchOperation, string suffi
162165

163166
return methodName;
164167
}
168+
169+
public static string GetActionName(OpenApiOperationDescription apiOperation, string resource, string suffix)
170+
{
171+
var actionType = apiOperation.Operation?.ExtensionData?["x-kubernetes-action"] as string;
172+
173+
if (string.IsNullOrEmpty(actionType))
174+
{
175+
return $"{apiOperation.Method.ToPascalCase()}{suffix}";
176+
}
177+
178+
var resourceNamespace = ParsePathSegmentAfterParameter(apiOperation.Path, "namespace").ToPascalCase();
179+
var resourceName = ParsePathSegmentAfterParameter(apiOperation.Path, "name").ToPascalCase();
180+
var actionMappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
181+
{
182+
{ "get", "Get" },
183+
{ "list", "List" },
184+
{ "put", "Put" },
185+
{ "patch", "Patch" },
186+
{ "post", "Post" },
187+
{ "delete", "Delete" },
188+
{ "deletecollection", "DeleteCollection" },
189+
{ "watch", "Watch" },
190+
{ "watchlist", "WatchList" },
191+
{ "proxy", "Proxy" },
192+
};
193+
194+
if (actionMappings.TryGetValue(actionType, out var actionPrefix))
195+
{
196+
return Regex.Replace($"{actionPrefix}{resourceNamespace}{resourceName}{suffix}", resource, string.Empty,
197+
RegexOptions.IgnoreCase);
198+
}
199+
200+
if (string.Equals("connect", actionType, StringComparison.OrdinalIgnoreCase))
201+
{
202+
return Regex.Replace($"Connect{apiOperation.Method}{resourceNamespace}{resourceName}{suffix}", resource,
203+
string.Empty,
204+
RegexOptions.IgnoreCase);
205+
}
206+
207+
return $"{actionType.ToPascalCase()}{suffix}";
208+
}
209+
210+
private static string ParsePathSegmentAfterParameter(string path, string variableName = "namespace")
211+
{
212+
var pattern = $@"/\{{{variableName}\}}/([^/]+)/?";
213+
214+
var match = Regex.Match(path, pattern);
215+
216+
if (match.Success && match.Groups.Count > 1)
217+
{
218+
return match.Groups[1].Value;
219+
}
220+
221+
return string.Empty;
222+
}
165223
}
166224
}

src/LibKubernetesGenerator/KubernetesClientSourceGenerator.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,42 @@ private static IContainer BuildContainer(OpenApiDocument swagger)
2121
builder.RegisterType<ClassNameHelper>()
2222
.WithParameter(new NamedParameter(nameof(swagger), swagger))
2323
.AsSelf()
24-
.AsImplementedInterfaces();
24+
.AsImplementedInterfaces()
25+
;
2526

2627
builder.RegisterType<StringHelpers>()
27-
.AsImplementedInterfaces();
28+
.AsImplementedInterfaces()
29+
;
2830

2931
builder.RegisterType<MetaHelper>()
30-
.AsImplementedInterfaces();
32+
.AsImplementedInterfaces()
33+
;
3134

3235
builder.RegisterType<PluralHelper>()
3336
.WithParameter(new TypedParameter(typeof(OpenApiDocument), swagger))
34-
.AsImplementedInterfaces();
37+
.AsImplementedInterfaces()
38+
;
3539

3640
builder.RegisterType<GeneralNameHelper>()
3741
.AsSelf()
38-
.AsImplementedInterfaces();
42+
.AsImplementedInterfaces()
43+
;
3944

4045
builder.RegisterType<TypeHelper>()
4146
.AsSelf()
42-
.AsImplementedInterfaces();
47+
.AsImplementedInterfaces()
48+
;
4349

4450
builder.RegisterType<ParamHelper>()
45-
.AsImplementedInterfaces();
51+
.AsImplementedInterfaces()
52+
;
4653

4754
builder.RegisterType<UtilHelper>()
48-
.AsImplementedInterfaces();
55+
.AsImplementedInterfaces()
56+
;
4957

50-
builder.RegisterType<ScriptObjectFactory>();
58+
builder.RegisterType<ScriptObjectFactory>()
59+
;
5160

5261
builder.RegisterType<ModelExtGenerator>();
5362
builder.RegisterType<ModelGenerator>();

src/LibKubernetesGenerator/LibKubernetesGenerator.target

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
</ItemGroup>
1717

1818
<ItemGroup>
19+
1920
<!-- Scriban No Dependency -->
2021
<PackageReference Include="Scriban" IncludeAssets="Build" />
2122

2223
<!-- CaseExtensions No Dependency -->
2324
<PackageReference Include="CaseExtensions" GeneratePathProperty="true" PrivateAssets="all" />
2425

26+
<!-- Humanizer -->
27+
<PackageReference Include="Humanizer.Core" GeneratePathProperty="true" PrivateAssets="all"/>
28+
2529
<!-- Autofac -->
2630
<PackageReference Include="Autofac" GeneratePathProperty="true" PrivateAssets="all" />
2731
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" GeneratePathProperty="true" PrivateAssets="all" />
@@ -43,6 +47,7 @@
4347
<Target Name="GetDependencyTargetPaths">
4448
<ItemGroup>
4549
<TargetPathWithTargetPlatformMoniker Include="$(PKGCaseExtensions)\lib\netstandard2.0\CaseExtensions.dll" IncludeRuntimeDependency="false" />
50+
<TargetPathWithTargetPlatformMoniker Include="$(PKGHumanizer_Core)\lib\netstandard2.0\Humanizer.dll" IncludeRuntimeDependency="false" />
4651

4752
<TargetPathWithTargetPlatformMoniker Include="$(PKGAutofac)\lib\netstandard2.0\Autofac.dll" IncludeRuntimeDependency="false" />
4853
<TargetPathWithTargetPlatformMoniker Include="$(PKGMicrosoft_Bcl_AsyncInterfaces)\lib\netstandard2.0\Microsoft.Bcl.AsyncInterfaces.dll" IncludeRuntimeDependency="false" />

0 commit comments

Comments
 (0)