How to read secret key and value from Kubernetes volume mount using Spring Boot

12/18/2021

I have mounted one volume which contained username and password inside pod. If I do:

kubectl  exec -it my-app -- cat /mnt/secrets-store/git-token

{"USERNAME":"usernameofgit","PASSWORD":"dhdhfhehfhel"}

I want to read this USERNAME and PASSWORD using Spring Boot.

-- Chintamani
kubernetes
spring
spring-boot
spring-boot-admin
spring-boot-maven-plugin

2 Answers

12/18/2021

When you have your volume mounted, then all you need to do is to read a JSON file from the Spring Boot application. I recommend reading Load Spring Boot Properties From a JSON File.

In short, you can create a class corresponding to your JSON file, something like this one.

@Component
@PropertySource("file:/mnt/secrets-store/git-token")
@ConfigurationProperties
public class GitToken {
    private String username;
    private String password;

   // getters and setters
}

Then, you need to add it to componentScan and you can autowire your class.

-- RafaƂ Leszko
Source: StackOverflow

12/18/2021

Assuming:

  • the file (git_token) format is fixed (JSON).
  • the file may not have an extension suffix (.json).

... we have some Problems!

I tried 2.3.5. Importing Extensionless Files like:

spring.config.import=/mnt/secrets-store/git-token[.json]

But it works only with YAML/.properties yet!(tested with spring-boot:2.6.1))

Same applies to 2.8. Type-safe Configuration Properties. ;(;(


In Spring-Boot we can (out-of-the box) provide JSON-config (only) as SPRING_APPLICATION_JSON environment/command line property, and it has to be the json string, and cannot be a path or file (yet).


The proposed (baeldung) article shows ways to "enable JSON properties", but it is a long article with many details, shows much code and has decent lacks/outdates (@Component on @ConfigurationProperties is rather "unconventional")..


I tried the following (on local machine, under the mentioned assumptions):

package com.example.demo;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  @Value("""
    #{@jacksonObjectMapper.readValue(
      T(java.nio.file.Files).newInputStream(
        T(java.nio.file.Path).of('/mnt/secrets-store/git-token')),
        T(com.example.demo.GitInfo)
    )}""" // watch out with @Value and text blocks! (otherwise: No converter found capable of converting from type [com.example.demo.GitInfo] to type [java.lang.String])
  )
  GitInfo gitInfo;

  @Bean
  CommandLineRunner runner() {
    return (String... args) -> {
      System.out.println(gitInfo.getUsername());
      System.out.println(gitInfo.getPassword());
    };
  }
}

@Data
class GitInfo {
  @JsonProperty("USERNAME")
  private String username;
  @JsonProperty("PASSWORD")
  private String password;
}

With (only) spring-boot-starter-web and lombok on board, it prints the expected output.


Solution outline:

-- xerx593
Source: StackOverflow