diff --git a/apps/mini-runtime/src/main/java/com/akto/hybrid_runtime/EnvConfig.java b/apps/mini-runtime/src/main/java/com/akto/hybrid_runtime/EnvConfig.java new file mode 100644 index 0000000000..045e79ea07 --- /dev/null +++ b/apps/mini-runtime/src/main/java/com/akto/hybrid_runtime/EnvConfig.java @@ -0,0 +1,38 @@ +package com.akto.hybrid_runtime; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.akto.dto.deployment.DeploymentConfig; +import com.akto.dto.deployment.EnvVariable; + +public final class EnvConfig { + + private static final Map envMap = new HashMap<>(); + + private EnvConfig() {} + + public static void hydrate(DeploymentConfig deploymentConfig) { + envMap.clear(); + if (deploymentConfig == null) return; + List vars = deploymentConfig.getEnvVars(); + if (vars == null) return; + for (EnvVariable v : vars) { + if (v == null || v.getKey() == null) continue; + envMap.put(v.getKey(), v.getValue()); + } + } + + public static String get(String key, String defaultValue) { + String v = envMap.get(key); + if (v != null) return v; + String sys = System.getenv(key); + return sys != null ? sys : defaultValue; + } + + public static Map snapshot() { + return Collections.unmodifiableMap(envMap); + } +} diff --git a/apps/mini-runtime/src/main/java/com/akto/hybrid_runtime/Main.java b/apps/mini-runtime/src/main/java/com/akto/hybrid_runtime/Main.java index 1df4181ff6..de2d0ba855 100644 --- a/apps/mini-runtime/src/main/java/com/akto/hybrid_runtime/Main.java +++ b/apps/mini-runtime/src/main/java/com/akto/hybrid_runtime/Main.java @@ -77,6 +77,23 @@ private static void printL(Object o) { static boolean isDashboardInstance = false; + private static void initEnvConfig() { + try { + String deploymentId = System.getenv("DEPLOYMENT_ID"); + if (deploymentId == null || deploymentId.isEmpty()) return; + com.akto.dto.deployment.DeploymentConfig dc = dataActor.fetchDeploymentConfig(deploymentId); + EnvConfig.hydrate(dc); + try { + Map snapshot = EnvConfig.snapshot(); + dataActor.sendDeploymentConfig(deploymentId, snapshot); + } catch (Exception e) { + loggerMaker.errorAndAddToDb(e, "Failed to send deployment config after hydrate"); + } + } catch (Exception e) { + loggerMaker.errorAndAddToDb(e, "initEnvConfig failed: " + e.getMessage()); + } + } + public static boolean tryForCollectionName(String message) { boolean ret = false; try { @@ -253,6 +270,7 @@ public static String getLogTopicName() { // REFERENCE: https://www.oreilly.com/library/view/kafka-the-definitive/9781491936153/ch04.html (But how do we Exit?) public static void main(String[] args) { + initEnvConfig(); //String mongoURI = System.getenv("AKTO_MONGO_CONN");; String configName = System.getenv("AKTO_CONFIG_NAME"); String topicName = getTopicName(); diff --git a/libs/dao/src/main/java/com/akto/dto/deployment/DeploymentConfig.java b/libs/dao/src/main/java/com/akto/dto/deployment/DeploymentConfig.java new file mode 100644 index 0000000000..8fed7becc6 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/deployment/DeploymentConfig.java @@ -0,0 +1,39 @@ +package com.akto.dto.deployment; + +import org.bson.codecs.pojo.annotations.BsonId; +import com.akto.dao.context.Context; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +public class DeploymentConfig { + + @BsonId + private String id; + private String name; + private String type; + private List envVars; + private int createdTs; + private int lastUpdatedTs; + + public static final String ID = "_id"; + public static final String NAME = "name"; + public static final String TYPE = "type"; + public static final String ENV_VARS = "envVars"; + public static final String CREATED_TS = "createdTs"; + public static final String LAST_UPDATED_TS = "lastUpdatedTs"; + + public DeploymentConfig(String id, String name, String type, List envVars) { + this.id = id; + this.name = name; + this.type = type; + this.envVars = envVars; + this.createdTs = Context.now(); + this.lastUpdatedTs = Context.now(); + } +} \ No newline at end of file diff --git a/libs/dao/src/main/java/com/akto/dto/deployment/EnvVariable.java b/libs/dao/src/main/java/com/akto/dto/deployment/EnvVariable.java new file mode 100644 index 0000000000..6ee59ca4f0 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/deployment/EnvVariable.java @@ -0,0 +1,16 @@ +package com.akto.dto.deployment; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class EnvVariable { + private String key; + private String value; + private boolean editable; +} \ No newline at end of file diff --git a/libs/utils/src/main/java/com/akto/data_actor/ClientActor.java b/libs/utils/src/main/java/com/akto/data_actor/ClientActor.java index 6255768319..6c0c2ff316 100644 --- a/libs/utils/src/main/java/com/akto/data_actor/ClientActor.java +++ b/libs/utils/src/main/java/com/akto/data_actor/ClientActor.java @@ -114,6 +114,44 @@ public static String buildDbAbstractorUrl() { return dbAbsHost + "/api"; } + @Override + public DeploymentConfig fetchDeploymentConfig(String deploymentId) { + Map> headers = buildHeaders(); + String endpoint = url + "/fetchDeploymentConfig?deploymentId=" + deploymentId; + OriginalHttpRequest request = new OriginalHttpRequest(endpoint, "", "GET", null, headers, ""); + try { + OriginalHttpResponse response = ApiExecutor.sendRequestBackOff(request, true, null, false, null); + if (response.getStatusCode() != 200 || response.getBody() == null) { + loggerMaker.errorAndAddToDb("non 2xx in fetchDeploymentConfig", LoggerMaker.LogDb.RUNTIME); + return null; + } + BasicDBObject payloadObj = BasicDBObject.parse(response.getBody()); + BasicDBObject dcObj = (BasicDBObject) payloadObj.get("deploymentConfig"); + if (dcObj == null) return null; + return objectMapper.readValue(dcObj.toJson(), DeploymentConfig.class); + } catch (Exception e) { + loggerMaker.errorAndAddToDb("error in fetchDeploymentConfig " + e, LoggerMaker.LogDb.RUNTIME); + return null; + } + } + + @Override + public void sendDeploymentConfig(String deploymentId, Map envVars) { + Map> headers = buildHeaders(); + BasicDBObject obj = new BasicDBObject(); + obj.put("deploymentId", deploymentId); + obj.put("envVars", envVars); + OriginalHttpRequest request = new OriginalHttpRequest(url + "/sendDeploymentConfig", "", "POST", obj.toString(), headers, ""); + try { + OriginalHttpResponse response = ApiExecutor.sendRequestBackOff(request, true, null, false, null); + if (response.getStatusCode() != 200) { + loggerMaker.errorAndAddToDb("non 2xx in sendDeploymentConfig", LoggerMaker.LogDb.RUNTIME); + } + } catch (Exception e) { + loggerMaker.errorAndAddToDb("error in sendDeploymentConfig " + e, LoggerMaker.LogDb.RUNTIME); + } + } + public AccountSettings fetchAccountSettings() { AccountSettings acc = null; for (int i=0; i < 5; i++) { diff --git a/libs/utils/src/main/java/com/akto/data_actor/DataActor.java b/libs/utils/src/main/java/com/akto/data_actor/DataActor.java index 2e6aa13c11..cc2fc26667 100644 --- a/libs/utils/src/main/java/com/akto/data_actor/DataActor.java +++ b/libs/utils/src/main/java/com/akto/data_actor/DataActor.java @@ -4,6 +4,7 @@ import com.akto.dto.billing.Organization; import com.akto.dto.billing.Tokens; import com.akto.dto.dependency_flow.Node; +import com.akto.dto.deployment.DeploymentConfig; import com.akto.dto.filter.MergedUrls; import com.akto.dto.jobs.JobExecutorType; import com.akto.dto.jobs.JobParams; @@ -313,4 +314,9 @@ public abstract class DataActor { public abstract void updateMcpReconRequestStatus(String requestId, String status, int serversFound); public abstract void storeMcpReconResultsBatch(List serverDataList); + + // Deployment configuration + public abstract DeploymentConfig fetchDeploymentConfig(String deploymentId); + + public abstract void sendDeploymentConfig(String deploymentId, Map envVars); }