Allow multi patch http content type header (#521)
* header from obj * update git version mod * remove json patch test * test for json patch
This commit is contained in:
10
.github/workflows/buildtest.yaml
vendored
10
.github/workflows/buildtest.yaml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
name: Dotnet build
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup dotnet SDK 2.1
|
||||
@@ -19,6 +19,10 @@ jobs:
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.x'
|
||||
- name: Setup dotnet SDK 5
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
- name: Setup Format
|
||||
run: dotnet tool install -g dotnet-format
|
||||
- name: Check Format
|
||||
@@ -48,6 +52,10 @@ jobs:
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.x'
|
||||
- name: Setup dotnet SDK 5
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
- name: Minikube
|
||||
run: minikube start
|
||||
- name: Test
|
||||
|
||||
40
src/KubernetesClient/Kubernetes.Header.cs
Normal file
40
src/KubernetesClient/Kubernetes.Header.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Net.Http.Headers;
|
||||
using k8s.Models;
|
||||
|
||||
namespace k8s
|
||||
{
|
||||
public partial class Kubernetes
|
||||
{
|
||||
public virtual MediaTypeHeaderValue GetHeader(object body)
|
||||
{
|
||||
if (body == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(body));
|
||||
}
|
||||
|
||||
return MediaTypeHeaderValue.Parse("application/json; charset=utf-8");
|
||||
}
|
||||
|
||||
|
||||
public virtual MediaTypeHeaderValue GetHeader(V1Patch body)
|
||||
{
|
||||
if (body == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(body));
|
||||
}
|
||||
|
||||
switch (body.Type)
|
||||
{
|
||||
case V1Patch.PatchType.JsonPatch:
|
||||
return MediaTypeHeaderValue.Parse("application/json-patch+json; charset=utf-8");
|
||||
case V1Patch.PatchType.MergePatch:
|
||||
return MediaTypeHeaderValue.Parse("application/merge-patch+json; charset=utf-8");
|
||||
case V1Patch.PatchType.StrategicMergePatch:
|
||||
return MediaTypeHeaderValue.Parse("application/strategic-merge-patch+json; charset=utf-8");
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(body.Type), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Authors>The Kubernetes Project Authors</Authors>
|
||||
<Copyright>2017 The Kubernetes Project Authors</Copyright>
|
||||
@@ -30,18 +30,19 @@
|
||||
<PackageReference Include="AutoMapper" Version="7.0.1" Condition="'$(TargetFramework)' == 'net452'" />
|
||||
<PackageReference Include="AutoMapper" Version="9.0.0" Condition="'$(TargetFramework)' != 'net452'" />
|
||||
<PackageReference Include="Fractions" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="1.1.2" Condition="'$(TargetFramework)' != 'netstandard2.0' and '$(TargetFramework)' != 'netcoreapp2.1'" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp2.1'" />
|
||||
<PackageReference Include="Nerdbank.GitVersioning" Version="3.0.50" PrivateAssets="all" />
|
||||
<PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.3" />
|
||||
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.10" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" Condition="'$(TargetFramework)' != 'netstandard2.0' and '$(TargetFramework)' != 'netcoreapp2.1'" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp2.1'" />
|
||||
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" Condition="'$(TargetFramework)' == 'net452'" />
|
||||
<PackageReference Include="YamlDotNet" Version="8.1.2" />
|
||||
<PackageReference Include="System.Buffers" Version="4.5.1" Condition="'$(TargetFramework)' != 'netcoreapp2.1'" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net452'">
|
||||
<Reference Include="System.Runtime.InteropServices" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.JsonPatch;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace k8s.Models
|
||||
@@ -9,6 +8,7 @@ namespace k8s.Models
|
||||
{
|
||||
public enum PatchType
|
||||
{
|
||||
Unknown,
|
||||
JsonPatch,
|
||||
MergePatch,
|
||||
StrategicMergePatch,
|
||||
@@ -16,31 +16,24 @@ namespace k8s.Models
|
||||
|
||||
public PatchType Type { get; private set; }
|
||||
|
||||
public V1Patch(IJsonPatchDocument jsonPatch)
|
||||
: this((object)jsonPatch)
|
||||
public V1Patch(object body, PatchType type)
|
||||
{
|
||||
}
|
||||
|
||||
public V1Patch(String body, PatchType type)
|
||||
: this(body)
|
||||
{
|
||||
this.Type = type;
|
||||
Content = body;
|
||||
Type = type;
|
||||
CustomInit();
|
||||
}
|
||||
|
||||
partial void CustomInit()
|
||||
{
|
||||
if (Content is IJsonPatchDocument)
|
||||
if (Content == null)
|
||||
{
|
||||
Type = PatchType.JsonPatch;
|
||||
return;
|
||||
throw new ArgumentNullException(nameof(Content), "object must be set");
|
||||
}
|
||||
|
||||
if (Content is String)
|
||||
if (Type == PatchType.Unknown)
|
||||
{
|
||||
return;
|
||||
throw new ArgumentException("patch type must be set", nameof(Type));
|
||||
}
|
||||
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
990
src/KubernetesClient/generated/Kubernetes.cs
generated
990
src/KubernetesClient/generated/Kubernetes.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -4,12 +4,14 @@
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>..\..\src\KubernetesClient\kubernetes-client.snk</AssemblyOriginatorKeyFile>
|
||||
<RootNamespace>k8s.E2E</RootNamespace>
|
||||
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0" />
|
||||
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using k8s.Models;
|
||||
using Microsoft.AspNetCore.JsonPatch;
|
||||
using Microsoft.Rest;
|
||||
using Xunit;
|
||||
|
||||
@@ -12,7 +15,7 @@ namespace k8s.E2E
|
||||
public void SimpleTest()
|
||||
{
|
||||
var namespaceParameter = "default";
|
||||
var podName = "k8s-e2e-pod";
|
||||
var podName = "k8scsharp-e2e-pod";
|
||||
|
||||
var client = CreateClient();
|
||||
|
||||
@@ -35,7 +38,7 @@ namespace k8s.E2E
|
||||
Metadata = new V1ObjectMeta { Name = podName, },
|
||||
Spec = new V1PodSpec
|
||||
{
|
||||
Containers = new[] { new V1Container() { Name = "k8s-e2e", Image = "nginx", }, },
|
||||
Containers = new[] { new V1Container() { Name = "k8scsharp-e2e", Image = "nginx", }, },
|
||||
},
|
||||
},
|
||||
namespaceParameter);
|
||||
@@ -49,6 +52,112 @@ namespace k8s.E2E
|
||||
}
|
||||
}
|
||||
|
||||
[MinikubeFact]
|
||||
public void PatchTest()
|
||||
{
|
||||
var namespaceParameter = "default";
|
||||
var podName = "k8scsharp-e2e-patch-pod";
|
||||
|
||||
var client = CreateClient();
|
||||
|
||||
void Cleanup()
|
||||
{
|
||||
var pods = client.ListNamespacedPod(namespaceParameter);
|
||||
while (pods.Items.Any(p => p.Metadata.Name == podName))
|
||||
{
|
||||
try
|
||||
{
|
||||
client.DeleteNamespacedPod(podName, namespaceParameter);
|
||||
}
|
||||
catch (HttpOperationException e)
|
||||
{
|
||||
if (e.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
client.CreateNamespacedPod(
|
||||
new V1Pod()
|
||||
{
|
||||
Metadata = new V1ObjectMeta { Name = podName, Labels = new Dictionary<string, string> { { "place", "holder" }, }, },
|
||||
Spec = new V1PodSpec
|
||||
{
|
||||
Containers = new[] { new V1Container() { Name = "k8scsharp-patch", Image = "nginx", }, },
|
||||
},
|
||||
},
|
||||
namespaceParameter);
|
||||
|
||||
|
||||
var pod = client.ListNamespacedPod(namespaceParameter).Items.First(p => p.Metadata.Name == podName);
|
||||
|
||||
var newlabels = new Dictionary<string, string>(pod.Metadata.Labels) { ["test"] = "test-jsonpatch" };
|
||||
var patch = new JsonPatchDocument<V1Pod>();
|
||||
patch.Replace(e => e.Metadata.Labels, newlabels);
|
||||
client.PatchNamespacedPod(new V1Patch(patch, V1Patch.PatchType.JsonPatch), pod.Metadata.Name, "default");
|
||||
|
||||
Assert.False(pod.Labels().ContainsKey("test"));
|
||||
|
||||
// refresh
|
||||
pod = client.ListNamespacedPod(namespaceParameter).Items.First(p => p.Metadata.Name == podName);
|
||||
|
||||
Assert.Equal("test-jsonpatch", pod.Labels()["test"]);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
{
|
||||
client.CreateNamespacedPod(
|
||||
new V1Pod()
|
||||
{
|
||||
Metadata = new V1ObjectMeta { Name = podName, Labels = new Dictionary<string, string> { { "place", "holder" }, }, },
|
||||
Spec = new V1PodSpec
|
||||
{
|
||||
Containers = new[] { new V1Container() { Name = "k8scsharp-patch", Image = "nginx", }, },
|
||||
},
|
||||
},
|
||||
namespaceParameter);
|
||||
|
||||
|
||||
var pod = client.ListNamespacedPod(namespaceParameter).Items.First(p => p.Metadata.Name == podName);
|
||||
|
||||
var patchStr = @"
|
||||
{
|
||||
""metadata"": {
|
||||
""labels"": {
|
||||
""test"": ""test-mergepatch""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
client.PatchNamespacedPod(new V1Patch(patchStr, V1Patch.PatchType.MergePatch), pod.Metadata.Name, "default");
|
||||
|
||||
Assert.False(pod.Labels().ContainsKey("test"));
|
||||
|
||||
// refresh
|
||||
pod = client.ListNamespacedPod(namespaceParameter).Items.First(p => p.Metadata.Name == podName);
|
||||
|
||||
Assert.Equal("test-mergepatch", pod.Labels()["test"]);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static IKubernetes CreateClient()
|
||||
{
|
||||
return new Kubernetes(KubernetesClientConfiguration.BuildDefaultConfig());
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using System.Linq;
|
||||
using k8s.Models;
|
||||
using Microsoft.AspNetCore.JsonPatch;
|
||||
using Xunit;
|
||||
|
||||
namespace k8s.Tests
|
||||
{
|
||||
public class JsonPatchTests
|
||||
{
|
||||
[Fact]
|
||||
public void PathContainsUpperCase()
|
||||
{
|
||||
var patch = new JsonPatchDocument<V1HorizontalPodAutoscaler>();
|
||||
patch.Replace(h => h.Spec.MinReplicas, 1);
|
||||
|
||||
Assert.Equal("/spec/minReplicas", patch.Operations.Single().path);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user