Automatically setup an analytics dashboard This plugin allows to add a step in the github gerrit workflow configuration to automatically setup an analytics dashboard. At the moment it is creating a customised docker-compose file that can be used to spin up the resuorces needed for the dashboard. Change-Id: If77502e0ff3b28355b87eed2e7fb0b65dbaf1eda
diff --git a/.gitignore b/.gitignore index 9c07d4a..b4790c7 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,2 +1,9 @@ *.class *.log +/bin/ +.project +.classpath +.settings/ +.idea +target +.DS_Store
diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..7b9e7ea --- /dev/null +++ b/build.sbt
@@ -0,0 +1,31 @@ +enablePlugins(GitVersioning) + +val gerritApiVersion = "2.15.1" +val pluginName = "analytics-wizard" + +git.useGitDescribe := true + +lazy val root = (project in file(".")) + .settings( + name := pluginName, + + scalaVersion := "2.12.5", + + libraryDependencies ++= Seq( + "com.google.inject" % "guice" % "3.0" % Provided, + "com.google.gerrit" % "gerrit-plugin-api" % gerritApiVersion % Provided withSources(), + "com.google.code.gson" % "gson" % "2.7" % Provided, + + "org.scalatest" %% "scalatest" % "3.0.4" % Test, + "net.codingwell" %% "scala-guice" % "4.1.0" % Test), + + assemblyJarName in assembly := s"$pluginName.jar", + + packageOptions in(Compile, packageBin) += Package.ManifestAttributes( + ("Gerrit-ApiType", "plugin"), + ("Gerrit-PluginName", pluginName), + ("Gerrit-Module", "com.googlesource.gerrit.plugins.analytics.wizard.Module"), + ("Implementation-Title", "Analytics plugin wizard") + ) + ) +
diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..9abea12 --- /dev/null +++ b/project/build.properties
@@ -0,0 +1 @@ +sbt.version=1.0.3
diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..45f9d0f --- /dev/null +++ b/project/plugins.sbt
@@ -0,0 +1,4 @@ +logLevel := Level.Warn +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") +addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.9.3") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4")
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetup.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetup.scala new file mode 100644 index 0000000..ada25a1 --- /dev/null +++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetup.scala
@@ -0,0 +1,64 @@ +// 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.io.PrintWriter + +trait ConfigWriter { + def write(filename: String, out: String) +} + +class ConfigWriterImpl extends ConfigWriter { + def write(filename: String, out: String) = { + val p = new PrintWriter(filename) + p.write(out) + p.close() + } +} + +case class AnalyticDashboardSetup(name: String, config: Option[String] = None)( + implicit val writer: ConfigWriter) { + + private val dockerComposeTemplate = { (name: String) => + s""" + |version: '3' + |services: + | kibana: + | build: kibana + | container_name: "kibana-for-${name}-project" + | environment: + | SERVER_BASEPATH: "/kibana" + | depends_on: + | - elasticsearch + | elasticsearch: + | build: elasticsearch + | container_name: "es-for-${name}-project" + | environment: + | - ES_JAVA_OPTS=-Xmx4g -Xms4g + | - http.host=0.0.0.0 + | volumes: + | - es-indexes:/usr/share/elasticsearch/data + """.stripMargin + } + + val configFileName = s"/tmp/docker-compose.${name}.yaml" + def createDashboardSetupFile(): Unit = { + writer.write(configFileName, dockerComposeTemplate(name)) + } + +} + +object AnalyticDashboardSetup { + implicit val writer = new ConfigWriterImpl() +}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticsWizardActions.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticsWizardActions.scala new file mode 100644 index 0000000..f0f6632 --- /dev/null +++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticsWizardActions.scala
@@ -0,0 +1,55 @@ +// 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 com.google.gerrit.extensions.restapi.{ + Response, + RestModifyView, + RestReadView +} +import com.google.gerrit.server.project.ProjectResource +import com.google.inject.Inject + +import scala.io.Source + +import AnalyticDashboardSetup.writer + +class GetAnalyticsStack @Inject()() extends RestReadView[ProjectResource] { + override def apply( + resource: ProjectResource): Response[AnalyticDashboardSetup] = { + + val projectName = resource.getControl.getProject.getName + Response.ok( + AnalyticDashboardSetup( + projectName, + Some( + Source + .fromFile(s"/tmp/docker-compose.${projectName}.yaml") + .getLines + .mkString))) + } +} + +class Input(var dashboardName: String) + +class PutAnalyticsStack @Inject()() + extends RestModifyView[ProjectResource, Input] { + override def apply(resource: ProjectResource, + input: Input): Response[String] = { + + val projectName = resource.getControl.getProject.getName + AnalyticDashboardSetup(projectName).createDashboardSetupFile() + Response.created(s"Dashboard configuration created for $projectName!") + } +}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/Module.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/Module.scala new file mode 100644 index 0000000..36d21dd --- /dev/null +++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/Module.scala
@@ -0,0 +1,31 @@ +// 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 com.google.gerrit.extensions.restapi.RestApiModule +import com.google.gerrit.server.project.ProjectResource.PROJECT_KIND +import com.google.inject.AbstractModule + +class Module extends AbstractModule { + + override protected def configure() { + install(new RestApiModule() { + override protected def configure() = { + get(PROJECT_KIND, "stack").to(classOf[GetAnalyticsStack]) + + put(PROJECT_KIND, "stack").to(classOf[PutAnalyticsStack]) + } + }) + } +}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetupSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetupSpec.scala new file mode 100644 index 0000000..717d213 --- /dev/null +++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetupSpec.scala
@@ -0,0 +1,21 @@ +package com.googlesource.gerrit.plugins.analytics.wizard + +import org.scalatest.{FlatSpec, Matchers} + +class AnalyticDashboardSetupSpec extends FlatSpec with Matchers { + behavior of "AnalyticDashboardSetup" + + it should "create a config file with correct name" in { + var gotFilename: Option[String] = None + class MockWriter extends ConfigWriter { + override def write(filename: String, out: String): Unit = { + gotFilename = Some(filename) + } + } + implicit val writer = new MockWriter() + + val ads = AnalyticDashboardSetup("aProject") + ads.createDashboardSetupFile() + gotFilename shouldBe Some(ads.configFileName) + } +}