Skip to content

Commit

Permalink
Added backwards compatible aws, gcp and azure secret resolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
sksamuel committed May 27, 2023
1 parent 362608f commit 369bedc
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.sksamuel.hoplite.StringNode
import com.sksamuel.hoplite.fp.flatMap
import com.sksamuel.hoplite.resolver.ContextResolver

abstract class AwsSecretsManagerRegexResolver(
abstract class AbstractAwsSecretsManagerContextResolver(
private val report: Boolean = false,
createClient: () -> AWSSecretsManager = { AWSSecretsManagerClientBuilder.standard().build() }
) : ContextResolver() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.sksamuel.hoplite.aws

import com.amazonaws.services.secretsmanager.AWSSecretsManager
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder

/**
* Replaces strings of the form ${{ aws-secrets-manager:path }} by looking up the path in AWS Secrets Manager.
* The [AWSSecretsManager] client is created from the [createClient] function which by default
* uses the default builder.
*/
class AwsSecretsManagerContextResolver(
report: Boolean = false,
createClient: () -> AWSSecretsManager = { AWSSecretsManagerClientBuilder.standard().build() }
) : AbstractAwsSecretsManagerContextResolver(report, createClient) {
override val contextKey: String = "aws-secrets-manager"
override val default: Boolean = false
}

@Deprecated("Included for backwards compatibility")
class Legacy1AwsSecretsManagerContextResolver(
report: Boolean = false,
createClient: () -> AWSSecretsManager = { AWSSecretsManagerClientBuilder.standard().build() }
) : AbstractAwsSecretsManagerContextResolver(report, createClient) {
override val contextKey: String = "awssm"
override val default: Boolean = false
}

@Deprecated("Included for backwards compatibility")
class Legacy2AwsSecretsManagerContextResolver(
report: Boolean = false,
createClient: () -> AWSSecretsManager = { AWSSecretsManagerClientBuilder.standard().build() }
) : AbstractAwsSecretsManagerContextResolver(report, createClient) {
override val contextKey: String = "secretsmanager"
override val default: Boolean = false
}

@Deprecated("Included for backwards compatibility")
class Legacy3AwsSecretsManagerContextResolver(
report: Boolean = false,
createClient: () -> AWSSecretsManager = { AWSSecretsManagerClientBuilder.standard().build() }
) : AbstractAwsSecretsManagerContextResolver(report, createClient) {
override val contextKey: String = "awssecret"
override val default: Boolean = false
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder
import com.sksamuel.hoplite.resolver.CompositeResolver
import com.sksamuel.hoplite.resolver.Resolver

fun createAwsSecretsManagerResolver(
fun AwsSecretsManagerContextResolvers(
report: Boolean = false,
createClient: () -> AWSSecretsManager = { AWSSecretsManagerClientBuilder.standard().build() }
): Resolver = CompositeResolver(AwsSecretsManagerContextResolver(report, createClient))
): Resolver = CompositeResolver(
AwsSecretsManagerContextResolver(report, createClient),
Legacy1AwsSecretsManagerContextResolver(report, createClient),
Legacy2AwsSecretsManagerContextResolver(report, createClient),
Legacy3AwsSecretsManagerContextResolver(report, createClient),
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import com.sksamuel.hoplite.ConfigResult
import com.sksamuel.hoplite.DecoderContext
import com.sksamuel.hoplite.Node
import com.sksamuel.hoplite.StringNode
import com.sksamuel.hoplite.resolver.CompositeResolver
import com.sksamuel.hoplite.resolver.ContextResolver
import com.sksamuel.hoplite.resolver.Resolver

class AzureKeyVaultContextResolver(
private val report: Boolean = false,
Expand All @@ -32,3 +34,35 @@ class AzureKeyVaultContextResolver(
return ops.value.fetchSecret(path, context, report)
}
}

class LegacyAzureKeyVaultContextResolver(
private val report: Boolean = false,
private val createClient: () -> SecretClient
) : ContextResolver() {

constructor(url: String) : this(url, false)
constructor(url: String, report: Boolean) : this(report = report, {
SecretClientBuilder()
.vaultUrl(url)
.credential(DefaultAzureCredentialBuilder().build())
.buildClient()
})

private val client = lazy { createClient() }
private val ops = lazy { AzureOps(client.value) }

override val contextKey = "azurekeyvault"
override val default: Boolean = true

override fun lookup(path: String, node: StringNode, root: Node, context: DecoderContext): ConfigResult<String?> {
return ops.value.fetchSecret(path, context, report)
}
}

fun AzureKeyVaultContextResolvers(
report: Boolean = false,
createClient: () -> SecretClient
): Resolver = CompositeResolver(
AzureKeyVaultContextResolver(report, createClient),
LegacyAzureKeyVaultContextResolver(report, createClient),
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import com.sksamuel.hoplite.fp.invalid
import com.sksamuel.hoplite.fp.valid
import com.sksamuel.hoplite.resolver.ContextResolver

class GcpSecretManagerResolver(
abstract class AbstractGcpSecretManagerContextResolver(
private val report: Boolean = false,
private val createClient: () -> SecretManagerServiceClient
) : ContextResolver() {

private val client = lazy { createClient() }
override val contextKey: String = "gcp-secrets-manager"
override val default: Boolean = false

companion object {
const val Section = "GCP Secret Manager Lookups"
}

override fun lookup(path: String, node: StringNode, root: Node, context: DecoderContext): ConfigResult<String?> {
return fetchSecret(path, context)
Expand All @@ -35,17 +37,13 @@ class GcpSecretManagerResolver(
}

if (value.isNullOrBlank())
ConfigFailure.PreprocessorWarning("Empty value for '$key' in GCP Secret Manager").invalid()
ConfigFailure.ResolverFailure("Empty value for '$key' in GCP Secret Manager").invalid()
else
value.valid()
} catch (e: ApiException) {
ConfigFailure.PreprocessorWarning("Could not locate secret '$key' in GCP Secret Manager").invalid()
ConfigFailure.ResolverFailure("Could not locate secret '$key' in GCP Secret Manager").invalid()
} catch (e: Exception) {
ConfigFailure.PreprocessorFailure("Failed loading secret '$key' from GCP Secret Manager", e).invalid()
ConfigFailure.ResolverException("Failed loading secret '$key' from GCP Secret Manager", e).invalid()
}
}

companion object {
const val Section = "GCP Secret Manager Lookups"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.sksamuel.hoplite.gcp

import com.google.cloud.secretmanager.v1.SecretManagerServiceClient
import com.sksamuel.hoplite.resolver.CompositeResolver
import com.sksamuel.hoplite.resolver.Resolver

class GcpSecretManagerContextResolver(
report: Boolean = false,
createClient: () -> SecretManagerServiceClient,
) : AbstractGcpSecretManagerContextResolver(report, createClient) {
override val contextKey: String = "gcp-secrets-manager"
override val default: Boolean = false
}

@Deprecated("Included for backwards compatibility. Prefer GcpSecretManagerContextResolver")
class LegacyGcpSecretManagerContextResolver(
report: Boolean = false,
createClient: () -> SecretManagerServiceClient,
) : AbstractGcpSecretManagerContextResolver(report, createClient) {
override val contextKey: String = "gcpsm"
override val default: Boolean = false
}

fun GcpSecretsManagerContextResolvers(
report: Boolean = false,
createClient: () -> SecretManagerServiceClient,
): Resolver = CompositeResolver(
GcpSecretManagerContextResolver(report, createClient),
LegacyGcpSecretManagerContextResolver(report, createClient),
)

0 comments on commit 369bedc

Please sign in to comment.