Skip to content

Commit

Permalink
Changed X509 to read directly from file (#35)
Browse files Browse the repository at this point in the history
* Changed X509 to read directly from file

* Changed line endings

* Cleanup and Added new tests
  • Loading branch information
xontab authored Feb 9, 2020
1 parent 4941ad1 commit 8b88d26
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 56 deletions.
81 changes: 43 additions & 38 deletions src/Orleans.Clustering.Kubernetes/API/KubeClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,50 +64,14 @@ public KubeClient(ILoggerFactory loggerFactory, HttpClientHandler httpClientHand
{
this._logger = loggerFactory?.CreateLogger<KubeClient>();

var namespaceFilePath = Path.Combine(SERVICE_ACCOUNT_PATH, SERVICE_ACCOUNT_NAMESPACE_FILENAME);
this._namespace = this.GetNamespace();

if (!File.Exists(namespaceFilePath))
{
this._logger?.LogWarning("Namespace file {namespaceFilePath} wasn't found. Are we running in a pod? If you are running unit tests outside a pod, please create the test namespace '{namespace}'.", namespaceFilePath, ORLEANS_NAMESPACE);

this._namespace = ORLEANS_NAMESPACE;
}
else
{
this._namespace = File.ReadAllText(namespaceFilePath);
}
this.RootCertificate = this.GetRootCertificate(certificate);

this._group = string.IsNullOrWhiteSpace(group) ? ORLEANS_GROUP : group.ToLowerInvariant();

var endpointUri = new Uri(string.IsNullOrWhiteSpace(apiEndpoint) ? IN_CLUSTER_KUBE_ENDPOINT : apiEndpoint);

var certificateData = certificate;

if (string.IsNullOrWhiteSpace(certificateData))
{
var rootCertificateFilePath = Path.Combine(SERVICE_ACCOUNT_PATH, SERVICE_ACCOUNT_ROOTCA_FILENAME);

if (File.Exists(rootCertificateFilePath))
{
certificateData = File.ReadAllText(rootCertificateFilePath);
}
else
{
this._logger?.LogWarning("Root Certificate file {rootCertificateFilePath} wasn't found, no certificate will be used.", rootCertificateFilePath);
}
}

if (!string.IsNullOrWhiteSpace(certificateData))
{
certificateData = certificateData
.Replace(BEGIN_CERT_LINE, string.Empty)
.Replace(END_CERT_LINE, string.Empty)
.Replace(RETURN_CHAR, string.Empty)
.Replace(NEWLINE_CHAR, string.Empty);

this.RootCertificate = new X509Certificate2(Convert.FromBase64String(certificateData));
}

var handler = httpClientHandler;

if (handler == null)
Expand Down Expand Up @@ -373,5 +337,46 @@ public async Task<TObject> UpdateCustomObject<TObject>(string version, string pl
}

#endregion

private string GetNamespace()
{
var namespaceFilePath = Path.Combine(SERVICE_ACCOUNT_PATH, SERVICE_ACCOUNT_NAMESPACE_FILENAME);
if (File.Exists(namespaceFilePath))
{
return File.ReadAllText(namespaceFilePath);
}

this._logger?.LogWarning(
"Namespace file {namespaceFilePath} wasn't found. Are we running in a pod? If you are running unit tests outside a pod, please create the test namespace '{namespace}'.",
namespaceFilePath, ORLEANS_NAMESPACE);

return ORLEANS_NAMESPACE;
}

private X509Certificate2 GetRootCertificate(string certificateData)
{
if (!string.IsNullOrWhiteSpace(certificateData))
{
var certificate = certificateData
.Replace(BEGIN_CERT_LINE, string.Empty)
.Replace(END_CERT_LINE, string.Empty)
.Replace(RETURN_CHAR, string.Empty)
.Replace(NEWLINE_CHAR, string.Empty);

return new X509Certificate2(Convert.FromBase64String(certificate));
}

var rootCertificateFilePath = Path.Combine(SERVICE_ACCOUNT_PATH, SERVICE_ACCOUNT_ROOTCA_FILENAME);
if (File.Exists(rootCertificateFilePath))
{
return new X509Certificate2(rootCertificateFilePath);
}

this._logger?.LogWarning(
"Root Certificate file {rootCertificateFilePath} wasn't found, no certificate will be used.",
rootCertificateFilePath);

return null;
}
}
}
16 changes: 16 additions & 0 deletions test/Orleans.Clustering.Kubernetes.Test/IgnoreInsidePodFact.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.IO;
using Xunit;

namespace Orleans.Clustering.Kubernetes.Test
{
public sealed class IgnoreInsidePodFact : FactAttribute
{
private const string rootCertificatePath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt";

public IgnoreInsidePodFact() {
if (File.Exists(rootCertificatePath)) {
this.Skip = "Ignore when running inside a Pod";
}
}
}
}
54 changes: 36 additions & 18 deletions test/Orleans.Clustering.Kubernetes.Test/KubeClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,49 @@ namespace Orleans.Clustering.Kubernetes.Test
public class KubeClientTests
{
[Fact]
public void RootCertificateConstructedFromCertificateParameterWhenProvided()
public void RootCertificateConstructedFromCertificateParameterWhenProvided_ReturnsValidRootCertificate()
{
const string certificate =
@"-----BEGIN CERTIFICATE-----
MIIC+zCCAeOgAwIBAgIJAIC+9fYZ2Xu1MA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
BAMMCWxvY2FsaG9zdDAeFw0xOTEwMDYxMjE2MDFaFw0yOTEwMDMxMjE2MDFaMBQx
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALWQJx3SZiW4plqZSpjz0PFU9QR3IcK27Du6Tr7wlBErfdEdUJ/TuC72EFWF
yR4/pCWfmiIwZnkxJGVwjaRbi0B/hza9ifbr+7uqxlVYZUN8lt5UtFpFuRvs5g69
uEutlJx/dUmvPQOoW1DzmqUAKlum8vzhcRZaSYKtWnLyGb0ec20B6Sa1nrEQtW0h
LofTJ6JvTk+MZmCTzIfeBsNz2iLDdSYDr7rlP/lWkJh+XjzFPBCDJILP1JUwPOrF
AUpwuejqm4BecjLlquPN8Lqpf7Zp1X5WCU81AQyuHXlv3FdayL8VTJGhoTRpCrvU
s5WnZgrOq3IAAk8agme+JbL6NqUCAwEAAaNQME4wHQYDVR0OBBYEFMNqhycFj+RF
LmxsR4EMu0mpnJL3MB8GA1UdIwQYMBaAFMNqhycFj+RFLmxsR4EMu0mpnJL3MAwG
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADqFsU9l2PJsCiGtU4C3tsAz
LwHUEvOHRjXFU9bN8LApyUIGo9qsTXLyLOLv0nIrDq1gELoKgAvuD1lbnWbcTcCG
q5/f9ttB6cT513ffm4GBTenTIHSq+FFZT6A2Mwko1+3Man2vznWjl/HF5eQ6PS7U
by/z6A9Nm1Rw8Uu541odWU8/KQCSO9c/Yo+1GsDIDj5lMfLRl21Mp/lPGbGGuGu5
iMRH8QYi7YQZ2GLbaLxSY7edJlmFGYTWWV9C9jKE3s/WMaJ6Dz7NXrQM4YOE00V8
bzUuNqNBUDUhQGQDOCem29+nhKT+GPWqDt2YRDFj80UJ5wt+ljddmlVhtRS/YgY=
-----END CERTIFICATE-----";
MIIC+zCCAeOgAwIBAgIJAIC+9fYZ2Xu1MA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
BAMMCWxvY2FsaG9zdDAeFw0xOTEwMDYxMjE2MDFaFw0yOTEwMDMxMjE2MDFaMBQx
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALWQJx3SZiW4plqZSpjz0PFU9QR3IcK27Du6Tr7wlBErfdEdUJ/TuC72EFWF
yR4/pCWfmiIwZnkxJGVwjaRbi0B/hza9ifbr+7uqxlVYZUN8lt5UtFpFuRvs5g69
uEutlJx/dUmvPQOoW1DzmqUAKlum8vzhcRZaSYKtWnLyGb0ec20B6Sa1nrEQtW0h
LofTJ6JvTk+MZmCTzIfeBsNz2iLDdSYDr7rlP/lWkJh+XjzFPBCDJILP1JUwPOrF
AUpwuejqm4BecjLlquPN8Lqpf7Zp1X5WCU81AQyuHXlv3FdayL8VTJGhoTRpCrvU
s5WnZgrOq3IAAk8agme+JbL6NqUCAwEAAaNQME4wHQYDVR0OBBYEFMNqhycFj+RF
LmxsR4EMu0mpnJL3MB8GA1UdIwQYMBaAFMNqhycFj+RFLmxsR4EMu0mpnJL3MAwG
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADqFsU9l2PJsCiGtU4C3tsAz
LwHUEvOHRjXFU9bN8LApyUIGo9qsTXLyLOLv0nIrDq1gELoKgAvuD1lbnWbcTcCG
q5/f9ttB6cT513ffm4GBTenTIHSq+FFZT6A2Mwko1+3Man2vznWjl/HF5eQ6PS7U
by/z6A9Nm1Rw8Uu541odWU8/KQCSO9c/Yo+1GsDIDj5lMfLRl21Mp/lPGbGGuGu5
iMRH8QYi7YQZ2GLbaLxSY7edJlmFGYTWWV9C9jKE3s/WMaJ6Dz7NXrQM4YOE00V8
bzUuNqNBUDUhQGQDOCem29+nhKT+GPWqDt2YRDFj80UJ5wt+ljddmlVhtRS/YgY=
-----END CERTIFICATE-----";

var client = new KubeClient(null, certificate: certificate);

Assert.NotNull(client.RootCertificate);
}

[Fact]
public void RootCertificateConstructedFromCertificateWithoutHeaders_ReturnsValidRootCertificate()
{
const string certificate = @"MIIC+zCCAeOgAwIBAgIJAIC+9fYZ2Xu1MA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xOTEwMDYxMjE2MDFaFw0yOTEwMDMxMjE2MDFaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWQJx3SZiW4plqZSpjz0PFU9QR3IcK27Du6Tr7wlBErfdEdUJ/TuC72EFWFyR4/pCWfmiIwZnkxJGVwjaRbi0B/hza9ifbr+7uqxlVYZUN8lt5UtFpFuRvs5g69uEutlJx/dUmvPQOoW1DzmqUAKlum8vzhcRZaSYKtWnLyGb0ec20B6Sa1nrEQtW0hLofTJ6JvTk+MZmCTzIfeBsNz2iLDdSYDr7rlP/lWkJh+XjzFPBCDJILP1JUwPOrFAUpwuejqm4BecjLlquPN8Lqpf7Zp1X5WCU81AQyuHXlv3FdayL8VTJGhoTRpCrvUs5WnZgrOq3IAAk8agme+JbL6NqUCAwEAAaNQME4wHQYDVR0OBBYEFMNqhycFj+RFLmxsR4EMu0mpnJL3MB8GA1UdIwQYMBaAFMNqhycFj+RFLmxsR4EMu0mpnJL3MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADqFsU9l2PJsCiGtU4C3tsAzLwHUEvOHRjXFU9bN8LApyUIGo9qsTXLyLOLv0nIrDq1gELoKgAvuD1lbnWbcTcCGq5/f9ttB6cT513ffm4GBTenTIHSq+FFZT6A2Mwko1+3Man2vznWjl/HF5eQ6PS7Uby/z6A9Nm1Rw8Uu541odWU8/KQCSO9c/Yo+1GsDIDj5lMfLRl21Mp/lPGbGGuGu5iMRH8QYi7YQZ2GLbaLxSY7edJlmFGYTWWV9C9jKE3s/WMaJ6Dz7NXrQM4YOE00V8bzUuNqNBUDUhQGQDOCem29+nhKT+GPWqDt2YRDFj80UJ5wt+ljddmlVhtRS/YgY=";

var client = new KubeClient(null, certificate: certificate);

Assert.NotNull(client.RootCertificate);
}

[IgnoreInsidePodFact]
public void RootCertificateMissing_ReturnsNullRootCertificate()
{
var client = new KubeClient(null);

Assert.Null(client.RootCertificate);
}
}
}

0 comments on commit 8b88d26

Please sign in to comment.