Skip to content

Commit

Permalink
Merge pull request #213 from NoxOrg/bugfix/secrets_must_not_throw_whe…
Browse files Browse the repository at this point in the history
…n_not_defined

Secrets bug fix
  • Loading branch information
jan-schutte authored Jul 12, 2023
2 parents 2ec5aa8 + 5d0dcc8 commit 5b7c47e
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 113 deletions.
44 changes: 24 additions & 20 deletions .nox/design/sample.solution.nox.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,11 @@ infrastructure:
port: 8080
user: whatsappUser
password: whatsappPassword

monitoring:
$ref: elastic.monitoring.nox.yaml

### This section is optional.
### In order to use elastic monitoring in the sample you have to start the elastic stack docker instance by running 'docker-compose -f docker-compose.elastic.yaml up -d'
# monitoring:
# $ref: elastic.monitoring.nox.yaml

translations:
name: SampleTranslationService
Expand All @@ -510,20 +512,22 @@ infrastructure:
serverUri: file:///C:/my-data-files
options: Source=File;Filename=country-data.json;

security:
secrets:
organizationSecretsServer:
name: org-vault
provider: hashicorpVault
serverUri: http://localhost:8300
password: root
validFor:
minutes: 10

solutionSecretsServer:
name: sln-vault
provider: hashicorpVault
serverUri: http://localhost:8300
password: root
validFor:
minutes: 10
### This section is optional.
### In order to use secrets in the sample you have to start the hashicorp vault docker instance by running 'docker-compose -f docker-compose.hashicorp.yaml up -d'
# security:
# secrets:
# organizationSecretsServer:
# name: org-vault
# provider: hashicorpVault
# serverUri: http://localhost:8300
# password: root
# validFor:
# minutes: 10
#
# solutionSecretsServer:
# name: sln-vault
# provider: hashicorpVault
# serverUri: http://localhost:8300
# password: root
# validFor:
# minutes: 10
4 changes: 2 additions & 2 deletions docker-compose.hashicorp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ services:
- /vault/data
- /etc/vault/logs
ports:
- "8200:8200/tcp"
- "8300:8300/tcp"
environment:
VAULT_DEV_ROOT_TOKEN_ID: "root"
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8300"
cap_add:
- IPC_LOCK
entrypoint: "vault server -dev"
Expand Down
69 changes: 0 additions & 69 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,73 +34,4 @@ services:
volumes:
- postgres:/var/lib/postgresql/data

apm-server:
container_name: apm-server
image: docker.elastic.co/apm/apm-server:7.17.10
cap_add: ["CHOWN", "DAC_OVERRIDE", "SETGID", "SETUID"]
cap_drop: ["ALL"]
ports:
- 8200:8200
networks:
- elastic
command: >
apm-server -e
-E apm-server.rum.enabled=true
-E setup.kibana.host=kibana:5601
-E setup.template.settings.index.number_of_replicas=0
-E apm-server.kibana.enabled=true
-E apm-server.kibana.host=kibana:5601
-E output.elasticsearch.hosts=["elasticsearch:9200"]
-E apm-server.kibana.username=elastic
-E apm-server.kibana.password=Developer*123
-E output.elasticsearch.username=elastic
-E output.elasticsearch.password=Developer*123
healthcheck:
interval: 10s
retries: 12
test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:8200/

vault:
container_name: hashi-vault
image: hashicorp/vault:latest
restart: always
volumes:
- /vault/data
- /etc/vault/logs
ports:
- "8300:8300/tcp"
environment:
VAULT_DEV_ROOT_TOKEN_ID: "root"
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8300"
cap_add:
- IPC_LOCK
entrypoint: "vault server -dev"
networks:
- vault-network

org-vault-init:
container_name: org-vault-init
image: alpine/curl
depends_on:
- vault
volumes:
- ./init_org_vault.sh:/usr/local/bin/init_vault.sh
command: ["sh", "-c", "/usr/local/bin/init_vault.sh"]
networks:
- vault-network

sln-vault-init:
container_name: sln-vault-init
image: alpine/curl
depends_on:
- vault
volumes:
- ./init_sln_vault.sh:/usr/local/bin/init_vault.sh
command: ["sh", "-c", "/usr/local/bin/init_vault.sh"]
networks:
- vault-network

