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:
Boshi Lian
2020-11-01 12:24:51 -08:00
committed by GitHub
parent 82c8ae059f
commit 16845bae1d
55 changed files with 212 additions and 179 deletions

View File

@@ -1,5 +1,4 @@
using System;
using System.IO;
using System.Threading.Tasks;
using k8s;
@@ -22,7 +21,8 @@ namespace logs
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);
var stream = response.Body;
stream.CopyTo(Console.OpenStandardOutput());

View File

@@ -106,7 +106,7 @@
<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 -->
<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 -->
<Rule Id="SA1201" Action="None" />
@@ -175,7 +175,7 @@
<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 -->
<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 -->
<Rule Id="SA1012" Action="Warning" />
@@ -205,10 +205,10 @@
<Rule Id="CA2225" Action="None" />
<!-- 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 -->
<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 -->
<Rule Id="CA5359" Action="None" />

View File

@@ -18,7 +18,7 @@ namespace k8s.Authentication
TokenFile = tokenFile;
}
public async Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
public Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
{
if (TokenExpiresAt < DateTime.UtcNow)
{
@@ -32,7 +32,7 @@ namespace k8s.Authentication
TokenExpiresAt = DateTime.UtcNow.AddMinutes(1);
}
return new AuthenticationHeaderValue("Bearer", token);
return Task.FromResult(new AuthenticationHeaderValue("Bearer", token));
}
}
}

View File

