forked from RedHatInsights/notifications-backend
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
36 changed files
with
524 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?xml version="1.0"?> | ||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" | ||
xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>notifications-connector-common-secrets-loader</artifactId> | ||
|
||
<parent> | ||
<groupId>com.redhat.cloud.notifications</groupId> | ||
<artifactId>notifications-parent</artifactId> | ||
<version>1.0.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<dependencies> | ||
|
||
<!-- Scope: compile --> | ||
|
||
<!-- notifications modules --> | ||
<dependency> | ||
<groupId>com.redhat.cloud.notifications</groupId> | ||
<artifactId>notifications-connector-common</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
|
||
<!-- Quarkus --> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-hibernate-validator</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-rest-client-reactive-jackson</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-smallrye-fault-tolerance</artifactId> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
|
||
<!-- The following plugin is required to inject beans from this module into other modules. --> | ||
<plugin> | ||
<groupId>org.jboss.jandex</groupId> | ||
<artifactId>jandex-maven-plugin</artifactId> | ||
<version>1.2.3</version> | ||
<executions> | ||
<execution> | ||
<id>make-index</id> | ||
<goals> | ||
<goal>jandex</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
|
||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>${compiler-plugin.version}</version> | ||
<configuration> | ||
<compilerArgs> | ||
<arg>-parameters</arg> | ||
</compilerArgs> | ||
</configuration> | ||
</plugin> | ||
|
||
<plugin> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<version>${surefire-plugin.version}</version> | ||
<configuration> | ||
<systemPropertyVariables> | ||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> | ||
</systemPropertyVariables> | ||
</configuration> | ||
</plugin> | ||
|
||
</plugins> | ||
</build> | ||
|
||
</project> |
10 changes: 10 additions & 0 deletions
10
...secrets-loader/src/main/java/com/redhat/cloud/notifications/connector/secrets/Secret.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.redhat.cloud.notifications.connector.secrets; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
|
||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
public class Secret { | ||
|
||
public String username; | ||
public String password; | ||
} |
8 changes: 8 additions & 0 deletions
8
...c/main/java/com/redhat/cloud/notifications/connector/secrets/SecretsExchangeProperty.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.redhat.cloud.notifications.connector.secrets; | ||
|
||
public class SecretsExchangeProperty { | ||
|
||
public static final String SECRET_ID = "secretId"; | ||
public static final String SECRET_PASSWORD = "secretPassword"; | ||
public static final String SECRET_USERNAME = "secretUsername"; | ||
} |
66 changes: 66 additions & 0 deletions
66
...-loader/src/main/java/com/redhat/cloud/notifications/connector/secrets/SecretsLoader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.redhat.cloud.notifications.connector.secrets; | ||
|
||
import io.micrometer.core.instrument.MeterRegistry; | ||
import io.micrometer.core.instrument.Timer; | ||
import io.quarkus.logging.Log; | ||
import jakarta.enterprise.context.ApplicationScoped; | ||
import jakarta.inject.Inject; | ||
import org.apache.camel.Exchange; | ||
import org.apache.camel.Processor; | ||
import org.eclipse.microprofile.config.inject.ConfigProperty; | ||
import org.eclipse.microprofile.rest.client.inject.RestClient; | ||
|
||
import static com.redhat.cloud.notifications.connector.ExchangeProperty.ORG_ID; | ||
import static com.redhat.cloud.notifications.connector.secrets.SecretsExchangeProperty.SECRET_ID; | ||
import static com.redhat.cloud.notifications.connector.secrets.SecretsExchangeProperty.SECRET_PASSWORD; | ||
import static com.redhat.cloud.notifications.connector.secrets.SecretsExchangeProperty.SECRET_USERNAME; | ||
|
||
@ApplicationScoped | ||
public class SecretsLoader implements Processor { | ||
|
||
private static final String SECRETS_LOADER_ENABLED = "notifications.connector.secrets-loader.enabled"; | ||
private static final String SOURCES_API_PSK = "notifications.connector.secrets-loader.sources-api-psk"; | ||
private static final String SOURCES_TIMER = "sources.get.secret.request"; | ||
|
||
@ConfigProperty(name = SECRETS_LOADER_ENABLED, defaultValue = "false") | ||
boolean secretsLoaderEnabled; | ||
|
||
@ConfigProperty(name = SOURCES_API_PSK) | ||
String sourcesApiPsk; | ||
|
||
@Inject | ||
MeterRegistry meterRegistry; | ||
|
||
@Inject | ||
@RestClient | ||
SourcesClient sourcesClient; | ||
|
||
@Override | ||
public void process(Exchange exchange) { | ||
if (secretsLoaderEnabled) { | ||
Long secretId = exchange.getProperty(SECRET_ID, Long.class); | ||
if (secretId != null) { | ||
String orgId = exchange.getProperty(ORG_ID, String.class); | ||
|
||
// TODO Lower the log level after the testing phase. | ||
Log.infof("Calling Sources to retrieve a secret [orgId=%s, secretId=%d]", orgId, secretId); | ||
|
||
Timer.Sample timer = Timer.start(meterRegistry); | ||
Secret secret = sourcesClient.getById(orgId, sourcesApiPsk, secretId); | ||
timer.stop(meterRegistry.timer(SOURCES_TIMER)); | ||
|
||
if (secret.username != null && !secret.username.isBlank()) { | ||
// TODO Lower the log level after the testing phase. | ||
Log.info("Found a secret username in the response from Sources"); | ||
exchange.setProperty(SECRET_USERNAME, secret.username); | ||
} | ||
|
||
if (secret.password != null && !secret.password.isBlank()) { | ||
// TODO Lower the log level after the testing phase. | ||
Log.info("Found a secret password in the response from Sources"); | ||
exchange.setProperty(SECRET_PASSWORD, secret.password); | ||
} | ||
} | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
...-loader/src/main/java/com/redhat/cloud/notifications/connector/secrets/SourcesClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.redhat.cloud.notifications.connector.secrets; | ||
|
||
import io.quarkus.rest.client.reactive.ClientExceptionMapper; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.ws.rs.GET; | ||
import jakarta.ws.rs.HeaderParam; | ||
import jakarta.ws.rs.Path; | ||
import jakarta.ws.rs.WebApplicationException; | ||
import jakarta.ws.rs.core.Response; | ||
import org.eclipse.microprofile.faulttolerance.Retry; | ||
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; | ||
import org.jboss.resteasy.reactive.RestPath; | ||
|
||
/** | ||
* <p>REST Client for the Sources API. The OpenAPI spec is available at:</p> | ||
* | ||
* <ul> | ||
* <li><a href="https://console.stage.redhat.com/docs/api/sources/v3.1">OpenApi v3.1 in the stage environment.</a></li> | ||
* <li><a href="https://console.redhat.com/docs/api/sources/v3.1">OpenApi v3.1 in the production environment.</a></li> | ||
* <li><a href="https://github.com/RedHatInsights/sources-api-go/blob/main/public/openapi-3-v3.1.json">OpenApi v3.1 JSON file on GitHub.</a></li> | ||
* </ul> | ||
* | ||
* <p>Please be aware of the following:</p> | ||
* | ||
* <ul> | ||
* <li>If sources is using a database backend, only the {@link Secret#password} field will get encrypted.</li> | ||
* <li>On the other hand, if sources is using the AWS Secrets Manager, then the whole secret will get encrypted.</li> | ||
* </ul> | ||
* | ||
* <p>The authentication to Sources works by using a service-to-service PSK that will be sent in the header that | ||
* Sources expects. At the same time, the organization id will be sent so that Sources knows to which tenants belongs | ||
* the operation that is going to be performed.</p> | ||
*/ | ||
@RegisterRestClient(configKey = "sources") | ||
public interface SourcesClient { | ||
|
||
/** | ||
* Get a single secret from Sources. In this case we need to hit the internal endpoint —which is only available for | ||
* requests coming from inside the cluster— to be able to get the password of these secrets. | ||
* @param xRhSourcesOrgId the organization id related to this operation for the tenant identification. | ||
* @param xRhSourcesPsk the sources PSK required for the authorization. | ||
* @param id the secret id. | ||
* @return a {@link Secret} instance. | ||
*/ | ||
@GET | ||
@Path("/internal/v2.0/secrets/{id}") | ||
@Retry | ||
Secret getById( | ||
@HeaderParam("x-rh-sources-org-id") @NotBlank String xRhSourcesOrgId, | ||
@HeaderParam("x-rh-sources-psk") @NotBlank String xRhSourcesPsk, | ||
@RestPath long id | ||
); | ||
|
||
/** | ||
* Throws a runtime exception with the client's response for an easier debugging. | ||
* @param response the received response from Sources. | ||
* @return the {@link RuntimeException} to be thrown. | ||
*/ | ||
@ClientExceptionMapper | ||
static RuntimeException toException(final Response response) { | ||
final var errMessage = String.format("Sources responded with a %s status: %s", response.getStatus(), response.readEntity(String.class)); | ||
|
||
throw new WebApplicationException(errMessage, response); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.