blob: d8f1ef0ceac62181926fe9864fedc3c535b01071 [file] [log] [blame]
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.googlesource.gerrit.plugins.analytics.wizard
import java.net.URL
import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Path}
import com.googlesource.gerrit.plugins.analytics.wizard.model.ETLConfig
trait ConfigWriter {
def write(outputPath: Path, out: String)
}
class ConfigWriterImpl extends ConfigWriter {
def write(outputPath: Path, out: String) {
Files.write(outputPath, out.getBytes(StandardCharsets.UTF_8))
}
}
case class AnalyticDashboardSetup(name: String,
dockerComposeYamlPath: Path,
gerritLocalUrl: URL,
etlConfig: ETLConfig)(implicit val writer: ConfigWriter) {
// Docker doesn't like container names with '/', hence the replace with '-'
// Furthermore timestamp has been added to avoid conflicts among container names, i.e.:
// A project named 'foo/bar' would be encoded as 'foo-bar' and thus its container
// would be potentially in conflict with another 'foo-bar' project's one
private val sanitisedName =
s"${name.replace("/", "-")}-${System.currentTimeMillis}"
private def analyticsArgs: String = {
val args = List(
Since(etlConfig.since.map(_.toString)),
Until(etlConfig.until.map(_.toString)),
ProjectPrefix(etlConfig.projectPrefix),
Aggregate(Some(etlConfig.aggregate.entryName)),
Password(etlConfig.password),
Username(etlConfig.username)
).filter(_.value.isDefined) mkString " "
s"$args --writeNotProcessedEventsTo file:///tmp/failed-events -e gitcommits"
}
private val dockerComposeTemplate = {
s"""
|version: '3'
|services:
|
| gerrit-analytics-etl-gitcommits:
| extra_hosts:
| - gerrit:${gerritLocalUrl.getHost}
| image: gerritforge/gerrit-analytics-etl-gitcommits:latest
| container_name: gerrit-analytics-etl-gitcommits
| environment:
| - ES_HOST=elasticsearch
| - GERRIT_URL=${gerritLocalUrl.getProtocol}://gerrit:${gerritLocalUrl.getPort}
| - ANALYTICS_ARGS=$analyticsArgs
| networks:
| - ek
| links:
| - elasticsearch
| depends_on:
| - elasticsearch
|
| dashboard-importer:
| image: gerritforge/analytics-dashboard-importer:latest
| networks:
| - ek
| links:
| - elasticsearch
| - kibana
|
| kibana:
| image: gerritforge/analytics-kibana:latest
| container_name: "kibana-for-${sanitisedName}-project"
| networks:
| - ek
| depends_on:
| - elasticsearch
| ports:
| - "5601:5601"
|
| elasticsearch:
| image: gerritforge/analytics-elasticsearch:latest
| container_name: "es-for-${sanitisedName}-project"
| networks:
| - ek
| environment:
| - ES_JAVA_OPTS=-Xmx1g -Xms1g
| - http.host=0.0.0.0
| - network.host=_site_
| - http.publish_host=_site_
| - http.cors.allow-origin=*
| - http.cors.enabled=true
|
| ports:
| - "9200:9200"
| - "9300:9300"
|networks:
| ek:
| driver: bridge
""".stripMargin
}
def createDashboardSetupFile(): Unit = {
writer.write(dockerComposeYamlPath, dockerComposeTemplate)
}
}
object AnalyticDashboardSetup {
implicit val writer = new ConfigWriterImpl()
}
sealed trait AnalyticsOption {
val name: String
val value: Option[String]
override def toString: String = s"$name ${value.getOrElse("")}"
}
case class Since(value: Option[String]) extends AnalyticsOption {
val name = "--since"
}
case class Until(value: Option[String]) extends AnalyticsOption {
val name = "--until"
}
case class ProjectPrefix(value: Option[String]) extends AnalyticsOption {
val name = "--prefix"
}
case class Aggregate(value: Option[String]) extends AnalyticsOption {
val name = "--aggregate"
}
case class Password(value: Option[String]) extends AnalyticsOption {
val name = "--password"
}
case class Username(value: Option[String]) extends AnalyticsOption {
val name = "--username"
}