@@ -282,7 +282,8 @@ namespace k8s
Array.Copy(this.buffer, 0, newBuffer, 0, this.WriteWaterMark);
int trailingDataLength = this.buffer.Length - this.ReadWaterMark;
Array.Copy(this.buffer,
Array.Copy(
this.buffer,
sourceIndex: this.ReadWaterMark,
destinationArray: newBuffer,
destinationIndex: newBuffer.Length - trailingDataLength,

View File

@@ -5,10 +5,8 @@ using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
namespace k8s
{

View File

@@ -1,7 +1,7 @@
using System;
namespace k8s.Exceptions
{
using System;
/// <summary>
/// The exception that is thrown when the kube config is invalid
/// </summary>

View File

@@ -1,7 +1,7 @@
using System;
namespace k8s.Exceptions
{
using System;
/// <summary>
/// The exception that is thrown when there is a client exception
/// </summary>

View File

@@ -1,22 +1,15 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using k8s.Models;
using Microsoft.Rest;
using Microsoft.Rest.TransientFaultHandling;
using Newtonsoft.Json.Converters;
using VersionConverter = k8s.Versioning.VersionConverter;
namespace k8s
{
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();
public static KubernetesEntityAttribute GetKubernetesTypeMetadata(this Type currentType)
{
@@ -29,7 +22,8 @@ namespace k8s
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();
obj.ApiVersion = !string.IsNullOrEmpty(metadata.Group) ? $"{metadata.Group}/{metadata.ApiVersion}" : metadata.ApiVersion;

View File

@@ -1,7 +1,5 @@
using System;
using Newtonsoft.Json;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
namespace k8s.Models
{

View File

@@ -1,9 +1,8 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels
{
using System.Collections.Generic;
using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;
/// <summary>
/// Contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
/// </summary>

View File

@@ -1,7 +1,7 @@
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels
{
using YamlDotNet.Serialization;
/// <summary>
/// Relates nicknames to cluster information.
/// </summary>

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels
{
using System.Collections.Generic;
using YamlDotNet.Serialization;
/// <summary>
/// Contains information about how to communicate with a kubernetes cluster
/// </summary>

View File

@@ -1,8 +1,8 @@
using System;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels
{
using System;
using YamlDotNet.Serialization;
/// <summary>
/// Relates nicknames to context information.
/// </summary>

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels
{
using System.Collections.Generic;
using YamlDotNet.Serialization;
/// <summary>
/// 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)

View File

@@ -5,8 +5,11 @@ namespace k8s.KubeConfigModels
{
public class ExecCredentialResponse
{
[JsonProperty("apiVersion")] public string ApiVersion { get; set; }
[JsonProperty("kind")] public string Kind { get; set; }
[JsonProperty("status")] public IDictionary<string, string> Status { get; set; }
[JsonProperty("apiVersion")]
public string ApiVersion { get; set; }
[JsonProperty("kind")]
public string Kind { get; set; }
[JsonProperty("status")]
public IDictionary<string, string> Status { get; set; }
}
}

View File

@@ -5,7 +5,8 @@ namespace k8s.KubeConfigModels
{
public class ExternalExecution
{
[YamlMember(Alias = "apiVersion")] public string ApiVersion { get; set; }
[YamlMember(Alias = "apiVersion")]
public string ApiVersion { get; set; }
/// <summary>
/// The command to execute. Required.

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels
{
using System.Collections.Generic;
using YamlDotNet.Serialization;
/// <summary>
/// kubeconfig configuration model. Holds the information needed to build connect to remote
/// Kubernetes clusters as a given user.
@@ -19,9 +19,11 @@ namespace k8s.KubeConfigModels
[YamlMember(Alias = "preferences")]
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>
/// Gets or sets the name of the context that you would like to use by default.

View File

@@ -1,7 +1,7 @@
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels
{
using YamlDotNet.Serialization;
/// <summary>
/// Relates nicknames to auth information.
/// </summary>

View File

@@ -1,9 +1,8 @@
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace k8s.KubeConfigModels
{
using System.Collections.Generic;
using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;
/// <summary>
/// Contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
/// </summary>

View File

@@ -22,7 +22,8 @@ namespace k8s
/// <param name="httpClient">
/// The <see cref="HttpClient" /> to use for all requests.
/// </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">
/// Whether or not the <see cref="Kubernetes"/> object should own the lifetime of <paramref name="httpClient"/>.
/// </param>
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient, bool disposeHttpClient) : this(
public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient, bool disposeHttpClient)
: this(
httpClient, disposeHttpClient)
{
ValidateConfig(config);
@@ -179,12 +181,14 @@ namespace k8s
/// <summary>A <see cref="DelegatingHandler"/> that simply forwards a request with no further processing.</summary>
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;

View File

@@ -23,7 +23,8 @@ namespace k8s
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,
cancellationToken: cancellationToken).ConfigureAwait(false))
using (Stream stdIn = muxedStream.GetStream(null, ChannelIndex.StdIn))

View File

@@ -96,7 +96,8 @@ namespace k8s
uriBuilder.Query =
query.Length == 0
? ""
: query.ToString(1,
: query.ToString(
1,
query.Length - 1); // UriBuilder.Query doesn't like leading '?' chars, so trim it
// Create HTTP transport objects
@@ -145,7 +146,8 @@ namespace k8s
{
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));
if (httpResponse.Content != null)
{
@@ -160,7 +162,8 @@ namespace k8s
throw ex;
}
return new Watcher<T>(async () =>
return new Watcher<T>(
async () =>
{
var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
StreamReader reader = new StreamReader(stream);

View File

@@ -37,7 +37,8 @@ namespace k8s
}
/// <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,
bool stderr = true, bool stdin = true, bool stdout = true, bool tty = true,
string webSocketSubProtol = WebSocketProtocol.V4BinaryWebsocketProtocol,

View File

@@ -76,7 +76,8 @@ namespace k8s
/// <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
/// 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)
{
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="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>
public static KubernetesClientConfiguration BuildConfigFromConfigFile(FileInfo kubeconfig,
public static KubernetesClientConfiguration BuildConfigFromConfigFile(
FileInfo kubeconfig,
string currentContext = null, string masterUrl = null, bool useRelativePaths = true)
{
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="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>
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)
{
if (kubeconfig == null)
@@ -126,7 +129,8 @@ namespace k8s
/// <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="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)
{
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="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>
public static async Task<KubernetesClientConfiguration> BuildConfigFromConfigFileAsync(Stream kubeconfig,
public static async Task<KubernetesClientConfiguration> BuildConfigFromConfigFileAsync(
Stream kubeconfig,
string currentContext = null, string masterUrl = 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="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>
public static KubernetesClientConfiguration BuildConfigFromConfigObject(K8SConfiguration k8SConfig,
public static KubernetesClientConfiguration BuildConfigFromConfigObject(
K8SConfiguration k8SConfig,
string currentContext = null, string masterUrl = null)
=> GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig);
private static KubernetesClientConfiguration GetKubernetesClientConfiguration(string currentContext,
private static KubernetesClientConfiguration GetKubernetesClientConfiguration(
string currentContext,
string masterUrl, K8SConfiguration k8SConfig)
{
var k8SConfiguration = new KubernetesClientConfiguration();
@@ -232,7 +239,8 @@ namespace k8s
private void SetClusterDetails(K8SConfiguration k8SConfig, Context activeContext)
{
var clusterDetails =
k8SConfig.Clusters.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.Cluster,
k8SConfig.Clusters.FirstOrDefault(c => c.Name.Equals(
activeContext.ContextDetails.Cluster,
StringComparison.OrdinalIgnoreCase));
if (clusterDetails?.ClusterEndpoint == null)
@@ -262,7 +270,8 @@ namespace k8s
}
else if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthority))
{
SslCaCerts = new X509Certificate2Collection(new X509Certificate2(GetFullPath(k8SConfig,
SslCaCerts = new X509Certificate2Collection(new X509Certificate2(GetFullPath(
k8SConfig,
clusterDetails.ClusterEndpoint.CertificateAuthority)));
}
}
@@ -275,7 +284,8 @@ namespace k8s
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));
if (userDetails == null)
@@ -343,15 +353,17 @@ namespace k8s
expires = DateTimeOffset.FromUnixTimeSeconds(expiresOn);
#endif
if (DateTimeOffset.Compare(expires,
DateTimeOffset.Now)
if (DateTimeOffset.Compare(
expires,
DateTimeOffset.Now)
<= 0)
{
var tenantId = config["tenant-id"];
var clientId = config["client-id"];
var apiServerId = config["apiserver-id"];
var refresh = config["refresh-token"];
var newToken = RenewAzureToken(tenantId,
var newToken = RenewAzureToken(
tenantId,
clientId,
apiServerId,
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
/// 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>
public static async Task<K8SConfiguration> LoadKubeConfigAsync(string kubeconfigPath = null,
public static async Task<K8SConfiguration> LoadKubeConfigAsync(
string kubeconfigPath = null,
bool useRelativePaths = true)
{
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
/// 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>
public static async Task<K8SConfiguration> LoadKubeConfigAsync(FileInfo kubeconfig,
public static async Task<K8SConfiguration> LoadKubeConfigAsync(
FileInfo kubeconfig,
bool useRelativePaths = true)
{
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.
/// See https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#merging-kubeconfig-files.
/// </remarks>
internal static async Task<K8SConfiguration> LoadKubeConfigAsync(FileInfo[] kubeConfigs,
internal static async Task<K8SConfiguration> LoadKubeConfigAsync(
FileInfo[] kubeConfigs,
bool useRelativePaths = true)
{
var basek8SConfig = await LoadKubeConfigAsync(kubeConfigs[0], useRelativePaths).ConfigureAwait(false);

View File

@@ -1,12 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using k8s.Models;
using Microsoft.Rest;
using Newtonsoft.Json;
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),
V1ListMeta metadata = default(V1ListMeta))
@@ -27,7 +27,8 @@ namespace k8s.Models
[JsonProperty(PropertyName = "apiVersion")]
public string ApiVersion { get; set; }
[JsonProperty(PropertyName = "items")] public IList<T> Items { get; set; }
[JsonProperty(PropertyName = "items")]
public IList<T> Items { get; set; }
/// <summary>
/// Gets or sets kind is a string value representing the REST resource

View File

@@ -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>
public static V1OwnerReference GetOwnerReference(this IMetadata<V1ObjectMeta> obj,
public static V1OwnerReference GetOwnerReference(
this IMetadata<V1ObjectMeta> obj,
IKubernetesObject<V1ObjectMeta> 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>
public static V1OwnerReference GetOwnerReference(this IMetadata<V1ObjectMeta> obj,
public static V1OwnerReference GetOwnerReference(
this IMetadata<V1ObjectMeta> obj,
Predicate<V1OwnerReference> 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
/// matching reference could be found.
/// </summary>
public static V1OwnerReference RemoveOwnerReference(this IMetadata<V1ObjectMeta> obj,
public static V1OwnerReference RemoveOwnerReference(
this IMetadata<V1ObjectMeta> obj,
IKubernetesObject<V1ObjectMeta> 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
/// any were removed.
/// </summary>
public static bool RemoveOwnerReferences(this IMetadata<V1ObjectMeta> obj,
public static bool RemoveOwnerReferences(
this IMetadata<V1ObjectMeta> obj,
Predicate<V1OwnerReference> predicate)
{
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
/// any were removed.
/// </summary>
public static bool RemoveOwnerReferences(this IMetadata<V1ObjectMeta> obj,
public static bool RemoveOwnerReferences(
this IMetadata<V1ObjectMeta> obj,
IKubernetesObject<V1ObjectMeta> owner) =>
RemoveOwnerReferences(obj, r => r.Matches(owner));

View File

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

View File

@@ -10,10 +10,11 @@ namespace k8s
public class StringQuotingEmitter : ChainedEventEmitter
{
// 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]+)?)?$");
public StringQuotingEmitter(IEventEmitter next) : base(next)
public StringQuotingEmitter(IEventEmitter next)
: base(next)
{
}
@@ -34,7 +35,7 @@ namespace k8s
break;
case TypeCode.String:
var val = eventInfo.Source.Value.ToString();
if (quotedRegex.IsMatch(val))
if (QuotedRegex.IsMatch(val))
{
eventInfo.Style = ScalarStyle.DoubleQuoted;
}

View File

@@ -16,7 +16,8 @@ namespace k8s.Models
public PathType Type { get; private set; }
public V1Patch(IJsonPatchDocument jsonPatch) : this((object)jsonPatch)
public V1Patch(IJsonPatchDocument jsonPatch)
: this((object)jsonPatch)
{
}

View File

@@ -6,14 +6,8 @@ namespace k8s.Versioning
{
public class KubernetesVersionComparer : IComparer<string>
{
public static KubernetesVersionComparer Instance { get; private set; }
private static readonly Regex _kubernetesVersionRegex;
static KubernetesVersionComparer()
{
_kubernetesVersionRegex = new Regex(@"^v(?<major>[0-9]+)((?<stream>alpha|beta)(?<minor>[0-9]+))?$", RegexOptions.Compiled);
Instance = new KubernetesVersionComparer();
}
public static KubernetesVersionComparer Instance { get; } = new KubernetesVersionComparer();
private static readonly Regex KubernetesVersionRegex = new Regex(@"^v(?<major>[0-9]+)((?<stream>alpha|beta)(?<minor>[0-9]+))?$", RegexOptions.Compiled);
internal KubernetesVersionComparer()
{
@@ -26,13 +20,13 @@ namespace k8s.Versioning
return StringComparer.CurrentCulture.Compare(x, y);
}
var matchX = _kubernetesVersionRegex.Match(x);
var matchX = KubernetesVersionRegex.Match(x);
if (!matchX.Success)
{
return StringComparer.CurrentCulture.Compare(x, y);
}
var matchY = _kubernetesVersionRegex.Match(y);
var matchY = KubernetesVersionRegex.Match(y);
if (!matchY.Success)
{
return StringComparer.CurrentCulture.Compare(x, y);

View File

@@ -59,7 +59,8 @@ namespace k8s.Versioning
.GroupBy(x => x.Kind)
.ToDictionary(x => x.Key, kindGroup => kindGroup
.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
}
@@ -152,7 +153,7 @@ namespace k8s.Versioning
.ForMember(dest => dest.AverageValue, opt => opt.MapFrom(src => src.TargetAverageValue))
.ForMember(dest => dest.Value, opt => opt.Ignore())
#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
.ForMember(dest => dest.Type, opt => opt.MapFrom((src, dest) => src.TargetAverageValue != null ? "AverageValue" : "Utilization"))
#endif

View File

@@ -12,23 +12,28 @@ namespace k8s
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>
[EnumMember(Value = "ADDED")] Added,
[EnumMember(Value = "ADDED")]
Added,
/// <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>
[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
/// the watch resource version was outdated and events were probably lost. In that case, the watch should be restarted.
/// </summary>
[EnumMember(Value = "ERROR")] Error,
[EnumMember(Value = "ERROR")]
Error,
/// <summary>Bookmarks may be emitted periodically to update the resource version. The object will
/// contain only the resource version.
/// </summary>
[EnumMember(Value = "BOOKMARK")] Bookmark,
[EnumMember(Value = "BOOKMARK")]
Bookmark,
}
public class Watcher<T> : IDisposable

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
@@ -15,7 +14,8 @@ namespace k8s
/// </summary>
internal class WatcherDelegatingHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
var originResponse = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

View File

@@ -19,12 +19,14 @@ namespace k8s
/// The action to invoke when the server closes the connection.
/// </param>
/// <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<Exception> onError = null,
Action onClosed = null)
{
return new Watcher<T>(async () =>
return new Watcher<T>(
async () =>
{
var response = await responseTask.ConfigureAwait(false);
@@ -49,7 +51,8 @@ namespace k8s
/// The action to invoke when the server closes the connection.
/// </param>
/// <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<Exception> onError = null,
Action onClosed = null)

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Net.WebSockets;
#if (NET452 || NETSTANDARD2_0)
using System.Net.Security;

View File

@@ -265,7 +265,8 @@ namespace k8s
set => _inner.ScalarStyle = value;
}
public T GetCustomAttribute<T>() where T : Attribute
public T GetCustomAttribute<T>()
where T : Attribute
{
return _inner.GetCustomAttribute<T>();
}

View File

@@ -3,8 +3,6 @@ using k8s.Models;
namespace k8s.Versioning
{
public static partial class VersionConverter
{
private static void AutoConfigurations(IMapperConfigurationExpression cfg)
@@ -160,6 +158,4 @@ namespace k8s.Versioning
cfg.CreateMap<V1beta1VolumeNodeResources, V1VolumeNodeResources>().ReverseMap();
}
}
}

View File

@@ -18,7 +18,6 @@ using Microsoft.Rest;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Remotion.Linq.Clauses;
using Xunit;
using Xunit.Abstractions;
@@ -89,8 +88,9 @@ namespace k8s.Tests
{
var header = cxt.Request.Headers["Authorization"].FirstOrDefault();
var expect = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.UTF8.GetBytes($"{testName}:{testPassword}")))
var expect = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.UTF8.GetBytes($"{testName}:{testPassword}")))
.ToString();
if (header != expect)

View File

@@ -1,7 +1,5 @@
using Nito.AsyncEx;
using System;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
@@ -262,7 +260,8 @@ namespace k8s.Tests
// Write data to the buffer
buffer.Write(this.writeData, 0, 0x03);
await TaskAssert.Completed(readTask,
await TaskAssert.Completed(
readTask,
timeout: TimeSpan.FromMilliseconds(1000),
message: "Timed out waiting for read task to complete.").ConfigureAwait(false);

View File

@@ -1,9 +1,6 @@
using System;
using Xunit;
using k8s;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Linq;
namespace k8s.Tests
@@ -42,7 +39,8 @@ namespace k8s.Tests
[Fact]
public void LoadFromFilesRelativePath()
{
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(KubeConfigWithRelativePathsFileName,
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(
KubeConfigWithRelativePathsFileName,
"federal-context");
// Just validate that this doesn't throw and private key is non-null
@@ -70,7 +68,8 @@ namespace k8s.Tests
[Fact]
public void LoadFromInlineDataRelativePath()
{
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(KubeConfigWithRelativePathsFileName,
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(
KubeConfigWithRelativePathsFileName,
"victorian-context");
// Just validate that this doesn't throw and private key is non-null

View File

@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Xunit;

View File

@@ -4,7 +4,6 @@ using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using k8s.Authentication;
using Xunit;
namespace k8s.Tests
{

View File

@@ -161,7 +161,8 @@ namespace k8s.Tests
public void CreatedFromPreLoadedConfig()
{
var k8sConfig =
KubernetesClientConfiguration.LoadKubeConfig(new FileInfo("assets/kubeconfig.yml"),
KubernetesClientConfiguration.LoadKubeConfig(
new FileInfo("assets/kubeconfig.yml"),
useRelativePaths: false);
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigObject(k8sConfig);
Assert.NotNull(cfg.Host);
@@ -173,7 +174,8 @@ namespace k8s.Tests
[Fact]
public void DefaultConfigurationLoaded()
{
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(new FileInfo("assets/kubeconfig.yml"),
var cfg = KubernetesClientConfiguration.BuildConfigFromConfigFile(
new FileInfo("assets/kubeconfig.yml"),
useRelativePaths: false);
Assert.NotNull(cfg.Host);
}
@@ -442,7 +444,8 @@ namespace k8s.Tests
var filePath = Path.GetFullPath("assets/kubeconfig.relative.yml");
var environmentVariable = "KUBECONFIG_LoadKubeConfigFromEnvironmentVariable_MultipleConfigs";
Environment.SetEnvironmentVariable(environmentVariable,
Environment.SetEnvironmentVariable(
environmentVariable,
string.Concat(filePath, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ';' : ':', filePath));
KubernetesClientConfiguration.KubeConfigEnvironmentVariable = environmentVariable;
@@ -576,7 +579,8 @@ namespace k8s.Tests
{
Assert.Equal(expected.Name, actual.Name);
Assert.Equal(expected.ClusterEndpoint.CertificateAuthority, actual.ClusterEndpoint.CertificateAuthority);
Assert.Equal(expected.ClusterEndpoint.CertificateAuthorityData,
Assert.Equal(
expected.ClusterEndpoint.CertificateAuthorityData,
actual.ClusterEndpoint.CertificateAuthorityData);
Assert.Equal(expected.ClusterEndpoint.Server, actual.ClusterEndpoint.Server);
Assert.Equal(expected.ClusterEndpoint.SkipTlsVerify, actual.ClusterEndpoint.SkipTlsVerify);

View File

@@ -83,7 +83,8 @@ namespace k8s.Tests.Logging
throw new ArgumentNullException(nameof(formatter));
}
TestOutput.WriteLine(string.Format("[{0}] {1}: {2}",
TestOutput.WriteLine(string.Format(
"[{0}] {1}: {2}",
level,
LoggerCategory,
formatter(state, exception)));

View File

@@ -75,7 +75,8 @@ namespace k8s.Tests.Mock
throw new NotImplementedException();
}
public override async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer,
public override async Task<WebSocketReceiveResult> ReceiveAsync(
ArraySegment<byte> buffer,
CancellationToken cancellationToken)
{
if (this.receiveBuffers.Count == 0)
@@ -113,7 +114,8 @@ namespace k8s.Tests.Mock
public override Task SendAsync(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage,
CancellationToken cancellationToken)
{
this.MessageSent?.Invoke(this,
this.MessageSent?.Invoke(
this,
new MessageDataEventArgs()
{
Data = new MessageData()

View File

@@ -1,7 +1,6 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
namespace k8s.Tests.Mock.Server.Controllers

View File

@@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
namespace k8s.Tests.Mock.Server.Controllers

View File

@@ -67,9 +67,9 @@ namespace k8s.Tests
stdout: true,
webSocketSubProtol: WebSocketProtocol.ChannelWebSocketProtocol,
cancellationToken: TestCancellation).ConfigureAwait(false);
Assert.Equal(WebSocketProtocol.ChannelWebSocketProtocol,
clientSocket
.SubProtocol); // For WebSockets, the Kubernetes API defaults to the binary channel (v1) protocol.
Assert.Equal(
WebSocketProtocol.ChannelWebSocketProtocol,
clientSocket.SubProtocol); // For WebSockets, the Kubernetes API defaults to the binary channel (v1) protocol.
testOutput.WriteLine(
$"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)
{
await Assert.ThrowsAsync<ArgumentNullException>(() => client.NamespacedPodExecAsync("pod-name",
"pod-namespace", "my-container", command, false, null, CancellationToken.None))
await Assert.ThrowsAsync<ArgumentNullException>(() => client.NamespacedPodExecAsync(
"pod-name",
"pod-namespace", "my-container", command, false, null, CancellationToken.None))
.ConfigureAwait(false);
}
}
@@ -223,8 +224,9 @@ namespace k8s.Tests
using (Kubernetes client = kubernetesMock.Object)
{
var ex = await Assert.ThrowsAsync<KubernetesException>(() => client.NamespacedPodExecAsync("pod-name",
"pod-namespace", "my-container", command, false, handler, CancellationToken.None))
var ex = await Assert.ThrowsAsync<KubernetesException>(() => client.NamespacedPodExecAsync(
"pod-name",
"pod-namespace", "my-container", command, false, handler, CancellationToken.None))
.ConfigureAwait(false);
Assert.Same(status, ex.Status);
}
@@ -269,8 +271,9 @@ namespace k8s.Tests
using (Kubernetes client = kubernetesMock.Object)
{
var ex = await Assert.ThrowsAsync<Exception>(() => client.NamespacedPodExecAsync("pod-name",
"pod-namespace", "my-container", command, false, handler, CancellationToken.None))
var ex = await Assert.ThrowsAsync<Exception>(() => client.NamespacedPodExecAsync(
"pod-name",
"pod-namespace", "my-container", command, false, handler, CancellationToken.None))
.ConfigureAwait(false);
Assert.Same(exception, ex);
}

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using k8s.Tests.Mock;
@@ -37,7 +36,8 @@ namespace k8s.Tests
stream.Write(b, 0, b.Length);
// 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.");
Assert.True(sentBuffer[0] == channelIndex, "The first sent byte is not channel index!");
Assert.True(sentBuffer[1] == 0xEF, "Incorrect payload!");
@@ -63,7 +63,8 @@ namespace k8s.Tests
stream.Write(b, 0, b.Length);
// 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.");
Assert.True(sentBuffer[0] == channelIndex, "The first sent byte is not channel index!");
Assert.True(sentBuffer[1] == 0xEF, "The first part of payload incorrect!");
@@ -119,7 +120,8 @@ namespace k8s.Tests
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.");
Assert.True(receivedBuffer[0] == 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);
Assert.True(receivedBuffer.Count == expectedCount,
Assert.True(
receivedBuffer.Count == expectedCount,
$"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[96] == 0xB1, "The first payload incorrect!");
@@ -237,7 +240,8 @@ namespace k8s.Tests
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.");
Assert.True(receivedBuffer[0] == 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);
Assert.True(receivedBuffer1.Count == expectedCount1,
Assert.True(
receivedBuffer1.Count == expectedCount1,
$"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.");
Assert.True(receivedBuffer1[0] == 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);
Assert.True(receivedBuffer1.Count == expectedCount1,
Assert.True(
receivedBuffer1.Count == expectedCount1,
$"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.");
Assert.True(receivedBuffer1[0] == 0xE1, "The first payload incorrect!");
Assert.True(receivedBuffer1[96] == 0xE1, "The first payload incorrect!");

View File

@@ -1,5 +1,4 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

View File

@@ -3,7 +3,6 @@ using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using k8s.Authentication;
using Xunit;
namespace k8s.Tests
{

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using k8s.Models;
using Xunit;
using FluentAssertions;

View File

@@ -8,11 +8,9 @@ using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using k8s.Exceptions;
using k8s.Models;
using k8s.Tests.Mock;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Nito.AsyncEx;
@@ -430,7 +428,8 @@ namespace k8s.Tests
{
internal bool Called { get; private set; }
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
Called = true;

View File

@@ -179,7 +179,8 @@ namespace k8s.Tests
{
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]);
}
else if (received.IsCanceled)

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using k8s.Models;
using Xunit;
@@ -114,7 +113,8 @@ metadata:
var pod = new V1Pod() { ApiVersion = "v1", Kind = "Pod", Metadata = new V1ObjectMeta() { Name = "foo" } };
var yaml = Yaml.SaveToString(pod);
Assert.Equal(ToLines(@"apiVersion: v1
Assert.Equal(
ToLines(@"apiVersion: v1
kind: Pod
metadata:
name: foo"), ToLines(yaml));
@@ -131,7 +131,8 @@ metadata:
};
var yaml = Yaml.SaveToString(pod);
Assert.Equal(ToLines(@"apiVersion: v1
Assert.Equal(
ToLines(@"apiVersion: v1
kind: Pod
metadata:
name: foo
@@ -170,7 +171,8 @@ metadata:
};
var yaml = Yaml.SaveToString(pod);
Assert.Equal(ToLines(@"apiVersion: v1
Assert.Equal(
ToLines(@"apiVersion: v1
kind: Pod
metadata:
name: foo