Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment Variables from Secrets #1715

Closed
evanshortiss opened this issue Sep 25, 2020 · 6 comments
Closed

Environment Variables from Secrets #1715

evanshortiss opened this issue Sep 25, 2020 · 6 comments

Comments

@evanshortiss
Copy link
Contributor

Hi, I'm working on a route where I use a JDBC connector to perform a DB INSERT. I'd like to inject the db connection details from an existing secret and load via System.getenv("DB_PASS"').

To configure the datasource I have the following:

    @BindToRegistry("dataSource")
    public BasicDataSource datasoure() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://postgres:5432/my-db");
        dataSource.setUsername("user"); // want to store these in a secret
        dataSource.setPassword("pass"); // want to store these in a secret
        return dataSource;
    }

With this my .to("jdbc:datasource") line is working, but the username and password are plaintext. I could use kamel --env to inject this, but I don't see how --env can reference a key in a secret. Is this possible?

Perhaps there's a way to set this in the application.properties that I am missing?

@lburgazzoli
Copy link
Contributor

lburgazzoli commented Sep 25, 2020

if your put the credential in a secret, then you can use

kamel run --secret your-secret

the secret is then mounted to the pod and its values are made available to the integration thus you can do something like:

@BindToRegistry("dataSource")
public BasicDataSource datasoure(
        @PropertyInject("db.usr") String usr,
        @PropertyInject("db.pwd") String pwd) {

    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName("org.postgresql.Driver");
    dataSource.setUrl("jdbc:postgresql://postgres:5432/my-db");
    dataSource.setUsername(usr); // <-- from secret 
    dataSource.setPassword(pwd); // <-- from secret 

    return dataSource;
}

@lburgazzoli
Copy link
Contributor

btw, note that you can configure the datasource using properties only, see https://camel.apache.org/components/latest/others/main.html#_specifying_custom_beans, in that case you can reference any other property using placeholder {{ }}, like:

camel.beans.dataSource = #class:org.apache.commons.dbcp.BasicDataSource
camel.beans.dataSource.driverClassName = org.postgresql.Driver
camel.beans.dataSource.url = jdbc:postgresql://postgres:5432/my-db
camel.beans.dataSource.username = {{db.usr}}
camel.beans.dataSource.password = {{db.pwd}}

@evanshortiss
Copy link
Contributor Author

evanshortiss commented Sep 25, 2020

Thank you @lburgazzoli, those are both nice options!

My confusion is stemming from the fact that normally I can attach a secret to the environment like so:

- name: POSTGRES_USER
            valueFrom:
                secretKeyRef:
                  key: POSTGRES_USER
                  name: db-login-secret

Then in properties, for say a Quarkus application, I can do db.usr=${POSTGRES_USER:default-user}. It seems like with kamel, the secret must contain a properties format file?

My reasoning for this question is I have my DB info in a pre-existing secret:

apiVersion: v1
data:
  POSTGRES_PASSWORD: cGFzc3dvcmQK
  POSTGRES_USER: dXNlcgo=
kind: Secret
metadata:
  name: db-login
type: Opaque

And I have my properties like so in a config map:

kafka.host=cluster-kafka-brokers
kafka.port=9092

kafka.serializerClass=kafka.serializer.StringEncoder

# Kafka meter consumer properties 
consumer.topic=meters
consumer.group=CamelMeters
consumer.maxPollRecords=5000
consumer.consumersCount=1
consumer.seekTo=beginning

# Can I pull these from a secret/environment?
camel.beans.dataSource.username = {{db.usr}}
camel.beans.dataSource.password = {{db.pwd}}

Is it possible to populate the dataSource properties via the existing secret?

@lburgazzoli
Copy link
Contributor

lburgazzoli commented Sep 25, 2020

So about the valueFrom we have some issue that could make it possible:

but they are not yet implemented so you either have to pack your credentials as a properties file or you can use some special resolvers, like:

camel.beans.dataSource = #class:org.apache.commons.dbcp.BasicDataSource
camel.beans.dataSource.driverClassName = org.postgresql.Driver
camel.beans.dataSource.url = jdbc:postgresql://postgres:5432/my-db
camel.beans.dataSource.username = {{secret:db-login/POSTGRES_USER}}
camel.beans.dataSource.password = {{secret:db-login/POSTGRES_PASSWORD}}

Note 1 you still need to tell kamel to mount the db-login secret with the --secret cli option.
Note 2 hope it works because I just realize there's no tests :)
Note 3 it should also work with @PropertyInject

@evanshortiss
Copy link
Contributor Author

hope it works because I just realize there's no tests

🤣 well good news, since it appears to be working! I used it with the PropertyInject

It would be very helpful to mention this on the docs for configmap/secret. If I can help by adding this example I'd be happy to do so 👍

Thank you for all your help @lburgazzoli!

@lburgazzoli
Copy link
Contributor

yes please go ahead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants