我如何使用 micronaut 3 和 google 秘密管理器?

How can I work with micronaut 3 and google secret manager?

目前正在将我的应用程序迁移到 Micronaut 3,我遇到了 micronaut-gcp 的一个问题。尤其是 google 秘密经理。我正在使用 gradle 和 Kotlin DSL。

实际配置:(不工作,使用插件 io.micronaut.library 版本 2.0.4

以前的配置:(不使用插件,使用 micronaut-bom

我/问题

我的目标是将一些秘密作为 key/value 对加载到 属性 源中。 我按照 documentation 说使用 bootstrap.yml 如下:

micronaut:
    config-client:
        enabled: true
gcp:
    secret-manager:
      keys:
        - MY_SECRET

然后在我的 class 中,我应该能够使用 @Value 注释注入该秘密值。实际上,我正在测试中这样做。我正在使用来自 jUnit5 的 @MicronautTest 注释,所以我有一些看起来像这样的东西:

@MicronautTest
public class MyClass {
  @Value("${my.secret}")
  private String mySecret;
}

然后问题来了,当运行任何测试时,它在初始化时失败说:

Error instantiating bean of type  [io.micronaut.gcp.secretmanager.client.DefaultSecretManagerClient]

Message: getTransportChannel() called when needsExecutor() is true
Path Taken: new DistributedPropertySourceLocator(ConfigurationClient configurationClient,Duration readTimeout) --> new DistributedPropertySourceLocator([ConfigurationClient configurationClient],Duration readTimeout) --> new DefaultCompositeConfigurationClient([ConfigurationClient[] configurationClients]) --> new SecretManagerConfigurationClient([SecretManagerClient secretManagerClient],SecretManagerConfigurationProperties configurationProperties) --> new DefaultSecretManagerClient([SecretManagerServiceClient client],Environment environment,GoogleCloudConfiguration googleCloudConfiguration,ExecutorService executorService)
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type  [io.micronaut.gcp.secretmanager.client.DefaultSecretManagerClient]

II/我试过什么?

当我看到它时,我在想 bootstrap.yaml 可能不起作用,我尝试通过注入 SecretManagerServiceClient 来使用较低的杠杆访问秘密管理器,如下所示:

@MicronautTest
public class MyClass {
  @Inject
  private SecretManagerServiceClient client;

  private void someTest() {
    String mySecret = client.getSecret("MY_SECRET");
  }
}

但采用相同的路径时出现相同的错误 Message: getTransportChannel() called when needsExecutor() is true

我也尝试升级到 micronaut 3.0.1,但没有任何改变。

III/ 我的解决方案

因为我的问题是在我的 ci/cd 过程的测试阶段检索一个秘密,并且因为我在我的 cloudbuild.yaml 中使用 Google Cloud Build. I could pass the secret using the availableSecrets 功能:

steps:
 ...
  - name: 'gradle'
    entrypoint: 'bash'
    args: ['./gradlew', 'test']
    secretEnv: ['MY_SECRET']
 ...

availableSecrets:
  secretManager:
  - versionName: projects/PROJECT_ID/secrets/MY_SECRET/versions/latest
    env: 'MY_SECRET'

然后将其传递到我的 application.yml:

my:
  secret: ${MY_SECRET}

然后在我的代码中:

@MicronautTest
public class MyClass {
  @Value("${my.secret}")
  private String mySecret;
}

但我觉得这个解决方案不太令人满意,因为我发现 bootstrap.yaml 一个更方便。

如果有人为我或 idea/advice 提供解决方案,我将很乐意接受。

祝你有愉快的一天!

我一直在那个兔子洞里。长话短说,我通过将 google-cloud-secretmanager 依赖项从 1.6.4 升级到例如2.0.2

像这样:

    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-secretmanager</artifactId>
      <version>2.0.2</version>
    </dependency>