networks:
elastic:
driver: bridge
vault-network:
21 changes: 15 additions & 6 deletions src/Nox.Secrets.Azure/AzureSecretsResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,25 @@ public AzureSecretsResolver(IPersistedSecretStore store, SecretsServer secretsSe
switch (_secretsServer.Provider)
{
case SecretsServerProvider.AzureKeyVault:
var azureVault = new AzureSecretsProvider(_secretsServer.ServerUri);
var azureSecrets = azureVault.GetSecretsAsync(unresolvedKeys.ToArray()).Result;
if (azureSecrets.Any())
try
{
resolvedSecrets.AddRange(azureSecrets);
var azureVault = new AzureSecretsProvider(_secretsServer.ServerUri);
var secrets = azureVault.GetSecretsAsync(unresolvedKeys.ToArray()).Result;
if (secrets.Any())
{
resolvedSecrets.AddRange(secrets);
}

foreach (var secret in secrets)
{
if (secret.Value != null) _store.Save($"{_storePrefix}{secret.Key}", secret.Value);
}
}
foreach (var azureSecret in azureSecrets)
catch (Exception ex)
{
if (azureSecret.Value != null) _store.Save($"{_storePrefix}{azureSecret.Key}", azureSecret.Value);
throw new NoxSecretsException("Unable to retrieve secrets from the Azure vault, are you connected to the internet and is the vault available?", ex);
}

break;
}
}
Expand Down
22 changes: 16 additions & 6 deletions src/Nox.Secrets.Hashicorp/HashicorpSecretsResolver.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Net.Sockets;
using Nox.Abstractions;
using Nox.Secrets.Abstractions;
using Nox.Solution;
Expand Down Expand Up @@ -53,16 +54,25 @@ public HashicorpSecretsResolver(IPersistedSecretStore store, SecretsServer secre
switch (_secretsServer.Provider)
{
case SecretsServerProvider.HashicorpVault:
var vault = new HashicorpSecretsProvider(_secretsServer.ServerUri, _secretsServer.Password!, _secretsServer.Name);
var azureSecrets = vault.GetSecretsAsync(unresolvedKeys.ToArray()).Result;
if (azureSecrets.Any())
try
{
resolvedSecrets.AddRange(azureSecrets);
var vault = new HashicorpSecretsProvider(_secretsServer.ServerUri, _secretsServer.Password!, _secretsServer.Name);
var secrets = vault.GetSecretsAsync(unresolvedKeys.ToArray()).Result;
if (secrets.Any())
{
resolvedSecrets.AddRange(secrets);
}

foreach (var secret in secrets)
{
if (secret.Value != null) _store.Save($"{_storePrefix}{secret.Key}", secret.Value);
}
}
foreach (var azureSecret in azureSecrets)
catch (Exception ex)
{
if (azureSecret.Value != null) _store.Save($"{_storePrefix}{azureSecret.Key}", azureSecret.Value);
throw new NoxSecretsException("Unable to retrieve secrets from the Hashicorp vault, are you connected to the internet and is the vault available?", ex);
}

break;
}
}
Expand Down
22 changes: 17 additions & 5 deletions src/Nox.Secrets/NoxSecretsResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class NoxSecretsResolver: INoxSecretsResolver
private readonly IPersistedSecretStore _store;
private ISecretsResolver? _userSecretsResolver;
private Solution.Secrets? _secretsConfig;
private bool _isConfigured = false;

public NoxSecretsResolver(IPersistedSecretStore store)
{
Expand All @@ -21,16 +22,27 @@ public void Configure(Solution.Secrets configuration, Assembly? assemblyWithSecr
{
_secretsConfig = configuration;
_userSecretsResolver = new UserSecretsResolver(assemblyWithSecrets ?? Assembly.GetExecutingAssembly());
_isConfigured = true;
}

public IReadOnlyDictionary<string, string?> Resolve(string[] keys)
{
if (_secretsConfig == null) throw new NoxSecretsException("Secrets resolver has not been initialized. Please call the ISecretResolver.Initialize method before attempting to resolve any secrets.");
if (!_isConfigured) throw new NoxSecretsException("Secrets resolver has not been configured. Please call the Configure method before attempting to resolve any secrets.");
var result = new Dictionary<string, string?>();
var orgSecrets = ResolveOrganizationSecrets(keys);
if (orgSecrets != null && orgSecrets.Any()) SetSecrets(orgSecrets!, result);
var slnSecrets = ResolveSolutionSecrets(keys);
if (slnSecrets != null && slnSecrets.Any()) SetSecrets(slnSecrets!, result);
if (_secretsConfig != null)
{
if (_secretsConfig.OrganizationSecretsServer != null)
{
var orgSecrets = ResolveOrganizationSecrets(keys);
if (orgSecrets != null && orgSecrets.Any()) SetSecrets(orgSecrets!, result);
}

if (_secretsConfig.SolutionSecretsServer != null)
{
var slnSecrets = ResolveSolutionSecrets(keys);
if (slnSecrets != null && slnSecrets.Any()) SetSecrets(slnSecrets!, result);
}
}
var userSecrets = _userSecretsResolver!.Resolve(keys);
if (userSecrets.Any()) SetSecrets(userSecrets, result);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public ODataDbContext(
INoxDatabaseProvider databaseProvider
) : base(options)
{
_noxSolution = noxSolution;
_dbProvider = databaseProvider;
_noxSolution = noxSolution;
_dbProvider = databaseProvider;
}

public DbSet<Country> Countries {get; set;} = null!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public SampleWebAppDbContext(
INoxDatabaseProvider databaseProvider
) : base(options)
{
_noxSolution = noxSolution;
_dbProvider = databaseProvider;
_noxSolution = noxSolution;
_dbProvider = databaseProvider;
}

public DbSet<Country> Countries {get; set;} = null!;
Expand Down
1 change: 0 additions & 1 deletion src/SampleWebApp/SampleWebApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
</ItemGroup>

<ItemGroup>

<ProjectReference Include="..\Nox.Generator\Nox.Generator.csproj" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
<ProjectReference Include="..\Nox.Abstractions\Nox.Abstractions.csproj" />
<ProjectReference Include="..\Nox.Lib\Nox.Lib.csproj" />
Expand Down

0 comments on commit 5b7c47e

Please sign in to comment.