diff --git a/pom.xml b/pom.xml index b45af2a..0608373 100644 --- a/pom.xml +++ b/pom.xml @@ -290,6 +290,13 @@ true shaded + + com.redhat.insights + ${shade.prefix} + + com.redhat.insights.agent.* + + org.apache ${shade.prefix}.org.apache @@ -343,6 +350,7 @@ + com.redhat.insights.agent.AgentMain com.redhat.insights.agent.AgentMain true diff --git a/src/main/java/com/redhat/insights/agent/AgentConfiguration.java b/src/main/java/com/redhat/insights/agent/AgentConfiguration.java index 010196f..9de991b 100644 --- a/src/main/java/com/redhat/insights/agent/AgentConfiguration.java +++ b/src/main/java/com/redhat/insights/agent/AgentConfiguration.java @@ -86,12 +86,26 @@ public boolean isOptingOut() { return false; } + @Override + public String toString() { + return "AgentConfiguration{" + "args=" + args + '}'; + } + public boolean isDebug() { return "true".equalsIgnoreCase(args.getOrDefault("debug", "false")); } - @Override - public String toString() { - return "AgentConfiguration{" + "args=" + args + '}'; + public boolean isFileOnly() { + return "true".equalsIgnoreCase(args.getOrDefault("file_only", "false")); + } + + // See https://issues.redhat.com/browse/MWTELE-93 for more information + public boolean isOCP() { + return "true".equalsIgnoreCase(args.getOrDefault("is_ocp", "false")); + } + + // See https://issues.redhat.com/browse/MWTELE-93 for more information + public boolean shouldDefer() { + return "true".equalsIgnoreCase(args.getOrDefault("should_defer", "false")); } } diff --git a/src/main/java/com/redhat/insights/agent/AgentMain.java b/src/main/java/com/redhat/insights/agent/AgentMain.java index 5a51d2a..b13b99b 100644 --- a/src/main/java/com/redhat/insights/agent/AgentMain.java +++ b/src/main/java/com/redhat/insights/agent/AgentMain.java @@ -67,12 +67,16 @@ public static void startAgent(String agentArgs, Instrumentation instrumentation) if (!oArgs.isPresent()) { return; } - AgentConfiguration args = oArgs.get(); + AgentConfiguration config = oArgs.get(); + + if (!shouldContinue(logger, config)) { + return; + } BlockingQueue jarsToSend = new LinkedBlockingQueue<>(); try { logger.info("Starting Red Hat Insights client"); - new AgentMain(logger, args, jarsToSend).start(); + new AgentMain(logger, config, jarsToSend).start(); ClassNoticer noticer = new ClassNoticer(logger, jarsToSend); instrumentation.addTransformer(noticer); } catch (Throwable t) { @@ -80,6 +84,40 @@ public static void startAgent(String agentArgs, Instrumentation instrumentation) } } + // Now we have the config, we need to check for the existence of the unshaded client, not just + // the agent. + // This is belt-and-braces in case this agent is ever loaded into an + // app that has built-in Insights support. + + // See https://issues.redhat.com/browse/MWTELE-93 for more information + static boolean shouldContinue(InsightsLogger logger, AgentConfiguration config) { + try { + // This obfuscation is necessary to work around the shader plugin which will try to helpfully + // rename the class name when we don't want it to. + String obfuscatedStem = "com.redhat"; + String obfuscatedSubPackageAndClass = ".insights.InsightsReportController"; + + Class.forName(obfuscatedStem + obfuscatedSubPackageAndClass); + if (config.isOCP()) { + if (config.shouldDefer()) { + logger.warning("Insights builtin support is available, deferring to that"); + return false; + } else { + logger.warning( + "Starting Red Hat Insights client: Builtin support for OpenShift is available, but" + + " the agent is configured to run anyway. Ensure that this configuration is correct."); + } + } else { + // Always defer if we're on RHEL + logger.warning("Insights builtin support is available, deferring to that"); + return false; + } + } catch (ClassNotFoundException __) { + // Builtin support not found, continue + } + return true; + } + /** * Parse the agent arguments from the form "key1=value1;key2=value2;..." * @@ -108,26 +146,29 @@ static Optional parseArgs(InsightsLogger logger, String agen } logger.debug(config.toString()); - if (!config.getMaybeAuthToken().isPresent()) { + if (shouldLookForCerts(config)) { Path certPath = Paths.get(config.getCertFilePath()); Path keyPath = Paths.get(config.getKeyFilePath()); if (!Files.exists(certPath) || !Files.exists(keyPath)) { - if (!out.containsKey("debug") || !"true".equals(out.get("debug"))) { - logger.error("Unable to start Red Hat Insights client: Missing certificate or key files"); - return Optional.empty(); - } + logger.error("Unable to start Red Hat Insights client: Missing certificate or key files"); + return Optional.empty(); } } return Optional.of(config); } + private static boolean shouldLookForCerts(AgentConfiguration config) { + boolean hasToken = !config.getMaybeAuthToken().isPresent(); + return !hasToken && !config.isDebug() && !config.isFileOnly(); + } + private void start() { final InsightsReport report = AgentBasicReport.of(logger, configuration); final PEMSupport pem = new PEMSupport(logger, configuration); Supplier httpClientSupplier; - if (configuration.isDebug()) { + if (configuration.isDebug() || configuration.isFileOnly()) { httpClientSupplier = () -> new InsightsFileWritingClient(logger, configuration); } else { httpClientSupplier = diff --git a/src/main/java/com/redhat/insights/agent/AgentSubreport.java b/src/main/java/com/redhat/insights/agent/AgentSubreport.java index 85b38e4..a3cf8be 100644 --- a/src/main/java/com/redhat/insights/agent/AgentSubreport.java +++ b/src/main/java/com/redhat/insights/agent/AgentSubreport.java @@ -30,7 +30,7 @@ public class AgentSubreport implements InsightsSubreport { activeGuesses.put("org.jboss.modules.Module", AgentSubreport::fingerprintJBoss); activeGuesses.put( "io.quarkus.bootstrap.runner.QuarkusEntryPoint", AgentSubreport::fingerprintQuarkus); - activeGuesses.put("org.apache.catalina.Server", __ -> "Tomcat / JWS"); + activeGuesses.put("org.apache.catalina.Server", AgentSubreport::fingerprintTomcat); } private AgentSubreport(InsightsLogger logger, ClasspathJarInfoSubreport jarsReport) { @@ -75,6 +75,15 @@ private void fingerprintReflectively(Collection jarInfos) { } } + static String fingerprintTomcat(Class qClazz) { + try { + Class.forName("org.apache.tomcat.vault.VaultInteraction"); + } catch (ClassNotFoundException __) { + return "Tomcat"; + } + return "JWS"; + } + static String fingerprintQuarkus(Class qClazz) { String quarkusVersion = qClazz.getPackage().getImplementationVersion(); return "Quarkus " + quarkusVersion; diff --git a/src/test/java/com/redhat/insights/agent/ClassNoticerTest.java b/src/test/java/com/redhat/insights/agent/ClassNoticerTest.java index cb8ba04..54b4ee5 100644 --- a/src/test/java/com/redhat/insights/agent/ClassNoticerTest.java +++ b/src/test/java/com/redhat/insights/agent/ClassNoticerTest.java @@ -4,9 +4,9 @@ import com.redhat.insights.InsightsCustomScheduledExecutor; import com.redhat.insights.InsightsReportController; import com.redhat.insights.InsightsScheduler; +import com.redhat.insights.agent.doubles.MockInsightsConfiguration; +import com.redhat.insights.agent.doubles.NoopInsightsLogger; import com.redhat.insights.config.InsightsConfiguration; -import com.redhat.insights.doubles.MockInsightsConfiguration; -import com.redhat.insights.doubles.NoopInsightsLogger; import com.redhat.insights.http.InsightsHttpClient; import com.redhat.insights.jars.JarInfo; import com.redhat.insights.logging.InsightsLogger; diff --git a/src/test/java/com/redhat/insights/doubles/MockInsightsConfiguration.java b/src/test/java/com/redhat/insights/agent/doubles/MockInsightsConfiguration.java similarity index 99% rename from src/test/java/com/redhat/insights/doubles/MockInsightsConfiguration.java rename to src/test/java/com/redhat/insights/agent/doubles/MockInsightsConfiguration.java index e3d7745..311e09d 100644 --- a/src/test/java/com/redhat/insights/doubles/MockInsightsConfiguration.java +++ b/src/test/java/com/redhat/insights/agent/doubles/MockInsightsConfiguration.java @@ -1,5 +1,5 @@ /* Copyright (C) Red Hat 2023 */ -package com.redhat.insights.doubles; +package com.redhat.insights.agent.doubles; import com.redhat.insights.config.DefaultInsightsConfiguration; import com.redhat.insights.config.InsightsConfiguration; diff --git a/src/test/java/com/redhat/insights/doubles/NoopInsightsLogger.java b/src/test/java/com/redhat/insights/agent/doubles/NoopInsightsLogger.java similarity index 93% rename from src/test/java/com/redhat/insights/doubles/NoopInsightsLogger.java rename to src/test/java/com/redhat/insights/agent/doubles/NoopInsightsLogger.java index cc58998..0144758 100644 --- a/src/test/java/com/redhat/insights/doubles/NoopInsightsLogger.java +++ b/src/test/java/com/redhat/insights/agent/doubles/NoopInsightsLogger.java @@ -1,5 +1,5 @@ /* Copyright (C) Red Hat 2023 */ -package com.redhat.insights.doubles; +package com.redhat.insights.agent.doubles; import com.redhat.insights.logging.InsightsLogger;