Skip to content

Commit

Permalink
add odic client support and rename the package to add inventory (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
akoserwal authored Aug 12, 2024
1 parent f2ea5e2 commit 767cfdb
Show file tree
Hide file tree
Showing 28 changed files with 1,637 additions and 42 deletions.
23 changes: 21 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,20 @@
<artifactId>pgv-java-stub</artifactId>
<version>1.0.4</version>
</dependency>
<!-- Default OIDC implementation. Must be provided by the user. -->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>11.13</version>
<scope>provided</scope>
</dependency>
<!-- Included only for @RegisterForReflection to support native Quarkus apps if applicable -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core</artifactId>
<version>3.12.3</version>
<scope>provided</scope>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
Expand All @@ -101,14 +115,19 @@
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<!-- Use Weld as a CDI container for CDI testing. -->
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-junit5</artifactId>
<version>4.0.3.Final</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down Expand Up @@ -220,7 +239,7 @@
</goals>
<configuration>
<!-- key -->
<keyname></keyname>
<keyname>18645E7B38C5CE94CC4183040B71CD10C1E47F3F</keyname>
</configuration>
</execution>
</executions>
Expand Down
17 changes: 0 additions & 17 deletions src/main/java/org/project_kessel/client/Config.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.project_kessel.client;
package org.project_kessel.inventory.client;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
Expand All @@ -15,11 +15,18 @@ public class CDIManagedClients {
InventoryGrpcClientsManager getManager(Config config) {
var isSecureClients = config.isSecureClients();
var targetUrl = config.targetUrl();

var authnEnabled = config.authenticationConfig().map(t -> !t.mode().equals(Config.AuthMode.DISABLED)).orElse(false);
if (isSecureClients) {
if(authnEnabled) {
return InventoryGrpcClientsManager.forSecureClients(targetUrl, config.authenticationConfig().get());
}
return InventoryGrpcClientsManager.forSecureClients(targetUrl);
}

if(authnEnabled) {
return InventoryGrpcClientsManager.forInsecureClients(targetUrl, config.authenticationConfig().get());
}

return InventoryGrpcClientsManager.forInsecureClients(targetUrl);
}

Expand Down
45 changes: 45 additions & 0 deletions src/main/java/org/project_kessel/inventory/client/Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.project_kessel.inventory.client;

import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import io.smallrye.config.WithName;

import java.util.Optional;

/**
* Interface for injecting config into container managed beans.
* It has the current limitation that only one underlying grpc connection can be configured.
* Does nothing if this client is not being managed by a container.
* Works directly for Quarkus. Might need an implementation class for future Spring Boot config.
*/
@ConfigMapping(prefix = "inventory-api")
public interface Config {
enum AuthMode {
DISABLED,
OIDC_CLIENT_CREDENTIALS
}

@WithDefault("false")
boolean isSecureClients();
String targetUrl();

@WithName("authn")
Optional<AuthenticationConfig> authenticationConfig();

interface AuthenticationConfig {
@WithDefault("disabled")
AuthMode mode();
@WithName("client")
Optional<OIDCClientCredentialsConfig> clientCredentialsConfig();
}

interface OIDCClientCredentialsConfig {
String issuer();
@WithName("id")
String clientId();
@WithName("secret")
String clientSecret();
Optional<String[]> scope();
Optional<String> oidcClientCredentialsMinterImplementation();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.project_kessel.client;
package org.project_kessel.inventory.client;

import io.grpc.*;
import org.project_kessel.inventory.client.authn.CallCredentialsFactory;

import java.util.HashMap;

Expand All @@ -18,6 +19,20 @@ public static synchronized InventoryGrpcClientsManager forInsecureClients(String
return insecureManagers.get(targetUrl);
}

public static synchronized InventoryGrpcClientsManager forInsecureClients(String targetUrl, Config.AuthenticationConfig authnConfig) throws RuntimeException {
if (!insecureManagers.containsKey(targetUrl)) {
try {
var manager = new InventoryGrpcClientsManager(targetUrl,
InsecureChannelCredentials.create(),
CallCredentialsFactory.create(authnConfig));
insecureManagers.put(targetUrl, manager);
} catch (CallCredentialsFactory.CallCredentialsCreationException e) {
throw new RuntimeException(e);
}
}
return insecureManagers.get(targetUrl);
}

public static synchronized InventoryGrpcClientsManager forSecureClients(String targetUrl) {
if (!secureManagers.containsKey(targetUrl)) {
var tlsChannelCredentials = TlsChannelCredentials.create();
Expand All @@ -27,6 +42,21 @@ public static synchronized InventoryGrpcClientsManager forSecureClients(String t
return secureManagers.get(targetUrl);
}

public static synchronized InventoryGrpcClientsManager forSecureClients(String targetUrl, Config.AuthenticationConfig authnConfig) {
if (!secureManagers.containsKey(targetUrl)) {
var tlsChannelCredentials = TlsChannelCredentials.create();
try {
var manager = new InventoryGrpcClientsManager(targetUrl,
tlsChannelCredentials,
CallCredentialsFactory.create(authnConfig));
secureManagers.put(targetUrl, manager);
} catch (CallCredentialsFactory.CallCredentialsCreationException e) {
throw new RuntimeException(e);
}
}
return secureManagers.get(targetUrl);
}


public static synchronized void shutdownAll() {
for (var manager : insecureManagers.values()) {
Expand Down Expand Up @@ -70,6 +100,18 @@ private InventoryGrpcClientsManager(String targetUrl, ChannelCredentials credent
this.channel = Grpc.newChannelBuilder(targetUrl, credentials).build();
}

/**
* Create a manager for a grpc channel with server credentials and credentials for per-rpc client authentication.
* @param targetUrl
* @param serverCredentials authenticates the server for TLS or are InsecureChannelCredentials
* @param authnCredentials authenticates the client on each rpc
*/
private InventoryGrpcClientsManager(String targetUrl, ChannelCredentials serverCredentials, CallCredentials authnCredentials) {
this.channel = Grpc.newChannelBuilder(targetUrl,
CompositeChannelCredentials.create(serverCredentials, authnCredentials)).build();
}


private void closeClientChannel() {
channel.shutdown();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package org.project_kessel.client;
package org.project_kessel.inventory.client;

import io.grpc.Channel;
import org.project_kessel.api.inventory.v1.*;


import java.util.logging.Logger;

public class InventoryHealthClient {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package org.project_kessel.client;
package org.project_kessel.inventory.client;

import io.grpc.Channel;
import io.grpc.stub.StreamObserver;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.operators.multi.processors.UnicastProcessor;
import org.project_kessel.api.inventory.v1beta1.*;


import java.util.logging.Logger;

public class K8sClustersClient {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package org.project_kessel.client;
package org.project_kessel.inventory.client;

import io.grpc.Channel;
import io.grpc.stub.StreamObserver;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.operators.multi.processors.UnicastProcessor;
import org.project_kessel.api.inventory.v1beta1.*;


import java.util.logging.Logger;

public class NotificationsIntegrationClient {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.project_kessel.client;
package org.project_kessel.inventory.client;

import io.grpc.Channel;
import io.grpc.stub.StreamObserver;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package org.project_kessel.client;
package org.project_kessel.inventory.client;

import io.grpc.Channel;
import io.grpc.stub.StreamObserver;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.operators.multi.processors.UnicastProcessor;
import org.project_kessel.api.inventory.v1beta1.*;


import java.util.logging.Logger;

public class PolicyRelationshipClient {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.project_kessel.client;
package org.project_kessel.inventory.client;

import io.grpc.Channel;
import io.grpc.stub.StreamObserver;
Expand All @@ -8,6 +8,8 @@
import org.project_kessel.api.inventory.v1beta1.CreateRhelHostResponse;
import org.project_kessel.api.inventory.v1beta1.KesselRhelHostServiceGrpc;



import java.util.logging.Logger;

public class RhelHostClient {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.project_kessel.inventory.client.authn;

import io.grpc.CallCredentials;
import org.project_kessel.inventory.client.Config;
import org.project_kessel.inventory.client.authn.oidc.client.OIDCClientCredentialsCallCredentials;

public class CallCredentialsFactory {

private CallCredentialsFactory() {

}

public static CallCredentials create(Config.AuthenticationConfig authnConfig) throws CallCredentialsCreationException {
if (authnConfig == null) {
throw new CallCredentialsCreationException("AuthenticationConfig is required to create CallCredentials and must not be null.");
}

try {
switch (authnConfig.mode()) {
case DISABLED: return null;
case OIDC_CLIENT_CREDENTIALS: return new OIDCClientCredentialsCallCredentials(authnConfig);
}
} catch (OIDCClientCredentialsCallCredentials.OIDCClientCredentialsCallCredentialsException e) {
throw new CallCredentialsCreationException("Failed to create OIDCClientCredentialsCallCredentials.", e);
}

return null;
}

public static class CallCredentialsCreationException extends Exception {
public CallCredentialsCreationException(String message) {
super(message);
}

public CallCredentialsCreationException(String message, Throwable cause) {
super(message, cause);
}
}
}
Loading

0 comments on commit 767cfdb

Please sign in to comment.