Created
October 24, 2025 19:46
-
-
Save octavioranieri/b6e05a3659e4dd7679f20713f92068b9 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| import org.apache.pekko.http.scaladsl.model.headers.BasicHttpCredentials | |
| import com.fasterxml.jackson.databind.node.ObjectNode | |
| import no.found.bootstrap.BootstrapUtils | |
| import no.found.json._ | |
| import no.found.util.Secrets.generateRandomString | |
| import no.found.zookeeper.CloudResourceModel._ | |
| import no.found.zookeeper.models._ | |
| import no.found.zookeeper.models.clusters._ | |
| import no.found.zookeeper.models.clusters.elasticsearch._ | |
| import no.found.zookeeper.models.services._ | |
| import org.mindrot.jbcrypt.BCrypt | |
| import scala.concurrent._ | |
| import scala.concurrent.duration._ | |
| import no.found.syntax.JsonSyntax._ | |
| // IMPORTANT | |
| // Before running, please make sure you have a logging-and-metrics deployment with system_owned property set to true | |
| def getElasticsearchAndKibanaIds(): (String, String) = { | |
| val deployments = zk"/deployments".list().result().get.values | |
| val loggingAndMetricsDeploymentNode = deployments.find { deployment => | |
| val name = zk"${deployment.path}".read().result().get.value.path("name") | |
| name.asText() == "logging-and-metrics" | |
| } | |
| val loggingAndMetricsObjectNode = loggingAndMetricsDeploymentNode.get.read().result().get.value | |
| val deploymentResources = loggingAndMetricsObjectNode.path("resources").as[List[ObjectNode]] | |
| val loggingAndMetricsElasticsearchClusterId = deploymentResources.find( _.path("kind").asText() == "elasticsearch").map(_.path("id")).map(_.asText()).get | |
| println(s"The logging-and-metrics' cluster's Elasticsearch ID is $loggingAndMetricsElasticsearchClusterId") | |
| val loggingAndMetricsKibanaId = deploymentResources.find( _.path("kind").asText() == "kibana").map(_.path("id")).map(_.asText()).get | |
| println(s"The logging-and-metrics' cluster's Kibana ID is $loggingAndMetricsKibanaId") | |
| (loggingAndMetricsElasticsearchClusterId, loggingAndMetricsKibanaId) | |
| } | |
| def rebuildLoggingMetrics(): Unit = { | |
| val (elasticsearchClusterId, kibanaClusterId) = getElasticsearchAndKibanaIds() | |
| // That's in order for the ApplyElasticsearchSystemClusterAssets and ApplyKibanaSystemClusterAssets constructor steps to work: | |
| val metricbeatSettingsAfterInitialUpdate = zk"/services/metricbeat/settings".update(settingsObjNode => { | |
| settingsObjNode.put("cluster_id", elasticsearchClusterId) | |
| settingsObjNode.put("kibana_cluster_id", kibanaClusterId) | |
| }).result().get.value | |
| println(s"Initial update of metricbeat settings to point to the logging-and-metrics cluster: ${metricbeatSettingsAfterInitialUpdate}.") | |
| println("Now stop for a moment and go apply a plan on the logging-and-metrics cluster. Check the constructor logs for traces of ApplyElasticsearchSystemClusterAssets and ApplyKibanaSystemClusterAssets.") | |
| scala.io.StdIn.readLine() | |
| println("Just checking - type something again if you want to continue ;-)") | |
| scala.io.StdIn.readLine() | |
| val cluster = ElasticsearchCluster(elasticsearchClusterId) | |
| val (clusterSettings, _) = Await.result(cluster.getData(), 1.minute) | |
| val bootstrapConfig = BootstrapUtils.newTemporaryShieldAdminUser | |
| ShieldConfigUtils.injectUserIntoClusterMetadata( | |
| bootstrapConfig, | |
| clusterSettings | |
| )(mapper, ToJson.DefaultOptions) | |
| val ingestUser = ShieldUser.defaultLoggingAndMetricsUsername | |
| val ingestPassword = generateRandomString(32) | |
| val ingestConfig = ShieldUser( | |
| username = ingestUser, | |
| password = Some(ingestPassword), | |
| passwordHash = BCrypt.hashpw(ingestPassword, BCrypt.gensalt()), | |
| roles = List(ShieldUser.defaultLoggingAndMetricsRole), | |
| validUntil = None | |
| ) | |
| ShieldConfigUtils.injectUserIntoClusterMetadata( | |
| ingestConfig, | |
| clusterSettings | |
| )(mapper, ToJson.DefaultOptions) | |
| val consoleUser = ShieldUser.defaultLoggingAndMetricsConsoleAPIUsername | |
| val consolePassword = generateRandomString(32) | |
| val consoleConfig = ShieldUser( | |
| username = consoleUser, | |
| password = Some(consolePassword), | |
| passwordHash = BCrypt.hashpw(consolePassword, BCrypt.gensalt()), | |
| roles = List(ShieldUser.defaultLoggingAndMetricsConsoleAPIRole), | |
| validUntil = None | |
| ) | |
| ShieldConfigUtils.injectUserIntoClusterMetadata( | |
| consoleConfig.copy(password = None), | |
| clusterSettings | |
| )(mapper, ToJson.DefaultOptions) | |
| Await.result(cluster.updateData(_ => clusterSettings, None), 1.minute) | |
| val serviceSettings = new ServiceSettings( | |
| ingestUser, | |
| ingestPassword, | |
| "containerhost:9244", | |
| cluster.name, | |
| Some(kibanaClusterId) | |
| ).toJson(mapper) | |
| val filebeatSettings = zk"/services/filebeat/settings".update(_ => serviceSettings).result().get.value | |
| println(s"Updated filebeat settings: $filebeatSettings") | |
| val metricbeatSettings = zk"/services/metricbeat/settings".update(_ => serviceSettings).result().get.value | |
| println(s"Updated metricbeat settings: $metricbeatSettings") | |
| val allocatorMetricbeatSettings = zk"/services/allocator-metricbeat/settings".update(_ => serviceSettings).result().get.value | |
| println(s"Updated allocator-metricbeat settings: $allocatorMetricbeatSettings") | |
| val adminconsoleSettings = zk"/services/adminconsole/settings".read().result().get.value | |
| val basicAuthCreds = BasicHttpCredentials(consoleConfig.username, consoleConfig.password.get) | |
| val lmSettings = adminconsoleSettings.path("found").path("adminconsole").path("regions").path("ece-region").path("metrics-cluster").path("additional_headers").asInstanceOf[ObjectNode] | |
| lmSettings.put("X-Found-Cluster", elasticsearchClusterId) | |
| lmSettings.put("Authorization", basicAuthCreds.value) | |
| val updatedAdminConsoleSettings = zk"/services/adminconsole/settings".update(_ => adminconsoleSettings).result().get.value | |
| println(s"Updated admin-console settings: $updatedAdminConsoleSettings") | |
| println("Logging and metrics data rebuilt") | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment