API v1.23.0 + system.text.json + remove WatchXXX API (#750)

* gen v1.23.0

* fix converter

* bump ver

* update readme runtime

* fix warning

* update dep ver

* newtonjson -> system.text.json

* generate for new json api

* readme lf

* dotnet fmt

* dotnet fmt tests/

* dotnet fmt

* Revert "dotnet fmt"

This reverts commit e14c59076143fe2218ed899295a00762f0ea2bd6.

* fix err introduce by dotnet fmt

* fix test

* remove deprecated /watch api

* generate code after /watch removed

* remove /watch related code

* trim Microsoft.Rest.Serialization
This commit is contained in:
Boshi Lian
2021-12-13 07:31:59 -08:00
committed by GitHub
parent 6c539873b5
commit eca9898902
699 changed files with 65366 additions and 128699 deletions

View File

@@ -4,7 +4,7 @@
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>

View File

@@ -151,16 +151,17 @@ ${GEN_DIR}/openapi/csharp.sh generated ../csharp.settings
| SDK Version | Kubernetes Version | .NET Targeting |
|-------------|--------------------|---------------------------------------|
| 7.0 | 1.23 | netstandard2.1;net5;net6 |
| 6.0 | 1.22 | netstandard2.1;net5 |
| 5.0 | 1.21 | netstandard2.1;net5 |
| 4.0 | 1.20 | netstandard2.0;netstandard2.1 |
| 3.0 | 1.19 | netstandard2.0;net452 |
| 2.0 | 1.18 | netstandard2.0;net453 |
| 2.0 | 1.18 | netstandard2.0;net452 |
| 1.6 | 1.16 | netstandard1.4;netstandard2.0;net452; |
| 1.4 | 1.13 | netstandard1.4;net451 |
| 1.3 | 1.12 | netstandard1.4;net452 |
* Starting form `2.0`, [dotnet sdk versioning](https://github.com/kubernetes-client/csharp/issues/400) adopted
* Starting from `2.0`, [dotnet sdk versioning](https://github.com/kubernetes-client/csharp/issues/400) adopted
* `Kubernetes Version` here means the version sdk models and apis were generated from
* Kubernetes api server guarantees the compatibility with `n-2` version. for exmaple, 1.19 based sdk should work with 1.21 cluster, but no guarantee works with 1.22 cluster. see also <https://kubernetes.io/releases/version-skew-policy/>

View File

@@ -1,3 +1,3 @@
export KUBERNETES_BRANCH=v1.22.0
export KUBERNETES_BRANCH=v1.23.0
export CLIENT_VERSION=0.0.1
export PACKAGE_NAME=k8s

View File

@@ -80,10 +80,10 @@ namespace KubernetesWatchGenerator
helper.RegisterHelper();
}
if (options.GenerateWatch)
{
container.Resolve<WatchGenerator>().Generate(swaggerUnprocessed, outputDirectory);
}
//if (options.GenerateWatch)
//{
// container.Resolve<WatchGenerator>().Generate(swaggerUnprocessed, outputDirectory);
//}
if (options.GenerateApi)
{
@@ -112,8 +112,8 @@ namespace KubernetesWatchGenerator
[Value(0, Required = true, HelpText = "path to src/KubernetesClient/generated")]
public string OutputPath { get; set; }
[Option("watch", Required = false, Default = true)]
public bool GenerateWatch { get; set; }
//[Option("watch", Required = false, Default = true)]
//public bool GenerateWatch { get; set; }
[Option("api", Required = false, Default = true)]
public bool GenerateApi { get; set; }

View File

@@ -109,7 +109,7 @@ namespace KubernetesGenerator
if (name == "pretty")
{
context.Write($"{name}.Value == true ? \"true\" : \"false\"");
context.Write($"{name}.Value ? \"true\" : \"false\"");
return;
}
@@ -118,10 +118,14 @@ namespace KubernetesGenerator
case JsonObjectType.String:
context.Write($"System.Uri.EscapeDataString({name})");
break;
default:
context.Write(
$"System.Uri.EscapeDataString(SafeJsonConvert.SerializeObject({name}, SerializationSettings).Trim('\"'))");
case JsonObjectType.Boolean:
context.Write($"{name}.Value ? \"true\" : \"false\"");
break;
case JsonObjectType.Integer:
context.Write($"{name}.Value");
break;
default:
throw new ArgumentException("type not supportted");
}
}
}

View File

