Skip to content

Commit

Permalink
Add Connector support for VMware Postgres TAS tile
Browse files Browse the repository at this point in the history
  • Loading branch information
bart-vmware committed Nov 1, 2023
1 parent ab9d517 commit 9b0a47a
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#nullable enable

using System.Text;
using Microsoft.Extensions.Configuration;

namespace Steeltoe.Configuration;
Expand All @@ -29,6 +30,43 @@ protected ConfigurationDictionaryMapper(IDictionary<string, string?> configurati
return value;
}

public string? MapArrayFromTo(string fromArrayKey, string toKey, string separator)
{
int arrayIndex = 0;
var toValueBuilder = new StringBuilder();

while (true)
{
string arrayElementKey = $"{BindingKey}{fromArrayKey}:{arrayIndex}";

if (!ConfigurationData.TryGetValue(arrayElementKey, out string? arrayElementValue))
{
break;
}

if (!string.IsNullOrEmpty(arrayElementValue))
{
if (toValueBuilder.Length > 0)
{
toValueBuilder.Append(separator);
}

toValueBuilder.Append(arrayElementValue);
}

arrayIndex++;
}

if (toValueBuilder.Length > 0)
{
string toValue = toValueBuilder.ToString();
SetToValue(toKey, toValue);
return toValue;
}

return null;
}

public string? MapFromAppendTo(string fromKey, string appendToKey, string separator)
{
string? valueToAppend = GetFromValue(fromKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal abstract class CloudFoundryPostProcessor : IConfigurationPostProcessor

public abstract void PostProcessConfiguration(PostProcessorConfigurationProvider provider, IDictionary<string, string?> configurationData);

protected IEnumerable<string> FilterKeys(IDictionary<string, string?> configurationData, string tagValueToFind)
protected ICollection<string> FilterKeys(IDictionary<string, string?> configurationData, string tagValueToFind)
{
List<string> keys = new();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,54 @@ namespace Steeltoe.Configuration.CloudFoundry.ServiceBinding.PostProcessors;

internal sealed class PostgreSqlCloudFoundryPostProcessor : CloudFoundryPostProcessor
{
private const string HostsSeparator = ",";

internal const string BindingType = "postgresql";
internal const string AlternateInputBindingType = "postgres";

public override void PostProcessConfiguration(PostProcessorConfigurationProvider provider, IDictionary<string, string?> configurationData)
{
foreach (string key in FilterKeys(configurationData, BindingType))
ICollection<string> keys = FilterKeys(configurationData, BindingType);
ICollection<string> alternateKeys = FilterKeys(configurationData, AlternateInputBindingType);

foreach (string key in keys.Concat(alternateKeys))
{
var mapper = ServiceBindingMapper.Create(configurationData, key, BindingType);

// Mapping from CloudFoundry service binding credentials to driver-specific connection string parameters.
// The available credentials are documented at:
// - VMware Broker: https://docs.vmware.com/en/VMware-Postgres-for-VMware-Tanzu-Application-Service/1.0/postgres/app-dev-guide.html
// - Azure Service Broker: https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-Azure/1.4/csb-azure/GUID-reference-azure-postgresql.html#binding-credentials-5
// - GCP Service Broker: https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-GCP/1.2/csb-gcp/GUID-reference-gcp-postgresql.html#binding-credentials-6
// - AWS Service Broker: https://docs.vmware.com/en/Tanzu-Cloud-Service-Broker-for-AWS/1.5/csb-aws/GUID-reference-aws-postgres.html#binding-credentials-3

mapper.MapFromTo("credentials:hostname", "host");
string? hosts = mapper.MapArrayFromTo("credentials:hosts", "host", HostsSeparator);

if (hosts != null)
{
if (hosts.Contains(HostsSeparator, StringComparison.Ordinal))
{
// https://www.npgsql.org/doc/failover-and-load-balancing.html
mapper.SetToValue("Target Session Attributes", "primary");
}
}
else
{
mapper.MapFromTo("credentials:hostname", "host");
}

mapper.MapFromTo("credentials:port", "port");
mapper.MapFromTo("credentials:name", "database");
mapper.MapFromTo("credentials:username", "username");

if (mapper.MapFromTo("credentials:db", "database") == null)
{
mapper.MapFromTo("credentials:name", "database");
}

if (mapper.MapFromTo("credentials:user", "username") == null)
{
mapper.MapFromTo("credentials:username", "username");
}

mapper.MapFromTo("credentials:password", "password");
mapper.MapFromToFile("credentials:sslcert", "SSL Certificate");
mapper.MapFromToFile("credentials:sslkey", "SSL Key");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,37 @@ public void Processes_PostgreSql_configuration()
GetFileContentAtKey(configurationData, $"{keyPrefix}:Root Certificate").Should().Be("test-ssl-root-cert");
}

[Fact]
public void Processes_PostgreSql_High_Availability_configuration()
{
var postProcessor = new PostgreSqlCloudFoundryPostProcessor();

var secrets = new[]
{
Tuple.Create("credentials:hosts:0", "test-host1"),
Tuple.Create("credentials:hosts:1", "test-host2"),
Tuple.Create("credentials:port", "test-port"),
Tuple.Create("credentials:db", "test-database"),
Tuple.Create("credentials:user", "test-username"),
Tuple.Create("credentials:password", "test-password")
};

Dictionary<string, string?> configurationData =
GetConfigurationData(PostgreSqlCloudFoundryPostProcessor.AlternateInputBindingType, TestProviderName, TestBindingName, secrets);

PostProcessorConfigurationProvider provider = GetConfigurationProvider(postProcessor);

postProcessor.PostProcessConfiguration(provider, configurationData);

string keyPrefix = GetOutputKeyPrefix(TestBindingName, PostgreSqlCloudFoundryPostProcessor.BindingType);
configurationData[$"{keyPrefix}:host"].Should().Be("test-host1,test-host2");
configurationData[$"{keyPrefix}:Target Session Attributes"].Should().Be("primary");
configurationData[$"{keyPrefix}:port"].Should().Be("test-port");
configurationData[$"{keyPrefix}:database"].Should().Be("test-database");
configurationData[$"{keyPrefix}:username"].Should().Be("test-username");
configurationData[$"{keyPrefix}:password"].Should().Be("test-password");
}

[Fact]
public void Processes_RabbitMQ_configuration()
{
Expand Down

0 comments on commit 9b0a47a

Please sign in to comment.