Style fix1 (#512)
* fix SA1505 and SA1508 * fix SA1116 * fix SA1009 * fix SA1019 * fix SA1127 * fix SA1128 * fix SA1134 * fix indent * allow CA2227 * fix CA1810 * using clean up * fix naming * fix CA1806 * fix await * Revert "fix CA1806" This reverts commit a3b465087fdaf26ec461272373ee9810a90de2cc. * fix dotnet format * allow SA1009
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using k8s;
|
using k8s;
|
||||||
|
|
||||||
@@ -22,7 +21,8 @@ namespace logs
|
|||||||
|
|
||||||
var pod = list.Items[0];
|
var pod = list.Items[0];
|
||||||
|
|
||||||
var response = await client.ReadNamespacedPodLogWithHttpMessagesAsync(pod.Metadata.Name,
|
var response = await client.ReadNamespacedPodLogWithHttpMessagesAsync(
|
||||||
|
pod.Metadata.Name,
|
||||||
pod.Metadata.NamespaceProperty, follow: true).ConfigureAwait(false);
|
pod.Metadata.NamespaceProperty, follow: true).ConfigureAwait(false);
|
||||||
var stream = response.Body;
|
var stream = response.Body;
|
||||||
stream.CopyTo(Console.OpenStandardOutput());
|
stream.CopyTo(Console.OpenStandardOutput());
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
<Rule Id="SA1314" Action="None" />
|
<Rule Id="SA1314" Action="None" />
|
||||||
|
|
||||||
<!-- A C# using directive is placed outside of a namespace element. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1200.md -->
|
<!-- A C# using directive is placed outside of a namespace element. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1200.md -->
|
||||||
<Rule Id="SA1200" Action="Warning" />
|
<Rule Id="SA1200" Action="Error" />
|
||||||
|
|
||||||
<!-- An element within a C# code file is out of order in relation to the other elements in the code. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1201.md -->
|
<!-- An element within a C# code file is out of order in relation to the other elements in the code. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1201.md -->
|
||||||
<Rule Id="SA1201" Action="None" />
|
<Rule Id="SA1201" Action="None" />
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
<Rule Id="SA1001" Action="Warning" />
|
<Rule Id="SA1001" Action="Warning" />
|
||||||
|
|
||||||
<!-- A closing parenthesis within a C# statement is not spaced correctly. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1009.md -->
|
<!-- A closing parenthesis within a C# statement is not spaced correctly. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1009.md -->
|
||||||
<Rule Id="SA1009" Action="Warning" />
|
<Rule Id="SA1009" Action="None" />
|
||||||
|
|
||||||
<!-- An opening brace within a C# element is not spaced correctly. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1012.md -->
|
<!-- An opening brace within a C# element is not spaced correctly. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1012.md -->
|
||||||
<Rule Id="SA1012" Action="Warning" />
|
<Rule Id="SA1012" Action="Warning" />
|
||||||
@@ -205,10 +205,10 @@
|
|||||||
<Rule Id="CA2225" Action="None" />
|
<Rule Id="CA2225" Action="None" />
|
||||||
|
|
||||||
<!-- Collection properties should be read only https://docs.microsoft.com/en-us/visualstudio/code-quality/CA2227 -->
|
<!-- Collection properties should be read only https://docs.microsoft.com/en-us/visualstudio/code-quality/CA2227 -->
|
||||||
<Rule Id="CA2227" Action="Warning" />
|
<Rule Id="CA2227" Action="None" />
|
||||||
|
|
||||||
<!-- Mark ISerializable types with SerializableAttribute https://docs.microsoft.com/en-us/visualstudio/code-quality/CA2237 -->
|
<!-- Mark ISerializable types with SerializableAttribute https://docs.microsoft.com/en-us/visualstudio/code-quality/CA2237 -->
|
||||||
<Rule Id="CA2237" Action="Warning" />
|
<Rule Id="CA2237" Action="None" />
|
||||||
|
|
||||||
<!-- Do Not Disable Certificate Validation https://docs.microsoft.com/en-us/visualstudio/code-quality/CA5359 -->
|
<!-- Do Not Disable Certificate Validation https://docs.microsoft.com/en-us/visualstudio/code-quality/CA5359 -->
|
||||||
<Rule Id="CA5359" Action="None" />
|
<Rule Id="CA5359" Action="None" />
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace k8s.Authentication
|
|||||||
TokenFile = tokenFile;
|
TokenFile = tokenFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
|
public Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (TokenExpiresAt < DateTime.UtcNow)
|
if (TokenExpiresAt < DateTime.UtcNow)
|
||||||
{
|
{
|
||||||
@@ -32,7 +32,7 @@ namespace k8s.Authentication
|
|||||||
TokenExpiresAt = DateTime.UtcNow.AddMinutes(1);
|
TokenExpiresAt = DateTime.UtcNow.AddMinutes(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AuthenticationHeaderValue("Bearer", token);
|
return Task.FromResult(new AuthenticationHeaderValue("Bearer", token));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,7 +282,8 @@ namespace k8s
|
|||||||
Array.Copy(this.buffer, 0, newBuffer, 0, this.WriteWaterMark);
|
Array.Copy(this.buffer, 0, newBuffer, 0, this.WriteWaterMark);
|
||||||
|
|
||||||
int trailingDataLength = this.buffer.Length - this.ReadWaterMark;
|
int trailingDataLength = this.buffer.Length - this.ReadWaterMark;
|
||||||
Array.Copy(this.buffer,
|
Array.Copy(
|
||||||
|
this.buffer,
|
||||||
sourceIndex: this.ReadWaterMark,
|
sourceIndex: this.ReadWaterMark,
|
||||||
destinationArray: newBuffer,
|
destinationArray: newBuffer,
|
||||||
destinationIndex: newBuffer.Length - trailingDataLength,
|
destinationIndex: newBuffer.Length - trailingDataLength,
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ using Org.BouncyCastle.Pkcs;
|
|||||||
using Org.BouncyCastle.Security;
|
using Org.BouncyCastle.Security;
|
||||||
using Org.BouncyCastle.X509;
|
using Org.BouncyCastle.X509;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace k8s
|
namespace k8s
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace k8s.Exceptions
|
namespace k8s.Exceptions
|
||||||
{
|
{
|
||||||
using System;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The exception that is thrown when the kube config is invalid
|
/// The exception that is thrown when the kube config is invalid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace k8s.Exceptions
|
namespace k8s.Exceptions
|
||||||
{
|
{
|
||||||
using System;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The exception that is thrown when there is a client exception
|
/// The exception that is thrown when there is a client exception
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,22 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using k8s.Models;
|
using k8s.Models;
|
||||||
using Microsoft.Rest;
|
|
||||||
using Microsoft.Rest.TransientFaultHandling;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
using VersionConverter = k8s.Versioning.VersionConverter;
|
|
||||||
|
|
||||||
namespace k8s
|
namespace k8s
|
||||||
{
|
{
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
public static KubernetesEntityAttribute GetKubernetesTypeMetadata<T>(this T obj) where T : IKubernetesObject =>
|
public static KubernetesEntityAttribute GetKubernetesTypeMetadata<T>(this T obj)
|
||||||
|
where T : IKubernetesObject
|
||||||
|
=>
|
||||||
obj.GetType().GetKubernetesTypeMetadata();
|
obj.GetType().GetKubernetesTypeMetadata();
|
||||||
public static KubernetesEntityAttribute GetKubernetesTypeMetadata(this Type currentType)
|
public static KubernetesEntityAttribute GetKubernetesTypeMetadata(this Type currentType)
|
||||||
{
|
{
|
||||||
@@ -29,7 +22,8 @@ namespace k8s
|
|||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T Initialize<T>(this T obj) where T : IKubernetesObject
|
public static T Initialize<T>(this T obj)
|
||||||
|
where T : IKubernetesObject
|
||||||
{
|
{
|
||||||
var metadata = obj.GetKubernetesTypeMetadata();
|
var metadata = obj.GetKubernetesTypeMetadata();
|
||||||
obj.ApiVersion = !string.IsNullOrEmpty(metadata.Group) ? $"{metadata.Group}/{metadata.ApiVersion}" : metadata.ApiVersion;
|
obj.ApiVersion = !string.IsNullOrEmpty(metadata.Group) ? $"{metadata.Group}/{metadata.ApiVersion}" : metadata.ApiVersion;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using YamlDotNet.Core.Events;
|
|
||||||
using YamlDotNet.Core.Tokens;
|
|
||||||
|
|
||||||
namespace k8s.Models
|
namespace k8s.Models
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace k8s.KubeConfigModels
|
namespace k8s.KubeConfigModels
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
|
/// Contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace k8s.KubeConfigModels
|
namespace k8s.KubeConfigModels
|
||||||
{
|
{
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Relates nicknames to cluster information.
|
/// Relates nicknames to cluster information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace k8s.KubeConfigModels
|
namespace k8s.KubeConfigModels
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains information about how to communicate with a kubernetes cluster
|
/// Contains information about how to communicate with a kubernetes cluster
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace k8s.KubeConfigModels
|
namespace k8s.KubeConfigModels
|
||||||
{
|
{
|
||||||
using System;
|
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Relates nicknames to context information.
|
/// Relates nicknames to context information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace k8s.KubeConfigModels
|
namespace k8s.KubeConfigModels
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a tuple of references to a cluster (how do I communicate with a kubernetes cluster),
|
/// Represents a tuple of references to a cluster (how do I communicate with a kubernetes cluster),
|
||||||
/// a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
|
/// a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ namespace k8s.KubeConfigModels
|
|||||||
{
|
{
|
||||||
public class ExecCredentialResponse
|
public class ExecCredentialResponse
|
||||||
{
|
{
|
||||||
[JsonProperty("apiVersion")] public string ApiVersion { get; set; }
|
[JsonProperty("apiVersion")]
|
||||||
[JsonProperty("kind")] public string Kind { get; set; }
|
public string ApiVersion { get; set; }
|
||||||
[JsonProperty("status")] public IDictionary<string, string> Status { get; set; }
|
[JsonProperty("kind")]
|
||||||
|
public string Kind { get; set; }
|
||||||
|
[JsonProperty("status")]
|
||||||
|
public IDictionary<string, string> Status { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ namespace k8s.KubeConfigModels
|
|||||||
{
|
{
|
||||||
public class ExternalExecution
|
public class ExternalExecution
|
||||||
{
|
{
|
||||||
[YamlMember(Alias = "apiVersion")] public string ApiVersion { get; set; }
|
[YamlMember(Alias = "apiVersion")]
|
||||||
|
public string ApiVersion { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The command to execute. Required.
|
/// The command to execute. Required.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace k8s.KubeConfigModels
|
namespace k8s.KubeConfigModels
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// kubeconfig configuration model. Holds the information needed to build connect to remote
|
/// kubeconfig configuration model. Holds the information needed to build connect to remote
|
||||||
/// Kubernetes clusters as a given user.
|
/// Kubernetes clusters as a given user.
|
||||||
@@ -19,9 +19,11 @@ namespace k8s.KubeConfigModels
|
|||||||
[YamlMember(Alias = "preferences")]
|
[YamlMember(Alias = "preferences")]
|
||||||
public IDictionary<string, object> Preferences { get; set; }
|
public IDictionary<string, object> Preferences { get; set; }
|
||||||
|
|
||||||
[YamlMember(Alias = "apiVersion")] public string ApiVersion { get; set; }
|
[YamlMember(Alias = "apiVersion")]
|
||||||
|
public string ApiVersion { get; set; }
|
||||||
|
|
||||||
[YamlMember(Alias = "kind")] public string Kind { get; set; }
|
[YamlMember(Alias = "kind")]
|
||||||
|
public string Kind { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name of the context that you would like to use by default.
|
/// Gets or sets the name of the context that you would like to use by default.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace k8s.KubeConfigModels
|
namespace k8s.KubeConfigModels
|
||||||
{
|
{
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Relates nicknames to auth information.
|
/// Relates nicknames to auth information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
namespace k8s.KubeConfigModels
|
namespace k8s.KubeConfigModels
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
|
||||||
using YamlDotNet.RepresentationModel;
|
|
||||||
using YamlDotNet.Serialization;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
|
/// Contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ namespace k8s
|
|||||||
/// <param name="httpClient">
|
/// <param name="httpClient">
|
||||||
/// The <see cref="HttpClient" /> to use for all requests.
|
/// The <see cref="HttpClient" /> to use for all requests.
|
||||||
/// </param>
|
/// </param>
|
||||||
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient) : this(config, httpClient, false)
|
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient)
|
||||||
|
: this(config, httpClient, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +39,8 @@ namespace k8s
|
|||||||
/// <param name="disposeHttpClient">
|
/// <param name="disposeHttpClient">
|
||||||
/// Whether or not the <see cref="Kubernetes"/> object should own the lifetime of <paramref name="httpClient"/>.
|
/// Whether or not the <see cref="Kubernetes"/> object should own the lifetime of <paramref name="httpClient"/>.
|
||||||
/// </param>
|
/// </param>
|
||||||
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient, bool disposeHttpClient) : this(
|
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient, bool disposeHttpClient)
|
||||||
|
: this(
|
||||||
httpClient, disposeHttpClient)
|
httpClient, disposeHttpClient)
|
||||||
{
|
{
|
||||||
ValidateConfig(config);
|
ValidateConfig(config);
|
||||||
@@ -179,12 +181,14 @@ namespace k8s
|
|||||||
/// <summary>A <see cref="DelegatingHandler"/> that simply forwards a request with no further processing.</summary>
|
/// <summary>A <see cref="DelegatingHandler"/> that simply forwards a request with no further processing.</summary>
|
||||||
private sealed class ForwardingHandler : DelegatingHandler
|
private sealed class ForwardingHandler : DelegatingHandler
|
||||||
{
|
{
|
||||||
public ForwardingHandler(HttpMessageHandler handler) : base(handler)
|
public ForwardingHandler(HttpMessageHandler handler)
|
||||||
|
: base(handler)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AppendDelegatingHandler<T>() where T : DelegatingHandler, new()
|
private void AppendDelegatingHandler<T>()
|
||||||
|
where T : DelegatingHandler, new()
|
||||||
{
|
{
|
||||||
var cur = FirstMessageHandler as DelegatingHandler;
|
var cur = FirstMessageHandler as DelegatingHandler;
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ namespace k8s
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var muxedStream = await this.MuxedStreamNamespacedPodExecAsync(name: name,
|
using (var muxedStream = await this.MuxedStreamNamespacedPodExecAsync(
|
||||||
|
name: name,
|
||||||
@namespace: @namespace, command: command, container: container, tty: tty,
|
@namespace: @namespace, command: command, container: container, tty: tty,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false))
|
cancellationToken: cancellationToken).ConfigureAwait(false))
|
||||||
using (Stream stdIn = muxedStream.GetStream(null, ChannelIndex.StdIn))
|
using (Stream stdIn = muxedStream.GetStream(null, ChannelIndex.StdIn))
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ namespace k8s
|
|||||||
uriBuilder.Query =
|
uriBuilder.Query =
|
||||||
query.Length == 0
|
query.Length == 0
|
||||||
? ""
|
? ""
|
||||||
: query.ToString(1,
|
: query.ToString(
|
||||||
|
1,
|
||||||
query.Length - 1); // UriBuilder.Query doesn't like leading '?' chars, so trim it
|
query.Length - 1); // UriBuilder.Query doesn't like leading '?' chars, so trim it
|
||||||
|
|
||||||
// Create HTTP transport objects
|
// Create HTTP transport objects
|
||||||
@@ -145,7 +146,8 @@ namespace k8s
|
|||||||
{
|
{
|
||||||
string responseContent = string.Empty;
|
string responseContent = string.Empty;
|
||||||
|
|
||||||
var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'",
|
var ex = new HttpOperationException(string.Format(
|
||||||
|
"Operation returned an invalid status code '{0}'",
|
||||||
httpResponse.StatusCode));
|
httpResponse.StatusCode));
|
||||||
if (httpResponse.Content != null)
|
if (httpResponse.Content != null)
|
||||||
{
|
{
|
||||||
@@ -160,7 +162,8 @@ namespace k8s
|
|||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Watcher<T>(async () =>
|
return new Watcher<T>(
|
||||||
|
async () =>
|
||||||
{
|
{
|
||||||
var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||||
StreamReader reader = new StreamReader(stream);
|
StreamReader reader = new StreamReader(stream);
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ namespace k8s
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public virtual async Task<IStreamDemuxer> MuxedStreamNamespacedPodExecAsync(string name,
|
public virtual async Task<IStreamDemuxer> MuxedStreamNamespacedPodExecAsync(
|
||||||
|
string name,
|
||||||
string @namespace = "default", IEnumerable<string> command = null, string container = null,
|
string @namespace = "default", IEnumerable<string> command = null, string container = null,
|
||||||
bool stderr = true, bool stdin = true, bool stdout = true, bool tty = true,
|
bool stderr = true, bool stdin = true, bool stdout = true, bool tty = true,
|
||||||
string webSocketSubProtol = WebSocketProtocol.V4BinaryWebsocketProtocol,
|
string webSocketSubProtol = WebSocketProtocol.V4BinaryWebsocketProtocol,
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ namespace k8s
|
|||||||
/// <param name="masterUrl">kube api server endpoint</param>
|
/// <param name="masterUrl">kube api server endpoint</param>
|
||||||
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
||||||
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
||||||
public static KubernetesClientConfiguration BuildConfigFromConfigFile(string kubeconfigPath = null,
|
public static KubernetesClientConfiguration BuildConfigFromConfigFile(
|
||||||
|
string kubeconfigPath = null,
|
||||||
string currentContext = null, string masterUrl = null, bool useRelativePaths = true)
|
string currentContext = null, string masterUrl = null, bool useRelativePaths = true)
|
||||||
{
|
{
|
||||||
return BuildConfigFromConfigFile(new FileInfo(kubeconfigPath ?? KubeConfigDefaultLocation), currentContext,
|
return BuildConfigFromConfigFile(new FileInfo(kubeconfigPath ?? KubeConfigDefaultLocation), currentContext,
|
||||||
@@ -91,7 +92,8 @@ namespace k8s
|
|||||||
/// <param name="masterUrl">override the kube api server endpoint, set null if do not want to override</param>
|
/// <param name="masterUrl">override the kube api server endpoint, set null if do not want to override</param>
|
||||||
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
||||||
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
||||||
public static KubernetesClientConfiguration BuildConfigFromConfigFile(FileInfo kubeconfig,
|
public static KubernetesClientConfiguration BuildConfigFromConfigFile(
|
||||||
|
FileInfo kubeconfig,
|
||||||
string currentContext = null, string masterUrl = null, bool useRelativePaths = true)
|
string currentContext = null, string masterUrl = null, bool useRelativePaths = true)
|
||||||
{
|
{
|
||||||
return BuildConfigFromConfigFileAsync(kubeconfig, currentContext, masterUrl, useRelativePaths).GetAwaiter()
|
return BuildConfigFromConfigFileAsync(kubeconfig, currentContext, masterUrl, useRelativePaths).GetAwaiter()
|
||||||
@@ -106,7 +108,8 @@ namespace k8s
|
|||||||
/// <param name="masterUrl">override the kube api server endpoint, set null if do not want to override</param>
|
/// <param name="masterUrl">override the kube api server endpoint, set null if do not want to override</param>
|
||||||
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
||||||
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
||||||
public static async Task<KubernetesClientConfiguration> BuildConfigFromConfigFileAsync(FileInfo kubeconfig,
|
public static async Task<KubernetesClientConfiguration> BuildConfigFromConfigFileAsync(
|
||||||
|
FileInfo kubeconfig,
|
||||||
string currentContext = null, string masterUrl = null, bool useRelativePaths = true)
|
string currentContext = null, string masterUrl = null, bool useRelativePaths = true)
|
||||||
{
|
{
|
||||||
if (kubeconfig == null)
|
if (kubeconfig == null)
|
||||||
@@ -126,7 +129,8 @@ namespace k8s
|
|||||||
/// <param name="kubeconfig">Stream of the kubeconfig, cannot be null</param>
|
/// <param name="kubeconfig">Stream of the kubeconfig, cannot be null</param>
|
||||||
/// <param name="currentContext">Override the current context in config, set null if do not want to override</param>
|
/// <param name="currentContext">Override the current context in config, set null if do not want to override</param>
|
||||||
/// <param name="masterUrl">Override the Kubernetes API server endpoint, set null if do not want to override</param>
|
/// <param name="masterUrl">Override the Kubernetes API server endpoint, set null if do not want to override</param>
|
||||||
public static KubernetesClientConfiguration BuildConfigFromConfigFile(Stream kubeconfig,
|
public static KubernetesClientConfiguration BuildConfigFromConfigFile(
|
||||||
|
Stream kubeconfig,
|
||||||
string currentContext = null, string masterUrl = null)
|
string currentContext = null, string masterUrl = null)
|
||||||
{
|
{
|
||||||
return BuildConfigFromConfigFileAsync(kubeconfig, currentContext, masterUrl).GetAwaiter().GetResult();
|
return BuildConfigFromConfigFileAsync(kubeconfig, currentContext, masterUrl).GetAwaiter().GetResult();
|
||||||
@@ -138,7 +142,8 @@ namespace k8s
|
|||||||
/// <param name="kubeconfig">Stream of the kubeconfig, cannot be null</param>
|
/// <param name="kubeconfig">Stream of the kubeconfig, cannot be null</param>
|
||||||
/// <param name="currentContext">Override the current context in config, set null if do not want to override</param>
|
/// <param name="currentContext">Override the current context in config, set null if do not want to override</param>
|
||||||
/// <param name="masterUrl">Override the Kubernetes API server endpoint, set null if do not want to override</param>
|
/// <param name="masterUrl">Override the Kubernetes API server endpoint, set null if do not want to override</param>
|
||||||
public static async Task<KubernetesClientConfiguration> BuildConfigFromConfigFileAsync(Stream kubeconfig,
|
public static async Task<KubernetesClientConfiguration> BuildConfigFromConfigFileAsync(
|
||||||
|
Stream kubeconfig,
|
||||||
string currentContext = null, string masterUrl = null)
|
string currentContext = null, string masterUrl = null)
|
||||||
{
|
{
|
||||||
if (kubeconfig == null)
|
if (kubeconfig == null)
|
||||||
@@ -165,11 +170,13 @@ namespace k8s
|
|||||||
/// <param name="k8sConfig">A <see cref="K8SConfiguration"/>, for example loaded from <see cref="LoadKubeConfigAsync(string, bool)" /></param>
|
/// <param name="k8sConfig">A <see cref="K8SConfiguration"/>, for example loaded from <see cref="LoadKubeConfigAsync(string, bool)" /></param>
|
||||||
/// <param name="currentContext">Override the current context in config, set null if do not want to override</param>
|
/// <param name="currentContext">Override the current context in config, set null if do not want to override</param>
|
||||||
/// <param name="masterUrl">Override the Kubernetes API server endpoint, set null if do not want to override</param>
|
/// <param name="masterUrl">Override the Kubernetes API server endpoint, set null if do not want to override</param>
|
||||||
public static KubernetesClientConfiguration BuildConfigFromConfigObject(K8SConfiguration k8SConfig,
|
public static KubernetesClientConfiguration BuildConfigFromConfigObject(
|
||||||
|
K8SConfiguration k8SConfig,
|
||||||
string currentContext = null, string masterUrl = null)
|
string currentContext = null, string masterUrl = null)
|
||||||
=> GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig);
|
=> GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig);
|
||||||
|
|
||||||
private static KubernetesClientConfiguration GetKubernetesClientConfiguration(string currentContext,
|
private static KubernetesClientConfiguration GetKubernetesClientConfiguration(
|
||||||
|
string currentContext,
|
||||||
string masterUrl, K8SConfiguration k8SConfig)
|
string masterUrl, K8SConfiguration k8SConfig)
|
||||||
{
|
{
|
||||||
var k8SConfiguration = new KubernetesClientConfiguration();
|
var k8SConfiguration = new KubernetesClientConfiguration();
|
||||||
@@ -232,7 +239,8 @@ namespace k8s
|
|||||||
private void SetClusterDetails(K8SConfiguration k8SConfig, Context activeContext)
|
private void SetClusterDetails(K8SConfiguration k8SConfig, Context activeContext)
|
||||||
{
|
{
|
||||||
var clusterDetails =
|
var clusterDetails =
|
||||||
k8SConfig.Clusters.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.Cluster,
|
k8SConfig.Clusters.FirstOrDefault(c => c.Name.Equals(
|
||||||
|
activeContext.ContextDetails.Cluster,
|
||||||
StringComparison.OrdinalIgnoreCase));
|
StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
if (clusterDetails?.ClusterEndpoint == null)
|
if (clusterDetails?.ClusterEndpoint == null)
|
||||||
@@ -262,7 +270,8 @@ namespace k8s
|
|||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthority))
|
else if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthority))
|
||||||
{
|
{
|
||||||
SslCaCerts = new X509Certificate2Collection(new X509Certificate2(GetFullPath(k8SConfig,
|
SslCaCerts = new X509Certificate2Collection(new X509Certificate2(GetFullPath(
|
||||||
|
k8SConfig,
|
||||||
clusterDetails.ClusterEndpoint.CertificateAuthority)));
|
clusterDetails.ClusterEndpoint.CertificateAuthority)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,7 +284,8 @@ namespace k8s
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userDetails = k8SConfig.Users.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.User,
|
var userDetails = k8SConfig.Users.FirstOrDefault(c => c.Name.Equals(
|
||||||
|
activeContext.ContextDetails.User,
|
||||||
StringComparison.OrdinalIgnoreCase));
|
StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
if (userDetails == null)
|
if (userDetails == null)
|
||||||
@@ -343,15 +353,17 @@ namespace k8s
|
|||||||
expires = DateTimeOffset.FromUnixTimeSeconds(expiresOn);
|
expires = DateTimeOffset.FromUnixTimeSeconds(expiresOn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (DateTimeOffset.Compare(expires,
|
if (DateTimeOffset.Compare(
|
||||||
DateTimeOffset.Now)
|
expires,
|
||||||
|
DateTimeOffset.Now)
|
||||||
<= 0)
|
<= 0)
|
||||||
{
|
{
|
||||||
var tenantId = config["tenant-id"];
|
var tenantId = config["tenant-id"];
|
||||||
var clientId = config["client-id"];
|
var clientId = config["client-id"];
|
||||||
var apiServerId = config["apiserver-id"];
|
var apiServerId = config["apiserver-id"];
|
||||||
var refresh = config["refresh-token"];
|
var refresh = config["refresh-token"];
|
||||||
var newToken = RenewAzureToken(tenantId,
|
var newToken = RenewAzureToken(
|
||||||
|
tenantId,
|
||||||
clientId,
|
clientId,
|
||||||
apiServerId,
|
apiServerId,
|
||||||
refresh);
|
refresh);
|
||||||
@@ -533,7 +545,8 @@ namespace k8s
|
|||||||
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
||||||
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
||||||
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
|
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
|
||||||
public static async Task<K8SConfiguration> LoadKubeConfigAsync(string kubeconfigPath = null,
|
public static async Task<K8SConfiguration> LoadKubeConfigAsync(
|
||||||
|
string kubeconfigPath = null,
|
||||||
bool useRelativePaths = true)
|
bool useRelativePaths = true)
|
||||||
{
|
{
|
||||||
var fileInfo = new FileInfo(kubeconfigPath ?? KubeConfigDefaultLocation);
|
var fileInfo = new FileInfo(kubeconfigPath ?? KubeConfigDefaultLocation);
|
||||||
@@ -560,7 +573,8 @@ namespace k8s
|
|||||||
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
/// <param name="useRelativePaths">When <see langword="true"/>, the paths in the kubeconfig file will be considered to be relative to the directory in which the kubeconfig
|
||||||
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
/// file is located. When <see langword="false"/>, the paths will be considered to be relative to the current working directory.</param>
|
||||||
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
|
/// <returns>Instance of the <see cref="K8SConfiguration"/> class</returns>
|
||||||
public static async Task<K8SConfiguration> LoadKubeConfigAsync(FileInfo kubeconfig,
|
public static async Task<K8SConfiguration> LoadKubeConfigAsync(
|
||||||
|
FileInfo kubeconfig,
|
||||||
bool useRelativePaths = true)
|
bool useRelativePaths = true)
|
||||||
{
|
{
|
||||||
if (!kubeconfig.Exists)
|
if (!kubeconfig.Exists)
|
||||||
@@ -640,7 +654,8 @@ namespace k8s
|
|||||||
/// The kube config files will be merges into a single <see cref="K8SConfiguration"/>, where first occurence wins.
|
/// The kube config files will be merges into a single <see cref="K8SConfiguration"/>, where first occurence wins.
|
||||||
/// See https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#merging-kubeconfig-files.
|
/// See https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#merging-kubeconfig-files.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
internal static async Task<K8SConfiguration> LoadKubeConfigAsync(FileInfo[] kubeConfigs,
|
internal static async Task<K8SConfiguration> LoadKubeConfigAsync(
|
||||||
|
FileInfo[] kubeConfigs,
|
||||||
bool useRelativePaths = true)
|
bool useRelativePaths = true)
|
||||||
{
|
{
|
||||||
var basek8SConfig = await LoadKubeConfigAsync(kubeConfigs[0], useRelativePaths).ConfigureAwait(false);
|
var basek8SConfig = await LoadKubeConfigAsync(kubeConfigs[0], useRelativePaths).ConfigureAwait(false);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using k8s.Models;
|
|
||||||
using Microsoft.Rest;
|
using Microsoft.Rest;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace k8s.Models
|
namespace k8s.Models
|
||||||
{
|
{
|
||||||
public class KubernetesList<T> : IMetadata<V1ListMeta>, IItems<T> where T : IKubernetesObject
|
public class KubernetesList<T> : IMetadata<V1ListMeta>, IItems<T>
|
||||||
|
where T : IKubernetesObject
|
||||||
{
|
{
|
||||||
public KubernetesList(IList<T> items, string apiVersion = default(string), string kind = default(string),
|
public KubernetesList(IList<T> items, string apiVersion = default(string), string kind = default(string),
|
||||||
V1ListMeta metadata = default(V1ListMeta))
|
V1ListMeta metadata = default(V1ListMeta))
|
||||||
@@ -27,7 +27,8 @@ namespace k8s.Models
|
|||||||
[JsonProperty(PropertyName = "apiVersion")]
|
[JsonProperty(PropertyName = "apiVersion")]
|
||||||
public string ApiVersion { get; set; }
|
public string ApiVersion { get; set; }
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "items")] public IList<T> Items { get; set; }
|
[JsonProperty(PropertyName = "items")]
|
||||||
|
public IList<T> Items { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets kind is a string value representing the REST resource
|
/// Gets or sets kind is a string value representing the REST resource
|
||||||
|
|||||||
@@ -245,12 +245,14 @@ namespace k8s.Models
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets <see cref="V1OwnerReference"/> that matches the given object, or null if no matching reference exists.</summary>
|
/// <summary>Gets <see cref="V1OwnerReference"/> that matches the given object, or null if no matching reference exists.</summary>
|
||||||
public static V1OwnerReference GetOwnerReference(this IMetadata<V1ObjectMeta> obj,
|
public static V1OwnerReference GetOwnerReference(
|
||||||
|
this IMetadata<V1ObjectMeta> obj,
|
||||||
IKubernetesObject<V1ObjectMeta> owner) =>
|
IKubernetesObject<V1ObjectMeta> owner) =>
|
||||||
GetOwnerReference(obj, r => r.Matches(owner));
|
GetOwnerReference(obj, r => r.Matches(owner));
|
||||||
|
|
||||||
/// <summary>Gets the <see cref="V1OwnerReference"/> that matches the given predicate, or null if no matching reference exists.</summary>
|
/// <summary>Gets the <see cref="V1OwnerReference"/> that matches the given predicate, or null if no matching reference exists.</summary>
|
||||||
public static V1OwnerReference GetOwnerReference(this IMetadata<V1ObjectMeta> obj,
|
public static V1OwnerReference GetOwnerReference(
|
||||||
|
this IMetadata<V1ObjectMeta> obj,
|
||||||
Predicate<V1OwnerReference> predicate)
|
Predicate<V1OwnerReference> predicate)
|
||||||
{
|
{
|
||||||
int index = FindOwnerReference(obj, predicate);
|
int index = FindOwnerReference(obj, predicate);
|
||||||
@@ -310,7 +312,8 @@ namespace k8s.Models
|
|||||||
/// <summary>Removes the first <see cref="V1OwnerReference"/> that matches the given object and returns it, or returns null if no
|
/// <summary>Removes the first <see cref="V1OwnerReference"/> that matches the given object and returns it, or returns null if no
|
||||||
/// matching reference could be found.
|
/// matching reference could be found.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static V1OwnerReference RemoveOwnerReference(this IMetadata<V1ObjectMeta> obj,
|
public static V1OwnerReference RemoveOwnerReference(
|
||||||
|
this IMetadata<V1ObjectMeta> obj,
|
||||||
IKubernetesObject<V1ObjectMeta> owner)
|
IKubernetesObject<V1ObjectMeta> owner)
|
||||||
{
|
{
|
||||||
int index = FindOwnerReference(obj, owner);
|
int index = FindOwnerReference(obj, owner);
|
||||||
@@ -326,7 +329,8 @@ namespace k8s.Models
|
|||||||
/// <summary>Removes all <see cref="V1OwnerReference">owner references</see> that match the given predicate, and returns true if
|
/// <summary>Removes all <see cref="V1OwnerReference">owner references</see> that match the given predicate, and returns true if
|
||||||
/// any were removed.
|
/// any were removed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool RemoveOwnerReferences(this IMetadata<V1ObjectMeta> obj,
|
public static bool RemoveOwnerReferences(
|
||||||
|
this IMetadata<V1ObjectMeta> obj,
|
||||||
Predicate<V1OwnerReference> predicate)
|
Predicate<V1OwnerReference> predicate)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
@@ -359,7 +363,8 @@ namespace k8s.Models
|
|||||||
/// <summary>Removes all <see cref="V1OwnerReference">owner references</see> that match the given object, and returns true if
|
/// <summary>Removes all <see cref="V1OwnerReference">owner references</see> that match the given object, and returns true if
|
||||||
/// any were removed.
|
/// any were removed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool RemoveOwnerReferences(this IMetadata<V1ObjectMeta> obj,
|
public static bool RemoveOwnerReferences(
|
||||||
|
this IMetadata<V1ObjectMeta> obj,
|
||||||
IKubernetesObject<V1ObjectMeta> owner) =>
|
IKubernetesObject<V1ObjectMeta> owner) =>
|
||||||
RemoveOwnerReferences(obj, r => r.Matches(owner));
|
RemoveOwnerReferences(obj, r => r.Matches(owner));
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace k8s
|
namespace k8s
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ namespace k8s
|
|||||||
public class StringQuotingEmitter : ChainedEventEmitter
|
public class StringQuotingEmitter : ChainedEventEmitter
|
||||||
{
|
{
|
||||||
// Patterns from https://yaml.org/spec/1.2/spec.html#id2804356
|
// Patterns from https://yaml.org/spec/1.2/spec.html#id2804356
|
||||||
private static readonly Regex quotedRegex =
|
private static readonly Regex QuotedRegex =
|
||||||
new Regex(@"^(\~|null|true|false|-?(0|[1-9][0-9]*)(\.[0-9]*)?([eE][-+]?[0-9]+)?)?$");
|
new Regex(@"^(\~|null|true|false|-?(0|[1-9][0-9]*)(\.[0-9]*)?([eE][-+]?[0-9]+)?)?$");
|
||||||
|
|
||||||
public StringQuotingEmitter(IEventEmitter next) : base(next)
|
public StringQuotingEmitter(IEventEmitter next)
|
||||||
|
: base(next)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ namespace k8s
|
|||||||
break;
|
break;
|
||||||
case TypeCode.String:
|
case TypeCode.String:
|
||||||
var val = eventInfo.Source.Value.ToString();
|
var val = eventInfo.Source.Value.ToString();
|
||||||
if (quotedRegex.IsMatch(val))
|
if (QuotedRegex.IsMatch(val))
|
||||||
{
|
{
|
||||||
eventInfo.Style = ScalarStyle.DoubleQuoted;
|
eventInfo.Style = ScalarStyle.DoubleQuoted;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ namespace k8s.Models
|
|||||||
|
|
||||||
public PathType Type { get; private set; }
|
public PathType Type { get; private set; }
|
||||||
|
|
||||||
public V1Patch(IJsonPatchDocument jsonPatch) : this((object)jsonPatch)
|
public V1Patch(IJsonPatchDocument jsonPatch)
|
||||||
|
: this((object)jsonPatch)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,8 @@ namespace k8s.Versioning
|
|||||||
{
|
{
|
||||||
public class KubernetesVersionComparer : IComparer<string>
|
public class KubernetesVersionComparer : IComparer<string>
|
||||||
{
|
{
|
||||||
public static KubernetesVersionComparer Instance { get; private set; }
|
public static KubernetesVersionComparer Instance { get; } = new KubernetesVersionComparer();
|
||||||
private static readonly Regex _kubernetesVersionRegex;
|
private static readonly Regex KubernetesVersionRegex = new Regex(@"^v(?<major>[0-9]+)((?<stream>alpha|beta)(?<minor>[0-9]+))?$", RegexOptions.Compiled);
|
||||||
|
|
||||||
static KubernetesVersionComparer()
|
|
||||||
{
|
|
||||||
_kubernetesVersionRegex = new Regex(@"^v(?<major>[0-9]+)((?<stream>alpha|beta)(?<minor>[0-9]+))?$", RegexOptions.Compiled);
|
|
||||||
Instance = new KubernetesVersionComparer();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal KubernetesVersionComparer()
|
internal KubernetesVersionComparer()
|
||||||
{
|
{
|
||||||
@@ -26,13 +20,13 @@ namespace k8s.Versioning
|
|||||||
return StringComparer.CurrentCulture.Compare(x, y);
|
return StringComparer.CurrentCulture.Compare(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
var matchX = _kubernetesVersionRegex.Match(x);
|
var matchX = KubernetesVersionRegex.Match(x);
|
||||||
if (!matchX.Success)
|
if (!matchX.Success)
|
||||||
{
|
{
|
||||||
return StringComparer.CurrentCulture.Compare(x, y);
|
return StringComparer.CurrentCulture.Compare(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
var matchY = _kubernetesVersionRegex.Match(y);
|
var matchY = KubernetesVersionRegex.Match(y);
|
||||||
if (!matchY.Success)
|
if (!matchY.Success)
|
||||||
{
|
{
|
||||||
return StringComparer.CurrentCulture.Compare(x, y);
|
return StringComparer.CurrentCulture.Compare(x, y);
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ namespace k8s.Versioning
|
|||||||
.GroupBy(x => x.Kind)
|
.GroupBy(x => x.Kind)
|
||||||
.ToDictionary(x => x.Key, kindGroup => kindGroup
|
.ToDictionary(x => x.Key, kindGroup => kindGroup
|
||||||
.GroupBy(x => x.ApiVersion)
|
.GroupBy(x => x.ApiVersion)
|
||||||
.ToDictionary(x => x.Key,
|
.ToDictionary(
|
||||||
|
x => x.Key,
|
||||||
versionGroup => versionGroup.Select(x => x.Type).Distinct().Single())); // should only be one type for each Kind/Version combination
|
versionGroup => versionGroup.Select(x => x.Type).Distinct().Single())); // should only be one type for each Kind/Version combination
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ namespace k8s.Versioning
|
|||||||
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
|
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
|
||||||
.ForMember(dest => dest.Value, opt => opt.Ignore())
|
.ForMember(dest => dest.Value, opt => opt.Ignore())
|
||||||
#if NET452
|
#if NET452
|
||||||
.ForMember(dest => dest.Type, opt => opt.ResolveUsing(src => src.TargetAverageValue != null ? "AverageValue" : "Utilization" ))
|
.ForMember(dest => dest.Type, opt => opt.ResolveUsing(src => src.TargetAverageValue != null ? "AverageValue" : "Utilization"))
|
||||||
#else
|
#else
|
||||||
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => src.TargetAverageValue != null ? "AverageValue" : "Utilization"))
|
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => src.TargetAverageValue != null ? "AverageValue" : "Utilization"))
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,23 +12,28 @@ namespace k8s
|
|||||||
public enum WatchEventType
|
public enum WatchEventType
|
||||||
{
|
{
|
||||||
/// <summary>Emitted when an object is created, modified to match a watch's filter, or when a watch is first opened.</summary>
|
/// <summary>Emitted when an object is created, modified to match a watch's filter, or when a watch is first opened.</summary>
|
||||||
[EnumMember(Value = "ADDED")] Added,
|
[EnumMember(Value = "ADDED")]
|
||||||
|
Added,
|
||||||
|
|
||||||
/// <summary>Emitted when an object is modified.</summary>
|
/// <summary>Emitted when an object is modified.</summary>
|
||||||
[EnumMember(Value = "MODIFIED")] Modified,
|
[EnumMember(Value = "MODIFIED")]
|
||||||
|
Modified,
|
||||||
|
|
||||||
/// <summary>Emitted when an object is deleted or modified to no longer match a watch's filter.</summary>
|
/// <summary>Emitted when an object is deleted or modified to no longer match a watch's filter.</summary>
|
||||||
[EnumMember(Value = "DELETED")] Deleted,
|
[EnumMember(Value = "DELETED")]
|
||||||
|
Deleted,
|
||||||
|
|
||||||
/// <summary>Emitted when an error occurs while watching resources. Most commonly, the error is 410 Gone which indicates that
|
/// <summary>Emitted when an error occurs while watching resources. Most commonly, the error is 410 Gone which indicates that
|
||||||
/// the watch resource version was outdated and events were probably lost. In that case, the watch should be restarted.
|
/// the watch resource version was outdated and events were probably lost. In that case, the watch should be restarted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[EnumMember(Value = "ERROR")] Error,
|
[EnumMember(Value = "ERROR")]
|
||||||
|
Error,
|
||||||
|
|
||||||
/// <summary>Bookmarks may be emitted periodically to update the resource version. The object will
|
/// <summary>Bookmarks may be emitted periodically to update the resource version. The object will
|
||||||
/// contain only the resource version.
|
/// contain only the resource version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[EnumMember(Value = "BOOKMARK")] Bookmark,
|
[EnumMember(Value = "BOOKMARK")]
|
||||||
|
Bookmark,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Watcher<T> : IDisposable
|
public class Watcher<T> : IDisposable
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -15,7 +14,8 @@ namespace k8s
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class WatcherDelegatingHandler : DelegatingHandler
|
internal class WatcherDelegatingHandler : DelegatingHandler
|
||||||
{
|
{
|
||||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
|
protected override async Task<HttpResponseMessage> SendAsync(
|
||||||
|
HttpRequestMessage request,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var originResponse = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
|
var originResponse = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
|
||||||
|
|||||||
@@ -19,12 +19,14 @@ namespace k8s
|
|||||||
/// The action to invoke when the server closes the connection.
|
/// The action to invoke when the server closes the connection.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>a watch object</returns>
|
/// <returns>a watch object</returns>
|
||||||
public static Watcher<T> Watch<T, L>(this Task<HttpOperationResponse<L>> responseTask,
|
public static Watcher<T> Watch<T, L>(
|
||||||
|
this Task<HttpOperationResponse<L>> responseTask,
|
||||||
Action<WatchEventType, T> onEvent,
|
Action<WatchEventType, T> onEvent,
|
||||||
Action<Exception> onError = null,
|
Action<Exception> onError = null,
|
||||||
Action onClosed = null)
|
Action onClosed = null)
|
||||||
{
|
{
|
||||||
return new Watcher<T>(async () =>
|
return new Watcher<T>(
|
||||||
|
async () =>
|
||||||
{
|
{
|
||||||
var response = await responseTask.ConfigureAwait(false);
|
var response = await responseTask.ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -49,7 +51,8 @@ namespace k8s
|
|||||||
/// The action to invoke when the server closes the connection.
|
/// The action to invoke when the server closes the connection.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>a watch object</returns>
|
/// <returns>a watch object</returns>
|
||||||
public static Watcher<T> Watch<T, L>(this HttpOperationResponse<L> response,
|
public static Watcher<T> Watch<T, L>(
|
||||||
|
this HttpOperationResponse<L> response,
|
||||||
Action<WatchEventType, T> onEvent,
|
Action<WatchEventType, T> onEvent,
|
||||||
Action<Exception> onError = null,
|
Action<Exception> onError = null,
|
||||||
Action onClosed = null)
|
Action onClosed = null)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
#if (NET452 || NETSTANDARD2_0)
|
#if (NET452 || NETSTANDARD2_0)
|
||||||
using System.Net.Security;
|
using System.Net.Security;
|
||||||
|
|||||||
@@ -265,7 +265,8 @@ namespace k8s
|
|||||||
set => _inner.ScalarStyle = value;
|
set => _inner.ScalarStyle = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetCustomAttribute<T>() where T : Attribute
|
public T GetCustomAttribute<T>()
|
||||||
|
where T : Attribute
|
||||||
{
|
{
|
||||||
return _inner.GetCustomAttribute<T>();
|
return _inner.GetCustomAttribute<T>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ using k8s.Models;
|
|||||||
|
|
||||||
namespace k8s.Versioning
|
namespace k8s.Versioning
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public static partial class VersionConverter
|
public static partial class VersionConverter
|
||||||
{
|
{
|
||||||
private static void AutoConfigurations(IMapperConfigurationExpression cfg)
|
private static void AutoConfigurations(IMapperConfigurationExpression cfg)
|
||||||
@@ -160,6 +158,4 @@ namespace k8s.Versioning
|
|||||||
cfg.CreateMap<V1beta1VolumeNodeResources, V1VolumeNodeResources>().ReverseMap();
|
cfg.CreateMap<V1beta1VolumeNodeResources, V1VolumeNodeResources>().ReverseMap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ using Microsoft.Rest;
|
|||||||
using Org.BouncyCastle.Crypto.Parameters;
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
using Org.BouncyCastle.Pkcs;
|
using Org.BouncyCastle.Pkcs;
|
||||||
using Org.BouncyCastle.Security;
|
using Org.BouncyCastle.Security;
|
||||||
using Remotion.Linq.Clauses;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
@@ -89,8 +88,9 @@ namespace k8s.Tests
|
|||||||
{
|
{
|
||||||
var header = cxt.Request.Headers["Authorization"].FirstOrDefault();
|
var header = cxt.Request.Headers["Authorization"].FirstOrDefault();
|
||||||
|
|
||||||
var expect = new AuthenticationHeaderValue("Basic",
|
var expect = new AuthenticationHeaderValue(
|
||||||
Convert.ToBase64String(Encoding.UTF8.GetBytes($"{testName}:{testPassword}")))
|
"Basic",
|
||||||
|
Convert.ToBase64String(Encoding.UTF8.GetBytes($"{testName}:{testPassword}")))
|
||||||
.ToString();
|
.ToString();
|
||||||
|
|
||||||
if (header != expect)
|
if (header != expect)
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Nito.AsyncEx;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@@ -262,7 +260,8 @@ namespace k8s.Tests
|
|||||||
// Write data to the buffer
|
// Write data to the buffer
|
||||||
buffer.Write(this.writeData, 0, 0x03);
|
buffer.Write(this.writeData, 0, 0x03);
|
||||||
|
|
||||||
await TaskAssert.Completed(readTask,
|
await TaskAssert.Completed(
|
||||||
|
readTask,
|
||||||
timeout: TimeSpan.FromMilliseconds(1000),
|
timeout: TimeSpan.FromMilliseconds(1000),
|
||||||
message: "Timed out waiting for read task to complete.").ConfigureAwait(false);
|
message: "Timed out waiting for read task to complete.").ConfigureAwait(false);
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using k8s;
|
|
||||||
using System.IO;
|
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Net.Security;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace k8s.Tests
|
namespace k8s.Tests
|
||||||
@@ -42,7 +39,8 @@ namespace k8s.Tests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void LoadFromFilesRelativePath()
|
public void LoadFromFilesRelativePath()
|
||||||
{
|
{
|
||||||
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(KubeConfigWithRelativePathsFileName,
|
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(
|
||||||
|
KubeConfigWithRelativePathsFileName,
|
||||||
"federal-context");
|
"federal-context");
|
||||||
|
|
||||||
// Just validate that this doesn't throw and private key is non-null
|
// Just validate that this doesn't throw and private key is non-null
|
||||||
@@ -70,7 +68,8 @@ namespace k8s.Tests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void LoadFromInlineDataRelativePath()
|
public void LoadFromInlineDataRelativePath()
|
||||||
{
|
{
|
||||||
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(KubeConfigWithRelativePathsFileName,
|
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(
|
||||||
|
KubeConfigWithRelativePathsFileName,
|
||||||
"victorian-context");
|
"victorian-context");
|
||||||
|
|
||||||
// Just validate that this doesn't throw and private key is non-null
|
// Just validate that this doesn't throw and private key is non-null
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net.Security;
|
using System.Net.Security;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using k8s.Authentication;
|
using k8s.Authentication;
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace k8s.Tests
|
namespace k8s.Tests
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -161,7 +161,8 @@ namespace k8s.Tests
|
|||||||
public void CreatedFromPreLoadedConfig()
|
public void CreatedFromPreLoadedConfig()
|
||||||
{
|
{
|
||||||
var k8sConfig =
|
var k8sConfig =
|
||||||
KubernetesClientConfiguration.LoadKubeConfig(new FileInfo("assets/kubeconfig.yml"),
|
KubernetesClientConfiguration.LoadKubeConfig(
|
||||||
|
new FileInfo("assets/kubeconfig.yml"),
|
||||||
useRelativePaths: false);
|
useRelativePaths: false);
|
||||||
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigObject(k8sConfig);
|
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigObject(k8sConfig);
|
||||||
Assert.NotNull(cfg.Host);
|
Assert.NotNull(cfg.Host);
|
||||||
@@ -173,7 +174,8 @@ namespace k8s.Tests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void DefaultConfigurationLoaded()
|
public void DefaultConfigurationLoaded()
|
||||||
{
|
{
|
||||||
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(new FileInfo("assets/kubeconfig.yml"),
|
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(
|
||||||
|
new FileInfo("assets/kubeconfig.yml"),
|
||||||
useRelativePaths: false);
|
useRelativePaths: false);
|
||||||
Assert.NotNull(cfg.Host);
|
Assert.NotNull(cfg.Host);
|
||||||
}
|
}
|
||||||
@@ -442,7 +444,8 @@ namespace k8s.Tests
|
|||||||
var filePath = Path.GetFullPath("assets/kubeconfig.relative.yml");
|
var filePath = Path.GetFullPath("assets/kubeconfig.relative.yml");
|
||||||
var environmentVariable = "KUBECONFIG_LoadKubeConfigFromEnvironmentVariable_MultipleConfigs";
|
var environmentVariable = "KUBECONFIG_LoadKubeConfigFromEnvironmentVariable_MultipleConfigs";
|
||||||
|
|
||||||
Environment.SetEnvironmentVariable(environmentVariable,
|
Environment.SetEnvironmentVariable(
|
||||||
|
environmentVariable,
|
||||||
string.Concat(filePath, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ';' : ':', filePath));
|
string.Concat(filePath, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ';' : ':', filePath));
|
||||||
KubernetesClientConfiguration.KubeConfigEnvironmentVariable = environmentVariable;
|
KubernetesClientConfiguration.KubeConfigEnvironmentVariable = environmentVariable;
|
||||||
|
|
||||||
@@ -576,7 +579,8 @@ namespace k8s.Tests
|
|||||||
{
|
{
|
||||||
Assert.Equal(expected.Name, actual.Name);
|
Assert.Equal(expected.Name, actual.Name);
|
||||||
Assert.Equal(expected.ClusterEndpoint.CertificateAuthority, actual.ClusterEndpoint.CertificateAuthority);
|
Assert.Equal(expected.ClusterEndpoint.CertificateAuthority, actual.ClusterEndpoint.CertificateAuthority);
|
||||||
Assert.Equal(expected.ClusterEndpoint.CertificateAuthorityData,
|
Assert.Equal(
|
||||||
|
expected.ClusterEndpoint.CertificateAuthorityData,
|
||||||
actual.ClusterEndpoint.CertificateAuthorityData);
|
actual.ClusterEndpoint.CertificateAuthorityData);
|
||||||
Assert.Equal(expected.ClusterEndpoint.Server, actual.ClusterEndpoint.Server);
|
Assert.Equal(expected.ClusterEndpoint.Server, actual.ClusterEndpoint.Server);
|
||||||
Assert.Equal(expected.ClusterEndpoint.SkipTlsVerify, actual.ClusterEndpoint.SkipTlsVerify);
|
Assert.Equal(expected.ClusterEndpoint.SkipTlsVerify, actual.ClusterEndpoint.SkipTlsVerify);
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ namespace k8s.Tests.Logging
|
|||||||
throw new ArgumentNullException(nameof(formatter));
|
throw new ArgumentNullException(nameof(formatter));
|
||||||
}
|
}
|
||||||
|
|
||||||
TestOutput.WriteLine(string.Format("[{0}] {1}: {2}",
|
TestOutput.WriteLine(string.Format(
|
||||||
|
"[{0}] {1}: {2}",
|
||||||
level,
|
level,
|
||||||
LoggerCategory,
|
LoggerCategory,
|
||||||
formatter(state, exception)));
|
formatter(state, exception)));
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ namespace k8s.Tests.Mock
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer,
|
public override async Task<WebSocketReceiveResult> ReceiveAsync(
|
||||||
|
ArraySegment<byte> buffer,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (this.receiveBuffers.Count == 0)
|
if (this.receiveBuffers.Count == 0)
|
||||||
@@ -113,7 +114,8 @@ namespace k8s.Tests.Mock
|
|||||||
public override Task SendAsync(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage,
|
public override Task SendAsync(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
this.MessageSent?.Invoke(this,
|
this.MessageSent?.Invoke(
|
||||||
|
this,
|
||||||
new MessageDataEventArgs()
|
new MessageDataEventArgs()
|
||||||
{
|
{
|
||||||
Data = new MessageData()
|
Data = new MessageData()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System;
|
using System;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace k8s.Tests.Mock.Server.Controllers
|
namespace k8s.Tests.Mock.Server.Controllers
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace k8s.Tests.Mock.Server.Controllers
|
namespace k8s.Tests.Mock.Server.Controllers
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ namespace k8s.Tests
|
|||||||
stdout: true,
|
stdout: true,
|
||||||
webSocketSubProtol: WebSocketProtocol.ChannelWebSocketProtocol,
|
webSocketSubProtol: WebSocketProtocol.ChannelWebSocketProtocol,
|
||||||
cancellationToken: TestCancellation).ConfigureAwait(false);
|
cancellationToken: TestCancellation).ConfigureAwait(false);
|
||||||
Assert.Equal(WebSocketProtocol.ChannelWebSocketProtocol,
|
Assert.Equal(
|
||||||
clientSocket
|
WebSocketProtocol.ChannelWebSocketProtocol,
|
||||||
.SubProtocol); // For WebSockets, the Kubernetes API defaults to the binary channel (v1) protocol.
|
clientSocket.SubProtocol); // For WebSockets, the Kubernetes API defaults to the binary channel (v1) protocol.
|
||||||
|
|
||||||
testOutput.WriteLine(
|
testOutput.WriteLine(
|
||||||
$"Client socket connected (socket state is {clientSocket.State}). Waiting for server-side socket to become available...");
|
$"Client socket connected (socket state is {clientSocket.State}). Waiting for server-side socket to become available...");
|
||||||
@@ -200,8 +200,9 @@ namespace k8s.Tests
|
|||||||
|
|
||||||
using (Kubernetes client = kubernetesMock.Object)
|
using (Kubernetes client = kubernetesMock.Object)
|
||||||
{
|
{
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>(() => client.NamespacedPodExecAsync("pod-name",
|
await Assert.ThrowsAsync<ArgumentNullException>(() => client.NamespacedPodExecAsync(
|
||||||
"pod-namespace", "my-container", command, false, null, CancellationToken.None))
|
"pod-name",
|
||||||
|
"pod-namespace", "my-container", command, false, null, CancellationToken.None))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,8 +224,9 @@ namespace k8s.Tests
|
|||||||
|
|
||||||
using (Kubernetes client = kubernetesMock.Object)
|
using (Kubernetes client = kubernetesMock.Object)
|
||||||
{
|
{
|
||||||
var ex = await Assert.ThrowsAsync<KubernetesException>(() => client.NamespacedPodExecAsync("pod-name",
|
var ex = await Assert.ThrowsAsync<KubernetesException>(() => client.NamespacedPodExecAsync(
|
||||||
"pod-namespace", "my-container", command, false, handler, CancellationToken.None))
|
"pod-name",
|
||||||
|
"pod-namespace", "my-container", command, false, handler, CancellationToken.None))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
Assert.Same(status, ex.Status);
|
Assert.Same(status, ex.Status);
|
||||||
}
|
}
|
||||||
@@ -269,8 +271,9 @@ namespace k8s.Tests
|
|||||||
|
|
||||||
using (Kubernetes client = kubernetesMock.Object)
|
using (Kubernetes client = kubernetesMock.Object)
|
||||||
{
|
{
|
||||||
var ex = await Assert.ThrowsAsync<Exception>(() => client.NamespacedPodExecAsync("pod-name",
|
var ex = await Assert.ThrowsAsync<Exception>(() => client.NamespacedPodExecAsync(
|
||||||
"pod-namespace", "my-container", command, false, handler, CancellationToken.None))
|
"pod-name",
|
||||||
|
"pod-namespace", "my-container", command, false, handler, CancellationToken.None))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
Assert.Same(exception, ex);
|
Assert.Same(exception, ex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using k8s.Tests.Mock;
|
using k8s.Tests.Mock;
|
||||||
@@ -37,7 +36,8 @@ namespace k8s.Tests
|
|||||||
stream.Write(b, 0, b.Length);
|
stream.Write(b, 0, b.Length);
|
||||||
|
|
||||||
// Send 100 bytes, expect 1 (channel index) + 100 (payload) = 101 bytes
|
// Send 100 bytes, expect 1 (channel index) + 100 (payload) = 101 bytes
|
||||||
Assert.True(await WaitForAsync(() => sentBuffer.Count == 101).ConfigureAwait(false),
|
Assert.True(
|
||||||
|
await WaitForAsync(() => sentBuffer.Count == 101).ConfigureAwait(false),
|
||||||
$"Demuxer error: expect to send 101 bytes, but actually send {sentBuffer.Count} bytes.");
|
$"Demuxer error: expect to send 101 bytes, but actually send {sentBuffer.Count} bytes.");
|
||||||
Assert.True(sentBuffer[0] == channelIndex, "The first sent byte is not channel index!");
|
Assert.True(sentBuffer[0] == channelIndex, "The first sent byte is not channel index!");
|
||||||
Assert.True(sentBuffer[1] == 0xEF, "Incorrect payload!");
|
Assert.True(sentBuffer[1] == 0xEF, "Incorrect payload!");
|
||||||
@@ -63,7 +63,8 @@ namespace k8s.Tests
|
|||||||
stream.Write(b, 0, b.Length);
|
stream.Write(b, 0, b.Length);
|
||||||
|
|
||||||
// Send 300 bytes in 2 messages, expect 1 (channel index) * 2 + 300 (payload) = 302 bytes
|
// Send 300 bytes in 2 messages, expect 1 (channel index) * 2 + 300 (payload) = 302 bytes
|
||||||
Assert.True(await WaitForAsync(() => sentBuffer.Count == 302).ConfigureAwait(false),
|
Assert.True(
|
||||||
|
await WaitForAsync(() => sentBuffer.Count == 302).ConfigureAwait(false),
|
||||||
$"Demuxer error: expect to send 302 bytes, but actually send {sentBuffer.Count} bytes.");
|
$"Demuxer error: expect to send 302 bytes, but actually send {sentBuffer.Count} bytes.");
|
||||||
Assert.True(sentBuffer[0] == channelIndex, "The first sent byte is not channel index!");
|
Assert.True(sentBuffer[0] == channelIndex, "The first sent byte is not channel index!");
|
||||||
Assert.True(sentBuffer[1] == 0xEF, "The first part of payload incorrect!");
|
Assert.True(sentBuffer[1] == 0xEF, "The first part of payload incorrect!");
|
||||||
@@ -119,7 +120,8 @@ namespace k8s.Tests
|
|||||||
|
|
||||||
await t.ConfigureAwait(false);
|
await t.ConfigureAwait(false);
|
||||||
|
|
||||||
Assert.True(receivedBuffer.Count == expectedCount,
|
Assert.True(
|
||||||
|
receivedBuffer.Count == expectedCount,
|
||||||
$"Demuxer error: expect to receive {expectedCount} bytes, but actually got {receivedBuffer.Count} bytes.");
|
$"Demuxer error: expect to receive {expectedCount} bytes, but actually got {receivedBuffer.Count} bytes.");
|
||||||
Assert.True(receivedBuffer[0] == 0xAA, "The first payload incorrect!");
|
Assert.True(receivedBuffer[0] == 0xAA, "The first payload incorrect!");
|
||||||
Assert.True(receivedBuffer[98] == 0xAA, "The first payload incorrect!");
|
Assert.True(receivedBuffer[98] == 0xAA, "The first payload incorrect!");
|
||||||
@@ -178,7 +180,8 @@ namespace k8s.Tests
|
|||||||
|
|
||||||
await t.ConfigureAwait(false);
|
await t.ConfigureAwait(false);
|
||||||
|
|
||||||
Assert.True(receivedBuffer.Count == expectedCount,
|
Assert.True(
|
||||||
|
receivedBuffer.Count == expectedCount,
|
||||||
$"Demuxer error: expect to receive {expectedCount} bytes, but actually got {receivedBuffer.Count} bytes.");
|
$"Demuxer error: expect to receive {expectedCount} bytes, but actually got {receivedBuffer.Count} bytes.");
|
||||||
Assert.True(receivedBuffer[0] == 0xB1, "The first payload incorrect!");
|
Assert.True(receivedBuffer[0] == 0xB1, "The first payload incorrect!");
|
||||||
Assert.True(receivedBuffer[96] == 0xB1, "The first payload incorrect!");
|
Assert.True(receivedBuffer[96] == 0xB1, "The first payload incorrect!");
|
||||||
@@ -237,7 +240,8 @@ namespace k8s.Tests
|
|||||||
|
|
||||||
await t.ConfigureAwait(false);
|
await t.ConfigureAwait(false);
|
||||||
|
|
||||||
Assert.True(receivedBuffer.Count == expectedCount,
|
Assert.True(
|
||||||
|
receivedBuffer.Count == expectedCount,
|
||||||
$"Demuxer error: expect to receive {expectedCount} bytes, but actually got {receivedBuffer.Count} bytes.");
|
$"Demuxer error: expect to receive {expectedCount} bytes, but actually got {receivedBuffer.Count} bytes.");
|
||||||
Assert.True(receivedBuffer[0] == 0xC2, "The first payload incorrect!");
|
Assert.True(receivedBuffer[0] == 0xC2, "The first payload incorrect!");
|
||||||
Assert.True(receivedBuffer[98] == 0xC2, "The first payload incorrect!");
|
Assert.True(receivedBuffer[98] == 0xC2, "The first payload incorrect!");
|
||||||
@@ -320,9 +324,11 @@ namespace k8s.Tests
|
|||||||
});
|
});
|
||||||
await Task.WhenAll(t1, t2, t3).ConfigureAwait(false);
|
await Task.WhenAll(t1, t2, t3).ConfigureAwait(false);
|
||||||
|
|
||||||
Assert.True(receivedBuffer1.Count == expectedCount1,
|
Assert.True(
|
||||||
|
receivedBuffer1.Count == expectedCount1,
|
||||||
$"Demuxer error: expect to receive {expectedCount1} bytes, but actually got {receivedBuffer1.Count} bytes.");
|
$"Demuxer error: expect to receive {expectedCount1} bytes, but actually got {receivedBuffer1.Count} bytes.");
|
||||||
Assert.True(receivedBuffer2.Count == expectedCount2,
|
Assert.True(
|
||||||
|
receivedBuffer2.Count == expectedCount2,
|
||||||
$"Demuxer error: expect to receive {expectedCount2} bytes, but actually got {receivedBuffer2.Count} bytes.");
|
$"Demuxer error: expect to receive {expectedCount2} bytes, but actually got {receivedBuffer2.Count} bytes.");
|
||||||
Assert.True(receivedBuffer1[0] == 0xD1, "The first payload incorrect!");
|
Assert.True(receivedBuffer1[0] == 0xD1, "The first payload incorrect!");
|
||||||
Assert.True(receivedBuffer1[98] == 0xD1, "The first payload incorrect!");
|
Assert.True(receivedBuffer1[98] == 0xD1, "The first payload incorrect!");
|
||||||
@@ -409,9 +415,11 @@ namespace k8s.Tests
|
|||||||
});
|
});
|
||||||
await Task.WhenAll(t1, t2, t3).ConfigureAwait(false);
|
await Task.WhenAll(t1, t2, t3).ConfigureAwait(false);
|
||||||
|
|
||||||
Assert.True(receivedBuffer1.Count == expectedCount1,
|
Assert.True(
|
||||||
|
receivedBuffer1.Count == expectedCount1,
|
||||||
$"Demuxer error: expect to receive {expectedCount1} bytes, but actually got {receivedBuffer1.Count} bytes.");
|
$"Demuxer error: expect to receive {expectedCount1} bytes, but actually got {receivedBuffer1.Count} bytes.");
|
||||||
Assert.True(receivedBuffer2.Count == expectedCount2,
|
Assert.True(
|
||||||
|
receivedBuffer2.Count == expectedCount2,
|
||||||
$"Demuxer error: expect to receive {expectedCount2} bytes, but actually got {receivedBuffer2.Count} bytes.");
|
$"Demuxer error: expect to receive {expectedCount2} bytes, but actually got {receivedBuffer2.Count} bytes.");
|
||||||
Assert.True(receivedBuffer1[0] == 0xE1, "The first payload incorrect!");
|
Assert.True(receivedBuffer1[0] == 0xE1, "The first payload incorrect!");
|
||||||
Assert.True(receivedBuffer1[96] == 0xE1, "The first payload incorrect!");
|
Assert.True(receivedBuffer1[96] == 0xE1, "The first payload incorrect!");
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using k8s.Authentication;
|
using k8s.Authentication;
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace k8s.Tests
|
namespace k8s.Tests
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using k8s.Models;
|
using k8s.Models;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ using System.Net;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using k8s.Exceptions;
|
|
||||||
using k8s.Models;
|
using k8s.Models;
|
||||||
using k8s.Tests.Mock;
|
using k8s.Tests.Mock;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
using Nito.AsyncEx;
|
using Nito.AsyncEx;
|
||||||
@@ -430,7 +428,8 @@ namespace k8s.Tests
|
|||||||
{
|
{
|
||||||
internal bool Called { get; private set; }
|
internal bool Called { get; private set; }
|
||||||
|
|
||||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
|
protected override Task<HttpResponseMessage> SendAsync(
|
||||||
|
HttpRequestMessage request,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Called = true;
|
Called = true;
|
||||||
|
|||||||
@@ -179,7 +179,8 @@ namespace k8s.Tests
|
|||||||
{
|
{
|
||||||
if (received.IsFaulted)
|
if (received.IsFaulted)
|
||||||
{
|
{
|
||||||
testOutput.WriteLine("Server socket operation to receive Close message failed: {0}",
|
testOutput.WriteLine(
|
||||||
|
"Server socket operation to receive Close message failed: {0}",
|
||||||
received.Exception.Flatten().InnerExceptions[0]);
|
received.Exception.Flatten().InnerExceptions[0]);
|
||||||
}
|
}
|
||||||
else if (received.IsCanceled)
|
else if (received.IsCanceled)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using k8s.Models;
|
using k8s.Models;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@@ -114,7 +113,8 @@ metadata:
|
|||||||
var pod = new V1Pod() { ApiVersion = "v1", Kind = "Pod", Metadata = new V1ObjectMeta() { Name = "foo" } };
|
var pod = new V1Pod() { ApiVersion = "v1", Kind = "Pod", Metadata = new V1ObjectMeta() { Name = "foo" } };
|
||||||
|
|
||||||
var yaml = Yaml.SaveToString(pod);
|
var yaml = Yaml.SaveToString(pod);
|
||||||
Assert.Equal(ToLines(@"apiVersion: v1
|
Assert.Equal(
|
||||||
|
ToLines(@"apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
name: foo"), ToLines(yaml));
|
name: foo"), ToLines(yaml));
|
||||||
@@ -131,7 +131,8 @@ metadata:
|
|||||||
};
|
};
|
||||||
|
|
||||||
var yaml = Yaml.SaveToString(pod);
|
var yaml = Yaml.SaveToString(pod);
|
||||||
Assert.Equal(ToLines(@"apiVersion: v1
|
Assert.Equal(
|
||||||
|
ToLines(@"apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
name: foo
|
name: foo
|
||||||
@@ -170,7 +171,8 @@ metadata:
|
|||||||
};
|
};
|
||||||
|
|
||||||
var yaml = Yaml.SaveToString(pod);
|
var yaml = Yaml.SaveToString(pod);
|
||||||
Assert.Equal(ToLines(@"apiVersion: v1
|
Assert.Equal(
|
||||||
|
ToLines(@"apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
name: foo
|
name: foo
|
||||||
|
|||||||
Reference in New Issue
Block a user