@@ -1,67 +1,57 @@
// <auto-generated>
// Code generated by https://github.com/kubernetes-client/csharp/tree/master/gen/KubernetesGenerator
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.
// </auto-generated>
// <auto-generated>
// Code generated by https://github.com/kubernetes-client/csharp/tree/master/gen/KubernetesGenerator
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.
// </auto-generated>
namespace k8s
{
using Microsoft.Rest;
using Models;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// </summary>
public partial interface IKubernetes : System.IDisposable
{
/// <summary>
/// The base URI of the service.
/// </summary>
System.Uri BaseUri { get; set; }
/// <summary>
/// Subscription credentials which uniquely identify client
/// subscription.
/// </summary>
ServiceClientCredentials Credentials { get; }
namespace k8s
{
using Microsoft.Rest;
using Models;
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// </summary>
public partial interface IKubernetes : System.IDisposable
{
/// <summary>
/// The base URI of the service.
/// </summary>
System.Uri BaseUri { get; set; }
/// <summary>
/// Gets or sets json serialization settings.
/// </summary>
JsonSerializerSettings SerializationSettings { get; }
/// <summary>
/// Gets or sets json deserialization settings.
/// </summary>
JsonSerializerSettings DeserializationSettings { get; }
/// <summary>
/// Subscription credentials which uniquely identify client
/// subscription.
/// </summary>
ServiceClientCredentials Credentials { get; }
{{#.}}
/// <summary>
/// {{ToXmlDoc operation.description}}
/// </summary>
{{#operation.parameters}}
/// <param name="{{GetDotNetName .}}">
/// {{ToXmlDoc description}}
/// </param>
{{/operation.parameters}}
/// <param name="customHeaders">
/// The headers that will be added to request.
/// </param>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
/// </param>
Task<HttpOperationResponse{{GetReturnType operation "<>"}}> {{GetMethodName operation "WithHttpMessagesAsync"}}(
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName . "true"}},
{{/operation.parameters}}
Dictionary<string, List<string>> customHeaders = null,
CancellationToken cancellationToken = default(CancellationToken));
{{/.}}
}
}
{{#.}}
/// <summary>
/// {{ToXmlDoc operation.description}}
/// </summary>
{{#operation.parameters}}
/// <param name="{{GetDotNetName .}}">
/// {{ToXmlDoc description}}
/// </param>
{{/operation.parameters}}
/// <param name="customHeaders">
/// The headers that will be added to request.
/// </param>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
/// </param>
Task<HttpOperationResponse{{GetReturnType operation "<>"}}> {{GetMethodName operation "WithHttpMessagesAsync"}}(
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName . "true"}},
{{/operation.parameters}}
IDictionary<string, IList<string>> customHeaders = null,
CancellationToken cancellationToken = default);
{{/.}}
}
}

View File

@@ -1,184 +1,103 @@
// <auto-generated>
// Code generated by https://github.com/kubernetes-client/csharp/tree/master/gen/KubernetesGenerator
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.
// </auto-generated>
namespace k8s
{
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
using Models;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
public partial class Kubernetes : ServiceClient<Kubernetes>, IKubernetes
{
{{#.}}
/// <inheritdoc/>
public async Task<HttpOperationResponse{{GetReturnType operation "<>"}}> {{GetMethodName operation "WithHttpMessagesAsync"}}(
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName . "true"}},
{{/operation.parameters}}
Dictionary<string, List<string>> customHeaders = null,
CancellationToken cancellationToken = default(CancellationToken))
{
var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(HttpClientTimeout);
{{#IfParamContains operation "watch"}}
if (watch == true)
{
cts.CancelAfter(Timeout.InfiniteTimeSpan);
}
{{/IfParamContains operation "watch"}}
cancellationToken = cts.Token;
{{#operation.parameters}}
{{#isRequired}}
if ({{GetDotNetName name}} == null)
{
throw new ValidationException(ValidationRules.CannotBeNull, "{{GetDotNetName name}}");
}
{{/isRequired}}
{{/operation.parameters}}
// Tracing
bool _shouldTrace = ServiceClientTracing.IsEnabled;
string _invocationId = null;
if (_shouldTrace)
{
_invocationId = ServiceClientTracing.NextInvocationId.ToString();
Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
{{#operation.parameters}}
tracingParameters.Add("{{GetDotNetName name}}", {{GetDotNetName name}});
{{/operation.parameters}}
tracingParameters.Add("cancellationToken", cancellationToken);
ServiceClientTracing.Enter(_invocationId, this, "{{GetMethodName operation ""}}", tracingParameters);
}
// Construct URL
var _baseUrl = BaseUri.AbsoluteUri;
var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "{{path}}").ToString();
{{#operation.parameters}}
{{#IfKindIs . "path"}}
_url = _url.Replace("{{AddCurly name}}", {{GetDotNetName name}});
{{/IfKindIs . "path"}}
{{/operation.parameters}}
_url = _url.Replace("/apis//", "/api/");
List<string> _queryParameters = new List<string>();
{{#operation.parameters}}
{{#IfKindIs . "query"}}
if ({{GetDotNetName name}} != null)
{
_queryParameters.Add(string.Format("{{name}}={0}", {{EscapeDataString name type}}));
}
{{/IfKindIs . "query"}}
{{/operation.parameters}}
if (_queryParameters.Count > 0)
{
_url += "?" + string.Join("&", _queryParameters);
}
// Create HTTP transport
var _httpRequest = new HttpRequestMessage();
HttpResponseMessage _httpResponse = null;
_httpRequest.Method = HttpMethod.{{Method}};
_httpRequest.RequestUri = new System.Uri(_url);
_httpRequest.Version = HttpVersion.Version20;
// Set Headers
if (customHeaders != null)
{
foreach(var _header in customHeaders)
{
_httpRequest.Headers.Remove(_header.Key);
_httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value);
}
}
// Serialize Request
string _requestContent = null;
{{#IfParamContains operation "body"}}
if(body != null)
{
_requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings);
_httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8);
_httpRequest.Content.Headers.ContentType = GetHeader(body);
}
{{/IfParamContains operation "body"}}
// Set Credentials
if (Credentials != null)
{
cancellationToken.ThrowIfCancellationRequested();
await Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
}
// Send Request
if (_shouldTrace)
{
ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();
_httpResponse = await HttpClient.SendAsync(_httpRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
if (_shouldTrace)
{
ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse);
}
HttpStatusCode _statusCode = _httpResponse.StatusCode;
cancellationToken.ThrowIfCancellationRequested();
if ((int)_statusCode != 200 && (int)_statusCode != 201 && (int)_statusCode != 202)
{
string _responseContent = null;
var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
if (_httpResponse.Content != null) {
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else {
_responseContent = string.Empty;
}
ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
if (_shouldTrace)
{
ServiceClientTracing.Error(_invocationId, ex);
}
_httpRequest.Dispose();
if (_httpResponse != null)
{
_httpResponse.Dispose();
}
throw ex;
}
// Create Result
{{#IfReturnType operation "void"}}
HttpOperationResponse _result = new HttpOperationResponse() { Request = _httpRequest, Response = _httpResponse };
{{/IfReturnType operation "void"}}
{{#IfReturnType operation "obj"}}
var _result = await CreateResultAsync{{GetReturnType operation "<>"}}(_httpRequest,
_httpResponse,
{{#IfParamContains operation "watch"}}
watch,
{{/IfParamContains operation "watch"}}
{{#IfParamDoesNotContain operation "watch"}}
false,
{{/IfParamDoesNotContain operation "watch"}}
cancellationToken);
{{/IfReturnType operation "obj"}}
{{#IfReturnType operation "stream"}}
var _result = new HttpOperationResponse{{GetReturnType operation "<>"}}() {
Request = _httpRequest,
Response = _httpResponse,
Body = await _httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false) };
{{/IfReturnType operation "stream"}}
if (_shouldTrace)
{
ServiceClientTracing.Exit(_invocationId, _result);
}
return _result;
}
{{/.}}
}
}
// <auto-generated>
// Code generated by https://github.com/kubernetes-client/csharp/tree/master/gen/KubernetesGenerator
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.
// </auto-generated>
namespace k8s
{
using Microsoft.Rest;
using Models;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
public partial class Kubernetes : ServiceClient<Kubernetes>, IKubernetes
{
{{#.}}
/// <inheritdoc/>
public async Task<HttpOperationResponse{{GetReturnType operation "<>"}}> {{GetMethodName operation "WithHttpMessagesAsync"}}(
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName . "true"}},
{{/operation.parameters}}
IDictionary<string, IList<string>> customHeaders = null,
CancellationToken cancellationToken = default(CancellationToken))
{
var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(HttpClientTimeout);
{{#IfParamContains operation "watch"}}
if (watch == true)
{
cts.CancelAfter(Timeout.InfiniteTimeSpan);
}
{{/IfParamContains operation "watch"}}
cancellationToken = cts.Token;
{{#operation.parameters}}
{{#isRequired}}
if ({{GetDotNetName name}} == null)
{
throw new ArgumentNullException("{{GetDotNetName name}}");
}
{{/isRequired}}
{{/operation.parameters}}
// Construct URL
var _baseUrl = BaseUri.AbsoluteUri;
var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "{{path}}").ToString();
{{#operation.parameters}}
{{#IfKindIs . "path"}}
_url = _url.Replace("{{AddCurly name}}", {{GetDotNetName name}});
{{/IfKindIs . "path"}}
{{/operation.parameters}}
_url = _url.Replace("/apis//", "/api/");
List<string> _queryParameters = new List<string>();
{{#operation.parameters}}
{{#IfKindIs . "query"}}
if ({{GetDotNetName name}} != null)
{
_queryParameters.Add(string.Format("{{name}}={0}", {{EscapeDataString name type}}));
}
{{/IfKindIs . "query"}}
{{/operation.parameters}}
if (_queryParameters.Count > 0)
{
_url += "?" + string.Join("&", _queryParameters);
}
// Create HTTP transport
var _httpRequest = CreateRequest(_url, HttpMethod.{{Method}}, customHeaders);
{{#IfParamContains operation "body"}}
var _httpResponse = await SendRequest(body, _httpRequest, cancellationToken);
{{/IfParamContains operation "body"}}
{{#IfParamDoesNotContain operation "body"}}
var _httpResponse = await SendRequestRaw("", _httpRequest, cancellationToken);
{{/IfParamDoesNotContain operation "body"}}
// Create Result
{{#IfReturnType operation "void"}}
HttpOperationResponse _result = new HttpOperationResponse() { Request = _httpRequest, Response = _httpResponse };
{{/IfReturnType operation "void"}}
{{#IfReturnType operation "obj"}}
var _result = await CreateResultAsync{{GetReturnType operation "<>"}}(_httpRequest,
_httpResponse,
{{#IfParamContains operation "watch"}}
watch,
{{/IfParamContains operation "watch"}}
{{#IfParamDoesNotContain operation "watch"}}
false,
{{/IfParamDoesNotContain operation "watch"}}
cancellationToken);
{{/IfReturnType operation "obj"}}
{{#IfReturnType operation "stream"}}
var _result = new HttpOperationResponse{{GetReturnType operation "<>"}}() {
Request = _httpRequest,
Response = _httpResponse,
Body = await _httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false) };
{{/IfReturnType operation "stream"}}
return _result;
}
{{/.}}
}
}

View File

@@ -1,99 +1,93 @@
// <auto-generated>
// Code generated by https://github.com/kubernetes-client/csharp/tree/master/gen/KubernetesGenerator
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.
// </auto-generated>
namespace k8s.Models
{
using Microsoft.Rest;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
/// <summary>
/// {{ToXmlDoc def.description}}
/// </summary>
public partial class {{clz}}
{
/// <summary>
/// Initializes a new instance of the {{GetClassName def}} class.
/// </summary>
public {{clz}}()
{
CustomInit();
}
/// <summary>
/// Initializes a new instance of the {{GetClassName def}} class.
/// </summary>
{{#properties}}
{{#isRequired}}
/// <param name="{{GetDotNetName name "fieldctor"}}">
/// {{ToXmlDoc description}}
/// </param>
{{/isRequired}}
{{/properties}}
{{#properties}}
{{^isRequired}}
/// <param name="{{GetDotNetName name "fieldctor"}}">
/// {{ToXmlDoc description}}
/// </param>
{{/isRequired}}
{{/properties}}
public {{clz}}({{GetModelCtorParam def}})
{
{{#properties}}
{{GetDotNetName name "field"}} = {{GetDotNetName name "fieldctor"}};
{{/properties}}
CustomInit();
}
/// <summary>
/// An initialization method that performs custom operations like setting defaults
/// </summary>
partial void CustomInit();
{{#properties}}
/// <summary>
/// {{ToXmlDoc description}}
/// </summary>
[JsonProperty(PropertyName = "{{name}}")]
public {{GetDotNetType .}} {{GetDotNetName name "field"}} { get; set; }
{{/properties}}
/// <summary>
/// Validate the object.
/// </summary>
/// <exception cref="ValidationException">
/// Thrown if validation fails
/// </exception>
public virtual void Validate()
{
{{#properties}}
{{#IfType . "object"}}
{{#isRequired}}
if ({{GetDotNetName name "field"}} == null)
{
throw new ValidationException(ValidationRules.CannotBeNull, "{{GetDotNetName name "field"}}");
}
{{/isRequired}}
{{/IfType . "object"}}
{{/properties}}
{{#properties}}
{{#IfType . "object"}}
{{GetDotNetName name "field"}}?.Validate();
{{/IfType . "object"}}
{{#IfType . "objectarray"}}
if ({{GetDotNetName name "field"}} != null){
foreach(var obj in {{GetDotNetName name "field"}})
{
obj.Validate();
}
}
{{/IfType . "objectarray"}}
{{/properties}}
}
}
}
// <auto-generated>
// Code generated by https://github.com/kubernetes-client/csharp/tree/master/gen/KubernetesGenerator
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.
// </auto-generated>
namespace k8s.Models
{
/// <summary>
/// {{ToXmlDoc def.description}}
/// </summary>
public partial class {{clz}}
{
/// <summary>
/// Initializes a new instance of the {{GetClassName def}} class.
/// </summary>
public {{clz}}()
{
CustomInit();
}
/// <summary>
/// Initializes a new instance of the {{GetClassName def}} class.
/// </summary>
{{#properties}}
{{#isRequired}}
/// <param name="{{GetDotNetName name "fieldctor"}}">
/// {{ToXmlDoc description}}
/// </param>
{{/isRequired}}
{{/properties}}
{{#properties}}
{{^isRequired}}
/// <param name="{{GetDotNetName name "fieldctor"}}">
/// {{ToXmlDoc description}}
/// </param>
{{/isRequired}}
{{/properties}}
public {{clz}}({{GetModelCtorParam def}})
{
{{#properties}}
{{GetDotNetName name "field"}} = {{GetDotNetName name "fieldctor"}};
{{/properties}}
CustomInit();
}
/// <summary>
/// An initialization method that performs custom operations like setting defaults
/// </summary>
partial void CustomInit();
{{#properties}}
/// <summary>
/// {{ToXmlDoc description}}
/// </summary>
[JsonPropertyName("{{name}}")]
public {{GetDotNetType .}} {{GetDotNetName name "field"}} { get; set; }
{{/properties}}
/// <summary>
/// Validate the object.
/// </summary>
/// <exception cref="ValidationException">
/// Thrown if validation fails
/// </exception>
public virtual void Validate()
{
{{#properties}}
{{#IfType . "object"}}
{{#isRequired}}
if ({{GetDotNetName name "field"}} == null)
{
throw new ArgumentNullException("{{GetDotNetName name "field"}}");
}
{{/isRequired}}
{{/IfType . "object"}}
{{/properties}}
{{#properties}}
{{#IfType . "object"}}
{{GetDotNetName name "field"}}?.Validate();
{{/IfType . "object"}}
{{#IfType . "objectarray"}}
if ({{GetDotNetName name "field"}} != null){
foreach(var obj in {{GetDotNetName name "field"}})
{
obj.Validate();
}
}
{{/IfType . "objectarray"}}
{{/properties}}
}
}
}

View File

@@ -1,7 +1,7 @@
{
"sdk": {
"version": "5.0.100",
"version": "6.0.100",
"rollForward": "latestMajor"
}
}

View File

@@ -1,11 +1,9 @@
using System;
using System.Diagnostics;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using k8s.Exceptions;
using Microsoft.Rest;
using Newtonsoft.Json.Linq;
namespace k8s.Authentication
{
@@ -61,9 +59,17 @@ namespace k8s.Authentication
throw new KubernetesClientException($"Unable to obtain a token via gcloud command. Error code {process.ExitCode}. \n {err}");
}
var json = JToken.Parse(await output.ConfigureAwait(false));
_token = json["credential"]["access_token"].Value<string>();
_expiry = json["credential"]["token_expiry"].Value<DateTime>();
dynamic json = JsonSerializer.Deserialize(await output.ConfigureAwait(false), new
{
credential = new
{
access_token = "",
token_expiry = DateTime.UtcNow,
},
}.GetType());
_token = json.credential.access_token;
_expiry = json.credential.token_expiry;
}
}
}

View File

@@ -1,7 +1,6 @@
using IdentityModel.OidcClient;
using k8s.Exceptions;
using Microsoft.Rest;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http.Headers;
using System.Threading;

View File

@@ -1,4 +1,3 @@
using System;
using System.Net.Http.Headers;
using System.IO;
using System.Threading;

View File

@@ -1,4 +1,3 @@
using System;
using System.Buffers;
using System.Diagnostics;
using System.Threading;

View File

@@ -6,7 +6,6 @@ using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
#endif
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;

View File

@@ -1,6 +1,3 @@
using Newtonsoft.Json;
using System.Collections.Generic;
namespace k8s.Models
{
/// <summary>
@@ -11,13 +8,13 @@ namespace k8s.Models
/// <summary>
/// Defines container name corresponding to the one from pod.spec.containers.
/// </summary>
[JsonProperty(PropertyName = "name")]
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// The resource usage.
/// </summary>
[JsonProperty(PropertyName = "usage")]
[JsonPropertyName("usage")]
public IDictionary<string, ResourceQuantity> Usage { get; set; }
}
}

View File

@@ -1,5 +1,3 @@
using System;
namespace k8s.Exceptions
{
/// <summary>

View File

@@ -1,5 +1,3 @@
using System;
namespace k8s.Exceptions
{
/// <summary>

View File

@@ -1,4 +1,3 @@
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using k8s.Models;

View File

@@ -1,4 +1,3 @@
using System;
using System.IO.Abstractions;
namespace k8s

View File

@@ -1,6 +1,3 @@
using Microsoft.Rest.Serialization;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
@@ -37,56 +34,56 @@ namespace k8s
where T : IKubernetesObject
{
var resp = await kubernetes.CreateClusterCustomObjectWithHttpMessagesAsync(obj, group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
public async Task<T> CreateNamespacedAsync<T>(T obj, string ns, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CreateNamespacedCustomObjectWithHttpMessagesAsync(obj, group, version, ns, plural, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
public async Task<T> ListAsync<T>(CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.ListClusterCustomObjectWithHttpMessagesAsync(group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
public async Task<T> ListNamespacedAsync<T>(string ns, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.ListNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
public async Task<T> ReadNamespacedAsync<T>(string ns, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.GetNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
public async Task<T> ReadAsync<T>(string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.GetClusterCustomObjectWithHttpMessagesAsync(group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
public async Task<T> DeleteAsync<T>(string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.DeleteClusterCustomObjectWithHttpMessagesAsync(group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
public async Task<T> DeleteNamespacedAsync<T>(string ns, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.DeleteNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
public void Dispose()

View File

@@ -0,0 +1,5 @@
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Text.Json;
global using System.Text.Json.Serialization;

View File

@@ -1,5 +1,3 @@
using System.Collections.Generic;
namespace k8s
{
/// <summary>

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

View File

@@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace k8s
{
public partial interface IKubernetes
{
/// <summary>
/// Watches for changes of an object.
/// </summary>
/// <typeparam name="T">
/// type of the object of Watcher{T}
/// </typeparam>
/// <param name="path">
/// The uri to the resource being watched
/// </param>
/// <param name="continue">
/// The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server the server will respond with a 410 ResourceExpired error indicating the client must restart their list without the continue field. This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.
/// </param>
/// <param name="fieldSelector">
/// A selector to restrict the list of returned objects by their fields. Defaults to everything.
/// </param>
/// <param name="includeUninitialized">
/// If true, partially initialized resources are included in the response.
/// </param>
/// <param name="labelSelector">
/// A selector to restrict the list of returned objects by their labels. Defaults to everything.
/// </param>
/// <param name="limit">
/// limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.
///
/// The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.
/// </param>
/// <param name="pretty">
/// If 'true', then the output is pretty printed.
/// </param>
/// <param name="timeoutSeconds">
/// Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.
/// </param>
/// <param name="resourceVersion">
/// When specified with a watch call, shows changes that occur after that particular version of a resource. Defaults to changes from the beginning of history. When specified for list: - if unset, then the result is returned from remote storage based on quorum-read flag; - if it's 0, then we simply return what we currently have in cache, no guarantee; - if set to non zero, then the result is at least as fresh as given rv.
/// </param>
/// <param name="customHeaders">
/// The headers that will be added to request.
/// </param>
/// <param name="onEvent">
/// The action to invoke when the server sends a new event.
/// </param>
/// <param name="onError">
/// The action to invoke when an error occurs.
/// </param>
/// <param name="onClosed">
/// The action to invoke when the server closes the connection.
/// </param>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
/// </param>
/// <returns>
/// A <see cref="Task"/> which represents the asynchronous operation, and returns a new watcher.
/// </returns>
Task<Watcher<T>> WatchObjectAsync<T>(string path, string @continue = null, string fieldSelector = null,
bool? includeUninitialized = null, string labelSelector = null, int? limit = null, bool? pretty = null,
int? timeoutSeconds = null, string resourceVersion = null,
Dictionary<string, List<string>> customHeaders = null, Action<WatchEventType, T> onEvent = null,
Action<Exception> onError = null, Action onClosed = null,
CancellationToken cancellationToken = default);
}
}

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;

View File

@@ -1,5 +1,3 @@
using Newtonsoft.Json;
namespace k8s
{
/// <summary>
@@ -20,7 +18,7 @@ namespace k8s
/// values. More info:
/// https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
/// </summary>
[JsonProperty(PropertyName = "apiVersion")]
[JsonPropertyName("apiVersion")]
string ApiVersion { get; set; }
/// <summary>
@@ -30,7 +28,7 @@ namespace k8s
/// More info:
/// https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
/// </summary>
[JsonProperty(PropertyName = "kind")]
[JsonPropertyName("kind")]
string Kind { get; set; }
}

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

View File

@@ -1,32 +1,33 @@
using System;
using Newtonsoft.Json;
namespace k8s.Models
{
internal class IntOrStringConverter : JsonConverter
internal class IntOrStringConverter : JsonConverter<IntstrIntOrString>
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
public override IntstrIntOrString Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var s = (value as IntstrIntOrString)?.Value;
switch (reader.TokenType)
{
case JsonTokenType.String:
return reader.GetString();
case JsonTokenType.Number:
return reader.GetInt64();
default:
break;
}
throw new NotSupportedException();
}
public override void Write(Utf8JsonWriter writer, IntstrIntOrString value, JsonSerializerOptions options)
{
var s = value?.Value;
if (int.TryParse(s, out var intv))
{
serializer.Serialize(writer, intv);
writer.WriteNumberValue(intv);
return;
}
serializer.Serialize(writer, s);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
return (IntstrIntOrString)serializer.Deserialize<string>(reader);
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(int) || objectType == typeof(string);
writer.WriteStringValue(s);
}
}
}

View File

@@ -1,4 +1,3 @@
using System;
using YamlDotNet.Core;
using YamlDotNet.Serialization;

View File

@@ -1,6 +1,3 @@
using System;
using Newtonsoft.Json;
namespace k8s.Models
{
[JsonConverter(typeof(IntOrStringConverter))]
@@ -11,6 +8,11 @@ namespace k8s.Models
return new IntstrIntOrString(Convert.ToString(v));
}
public static implicit operator IntstrIntOrString(long v)
{
return new IntstrIntOrString(Convert.ToString(v));
}
public static implicit operator string(IntstrIntOrString v)
{
return v?.Value;

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels

View File

@@ -1,15 +1,12 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace k8s.KubeConfigModels
{
public class ExecCredentialResponse
{
[JsonProperty("apiVersion")]
[JsonPropertyName("apiVersion")]
public string ApiVersion { get; set; }
[JsonProperty("kind")]
[JsonPropertyName("kind")]
public string Kind { get; set; }
[JsonProperty("status")]
[JsonPropertyName("status")]
public IDictionary<string, string> Status { get; set; }
}
}

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels

View File

@@ -1,6 +1,3 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
@@ -10,7 +7,6 @@ using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using k8s.Exceptions;
using k8s.Models;
using Microsoft.Rest;
namespace k8s
@@ -139,8 +135,6 @@ namespace k8s
private void CustomInitialize()
{
DeserializationSettings.Converters.Add(new V1Status.V1StatusObjectViewConverter());
SerializationSettings.DateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.ffffffK";
}
/// <summary>A <see cref="DelegatingHandler"/> that simply forwards a request with no further processing.</summary>

View File

@@ -1,10 +1,6 @@
using k8s.Models;
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -41,7 +37,7 @@ namespace k8s
// StatusError is defined here:
// https://github.com/kubernetes/kubernetes/blob/068e1642f63a1a8c48c16c18510e8854a4f4e7c5/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go#L37
var returnMessage = SafeJsonConvert.DeserializeObject<V1Status>(errors);
var returnMessage = KubernetesJson.Deserialize<V1Status>(errors);
return GetExitCodeOrThrow(returnMessage);
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Net.Http.Headers;
using k8s.Models;

View File

@@ -1,179 +0,0 @@
using Microsoft.Rest;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace k8s
{
public partial class Kubernetes
{
/// <inheritdoc/>
public async Task<Watcher<T>> WatchObjectAsync<T>(string path, string @continue = null,
string fieldSelector = null, bool? includeUninitialized = null, string labelSelector = null,
int? limit = null, bool? pretty = null, int? timeoutSeconds = null, string resourceVersion = null,
Dictionary<string, List<string>> customHeaders = null, Action<WatchEventType, T> onEvent = null,
Action<Exception> onError = null, Action onClosed = null,
CancellationToken cancellationToken = default)
{
// Tracing
var shouldTrace = ServiceClientTracing.IsEnabled;
string invocationId = null;
if (shouldTrace)
{
invocationId = ServiceClientTracing.NextInvocationId.ToString();
var tracingParameters = new Dictionary<string, object>();
tracingParameters.Add("path", path);
tracingParameters.Add("continue", @continue);
tracingParameters.Add("fieldSelector", fieldSelector);
tracingParameters.Add("includeUninitialized", includeUninitialized);
tracingParameters.Add("labelSelector", labelSelector);
tracingParameters.Add("limit", limit);
tracingParameters.Add("pretty", pretty);
tracingParameters.Add("timeoutSeconds", timeoutSeconds);
tracingParameters.Add("resourceVersion", resourceVersion);
ServiceClientTracing.Enter(invocationId, this, nameof(WatchObjectAsync), tracingParameters);
}
// Construct URL
var uriBuilder = new UriBuilder(BaseUri);
if (!uriBuilder.Path.EndsWith("/", StringComparison.InvariantCulture))
{
uriBuilder.Path += "/";
}
uriBuilder.Path += path;
var query = new StringBuilder();
// Don't sent watch, because setting that value will cause the WatcherDelegatingHandler to kick in. That class
// "eats" the first line, which is something we don't want.
// query = QueryHelpers.AddQueryString(query, "watch", "true");
if (@continue != null)
{
Utilities.AddQueryParameter(query, "continue", @continue);
}
if (!string.IsNullOrEmpty(fieldSelector))
{
Utilities.AddQueryParameter(query, "fieldSelector", fieldSelector);
}
if (includeUninitialized != null)
{
Utilities.AddQueryParameter(query, "includeUninitialized",
includeUninitialized.Value ? "true" : "false");
}
if (!string.IsNullOrEmpty(labelSelector))
{
Utilities.AddQueryParameter(query, "labelSelector", labelSelector);
}
if (limit != null)
{
Utilities.AddQueryParameter(query, "limit", limit.Value.ToString());
}
if (pretty != null)
{
Utilities.AddQueryParameter(query, "pretty", pretty.Value ? "true" : "false");
}
if (timeoutSeconds != null)
{
Utilities.AddQueryParameter(query, "timeoutSeconds", timeoutSeconds.Value.ToString());
}
if (!string.IsNullOrEmpty(resourceVersion))
{
Utilities.AddQueryParameter(query, "resourceVersion", resourceVersion);
}
uriBuilder.Query =
query.Length == 0
? ""
: query.ToString(
1,
query.Length - 1); // UriBuilder.Query doesn't like leading '?' chars, so trim it
// Create HTTP transport objects
var httpRequest = new HttpRequestMessage(HttpMethod.Get, uriBuilder.ToString());
// Set Credentials
if (Credentials != null)
{
cancellationToken.ThrowIfCancellationRequested();
await Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);
}
// Set Headers
if (customHeaders != null)
{
foreach (var header in customHeaders)
{
if (httpRequest.Headers.Contains(header.Key))
{
httpRequest.Headers.Remove(header.Key);
}
httpRequest.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
}
// Send Request
if (shouldTrace)
{
ServiceClientTracing.SendRequest(invocationId, httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();
var httpResponse = await HttpClient
.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false);
if (shouldTrace)
{
ServiceClientTracing.ReceiveResponse(invocationId, httpResponse);
}
cancellationToken.ThrowIfCancellationRequested();
if (httpResponse.StatusCode != HttpStatusCode.OK)
{
var responseContent = string.Empty;
var ex = new HttpOperationException(string.Format(
"Operation returned an invalid status code '{0}'",
httpResponse.StatusCode));
if (httpResponse.Content != null)
{
#if NET5_0
responseContent = await httpResponse.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
#else
responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
#endif
}
ex.Request = new HttpRequestMessageWrapper(httpRequest, responseContent);
ex.Response = new HttpResponseMessageWrapper(httpResponse, string.Empty);
httpRequest.Dispose();
httpResponse?.Dispose();
throw ex;
}
return new Watcher<T>(
async () =>
{
var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
var reader = new StreamReader(stream);
return reader;
}, onEvent, onError, onClosed);
}
}
}

View File

@@ -1,13 +1,8 @@
using k8s.Models;
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.WebSockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
@@ -371,12 +366,12 @@ namespace k8s
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
#endif
// Try to parse the content as a V1Status object
var genericObject = SafeJsonConvert.DeserializeObject<KubernetesObject>(content);
var genericObject = KubernetesJson.Deserialize<KubernetesObject>(content);
V1Status status = null;
if (genericObject.ApiVersion == "v1" && genericObject.Kind == "Status")
{
status = SafeJsonConvert.DeserializeObject<V1Status>(content);
status = KubernetesJson.Deserialize<V1Status>(content);
}
var ex =

View File

@@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
using Newtonsoft.Json;
namespace k8s
{
@@ -15,17 +12,7 @@ namespace k8s
/// <summary>
/// The base URI of the service.
/// </summary>
public System.Uri BaseUri { get; set; }
/// <summary>
/// Gets json serialization settings.
/// </summary>
public JsonSerializerSettings SerializationSettings { get; private set; }
/// <summary>
/// Gets json deserialization settings.
/// </summary>
public JsonSerializerSettings DeserializationSettings { get; private set; }
public Uri BaseUri { get; set; }
/// <summary>
/// Subscription credentials which uniquely identify client subscription.
@@ -82,10 +69,10 @@ namespace k8s
/// <param name='handlers'>
/// Optional. The delegating handlers to add to the http client pipeline.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// Thrown when a required parameter is null
/// </exception>
protected Kubernetes(System.Uri baseUri, params DelegatingHandler[] handlers)
protected Kubernetes(Uri baseUri, params DelegatingHandler[] handlers)
: this(handlers)
{
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
@@ -103,10 +90,10 @@ namespace k8s
/// <param name='handlers'>
/// Optional. The delegating handlers to add to the http client pipeline.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// Thrown when a required parameter is null
/// </exception>
protected Kubernetes(System.Uri baseUri, HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
protected Kubernetes(Uri baseUri, HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
: this(rootHandler, handlers)
{
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
@@ -121,7 +108,7 @@ namespace k8s
/// <param name='handlers'>
/// Optional. The delegating handlers to add to the http client pipeline.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// Thrown when a required parameter is null
/// </exception>
public Kubernetes(ServiceClientCredentials credentials, params DelegatingHandler[] handlers)
@@ -142,7 +129,7 @@ namespace k8s
/// </param>
/// <param name='disposeHttpClient'>
/// True: will dispose the provided httpClient on calling Kubernetes.Dispose(). False: will not dispose provided httpClient</param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// Thrown when a required parameter is null
/// </exception>
public Kubernetes(ServiceClientCredentials credentials, HttpClient httpClient, bool disposeHttpClient)
@@ -164,7 +151,7 @@ namespace k8s
/// <param name='handlers'>
/// Optional. The delegating handlers to add to the http client pipeline.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// Thrown when a required parameter is null
/// </exception>
public Kubernetes(ServiceClientCredentials credentials, HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
@@ -186,10 +173,10 @@ namespace k8s
/// <param name='handlers'>
/// Optional. The delegating handlers to add to the http client pipeline.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// Thrown when a required parameter is null
/// </exception>
public Kubernetes(System.Uri baseUri, ServiceClientCredentials credentials, params DelegatingHandler[] handlers)
public Kubernetes(Uri baseUri, ServiceClientCredentials credentials, params DelegatingHandler[] handlers)
: this(handlers)
{
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
@@ -212,10 +199,10 @@ namespace k8s
/// <param name='handlers'>
/// Optional. The delegating handlers to add to the http client pipeline.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// Thrown when a required parameter is null
/// </exception>
public Kubernetes(System.Uri baseUri, ServiceClientCredentials credentials, HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
public Kubernetes(Uri baseUri, ServiceClientCredentials credentials, HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
: this(rootHandler, handlers)
{
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
@@ -228,32 +215,7 @@ namespace k8s
/// </summary>
private void Initialize()
{
BaseUri = new System.Uri("http://localhost");
SerializationSettings = new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat,
DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc,
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize,
ContractResolver = new ReadOnlyJsonContractResolver(),
Converters = new List<JsonConverter>
{
new Iso8601TimeSpanConverter(),
},
};
DeserializationSettings = new JsonSerializerSettings
{
DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat,
DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc,
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize,
ContractResolver = new ReadOnlyJsonContractResolver(),
Converters = new List<JsonConverter>
{
new Iso8601TimeSpanConverter(),
},
};
BaseUri = new Uri("http://localhost");
CustomInitialize();
}
@@ -268,16 +230,13 @@ namespace k8s
try
{
JsonSerializer jsonSerializer = JsonSerializer.Create(DeserializationSettings);
jsonSerializer.CheckAdditionalContent = true;
#if NET5_0_OR_GREATER
using (Stream stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false))
#else
using (Stream stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false))
#endif
using (JsonTextReader reader = new JsonTextReader(new StreamReader(stream)))
{
result.Body = (T)jsonSerializer.Deserialize(reader, typeof(T));
result.Body = KubernetesJson.Deserialize<T>(stream);
}
}
catch (JsonException ex)
@@ -289,5 +248,79 @@ namespace k8s
return result;
}
private HttpRequestMessage CreateRequest(string url, HttpMethod method, IDictionary<string, IList<string>> customHeaders)
{
var httpRequest = new HttpRequestMessage();
httpRequest.Method = method;
httpRequest.RequestUri = new Uri(url);
httpRequest.Version = HttpVersion.Version20;
// Set Headers
if (customHeaders != null)
{
foreach (var header in customHeaders)
{
httpRequest.Headers.Remove(header.Key);
httpRequest.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
}
return httpRequest;
}
private Task<HttpResponseMessage> SendRequest<T>(T body, HttpRequestMessage httpRequest, CancellationToken cancellationToken)
{
if (body != null)
{
var requestContent = KubernetesJson.Serialize(body);
httpRequest.Content = new StringContent(requestContent, System.Text.Encoding.UTF8);
httpRequest.Content.Headers.ContentType = GetHeader(body);
return SendRequestRaw(requestContent, httpRequest, cancellationToken);
}
return SendRequestRaw("", httpRequest, cancellationToken);
}
private async Task<HttpResponseMessage> SendRequestRaw(string requestContent, HttpRequestMessage httpRequest, CancellationToken cancellationToken)
{
// Set Credentials
if (Credentials != null)
{
cancellationToken.ThrowIfCancellationRequested();
await Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);
}
// Send Request
cancellationToken.ThrowIfCancellationRequested();
var httpResponse = await HttpClient.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
HttpStatusCode statusCode = httpResponse.StatusCode;
cancellationToken.ThrowIfCancellationRequested();
if (!httpResponse.IsSuccessStatusCode)
{
string responseContent = null;
var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", statusCode));
if (httpResponse.Content != null)
{
responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else
{
responseContent = string.Empty;
}
ex.Request = new HttpRequestMessageWrapper(httpRequest, requestContent);
ex.Response = new HttpResponseMessageWrapper(httpResponse, responseContent);
httpRequest.Dispose();
if (httpResponse != null)
{
httpResponse.Dispose();
}
throw ex;
}
return httpResponse;
}
}
}

View File

@@ -23,6 +23,7 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<LangVersion>10.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
@@ -33,15 +34,16 @@
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="Fractions" Version="7.0.0" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.4.240" PrivateAssets="all" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" Condition="'$(TargetFramework)' == 'netstandard2.1'" />
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.23" />
<PackageReference Include="prometheus-net" Version="5.0.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.13.1" />
<PackageReference Include="System.IO.Abstractions" Version="13.2.47" />
<PackageReference Include="System.Text.Encodings.Web" Version="5.0.1" />
<PackageReference Include="YamlDotNet" Version="11.2.1" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="IdentityModel.OidcClient" Version="4.0.0" />
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.23" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" Condition="'$(TargetFramework)' == 'netstandard2.1'" />
<PackageReference Include="System.Text.Json" Version="6.0.0" Coondition="'$(TargetFramework)' == 'netstandard2.1'" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
@@ -487,7 +483,7 @@ namespace k8s
var process = new Process();
process.StartInfo.EnvironmentVariables.Add("KUBERNETES_EXEC_INFO", JsonConvert.SerializeObject(execInfo));
process.StartInfo.EnvironmentVariables.Add("KUBERNETES_EXEC_INFO", JsonSerializer.Serialize(execInfo));
if (config.EnvironmentVariables != null)
{
foreach (var configEnvironmentVariable in config.EnvironmentVariables)
@@ -559,7 +555,7 @@ namespace k8s
try
{
var responseObject = JsonConvert.DeserializeObject<ExecCredentialResponse>(stdout);
var responseObject = KubernetesJson.Deserialize<ExecCredentialResponse>(stdout);
if (responseObject == null || responseObject.ApiVersion != config.ApiVersion)
{
throw new KubeConfigException(
@@ -584,7 +580,7 @@ namespace k8s
throw new KubeConfigException($"external exec failed missing token or clientCertificateData field in plugin output");
}
}
catch (JsonSerializationException ex)
catch (JsonException ex)
{
throw new KubeConfigException($"external exec failed due to failed deserialization process: {ex}");
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Net.Http;
namespace k8s

View File

@@ -1,4 +1,3 @@
using System;
using System.IO;
using k8s.Authentication;
using k8s.Exceptions;

View File

@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Rest;

View File

@@ -1,5 +1,3 @@
using System;
namespace k8s.Models
{
/// <summary>

View File

@@ -1,5 +1,4 @@
using k8s.Models;
using System;
using System.Runtime.Serialization;
namespace k8s

View File

@@ -0,0 +1,85 @@
using k8s.Models;
using System.Globalization;
using System.IO;
using System.Xml;
namespace k8s
{
internal static class KubernetesJson
{
private static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions();
private class Iso8601TimeSpanConverter : JsonConverter<TimeSpan>
{
public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var str = reader.GetString();
return XmlConvert.ToTimeSpan(str);
}
public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
{
var iso8601TimeSpanString = XmlConvert.ToString(value); // XmlConvert for TimeSpan uses ISO8601, so delegate serialization to it
writer.WriteStringValue(iso8601TimeSpanString);
}
}
private class KubernetesDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
private const string SerializeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.ffffffK";
private const string Iso8601Format = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK";
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var str = reader.GetString();
return DateTimeOffset.ParseExact(str, new[] { Iso8601Format, SerializeFormat }, CultureInfo.InvariantCulture);
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString(SerializeFormat));
}
}
private class KubernetesDateTimeConverter : JsonConverter<DateTime>
{
private static readonly JsonConverter<DateTimeOffset> UtcConverter = new KubernetesDateTimeOffsetConverter();
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return UtcConverter.Read(ref reader, typeToConvert, options).UtcDateTime;
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
UtcConverter.Write(writer, value, options);
}
}
static KubernetesJson()
{
JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
JsonSerializerOptions.Converters.Add(new Iso8601TimeSpanConverter());
JsonSerializerOptions.Converters.Add(new KubernetesDateTimeConverter());
JsonSerializerOptions.Converters.Add(new KubernetesDateTimeOffsetConverter());
JsonSerializerOptions.Converters.Add(new V1Status.V1StatusObjectViewConverter());
JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
}
public static TValue Deserialize<TValue>(string json)
{
return JsonSerializer.Deserialize<TValue>(json, JsonSerializerOptions);
}
public static TValue Deserialize<TValue>(Stream json)
{
return JsonSerializer.Deserialize<TValue>(json, JsonSerializerOptions);
}
public static string Serialize(object value)
{
return JsonSerializer.Serialize(value, JsonSerializerOptions);
}
}
}

View File

@@ -1,7 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.Rest;
using Newtonsoft.Json;
namespace k8s.Models
{
@@ -24,10 +21,10 @@ namespace k8s.Models
/// values. More info:
/// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
/// </summary>
[JsonProperty(PropertyName = "apiVersion")]
[JsonPropertyName("apiVersion")]
public string ApiVersion { get; set; }
[JsonProperty(PropertyName = "items")]
[JsonPropertyName("items")]
public IList<T> Items { get; set; }
/// <summary>
@@ -37,13 +34,13 @@ namespace k8s.Models
/// More info:
/// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
/// </summary>
[JsonProperty(PropertyName = "kind")]
[JsonPropertyName("kind")]
public string Kind { get; set; }
/// <summary>
/// Gets or sets standard object's metadata.
/// </summary>
[JsonProperty(PropertyName = "metadata")]
[JsonPropertyName("metadata")]
public V1ListMeta Metadata { get; set; }
/// <summary>
@@ -56,7 +53,7 @@ namespace k8s.Models
{
if (Items == null)
{
throw new ValidationException(ValidationRules.CannotBeNull, "Items");
throw new ArgumentNullException("Items");
}
if (Items != null)

View File

@@ -1,5 +1,4 @@
using k8s.Models;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
namespace k8s
@@ -16,8 +15,8 @@ namespace k8s
/// <returns>the metrics <see cref="PodMetricsList"/></returns>
public static async Task<NodeMetricsList> GetKubernetesNodesMetricsAsync(this IKubernetes kubernetes)
{
var customObject = (JObject)await kubernetes.GetClusterCustomObjectAsync("metrics.k8s.io", "v1beta1", "nodes", string.Empty).ConfigureAwait(false);
return customObject.ToObject<NodeMetricsList>();
var customObject = (JsonElement)await kubernetes.GetClusterCustomObjectAsync("metrics.k8s.io", "v1beta1", "nodes", string.Empty).ConfigureAwait(false);
return customObject.Deserialize<NodeMetricsList>();
}
/// <summary>
@@ -27,8 +26,8 @@ namespace k8s
/// <returns>the metrics <see cref="PodMetricsList"/></returns>
public static async Task<PodMetricsList> GetKubernetesPodsMetricsAsync(this IKubernetes kubernetes)
{
var customObject = (JObject)await kubernetes.GetClusterCustomObjectAsync("metrics.k8s.io", "v1beta1", "pods", string.Empty).ConfigureAwait(false);
return customObject.ToObject<PodMetricsList>();
var customObject = (JsonElement)await kubernetes.GetClusterCustomObjectAsync("metrics.k8s.io", "v1beta1", "pods", string.Empty).ConfigureAwait(false);
return customObject.Deserialize<PodMetricsList>();
}
/// <summary>
@@ -39,8 +38,8 @@ namespace k8s
/// <returns>the metrics <see cref="PodMetricsList"/></returns>
public static async Task<PodMetricsList> GetKubernetesPodsMetricsByNamespaceAsync(this IKubernetes kubernetes, string namespaceParameter)
{
var customObject = (JObject)await kubernetes.GetNamespacedCustomObjectAsync("metrics.k8s.io", "v1beta1", namespaceParameter, "pods", string.Empty).ConfigureAwait(false);
return customObject.ToObject<PodMetricsList>();
var customObject = (JsonElement)await kubernetes.GetNamespacedCustomObjectAsync("metrics.k8s.io", "v1beta1", namespaceParameter, "pods", string.Empty).ConfigureAwait(false);
return customObject.Deserialize<PodMetricsList>();
}
}
}

View File

@@ -1,5 +1,3 @@
using Newtonsoft.Json;
namespace k8s
{
/// <summary>
@@ -20,7 +18,7 @@ namespace k8s
/// values. More info:
/// https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
/// </summary>
[JsonProperty(PropertyName = "apiVersion")]
[JsonPropertyName("apiVersion")]
public string ApiVersion { get; set; }
/// <summary>
@@ -30,7 +28,7 @@ namespace k8s
/// More info:
/// https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
/// </summary>
[JsonProperty(PropertyName = "kind")]
[JsonPropertyName("kind")]
public string Kind { get; set; }
}
}

View File

@@ -1,6 +1,5 @@
// Derived from
// https://github.com/kubernetes-client/java/blob/master/util/src/main/java/io/kubernetes/client/apimachinery/KubernetesResource.java
using System;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Web;

View File

@@ -1,5 +1,3 @@
using System;
namespace k8s.LeaderElection
{
public class LeaderElectionConfig

View File

@@ -1,5 +1,3 @@
using System;
namespace k8s.LeaderElection
{
/// <summary>

View File

@@ -1,4 +1,3 @@
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

View File

@@ -1,4 +1,3 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using k8s.Models;

View File

@@ -1,23 +1,14 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using k8s.Models;
using Microsoft.Rest;
using Newtonsoft.Json;
namespace k8s.LeaderElection.ResourceLock
{
public abstract class MetaObjectAnnotationLock<T> : MetaObjectLock<T>
where T : class, IMetadata<V1ObjectMeta>, new()
{
private readonly JsonSerializerSettings serializationSettings;
private readonly JsonSerializerSettings derializationSettings;
protected MetaObjectAnnotationLock(IKubernetes client, string @namespace, string name, string identity)
: base(client, @namespace, name, identity)
{
serializationSettings = client.SerializationSettings;
derializationSettings = client.DeserializationSettings;
}
private const string LeaderElectionRecordAnnotationKey = "control-plane.alpha.kubernetes.io/leader";
@@ -31,20 +22,14 @@ namespace k8s.LeaderElection.ResourceLock
return new LeaderElectionRecord();
}
var record =
JsonConvert.DeserializeObject<LeaderElectionRecord>(
recordRawStringContent,
derializationSettings);
var record = KubernetesJson.Deserialize<LeaderElectionRecord>(recordRawStringContent);
return record;
}
protected override T SetLeaderElectionRecord(LeaderElectionRecord record, T metaObj)
{
metaObj.SetAnnotation(
LeaderElectionRecordAnnotationKey,
JsonConvert.SerializeObject(record, serializationSettings));
metaObj.SetAnnotation(LeaderElectionRecordAnnotationKey, KubernetesJson.Serialize(record));
return metaObj;
}
}

View File

@@ -1,9 +1,8 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using k8s.Models;
using Microsoft.Rest;
using Newtonsoft.Json;
namespace k8s.LeaderElection.ResourceLock
{

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;

View File

@@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace k8s.Models
{
/// <summary>Adds convenient extensions for Kubernetes objects.</summary>

View File

@@ -1,4 +1,3 @@
using System;
using System.IO;
namespace k8s

View File

@@ -1,7 +1,3 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace k8s.Models
{
/// <summary>
@@ -12,25 +8,25 @@ namespace k8s.Models
/// <summary>
/// The kubernetes standard object's metadata.
/// </summary>
[JsonProperty(PropertyName = "metadata")]
[JsonPropertyName("metadata")]
public V1ObjectMeta Metadata { get; set; }
/// <summary>
/// The timestamp when metrics were collected.
/// </summary>
[JsonProperty(PropertyName = "timestamp")]
[JsonPropertyName("timestamp")]
public DateTime? Timestamp { get; set; }
/// <summary>
/// The interval from which metrics were collected.
/// </summary>
[JsonProperty(PropertyName = "window")]
[JsonPropertyName("window")]
public string Window { get; set; }
/// <summary>
/// The resource usage.
/// </summary>
[JsonProperty(PropertyName = "usage")]
[JsonPropertyName("usage")]
public IDictionary<string, ResourceQuantity> Usage { get; set; }
}
}

View File

@@ -1,6 +1,3 @@
using Newtonsoft.Json;
using System.Collections.Generic;
namespace k8s.Models
{
public class NodeMetricsList
@@ -8,25 +5,25 @@ namespace k8s.Models
/// <summary>
/// Defines the versioned schema of this representation of an object.
/// </summary>
[JsonProperty(PropertyName = "apiVersion")]
[JsonPropertyName("apiVersion")]
public string ApiVersion { get; set; }
/// <summary>
/// Defines the REST resource this object represents.
/// </summary>
[JsonProperty(PropertyName = "kind")]
[JsonPropertyName("kind")]
public string Kind { get; set; }
/// <summary>
/// The kubernetes standard object's metadata.
/// </summary>
[JsonProperty(PropertyName = "metadata")]
[JsonPropertyName("metadata")]
public V1ObjectMeta Metadata { get; set; }
/// <summary>
/// The list of node metrics.
/// </summary>
[JsonProperty(PropertyName = "items")]
[JsonPropertyName("items")]
public IEnumerable<NodeMetrics> Items { get; set; }
}
}

View File

@@ -1,7 +1,3 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace k8s.Models
{
/// <summary>
@@ -12,25 +8,25 @@ namespace k8s.Models
/// <summary>
/// The kubernetes standard object's metadata.
/// </summary>
[JsonProperty(PropertyName = "metadata")]
[JsonPropertyName("metadata")]
public V1ObjectMeta Metadata { get; set; }
/// <summary>
/// The timestamp when metrics were collected.
/// </summary>
[JsonProperty(PropertyName = "timestamp")]
[JsonPropertyName("timestamp")]
public DateTime? Timestamp { get; set; }
/// <summary>
/// The interval from which metrics were collected.
/// </summary>
[JsonProperty(PropertyName = "window")]
[JsonPropertyName("window")]
public string Window { get; set; }
/// <summary>
/// The list of containers metrics.
/// </summary>
[JsonProperty(PropertyName = "containers")]
[JsonPropertyName("containers")]
public List<ContainerMetrics> Containers { get; set; }
}
}

View File

@@ -1,6 +1,3 @@
using Newtonsoft.Json;
using System.Collections.Generic;
namespace k8s.Models
{
public class PodMetricsList
@@ -8,25 +5,25 @@ namespace k8s.Models
/// <summary>
/// Defines the versioned schema of this representation of an object.
/// </summary>
[JsonProperty(PropertyName = "apiVersion")]
[JsonPropertyName("apiVersion")]
public string ApiVersion { get; set; }
/// <summary>
/// Defines the REST resource this object represents.
/// </summary>
[JsonProperty(PropertyName = "kind")]
[JsonPropertyName("kind")]
public string Kind { get; set; }
/// <summary>
/// The kubernetes standard object's metadata.
/// </summary>
[JsonProperty(PropertyName = "metadata")]
[JsonPropertyName("metadata")]
public V1ObjectMeta Metadata { get; set; }
/// <summary>
/// The list of pod metrics.
/// </summary>
[JsonProperty(PropertyName = "items")]
[JsonPropertyName("items")]
public IEnumerable<PodMetrics> Items { get; set; }
}
}

View File

@@ -1,5 +1,4 @@
using Prometheus;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

View File

@@ -1,32 +1,15 @@
using System;
using Newtonsoft.Json;
namespace k8s.Models
{
internal class QuantityConverter : JsonConverter
internal class QuantityConverter : JsonConverter<ResourceQuantity>
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
public override ResourceQuantity Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var q = (ResourceQuantity)value;
if (q != null)
{
serializer.Serialize(writer, q.ToString());
return;
}
serializer.Serialize(writer, value);
return new ResourceQuantity(reader.GetString());
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
public override void Write(Utf8JsonWriter writer, ResourceQuantity value, JsonSerializerOptions options)
{
return new ResourceQuantity(serializer.Deserialize<string>(reader));
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
writer.WriteStringValue(value?.ToString());
}
}
}

View File

@@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Numerics;
using Fractions;
using Newtonsoft.Json;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;

View File

@@ -1,6 +1,4 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.WebSockets;

View File

@@ -1,4 +1,3 @@
using System;
using System.Text.RegularExpressions;
using YamlDotNet.Core;
using YamlDotNet.Serialization;

View File

@@ -1,5 +1,3 @@
using System;
namespace k8s.Util.Common
{
public class BadNotificationException : Exception

View File

@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
namespace k8s.Util.Common
{
internal static class CollectionsExtensions

View File

@@ -1,11 +1,8 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using k8s.Models;
using k8s.Util.Common.Generic.Options;
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
namespace k8s.Util.Common.Generic
{
@@ -241,7 +238,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.GetClusterCustomObjectWithHttpMessagesAsync(group: _apiGroup, plural: _resourcePlural, version: _apiVersion, name: name, cancellationToken: cancellationToken)
.ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -268,7 +265,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.GetNamespacedCustomObjectWithHttpMessagesAsync(group: _apiGroup, plural: _resourcePlural, version: _apiVersion, name: name, namespaceParameter: namespaceProperty,
cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -289,7 +286,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.ListClusterCustomObjectWithHttpMessagesAsync(group: _apiGroup, plural: _resourcePlural, version: _apiVersion, resourceVersion: listOptions.ResourceVersion,
continueParameter: listOptions.Continue, fieldSelector: listOptions.FieldSelector, labelSelector: listOptions.LabelSelector, limit: listOptions.Limit,
timeoutSeconds: listOptions.TimeoutSeconds, cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -317,7 +314,7 @@ namespace k8s.Util.Common.Generic
continueParameter: listOptions.Continue, fieldSelector: listOptions.FieldSelector, labelSelector: listOptions.LabelSelector, limit: listOptions.Limit,
timeoutSeconds: listOptions.TimeoutSeconds, namespaceParameter: namespaceProperty, cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -352,7 +349,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.CreateClusterCustomObjectWithHttpMessagesAsync(body: obj, group: _apiGroup, plural: _resourcePlural, version: _apiVersion, dryRun: createOptions.DryRun,
fieldManager: createOptions.FieldManager, cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -380,7 +377,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.CreateNamespacedCustomObjectWithHttpMessagesAsync(body: obj, group: _apiGroup, plural: _resourcePlural, version: _apiVersion,
namespaceParameter: namespaceProperty, dryRun: createOptions.DryRun, fieldManager: createOptions.FieldManager, cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -420,7 +417,7 @@ namespace k8s.Util.Common.Generic
version: _apiVersion, dryRun: updateOptions.DryRun, fieldManager: updateOptions.FieldManager, cancellationToken: cancellationToken).ConfigureAwait(false);
}
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -475,7 +472,7 @@ namespace k8s.Util.Common.Generic
dryRun: updateOptions.DryRun, fieldManager: updateOptions.FieldManager, force: updateOptions.Force, cancellationToken: cancellationToken).ConfigureAwait(false);
}
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -507,7 +504,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.PatchClusterCustomObjectWithHttpMessagesAsync(body: obj, group: _apiGroup, version: _apiVersion, plural: _resourcePlural, name: name, dryRun: patchOptions.DryRun,
fieldManager: patchOptions.FieldManager, force: patchOptions.Force, cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -545,7 +542,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.PatchNamespacedCustomObjectWithHttpMessagesAsync(body: obj, group: _apiGroup, version: _apiVersion, namespaceParameter: namespaceProperty, plural: _resourcePlural,
name: name, dryRun: patchOptions.DryRun, fieldManager: patchOptions.FieldManager, force: patchOptions.Force, cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -566,7 +563,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.DeleteClusterCustomObjectWithHttpMessagesAsync(
group: _apiGroup, version: _apiVersion, plural: _resourcePlural, name: name, body: deleteOptions, cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>
@@ -593,7 +590,7 @@ namespace k8s.Util.Common.Generic
var resp = await _client.DeleteNamespacedCustomObjectWithHttpMessagesAsync(group: _apiGroup, version: _apiVersion, namespaceParameter: namespaceProperty, plural: _resourcePlural,
name: name, body: deleteOptions, cancellationToken: cancellationToken).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
}
/// <summary>

View File

@@ -1,5 +1,3 @@
using Newtonsoft.Json;
namespace k8s.Util.Common.Generic.Options
{
public class CreateOptions

View File

@@ -1,5 +1,3 @@
using Newtonsoft.Json;
namespace k8s.Util.Common.Generic.Options
{
public class ListOptions

View File

@@ -1,5 +1,3 @@
using Newtonsoft.Json;
namespace k8s.Util.Common.Generic.Options
{
public class PatchOptions

View File

@@ -1,5 +1,3 @@
using Newtonsoft.Json;
namespace k8s.Util.Common.Generic.Options
{
public class UpdateOptions

View File

@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using k8s.Models;
using k8s.Util.Common;

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using k8s.Models;
namespace k8s.Util.Informer.Cache

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using k8s.Models;
namespace k8s.Util.Informer.Cache

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using k8s.Models;
namespace k8s.Util.Informer.Cache

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using k8s.Models;
namespace k8s.Util.Informer.Cache

View File

@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
namespace k8s.Util.Informer.Cache
{
public class MutablePair<TLeft, TRight>

View File

@@ -1,4 +1,3 @@
using System;
using System.Text;
namespace k8s

View File

@@ -1,6 +1,3 @@
using System;
using Newtonsoft.Json;
namespace k8s.Models
{
[JsonConverter(typeof(V1PatchJsonConverter))]

View File

@@ -1,32 +1,22 @@
using System;
using Newtonsoft.Json;
namespace k8s.Models
{
internal class V1PatchJsonConverter : JsonConverter
internal class V1PatchJsonConverter : JsonConverter<V1Patch>
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var content = (value as V1Patch)?.Content;
if (content is string s)
{
writer.WriteRaw(s);
return;
}
serializer.Serialize(writer, (value as V1Patch)?.Content);
}
// no read patch object supported at the moment
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
public override V1Patch Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
public override void Write(Utf8JsonWriter writer, V1Patch value, JsonSerializerOptions options)
{
return objectType == typeof(V1Patch);
var content = value?.Content;
if (content is string s)
{
writer.WriteRawValue(s);
return;
}
JsonSerializer.Serialize(writer, content, options);
}
}
}

View File

@@ -1,26 +1,16 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace k8s.Models
{
public partial class V1Status
{
internal class V1StatusObjectViewConverter : JsonConverter
internal class V1StatusObjectViewConverter : JsonConverter<V1Status>
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
public override V1Status Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
serializer.Serialize(writer, value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
var obj = JToken.Load(reader);
var obj = JsonElement.ParseValue(ref reader);
try
{
return obj.ToObject(objectType);
return obj.Deserialize<V1Status>();
}
catch (JsonException)
{
@@ -30,19 +20,19 @@ namespace k8s.Models
return new V1Status { _original = obj, HasObject = true };
}
public override bool CanConvert(Type objectType)
public override void Write(Utf8JsonWriter writer, V1Status value, JsonSerializerOptions options)
{
return typeof(V1Status) == objectType;
throw new NotImplementedException(); // will not send v1status to server
}
}
private JToken _original;
private JsonElement _original;
public bool HasObject { get; private set; }
public T ObjectView<T>()
{
return _original.ToObject<T>();
return _original.Deserialize<T>();
}
}
}

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace k8s.Versioning

View File

@@ -1,13 +1,8 @@
// WARNING: DO NOT LEAVE COMMENTED CODE IN THIS FILE. IT GETS SCANNED BY GEN PROJECT SO IT CAN EXCLUDE ANY MANUALLY DEFINED MAPS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using AutoMapper;
using k8s.Models;
using Newtonsoft.Json;
namespace k8s.Versioning
{
@@ -134,21 +129,16 @@ namespace k8s.Versioning
obj.Kind = metadata.Kind;
});
});
cfg.CreateMap<V1Subject, V1alpha1Subject>()
.ForMember(dest => dest.ApiVersion, opt => opt.Ignore())
.ForMember(dest => dest.Name, opt => opt.Ignore())
.ForMember(dest => dest.NamespaceProperty, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V1beta1Subject, V1alpha1Subject>()
.ForMember(dest => dest.ApiVersion, opt => opt.Ignore())
.ForMember(dest => dest.Name, opt => opt.Ignore())
.ForMember(dest => dest.NamespaceProperty, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V1Subject, V1beta1Subject>()
.ForMember(dest => dest.Group, opt => opt.Ignore())
.ForMember(dest => dest.ServiceAccount, opt => opt.Ignore())
.ForMember(dest => dest.User, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V1Subject, V1beta2Subject>()
.ForMember(dest => dest.Group, opt => opt.Ignore())
.ForMember(dest => dest.ServiceAccount, opt => opt.Ignore())
.ForMember(dest => dest.User, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V1alpha1RuntimeClass, V1RuntimeClass>()
.ForMember(dest => dest.Handler, opt => opt.MapFrom(src => src.Spec.RuntimeHandler))
@@ -169,28 +159,54 @@ namespace k8s.Versioning
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.CurrentAverageValue))
.ForMember(dest => dest.AverageUtilization, opt => opt.MapFrom(src => src.CurrentAverageUtilization))
.ForMember(dest => dest.Value, opt => opt.Ignore());
cfg.CreateMap<V2beta1ResourceMetricStatus, V2MetricValueStatus>()
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.CurrentAverageValue))
.ForMember(dest => dest.AverageUtilization, opt => opt.MapFrom(src => src.CurrentAverageUtilization))
.ForMember(dest => dest.Value, opt => opt.Ignore());
cfg.CreateMap<V2beta1ResourceMetricStatus, V2beta2ResourceMetricStatus>()
.ForMember(dest => dest.Current, opt => opt.MapFrom(src => src));
cfg.CreateMap<V2beta2ResourceMetricStatus, V2beta1ResourceMetricStatus>()
.ForMember(dest => dest.CurrentAverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(dest => dest.CurrentAverageUtilization, opt => opt.MapFrom(src => src.Current.AverageUtilization));
cfg.CreateMap<V2beta1ResourceMetricStatus, V2ResourceMetricStatus>()
.ForMember(dest => dest.Current, opt => opt.MapFrom(src => src));
cfg.CreateMap<V2ResourceMetricStatus, V2beta1ResourceMetricStatus>()
.ForMember(dest => dest.CurrentAverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(dest => dest.CurrentAverageUtilization, opt => opt.MapFrom(src => src.Current.AverageUtilization));
cfg.CreateMap<V2beta1ResourceMetricSource, V2beta2MetricTarget>()
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
.ForMember(dest => dest.Value, opt => opt.Ignore())
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => src.TargetAverageValue != null ? "AverageValue" : "Utilization"))
.ForMember(dest => dest.AverageUtilization, opt => opt.MapFrom(src => src.TargetAverageUtilization));
cfg.CreateMap<V2beta1ResourceMetricSource, V2MetricTarget>()
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
.ForMember(dest => dest.Value, opt => opt.Ignore())
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => src.TargetAverageValue != null ? "AverageValue" : "Utilization"))
.ForMember(dest => dest.AverageUtilization, opt => opt.MapFrom(src => src.TargetAverageUtilization));
cfg.CreateMap<V2beta1ResourceMetricSource, V2beta2ResourceMetricSource>()
.ForMember(dest => dest.Target, opt => opt.MapFrom(src => src));
cfg.CreateMap<V2beta2ResourceMetricSource, V2beta1ResourceMetricSource>()
.ForMember(dest => dest.TargetAverageUtilization, opt => opt.MapFrom(src => src.Target.AverageUtilization))
.ForMember(dest => dest.TargetAverageValue, opt => opt.MapFrom(src => src.Target.Value));
cfg.CreateMap<V2beta1ResourceMetricSource, V2ResourceMetricSource>()
.ForMember(dest => dest.Target, opt => opt.MapFrom(src => src));
cfg.CreateMap<V2ResourceMetricSource, V2beta1ResourceMetricSource>()
.ForMember(dest => dest.TargetAverageUtilization, opt => opt.MapFrom(src => src.Target.AverageUtilization))
.ForMember(dest => dest.TargetAverageValue, opt => opt.MapFrom(src => src.Target.Value));
cfg.CreateMap<V2beta1PodsMetricStatus, V2beta2MetricValueStatus>()
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.CurrentAverageValue))
.ForMember(dest => dest.Value, opt => opt.Ignore())
.ForMember(dest => dest.AverageUtilization, opt => opt.Ignore());
cfg.CreateMap<V2beta1PodsMetricStatus, V2MetricValueStatus>()
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.CurrentAverageValue))
.ForMember(dest => dest.Value, opt => opt.Ignore())
.ForMember(dest => dest.AverageUtilization, opt => opt.Ignore());
cfg.CreateMap<V2beta1PodsMetricStatus, V2beta2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Selector));
cfg.CreateMap<V2beta1PodsMetricStatus, V2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Selector));
cfg.CreateMap<V2beta1PodsMetricStatus, V2beta2PodsMetricStatus>()
.ForMember(dest => dest.Current, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Metric, opt => opt.MapFrom(src => src));
@@ -198,15 +214,31 @@ namespace k8s.Versioning
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Metric.Selector))
.ForMember(dest => dest.CurrentAverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(dest => dest.MetricName, opt => opt.MapFrom(src => src.Metric.Name));
cfg.CreateMap<V2beta1PodsMetricStatus, V2PodsMetricStatus>()
.ForMember(dest => dest.Current, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Metric, opt => opt.MapFrom(src => src));
cfg.CreateMap<V2PodsMetricStatus, V2beta1PodsMetricStatus>()
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Metric.Selector))
.ForMember(dest => dest.CurrentAverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(dest => dest.MetricName, opt => opt.MapFrom(src => src.Metric.Name));
cfg.CreateMap<V2beta1PodsMetricSource, V2beta2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Selector))
.ReverseMap();
cfg.CreateMap<V2beta1PodsMetricSource, V2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Selector))
.ReverseMap();
cfg.CreateMap<V2beta1PodsMetricSource, V2beta2MetricTarget>()
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => "AverageValue"))
.ForMember(dest => dest.Value, opt => opt.Ignore())
.ForMember(dest => dest.AverageUtilization, opt => opt.Ignore());
cfg.CreateMap<V2beta1PodsMetricSource, V2MetricTarget>()
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => "AverageValue"))
.ForMember(dest => dest.Value, opt => opt.Ignore())
.ForMember(dest => dest.AverageUtilization, opt => opt.Ignore());
cfg.CreateMap<V2beta1PodsMetricSource, V2beta2PodsMetricSource>()
.ForMember(dest => dest.Metric, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Target, opt => opt.MapFrom(src => src));
@@ -214,15 +246,31 @@ namespace k8s.Versioning
.ForMember(x => x.Selector, opt => opt.MapFrom(src => src.Metric.Selector))
.ForMember(x => x.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(x => x.TargetAverageValue, opt => opt.MapFrom(src => src.Target.AverageValue));
cfg.CreateMap<V2beta1PodsMetricSource, V2PodsMetricSource>()
.ForMember(dest => dest.Metric, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Target, opt => opt.MapFrom(src => src));
cfg.CreateMap<V2PodsMetricSource, V2beta1PodsMetricSource>()
.ForMember(x => x.Selector, opt => opt.MapFrom(src => src.Metric.Selector))
.ForMember(x => x.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(x => x.TargetAverageValue, opt => opt.MapFrom(src => src.Target.AverageValue));
cfg.CreateMap<V2beta1ObjectMetricStatus, V2beta2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Selector))
.ReverseMap();
cfg.CreateMap<V2beta1ObjectMetricStatus, V2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Selector))
.ReverseMap();
cfg.CreateMap<V2beta1ObjectMetricStatus, V2beta2MetricValueStatus>()
.ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.CurrentValue))
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.AverageValue))
.ForMember(dest => dest.AverageUtilization, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V2beta1ObjectMetricStatus, V2MetricValueStatus>()
.ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.CurrentValue))
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.AverageValue))
.ForMember(dest => dest.AverageUtilization, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V2beta1ObjectMetricStatus, V2beta2ObjectMetricStatus>()
.ForMember(x => x.Current, opt => opt.MapFrom(src => src))
.ForMember(x => x.Metric, opt => opt.MapFrom(src => src))
@@ -233,11 +281,26 @@ namespace k8s.Versioning
.ForMember(x => x.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(x => x.Target, opt => opt.MapFrom(src => src.DescribedObject))
.ForMember(x => x.Selector, opt => opt.MapFrom(src => src.Metric.Selector));
cfg.CreateMap<V2beta1ObjectMetricStatus, V2ObjectMetricStatus>()
.ForMember(x => x.Current, opt => opt.MapFrom(src => src))
.ForMember(x => x.Metric, opt => opt.MapFrom(src => src))
.ForMember(x => x.DescribedObject, opt => opt.MapFrom(src => src.Target));
cfg.CreateMap<V2ObjectMetricStatus, V2beta1ObjectMetricStatus>()
.ForMember(x => x.CurrentValue, opt => opt.MapFrom(src => src.Current.Value))
.ForMember(x => x.AverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(x => x.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(x => x.Target, opt => opt.MapFrom(src => src.DescribedObject))
.ForMember(x => x.Selector, opt => opt.MapFrom(src => src.Metric.Selector));
cfg.CreateMap<V2beta1ExternalMetricSource, V2beta2MetricTarget>()
.ForMember(x => x.Value, opt => opt.MapFrom(src => src.TargetValue))
.ForMember(x => x.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
.ForMember(x => x.AverageUtilization, opt => opt.Ignore())
.ForMember(x => x.Type, opt => opt.MapFrom((src, dest) => src.TargetValue != null ? "Value" : "AverageValue"));
cfg.CreateMap<V2beta1ExternalMetricSource, V2MetricTarget>()
.ForMember(x => x.Value, opt => opt.MapFrom(src => src.TargetValue))
.ForMember(x => x.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
.ForMember(x => x.AverageUtilization, opt => opt.Ignore())
.ForMember(x => x.Type, opt => opt.MapFrom((src, dest) => src.TargetValue != null ? "Value" : "AverageValue"));
cfg.CreateMap<V2beta1ExternalMetricSource, V2beta2ExternalMetricSource>()
.ForMember(x => x.Metric, opt => opt.MapFrom(src => src))
.ForMember(x => x.Target, opt => opt.MapFrom(src => src));
@@ -246,6 +309,14 @@ namespace k8s.Versioning
.ForMember(x => x.TargetAverageValue, opt => opt.MapFrom(src => src.Target.AverageValue))
.ForMember(x => x.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(x => x.MetricSelector, opt => opt.MapFrom(src => src.Metric.Selector));
cfg.CreateMap<V2beta1ExternalMetricSource, V2ExternalMetricSource>()
.ForMember(x => x.Metric, opt => opt.MapFrom(src => src))
.ForMember(x => x.Target, opt => opt.MapFrom(src => src));
cfg.CreateMap<V2ExternalMetricSource, V2beta1ExternalMetricSource>()
.ForMember(x => x.TargetValue, opt => opt.MapFrom(src => src.Target.Value))
.ForMember(x => x.TargetAverageValue, opt => opt.MapFrom(src => src.Target.AverageValue))
.ForMember(x => x.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(x => x.MetricSelector, opt => opt.MapFrom(src => src.Metric.Selector));
cfg.CreateMap<V2beta1ExternalMetricStatus, V2beta2ExternalMetricStatus>()
.ForMember(x => x.Current, opt => opt.MapFrom(src => src))
.ForMember(x => x.Metric, opt => opt.MapFrom(src => src));
@@ -254,20 +325,42 @@ namespace k8s.Versioning
.ForMember(x => x.CurrentAverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(x => x.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(x => x.MetricSelector, opt => opt.MapFrom(src => src.Metric.Selector));
cfg.CreateMap<V2beta1ExternalMetricStatus, V2ExternalMetricStatus>()
.ForMember(x => x.Current, opt => opt.MapFrom(src => src))
.ForMember(x => x.Metric, opt => opt.MapFrom(src => src));
cfg.CreateMap<V2ExternalMetricStatus, V2beta1ExternalMetricStatus>()
.ForMember(x => x.CurrentValue, opt => opt.MapFrom(src => src.Current.Value))
.ForMember(x => x.CurrentAverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(x => x.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(x => x.MetricSelector, opt => opt.MapFrom(src => src.Metric.Selector));
cfg.CreateMap<V2beta1ExternalMetricStatus, V2beta2MetricIdentifier>()
.ForMember(x => x.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(x => x.Selector, opt => opt.MapFrom(src => src.MetricSelector))
.ReverseMap();
cfg.CreateMap<V2beta1ExternalMetricStatus, V2MetricIdentifier>()
.ForMember(x => x.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(x => x.Selector, opt => opt.MapFrom(src => src.MetricSelector))
.ReverseMap();
cfg.CreateMap<V2beta1ExternalMetricStatus, V2beta2MetricValueStatus>()
.ForMember(x => x.Value, opt => opt.MapFrom(src => src.CurrentValue))
.ForMember(x => x.AverageValue, opt => opt.MapFrom(src => src.CurrentAverageValue))
.ForMember(x => x.AverageUtilization, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V2beta1ExternalMetricStatus, V2MetricValueStatus>()
.ForMember(x => x.Value, opt => opt.MapFrom(src => src.CurrentValue))
.ForMember(x => x.AverageValue, opt => opt.MapFrom(src => src.CurrentAverageValue))
.ForMember(x => x.AverageUtilization, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V2beta1ObjectMetricSource, V2beta2MetricTarget>()
.ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.TargetValue))
.ForMember(dest => dest.AverageUtilization, opt => opt.Ignore())
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.AverageValue))
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => src.TargetValue != null ? "Value" : "AverageValue"));
cfg.CreateMap<V2beta1ObjectMetricSource, V2MetricTarget>()
.ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.TargetValue))
.ForMember(dest => dest.AverageUtilization, opt => opt.Ignore())
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.AverageValue))
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => src.TargetValue != null ? "Value" : "AverageValue"));
cfg.CreateMap<V2beta1ObjectMetricSource, V2beta2ObjectMetricSource>()
.ForMember(dest => dest.Metric, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Target, opt => opt.MapFrom(src => src))
@@ -278,13 +371,30 @@ namespace k8s.Versioning
.ForMember(dest => dest.TargetValue, opt => opt.MapFrom(src => src.Target.Value))
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.Target.AverageValue))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Metric.Selector));
cfg.CreateMap<V2beta1ObjectMetricSource, V2ObjectMetricSource>()
.ForMember(dest => dest.Metric, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.Target, opt => opt.MapFrom(src => src))
.ForMember(dest => dest.DescribedObject, opt => opt.MapFrom(src => src.Target));
cfg.CreateMap<V2ObjectMetricSource, V2beta1ObjectMetricSource>()
.ForMember(dest => dest.Target, opt => opt.MapFrom(src => src.DescribedObject))
.ForMember(dest => dest.MetricName, opt => opt.MapFrom(src => src.Metric.Name))
.ForMember(dest => dest.TargetValue, opt => opt.MapFrom(src => src.Target.Value))
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.Target.AverageValue))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Metric.Selector));
cfg.CreateMap<V2beta1ObjectMetricSource, V2beta2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Selector))
.ReverseMap();
cfg.CreateMap<V2beta1ObjectMetricSource, V2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.Selector))
.ReverseMap();
cfg.CreateMap<V2beta1ExternalMetricSource, V2beta2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.MetricSelector));
cfg.CreateMap<V2beta1ExternalMetricSource, V2MetricIdentifier>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MetricName))
.ForMember(dest => dest.Selector, opt => opt.MapFrom(src => src.MetricSelector));
cfg.CreateMap<V2beta2MetricTarget, V2beta1ExternalMetricSource>() // todo: not needed
.ForMember(dest => dest.MetricName, opt => opt.Ignore())
.ForMember(dest => dest.MetricSelector, opt => opt.Ignore())
@@ -297,6 +407,11 @@ namespace k8s.Versioning
.ForMember(dest => dest.Behavior, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V1HorizontalPodAutoscalerSpec, V2HorizontalPodAutoscalerSpec>()
.ForMember(dest => dest.Metrics, opt => opt.Ignore())
.ForMember(dest => dest.Behavior, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V1HorizontalPodAutoscalerSpec, V2beta1HorizontalPodAutoscalerSpec>()
.ForMember(dest => dest.Metrics, opt => opt.Ignore())
.ReverseMap();
@@ -305,6 +420,10 @@ namespace k8s.Versioning
.ForMember(dest => dest.Behavior, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V2beta1HorizontalPodAutoscalerSpec, V2HorizontalPodAutoscalerSpec>()
.ForMember(dest => dest.Behavior, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V1HorizontalPodAutoscalerStatus, V2beta1HorizontalPodAutoscalerStatus>()
.ForMember(dest => dest.Conditions, opt => opt.Ignore())
.ForMember(dest => dest.CurrentMetrics, opt => opt.Ignore())
@@ -313,6 +432,10 @@ namespace k8s.Versioning
.ForMember(dest => dest.Conditions, opt => opt.Ignore())
.ForMember(dest => dest.CurrentMetrics, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<V1HorizontalPodAutoscalerStatus, V2HorizontalPodAutoscalerStatus>()
.ForMember(dest => dest.Conditions, opt => opt.Ignore())
.ForMember(dest => dest.CurrentMetrics, opt => opt.Ignore())
.ReverseMap();
cfg.CreateMap<Corev1EventSeries, V1beta1EventSeries>()
.ForMember(dest => dest.LastObservedTime, opt => opt.MapFrom(src => src.LastObservedTime))
@@ -333,17 +456,20 @@ namespace k8s.Versioning
.ForMember(dest => dest.TargetAverageUtilization, opt => opt.MapFrom(src => src.Target.AverageUtilization))
.ReverseMap();
cfg.CreateMap<V2ContainerResourceMetricSource, V2beta1ContainerResourceMetricSource>()
.ForMember(dest => dest.TargetAverageValue, opt => opt.MapFrom(src => src.Target.AverageValue))
.ForMember(dest => dest.TargetAverageUtilization, opt => opt.MapFrom(src => src.Target.AverageUtilization))
.ReverseMap();
cfg.CreateMap<V2beta2ContainerResourceMetricStatus, V2beta1ContainerResourceMetricStatus>()
.ForMember(dest => dest.CurrentAverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(dest => dest.CurrentAverageUtilization, opt => opt.MapFrom(src => src.Current.AverageUtilization))
.ReverseMap();
cfg.CreateMap<V1alpha1RoleBinding, V1RoleBinding>().ReverseMap();
cfg.CreateMap<V1alpha1ClusterRoleBinding, V1ClusterRoleBinding>().ReverseMap();
cfg.CreateMap<V1alpha1ClusterRoleBindingList, V1ClusterRoleBindingList>().ReverseMap();
cfg.CreateMap<V2ContainerResourceMetricStatus, V2beta1ContainerResourceMetricStatus>()
.ForMember(dest => dest.CurrentAverageValue, opt => opt.MapFrom(src => src.Current.AverageValue))
.ForMember(dest => dest.CurrentAverageUtilization, opt => opt.MapFrom(src => src.Current.AverageUtilization))
.ReverseMap();
cfg.CreateMap<V1beta1Endpoint, V1Endpoint>()
.ForMember(dest => dest.DeprecatedTopology, opt => opt.Ignore())

View File

@@ -1,13 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using k8s.Models;
using Microsoft.Rest.Serialization;
namespace k8s
{
@@ -120,8 +116,10 @@ namespace k8s
public class WatchEvent
{
[JsonPropertyName("type")]
public WatchEventType Type { get; set; }
[JsonPropertyName("object")]
public T Object { get; set; }
}
@@ -189,17 +187,17 @@ namespace k8s
try
{
var genericEvent = SafeJsonConvert.DeserializeObject<Watcher<KubernetesObject>.WatchEvent>(line);
var genericEvent = KubernetesJson.Deserialize<Watcher<KubernetesObject>.WatchEvent>(line);
if (genericEvent.Object.Kind == "Status")
{
var statusEvent = SafeJsonConvert.DeserializeObject<Watcher<V1Status>.WatchEvent>(line);
var statusEvent = KubernetesJson.Deserialize<Watcher<V1Status>.WatchEvent>(line);
var exception = new KubernetesException(statusEvent.Object);
onError?.Invoke(exception);
}
else
{
@event = SafeJsonConvert.DeserializeObject<WatchEvent>(line);
@event = KubernetesJson.Deserialize<WatchEvent>(line);
}
}
catch (Exception e)

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using k8s.Exceptions;

View File

@@ -1,6 +1,4 @@
using System;
using System.Net.WebSockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;

View File

@@ -1,8 +1,4 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@@ -219,13 +215,13 @@ namespace k8s
{
foreach (var property in type.GetProperties())
{
var jsonAttribute = property.GetCustomAttribute<JsonPropertyAttribute>();
var jsonAttribute = property.GetCustomAttribute<JsonPropertyNameAttribute>();
if (jsonAttribute == null)
{
continue;
}
var yamlAttribute = new YamlMemberAttribute { Alias = jsonAttribute.PropertyName, ApplyNamingConventions = false };
var yamlAttribute = new YamlMemberAttribute { Alias = jsonAttribute.Name, ApplyNamingConventions = false };
builder.WithAttributeOverride(type, property.Name, yamlAttribute);
}
}

View File

@@ -1,2 +1,2 @@
Requested Commit: v3.3.4
Actual Commit: 2353d71d4b02be6dbabe25aac1a9e56eb3b812a2
Requested Commit: v5.1.0
Actual Commit: e023eaa8218da996140148161978953cc698d014

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More