# VinylDNS
-VinylDNS is a vendor agnostic front-end for enabling self-service DNS and streamlining DNS operations.
-VinylDNS manages millions of DNS records supporting thousands of engineers in production at [Comcast](http://www.comcast.com).
-The platform provides fine-grained access controls, auditing of all changes, a self-service user interface,
-secure RESTful API, and integration with infrastructure automation tools like Ansible and Terraform.
-It is designed to integrate with your existing DNS infrastructure, and provides extensibility to fit your installation.
+
+VinylDNS is a vendor-agnostic front-end for enabling self-service DNS and streamlining DNS operations. VinylDNS manages
+millions of DNS records supporting thousands of engineers in production at [Comcast](http://www.comcast.com). The
+platform provides fine-grained access controls, auditing of all changes, a self-service user interface, secure RESTful
+API, and integration with infrastructure automation tools like Ansible and Terraform. It is designed to integrate with
+your existing DNS infrastructure, and provides extensibility to fit your installation.
VinylDNS helps secure DNS management via:
+
- AWS Sig4 signing of all messages to ensure that the message that was sent was not altered in transit
- Throttling of DNS updates to rate limit concurrent updates against your DNS systems
- Encrypting user secrets and TSIG keys at rest and in-transit
- Recording every change made to DNS records and zones
Integration is simple with first-class language support including:
+
- Java
- Python
- Go
- JavaScript
## Table of Contents
+
- [Quickstart](#quickstart)
- [Code of Conduct](#code-of-conduct)
- [Developer Guide](#developer-guide)
@@ -42,10 +46,12 @@ Integration is simple with first-class language support including:
- [Credits](#credits)
## Quickstart
-Docker images for VinylDNS live on Docker Hub at .
-To start up a local instance of VinylDNS on your machine with docker:
-1. Ensure that you have [docker](https://docs.docker.com/install/) and [docker-compose](https://docs.docker.com/compose/install/)
+Docker images for VinylDNS live on Docker Hub at . To start up a local instance of
+VinylDNS on your machine with docker:
+
+1. Ensure that you have [docker](https://docs.docker.com/install/)
+ and [docker-compose](https://docs.docker.com/compose/install/)
1. Clone the repo: `git clone https://github.com/vinyldns/vinyldns.git`
1. Navigate to repo: `cd vinyldns`
1. Run `./quickstart/quickstart-vinyldns.sh`. This will start up the api at `localhost:9000` and the portal
@@ -76,7 +82,8 @@ endpoint `http://localhost:9000`
### Verifying Your Changes
-VinylDNS will synchronize with the DNS backend. For the Quickstart this should be running on port `19001` on `localhost`.
+VinylDNS will synchronize with the DNS backend. For the Quickstart this should be running on port `19001` on `localhost`
+.
To verify your changes, you can use a DNS resolution utility like `dig`
@@ -106,7 +113,7 @@ the record data we entered.
This project, and everyone participating in it, are governed by the [VinylDNS Code Of Conduct](CODE_OF_CONDUCT.md). By
participating, you agree to this Code. Please report any violations to the code of conduct to
-vinyldns-core@googlegroups.com.
+[vinyldns-core@googlegroups.com](mailto:vinyldns-core@googlegroups.com).
## Developer Guide
@@ -118,9 +125,10 @@ See the [Contributing Guide](CONTRIBUTING.md).
## Contact
-- If you have any security concerns please contact the maintainers directly vinyldns-core@googlegroups.com
+- If you have any security concerns please contact the maintainers directly [vinyldns-core@googlegroups.com](mailto:vinyldns-core@googlegroups.com)
## Maintainers and Contributors
+
The current maintainers (people who can merge pull requests) are:
- Ryan Emerle ([@remerle](https://github.com/remerle))
@@ -129,17 +137,25 @@ The current maintainers (people who can merge pull requests) are:
See [AUTHORS.md](AUTHORS.md) for the full list of contributors to VinylDNS.
-See [MAINTAINERS.md](MAINTAINERS.md) for documentation specific to maintainers
+See [MAINTAINERS.md](MAINTAINERS.md) for documentation specific to maintainers
## Credits
-VinylDNS would not be possible without the help of many other pieces of open source software. Thank you open source world!
-Initial development of DynamoDBHelper done by [Roland Kuhn](https://github.com/rkuhn) from https://github.com/akka/akka-persistence-dynamodb/blob/8d7495821faef754d97759f0d3d35ed18fc17cc7/src/main/scala/akka/persistence/dynamodb/journal/DynamoDBHelper.scala
+VinylDNS would not be possible without the help of many other pieces of open source software. Thank you open source
+world!
-Given the Apache 2.0 license of VinylDNS, we specifically want to call out the following libraries and their corresponding licenses shown below.
-- [logback-classic](https://github.com/qos-ch/logback) - [Eclipse Public License 1.0](https://www.eclipse.org/legal/epl-v10.html)
-- [logback-core](https://github.com/qos-ch/logback) - [Eclipse Public License 1.0](https://www.eclipse.org/legal/epl-v10.html)
-- [h2 database](http://h2database.com) - [Mozilla Public License, version 2.0](https://www.mozilla.org/MPL/2.0/)
-- [pureconfig](https://github.com/pureconfig/pureconfig) - [Mozilla Public License, version 2.0](https://www.mozilla.org/MPL/2.0/)
-- [pureconfig-macros](https://github.com/pureconfig/pureconfig) - [Mozilla Public License, version 2.0](https://www.mozilla.org/MPL/2.0/)
-- [junit](https://junit.org/junit4/) - [Eclipse Public License 1.0](https://www.eclipse.org/legal/epl-v10.html)
+Given the Apache 2.0 license of VinylDNS, we specifically want to call out the following libraries and their
+corresponding licenses shown below.
+
+- [logback-classic](https://github.com/qos-ch/logback)
+ - [Eclipse Public License 1.0](https://www.eclipse.org/legal/epl-v10.html)
+- [logback-core](https://github.com/qos-ch/logback)
+ - [Eclipse Public License 1.0](https://www.eclipse.org/legal/epl-v10.html)
+- [h2 database](http://h2database.com)
+ - [Mozilla Public License, version 2.0](https://www.mozilla.org/MPL/2.0/)
+- [pureconfig](https://github.com/pureconfig/pureconfig)
+ - [Mozilla Public License, version 2.0](https://www.mozilla.org/MPL/2.0/)
+- [pureconfig-macros](https://github.com/pureconfig/pureconfig)
+ - [Mozilla Public License, version 2.0](https://www.mozilla.org/MPL/2.0/)
+- [junit](https://junit.org/junit4/)
+ - [Eclipse Public License 1.0](https://www.eclipse.org/legal/epl-v10.html)
diff --git a/build.sbt b/build.sbt
index 318c3ac1d..a1af2654b 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,14 +1,12 @@
import CompilerOptions._
import Dependencies._
-import Resolvers._
import microsites._
import org.scalafmt.sbt.ScalafmtPlugin._
import scoverage.ScoverageKeys.{coverageFailOnMinimum, coverageMinimum}
+import scala.language.postfixOps
import scala.util.Try
-resolvers ++= additionalResolvers
-
lazy val IntegrationTest = config("it").extend(Test)
// settings that should be inherited by all projects
@@ -18,6 +16,7 @@ lazy val sharedSettings = Seq(
organizationName := "Comcast Cable Communications Management, LLC",
startYear := Some(2018),
licenses += ("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")),
+ maintainer := "VinylDNS Maintainers ",
scalacOptions ++= scalacOptionsByV(scalaVersion.value),
scalacOptions in (Compile, doc) += "-no-link-warnings",
// Use wart remover to eliminate code badness
@@ -64,7 +63,7 @@ lazy val apiSettings = Seq(
)
lazy val apiAssemblySettings = Seq(
- assemblyOutputPath in assembly := file("assembly/vinyldns.jar"),
+ assemblyOutputPath in assembly := file("artifacts/vinyldns-api.jar"),
test in assembly := {},
mainClass in assembly := Some("vinyldns.api.Boot"),
mainClass in reStart := Some("vinyldns.api.Boot"),
@@ -79,45 +78,11 @@ lazy val apiAssemblySettings = Seq(
}
)
-lazy val noPublishSettings = Seq(
- publish := {},
- publishLocal := {},
- publishArtifact := false
-)
-
-lazy val apiPublishSettings = Seq(
- publishArtifact := false,
- publishLocal := (publishLocal in Docker).value,
- publish := (publish in Docker).value
-)
-
-lazy val portalPublishSettings = Seq(
- publishArtifact := false,
- publishLocal := (publishLocal in Docker).value,
- publish := (publish in Docker).value,
- // for sbt-native-packager (docker) to exclude local.conf
- mappings in Universal ~= (_.filterNot {
- case (file, _) => file.getName.equals("local.conf")
- }),
- // for local.conf to be excluded in jars
- mappings in (Compile, packageBin) ~= (_.filterNot {
- case (file, _) => file.getName.equals("local.conf")
- })
-)
-
-lazy val pbSettings = Seq(
- PB.targets in Compile := Seq(
- PB.gens.java("2.6.1") -> (sourceManaged in Compile).value
- ),
- PB.protocVersion := "-v261"
-)
-
lazy val allApiSettings = Revolver.settings ++ Defaults.itSettings ++
apiSettings ++
sharedSettings ++
apiAssemblySettings ++
- testSettings ++
- apiPublishSettings
+ testSettings
lazy val api = (project in file("modules/api"))
.enablePlugins(JavaAppPackaging, AutomateHeaderPlugin)
@@ -146,8 +111,10 @@ lazy val coreBuildSettings = Seq(
name := "core",
// do not use unused params as NoOpCrypto ignores its constructor, we should provide a way
// to write a crypto plugin so that we fall back to a noarg constructor
- scalacOptions ++= scalacOptionsByV(scalaVersion.value).filterNot(_ == "-Ywarn-unused:params")
-) ++ pbSettings
+ scalacOptions ++= scalacOptionsByV(scalaVersion.value).filterNot(_ == "-Ywarn-unused:params"),
+ PB.targets in Compile := Seq(PB.gens.java("2.6.1") -> (sourceManaged in Compile).value),
+ PB.protocVersion := "-v261"
+)
lazy val corePublishSettings = Seq(
publishMavenStyle := true,
@@ -156,7 +123,6 @@ lazy val corePublishSettings = Seq(
false
},
autoAPIMappings := true,
- publish in Docker := {},
mainClass := None,
homepage := Some(url("https://vinyldns.io")),
scmInfo := Some(
@@ -233,42 +199,47 @@ val checkJsHeaders =
val createJsHeaders =
TaskKey[Unit]("createJsHeaders", "Runs script to prepend APL 2.0 license headers to files")
+lazy val portalSettings = Seq(
+ libraryDependencies ++= portalDependencies,
+ routesGenerator := InjectedRoutesGenerator,
+ coverageExcludedPackages := ";views.html.*;router.*;controllers\\.javascript.*;.*Reverse.*",
+ javaOptions in Test += "-Dconfig.file=conf/application-test.conf",
+ // ads the version when working locally with sbt run
+ PlayKeys.devSettings += "vinyldns.base-version" -> (version in ThisBuild).value,
+ // adds an extra classpath to the portal loading so we can externalize jars, make sure to create the lib_extra
+ // directory and lay down any dependencies that are required when deploying
+ scriptClasspath in bashScriptDefines ~= (cp => cp :+ "lib_extra/*"),
+ mainClass in reStart := None,
+ // we need to filter out unused for the portal as the play framework needs a lot of unused things
+ scalacOptions ~= { opts =>
+ opts.filterNot(p => p.contains("unused"))
+ },
+ // runs our prepare portal process
+ preparePortal := {
+ import scala.sys.process._
+ "./modules/portal/prepare-portal.sh" !
+ },
+ checkJsHeaders := {
+ import scala.sys.process._
+ "./utils/add-license-headers.sh -d=modules/portal/public/lib -f=js -c" !
+ },
+ createJsHeaders := {
+ import scala.sys.process._
+ "./utils/add-license-headers.sh -d=modules/portal/public/lib -f=js" !
+ },
+
+ // Change the path of the output to artifacts/vinyldns-portal.zip
+ target in Universal := file("artifacts/"),
+ packageName in Universal := "vinyldns-portal"
+)
+
lazy val portal = (project in file("modules/portal"))
.enablePlugins(PlayScala, AutomateHeaderPlugin)
.settings(sharedSettings)
.settings(testSettings)
- .settings(portalPublishSettings)
+ .settings(portalSettings)
.settings(
name := "portal",
- libraryDependencies ++= portalDependencies,
- routesGenerator := InjectedRoutesGenerator,
- coverageExcludedPackages := ";views.html.*;router.*;controllers\\.javascript.*;.*Reverse.*",
- javaOptions in Test += "-Dconfig.file=conf/application-test.conf",
- // ads the version when working locally with sbt run
- PlayKeys.devSettings += "vinyldns.base-version" -> (version in ThisBuild).value,
- // adds an extra classpath to the portal loading so we can externalize jars, make sure to create the lib_extra
- // directory and lay down any dependencies that are required when deploying
- scriptClasspath in bashScriptDefines ~= (cp => cp :+ "lib_extra/*"),
- mainClass in reStart := None,
- // we need to filter out unused for the portal as the play framework needs a lot of unused things
- scalacOptions ~= { opts =>
- opts.filterNot(p => p.contains("unused"))
- },
- // runs our prepare portal process
- preparePortal := {
- import scala.sys.process._
- "./modules/portal/prepare-portal.sh" !
- },
- checkJsHeaders := {
- import scala.sys.process._
- "./utils/add-license-headers.sh -d=modules/portal/public/lib -f=js -c" !
- },
- createJsHeaders := {
- import scala.sys.process._
- "./utils/add-license-headers.sh -d=modules/portal/public/lib -f=js" !
- },
- // change the name of the output to portal.zip
- packageName in Universal := "portal"
)
.dependsOn(mysql)
diff --git a/build/assemble_api_jar.sh b/build/assemble_api.sh
old mode 100755
new mode 100644
similarity index 73%
rename from build/assemble_api_jar.sh
rename to build/assemble_api.sh
index 5e7c6f34b..ab9970ce6
--- a/build/assemble_api_jar.sh
+++ b/build/assemble_api.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#
-# This script will build the vinyldns.jar file using Docker. The file will
-# be placed in the configured location (currently `assembly/` off of the root)
+# This script will build the vinyldns-api.jar file using Docker. The file will
+# be placed in the configured location (currently `artifacts/` off of the root)
#
set -euo pipefail
@@ -11,7 +11,7 @@ DIR=$(
)
usage() {
- echo "USAGE: assemble_jar.sh [options]"
+ echo "USAGE: assemble_api.sh [options]"
echo -e "\t-n, --no-clean do no perform a clean before assembling the jar"
echo -e "\t-u, --update update the underlying docker image"
}
@@ -37,6 +37,7 @@ done
if ! [[ $SKIP_CLEAN -eq 1 ]]; then
"${DIR}/deep_clean.sh"
+ rm "${DIR}/../artifacts/vinyldns-api.jar" &> /dev/null || true
fi
if [[ $UPDATE_DOCKER -eq 1 ]]; then
@@ -44,5 +45,5 @@ if [[ $UPDATE_DOCKER -eq 1 ]]; then
docker pull vinyldns/build:base-test-integration
fi
-echo "Building VinylDNS API jar file"
+echo "Building VinylDNS API artifact"
docker run -i --rm -e RUN_SERVICES=none -v "${DIR}/..:/build" vinyldns/build:base-test-integration -- sbt 'api/assembly'
diff --git a/build/assemble_portal.sh b/build/assemble_portal.sh
new file mode 100644
index 000000000..ad10103c0
--- /dev/null
+++ b/build/assemble_portal.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+#
+# This script will build the vinyldns-portal.zip file using Docker. The file will
+# be placed in the configured location (currently `artifacts/` off of the root)
+#
+set -euo pipefail
+
+DIR=$(
+ cd "$(dirname "$0")"
+ pwd -P
+)
+
+usage() {
+ echo "USAGE: assemble_portal.sh [options]"
+ echo -e "\t-n, --no-clean do no perform a clean before assembling the jar"
+ echo -e "\t-u, --update update the underlying docker image"
+}
+
+SKIP_CLEAN=0
+UPDATE_DOCKER=0
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --no-clean | -n)
+ SKIP_CLEAN=1
+ shift
+ ;;
+ --update | -u)
+ UPDATE_DOCKER=1
+ shift
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+if ! [[ $SKIP_CLEAN -eq 1 ]]; then
+ "${DIR}/deep_clean.sh"
+ rm "${DIR}/../artifacts/vinyldns-portal.zip" &> /dev/null || true
+ rm -rf "${DIR}/../artifacts/scripts" &> /dev/null || true
+fi
+
+if [[ $UPDATE_DOCKER -eq 1 ]]; then
+ echo "Pulling latest version of 'vinyldns/build:base-test-integration'"
+ docker pull vinyldns/build:base-test-integration
+fi
+
+echo "Building VinylDNS Portal artifact"
+docker run -i --rm -e RUN_SERVICES=none -v "${DIR}/..:/build" vinyldns/build:base-test-integration -- sbt 'portal/dist'
diff --git a/build/docker/README.md b/build/docker/README.md
index b913d5d62..e195766f3 100644
--- a/build/docker/README.md
+++ b/build/docker/README.md
@@ -60,9 +60,9 @@ The default build for vinyldns api assumes an **ALL MYSQL** installation.
it is set as part of the container build
**Volumes**
-- `/opt/docker/conf/` - if you need to have your own application config file. This is **MANDATORY** for
+- `/opt/vinyldns/conf/` - if you need to have your own application config file. This is **MANDATORY** for
any production environments. Typically, you will add your own `application.conf` file in here with your settings.
-- `/opt/docker/lib_extra/` - if you need to have additional jar files available to your VinylDNS instance.
+- `/opt/vinyldns/lib_extra/` - if you need to have additional jar files available to your VinylDNS instance.
Rarely used, but if you want to bring your own message queue or database you can put the `jar` files there
### vinyldns/portal
@@ -74,7 +74,7 @@ The default build for vinyldns portal assumes an **ALL MYSQL** installation.
it is set as part of the container build
**Volumes**
-- `/opt/docker/conf/` - if you need to have your own application config file. This is **MANDATORY** for
+- `/opt/vinyldns/conf/` - if you need to have your own application config file. This is **MANDATORY** for
any production environments. Typically, you will add your own `application.conf` file in here with your settings.
-- `/opt/docker/lib_extra/` - if you need to have additional jar files available to your VinylDNS instance.
+- `/opt/vinyldns/lib_extra/` - if you need to have additional jar files available to your VinylDNS instance.
Rarely used, but if you want to bring your own message queue or database you can put the `jar` files there
diff --git a/build/docker/api/Dockerfile b/build/docker/api/Dockerfile
index 3a228f48e..89ea8d028 100644
--- a/build/docker/api/Dockerfile
+++ b/build/docker/api/Dockerfile
@@ -5,7 +5,7 @@ WORKDIR /build
## Run the build if we don't already have a vinyldns.jar
RUN mkdir -p /opt/vinyldns/conf && \
- if [ -f assembly/vinyldns.jar ]; then cp assembly/vinyldns.jar /opt/vinyldns/; fi && \
+ if [ -f artifacts/vinyldns-api.jar ]; then cp artifacts/vinyldns-api.jar /opt/vinyldns/; fi && \
if [ ! -f /opt/vinyldns/vinyldns.jar ]; then \
env SBT_OPTS="-XX:+UseConcMarkSweepGC -Xmx4G -Xms1G" \
sbt -Dbuild.scalafmtOnCompile=false -Dbuild.lintOnCompile=fase ";project api;coverageOff;assembly" \
@@ -16,21 +16,24 @@ FROM adoptopenjdk/openjdk11:jdk-11.0.8_10-alpine
ARG DOCKER_FILE_PATH
ARG VINYLDNS_VERSION
-RUN apk add --update --no-cache bash && mkdir -p /opt/vinyldns/lib_extra
+RUN test -n "VINYLDNS_VERSION" || (echo "VINYLDNS_VERSION not set" && false) && \
+ test -n "DOCKER_FILE_PATH" || (echo "DOCKER_FILE_PATH not set" && false) && \
+ apk add --update --no-cache bash && \
+ mkdir -p /opt/vinyldns/lib_extra && \
+ echo "${VINYLDNS_VERSION}" > /opt/vinyldns/version
COPY --from=base-build /opt/vinyldns /opt/vinyldns
COPY ${DOCKER_FILE_PATH}/application.conf /opt/vinyldns/conf
COPY ${DOCKER_FILE_PATH}/logback.xml /opt/vinyldns/conf
-RUN echo "${VINYLDNS_VERSION}" > /opt/vinyldns/conf/version
-
# Mount the volume for config file and lib extras
VOLUME ["/opt/vinyldns/lib_extra/", "/opt/vinyldns/conf/"]
EXPOSE 9000
-ENTRYPOINT ["/bin/bash", "-c", "java -Dconfig.file=/opt/vinyldns/conf/application.conf \
+ENV JVM_OPTS=""
+ENTRYPOINT ["/bin/bash", "-c", "java ${JVM_OPTS} -Dconfig.file=/opt/vinyldns/conf/application.conf \
-Dlogback.configurationFile=/opt/vinyldns/conf/logback.xml \
- -Dvinyldns.version=$(cat /opt/vinyldns/conf/version) \
+ -Dvinyldns.version=$(cat /opt/vinyldns/version) \
-cp /opt/vinyldns/lib_extra/* \
-jar /opt/vinyldns/vinyldns.jar" ]
diff --git a/build/docker/api/Makefile b/build/docker/api/Makefile
index d0eb622c2..f9ba5fd59 100644
--- a/build/docker/api/Makefile
+++ b/build/docker/api/Makefile
@@ -10,7 +10,7 @@ ifneq ($(REQ_MAKE_VER),$(firstword $(sort $(MAKE_VERSION) $(REQ_MAKE_VER))))
endif
# Extract arguments for `make run`
-EXTRACT_ARGS=true
+EXTRACT_ARGS=false
ifeq (run,$(firstword $(MAKECMDGOALS)))
EXTRACT_ARGS=true
endif
@@ -18,8 +18,8 @@ ifeq ($(EXTRACT_ARGS),true)
# use the rest as arguments for "run"
WITH_ARGS ?= $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
endif
-ifdef $(WITH_ARGS)
- ARG_SEPARATOR=--
+ifneq ($(WITH_ARGS),)
+ ARG_SEPARATOR=--
endif
%:
@@ -40,7 +40,7 @@ build:
run:
@set -euo pipefail
docker network create --driver bridge vinyldns_net &> /dev/null || true
- test -t 1 && USE_TTY="-t"
+ USE_TTY="" && test -t 1 && USE_TTY="-t"
docker run -i $${USE_TTY} --rm --env-file "$(ROOT_DIR)/../.env" --network vinyldns_net $(DOCKER_PARAMS) -v "$$(pwd)/:/opt/vinyldns/conf/" -p 9000:9000 $(IMAGE_NAME):$(IMAGE_TAG) $(ARG_SEPARATOR) $(WITH_ARGS)
publish: build
diff --git a/build/docker/api/application.conf b/build/docker/api/application.conf
index 2e9be4d49..201018765 100644
--- a/build/docker/api/application.conf
+++ b/build/docker/api/application.conf
@@ -1,5 +1,4 @@
vinyldns {
-
base-version = "0.0.0-local-dev"
version = ${vinyldns.base-version} # default to the base version if not overridden
version = ${?VINYLDNS_VERSION} # override the base version via env var
@@ -125,6 +124,7 @@ vinyldns {
class-name = ${?EMAIL_CLASS_NAME}
settings = {
from = "VinylDNS "
+ from = ${?EMAIL_FROM}
}
}
@@ -161,12 +161,13 @@ vinyldns {
"ns1.parent.com4."
]
+ # Note: This MUST match the Portal or strange errors will ensue, NoOpCrypto should not be used for production
crypto {
type = "vinyldns.core.crypto.NoOpCrypto"
+ type = ${?CRYPTO_TYPE}
+ secret = ${?CRYPTO_SECRET}
}
- data-stores = ["mysql"]
-
mysql {
settings {
# JDBC Settings, these are all values in scalikejdbc-config, not our own
@@ -184,49 +185,11 @@ vinyldns {
user = ${?JDBC_USER}
password = ""
password = ${?JDBC_PASSWORD}
- # see https://github.com/brettwooldridge/HikariCP
- connection-timeout-millis = 1000
- idle-timeout = 10000
- max-lifetime = 600000
- maximum-pool-size = 20
- minimum-idle = 20
- register-mbeans = true
- }
- # Repositories that use this data store are listed here
- repositories {
- zone {
- # no additional settings for now
- }
- batch-change {
- # no additional settings for now
- }
- user {
-
- }
- record-set {
-
- }
- group {
-
- }
- membership {
-
- }
- group-change {
-
- }
- zone-change {
-
- }
- record-change {
-
- }
}
}
backends = []
-
# FQDNs / IPs that cannot be modified via VinylDNS
# regex-list used for all record types except PTR
# ip-list used exclusively for PTR records
@@ -343,3 +306,7 @@ akka.http {
illegal-header-warnings = on
}
}
+
+# You can provide configuration overrides via local.conf if you don't want to replace everything in
+# this configuration file
+include "local.conf"
diff --git a/build/docker/portal/Dockerfile b/build/docker/portal/Dockerfile
index d51332172..e1194a574 100644
--- a/build/docker/portal/Dockerfile
+++ b/build/docker/portal/Dockerfile
@@ -1,37 +1,47 @@
-FROM vinyldns/build:base-build-portal as builder
+FROM vinyldns/build:base-build-portal as base-build
ARG VINYLDNS_VERSION
+COPY . /build
+WORKDIR /build
-COPY . /vinyldns
-
-WORKDIR /vinyldns
-RUN cp /build/node_modules.tar.xz /vinyldns/modules/portal && \
- cd /vinyldns/modules/portal && tar Jxf node_modules.tar.xz && \
- cd /vinyldns
-
-RUN sbt "set version in ThisBuild := \"${VINYLDNS_VERSION}\"; project portal; preparePortal"
-RUN sbt "set version in ThisBuild := \"${VINYLDNS_VERSION}\"; project portal; universal:packageZipTarball"
+RUN mkdir -p /opt/vinyldns/conf && \
+ if [ -f artifacts/vinyldns-portal.zip ]; then \
+ unzip artifacts/vinyldns-portal.zip -d /opt/vinyldns && \
+ mv /opt/vinyldns/vinyldns-portal/{lib,share,conf} /opt/vinyldns && \
+ rm -rf /opt/vinyldns/vinyldns-portal*; \
+ fi && \
+ if [ ! -f /opt/vinyldns/lib/vinyldns.portal*.jar ]; then \
+ cp /build/node_modules.tar.xz /build/modules/portal && \
+ cd /build/modules/portal && tar Jxf node_modules.tar.xz && \
+ cd /build && \
+ modules/portal/prepare-portal.sh && \
+ sbt "set version in ThisBuild := \"${VINYLDNS_VERSION}\"; project portal; dist" && \
+ unzip artifacts/vinyldns-portal.zip -d /opt/vinyldns && \
+ mv /opt/vinyldns/vinyldns-portal/{lib,share,conf} /opt/vinyldns && \
+ rm -rf /opt/vinyldns/vinyldns-portal*; \
+ fi
FROM adoptopenjdk/openjdk11:jdk-11.0.8_10-alpine
ARG DOCKER_FILE_PATH
ARG VINYLDNS_VERSION
-RUN test -n "VINYLDNS_VERSION" || (echo "VINYLDNS_VERSION not set" && false)
-COPY --from=builder /vinyldns/modules/portal/target/universal/portal.tgz /
-
-RUN apk add --update --no-cache bash && \
+RUN test -n "VINYLDNS_VERSION" || (echo "VINYLDNS_VERSION not set" && false) && \
+ test -n "DOCKER_FILE_PATH" || (echo "DOCKER_FILE_PATH not set" && false) && \
+ apk add --update --no-cache bash && \
mkdir -p /opt/vinyldns/lib_extra && \
- tar -xzf /portal.tgz && \
- rm /portal.tgz && \
- mv /portal/* /opt/vinyldns && \
- echo "${VINYLDNS_VERSION}" > /opt/vinyldns/conf/version
+ echo "${VINYLDNS_VERSION}" > /opt/vinyldns/version
+
+COPY --from=base-build /opt/vinyldns /opt/vinyldns
+COPY ${DOCKER_FILE_PATH}/application.conf /opt/vinyldns/conf
+COPY ${DOCKER_FILE_PATH}/logback.xml /opt/vinyldns/conf
-COPY ${DOCKER_FILE_PATH}/application.conf /opt/vinyldns/conf/
VOLUME ["/opt/vinyldns/lib_extra/", "/opt/vinyldns/conf/"]
EXPOSE 9001
-ENTRYPOINT ["/bin/bash","-c", "java -Dvinyldns.version=$(cat /opt/vinyldns/conf/version) \
- -Dconfig.file=/opt/vinyldns/conf/application.conf \
- -cp /opt/vinyldns/conf:/opt/vinyldns/lib/*:/opt/vinyldns/lib_extra/* \
- play.core.server.ProdServerStart"]
+ENV JVM_OPTS=""
+ENTRYPOINT ["/bin/bash","-c", "java ${JVM_OPTS} -Dvinyldns.version=$(cat /opt/vinyldns/version) \
+ -Dlogback.configurationFile=/opt/vinyldns/conf/logback.xml \
+ -Dconfig.file=/opt/vinyldns/conf/application.conf \
+ -cp /opt/vinyldns/conf:/opt/vinyldns/lib/*:/opt/vinyldns/lib_extra/* \
+ play.core.server.ProdServerStart"]
diff --git a/build/docker/portal/Makefile b/build/docker/portal/Makefile
index eaad9a558..be2b8b2a5 100644
--- a/build/docker/portal/Makefile
+++ b/build/docker/portal/Makefile
@@ -10,7 +10,7 @@ ifneq ($(REQ_MAKE_VER),$(firstword $(sort $(MAKE_VERSION) $(REQ_MAKE_VER))))
endif
# Extract arguments for `make run`
-EXTRACT_ARGS=true
+EXTRACT_ARGS=false
ifeq (run,$(firstword $(MAKECMDGOALS)))
EXTRACT_ARGS=true
endif
@@ -18,8 +18,8 @@ ifeq ($(EXTRACT_ARGS),true)
# use the rest as arguments for "run"
WITH_ARGS ?= $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
endif
-ifdef $(WITH_ARGS)
- ARG_SEPARATOR=--
+ifneq ($(WITH_ARGS),)
+ ARG_SEPARATOR=--
endif
%:
@@ -44,8 +44,8 @@ build:
run:
@set -euo pipefail
docker network create --driver bridge vinyldns_net &> /dev/null || true
- test -t 1 && USE_TTY="-t"
- docker run -i $${USE_TTY} --rm --network vinyldns_net --env-file "$(ROOT_DIR)/../.env" $(DOCKER_PARAMS) -v "$$(pwd)/application.conf:/opt/vinyldns/conf/application.conf" -p 9001:9001 $(IMAGE_NAME):$(IMAGE_TAG) $(ARG_SEPARATOR) $(WITH_ARGS)
+ USE_TTY="" && test -t 1 && USE_TTY="-t"
+ docker run -i $${USE_TTY} --rm --network vinyldns_net --env-file "$(ROOT_DIR)/../.env" $(DOCKER_PARAMS) -v "$$(pwd)/application.conf:/opt/vinyldns/conf/application.conf" -v "$$(pwd)/logback.xml:/opt/vinyldns/conf/logback.xml" -p 9001:9001 $(IMAGE_NAME):$(IMAGE_TAG) $(ARG_SEPARATOR) $(WITH_ARGS)
publish: build
@set -euo pipefail
diff --git a/build/docker/portal/application.conf b/build/docker/portal/application.conf
index 40ae2c83a..35c7809e1 100644
--- a/build/docker/portal/application.conf
+++ b/build/docker/portal/application.conf
@@ -18,7 +18,9 @@ LDAP {
]
context {
initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory"
+ initialContextFactory = ${?LDAP_INITIAL_CONTEXT_CLASS}
securityAuthentication = "simple"
+ securityAuthentication = ${?LDAP_SECURITY_AUTH}
# Note: The following assumes a purely docker setup, using container_name = vinyldns-ldap
providerUrl = "ldap://vinyldns-ldap:19004"
@@ -29,13 +31,17 @@ LDAP {
# company for example)
user-sync {
enabled = false
+ enabled = ${?USER_SYNC_ENABLED}
hours-polling-interval = 1
+ hours-polling-interval = ${?USER_SYNC_POLL_INTERVAL}
}
}
-# Note: This MUST match the API or strange errors will ensure, NoCrypto should not be used for production
+# Note: This MUST match the API or strange errors will ensue, NoOpCrypto should not be used for production
crypto {
type = "vinyldns.core.crypto.NoOpCrypto"
+ type = ${?CRYPTO_TYPE}
+ secret = ${?CRYPTO_SECRET}
}
http.port = 9001
@@ -43,20 +49,14 @@ http.port = ${?PORTAL_PORT}
data-stores = ["mysql"]
-# Note: The default mysql settings assume a local docker compose setup with mysql named vinyldns-mysql
-# follow the configuration guide to point to your mysql
-# Only 3 repositories are needed for portal: user, task, user-change
-mysql {
- repositories {
- user {
- }
- task {
- }
- user-change {
- }
- }
-}
+# Must be true to manage shared zones through the portal
+shared-display-enabled = true
+shared-display-enabled = ${?SHARED_ZONES_ENABLED}
# You generate this yourself following https://www.playframework.com/documentation/2.7.x/ApplicationSecret
-play.http.secret.key = "rpkTGtoJvLIdIV?WU=0@yW^x:pcEGyAt`^p/P3G0fpbj9:uDnD@caSjCDqA0@tB="
+play.http.secret.key = "changeme"
play.http.secret.key = ${?PLAY_HTTP_SECRET_KEY}
+
+# You can provide configuration overrides via local.conf if you don't want to replace everything in
+# this configuration file
+include "local.conf"
diff --git a/build/docker/portal/logback.xml b/build/docker/portal/logback.xml
new file mode 100644
index 000000000..f8a08e496
--- /dev/null
+++ b/build/docker/portal/logback.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ %d{"yyyy-MM-dd HH:mm:ss,SSS"} %coloredLevel - %logger - %message%n%xException
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/run_all_tests.sh b/build/run_all_tests.sh
index ea9312107..36cdc2c62 100755
--- a/build/run_all_tests.sh
+++ b/build/run_all_tests.sh
@@ -4,8 +4,8 @@ DIR=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
source "${DIR}/../utils/includes/terminal_colors.sh"
-if [ ! -d "${DIR}/../assembly" ] || [ ! -f "${DIR}/../assembly/vinyldns.jar" ]; then
- echo -e "${F_YELLOW}Warning:${F_RESET} you might want to run 'build/assemble_api_jar.sh' first to improve performance"
+if [ ! -d "${DIR}/../artifacts" ] || [ ! -f "${DIR}/../artifacts/vinyldns-api.jar" ]; then
+ echo -e "${F_YELLOW}Warning:${F_RESET} you might want to run 'build/assemble_api.sh' first to improve performance"
fi
echo "Running unit and integration tests..."
diff --git a/modules/docs/Makefile b/modules/docs/Makefile
index 05bde5c82..0076476ad 100644
--- a/modules/docs/Makefile
+++ b/modules/docs/Makefile
@@ -30,5 +30,5 @@ all: run
run:
@set -euo pipefail
cd ../..
- test -t 1 && USE_TTY="-t"
+ USE_TTY="" && test -t 1 && USE_TTY="-t"
docker run -i $${USE_TTY} --rm -p "4000:4000" -v "$$(pwd):/build" vinyldns/build:base-build-docs /bin/bash
diff --git a/modules/docs/src/main/mdoc/operator/setup-api.md b/modules/docs/src/main/mdoc/operator/setup-api.md
index a88cc5ce7..722650be1 100644
--- a/modules/docs/src/main/mdoc/operator/setup-api.md
+++ b/modules/docs/src/main/mdoc/operator/setup-api.md
@@ -29,9 +29,9 @@ purposes.
## Volume Mounts
The API exposes volumes that allow the user to customize the runtime. Those mounts include:
-* `/opt/docker/lib_extra` - place here additional jar files that need to be loaded into the classpath when the application starts up.
+* `/opt/vinyldns/lib_extra` - place here additional jar files that need to be loaded into the classpath when the application starts up.
This is used for "plugins" that are proprietary or not part of the standard build. All jar files here will be placed on the class path.
-* `/opt/docker/conf` - place an `application.conf` file here with your own custom settings. Once you have your config created,
+* `/opt/vinyldns/conf` - place an `application.conf` file here with your own custom settings. Once you have your config created,
place here.
## Ports
diff --git a/modules/docs/src/main/mdoc/operator/setup-portal.md b/modules/docs/src/main/mdoc/operator/setup-portal.md
index 527d75376..f16369c80 100644
--- a/modules/docs/src/main/mdoc/operator/setup-portal.md
+++ b/modules/docs/src/main/mdoc/operator/setup-portal.md
@@ -1,11 +1,11 @@
---
-layout: docs
-title: "Setup the Portal Server"
+layout: docs title: "Setup the Portal Server"
section: "operator_menu"
---
# Setup the Portal Server
-The Portal Server is the web UI for VinylDNS. To setup the Portal server, follow these steps:
+
+The Portal Server is the web UI for VinylDNS. To setup the Portal server, follow these steps:
1. [Setup API Server](setup-api.html)
1. [Setup LDAP](setup-ldap.html)
@@ -16,21 +16,32 @@ Once you have you pre-requisites ready, review the [Portal Configuration Guide](
your configuration file.
# Using the Portal Docker Image
+
The Portal server is provided as a [VinylDNS Portal Image](https://hub.docker.com/r/vinyldns/portal/).
The API server is _stateless_, allowing you to run multiple instances in multiple data centers for high-availability
purposes.
## Volume mounts
-* `/opt/docker/lib_extra` - place here additional jar files that need to be loaded into the classpath when the application starts up.
-This is used for "plugins" that are proprietary or not part of the standard build. All jar files here will be placed on the class path.
-* `/opt/docker/conf/application.conf` - to override default configuration settings. Follow the [Portal Configuration Guide](config-portal.html)
-* `/opt/docker/conf/application.ini` - to pass additional JVM options
-* `/opt/docker/conf/trustStore.jks` - to make available a custom trustStore, which has to be set in `/opt/docker/conf/application.ini` as `-Djavax.net.ssl.trustStore=/opt/docker/conf/trustStore.jks`
+
+* `/opt/vinyldns/lib_extra` - place here additional jar files that need to be loaded into the classpath when the
+ application starts up. This is used for "plugins" that are proprietary or not part of the standard build. All jar
+ files here will be placed on the class path.
+* `/opt/vinyldns/conf/application.conf` - to override default configuration settings. Follow
+ the [Portal Configuration Guide](config-portal.html)
## Configuring a custom Java trustStore
-To add a custom Java trustStore for LDAP certs, add the trustStore to `/opt/docker/conf/trustStore.jks`.
- Then add `-Djavax.net.ssl.trustStore=/opt/docker/conf/trustStore.jks` to `/opt/docker/conf/application.ini`.
+
+To add a custom Java trustStore for LDAP certs, add the trustStore to `/opt/vinyldns/conf/trustStore.jks`. Then
+add `-Djavax.net.ssl.trustStore=/opt/vinyldns/conf/trustStore.jks` to the `JVM_OPTS` environment variable for the
+container.
+
+Example:
+
+```text
+docker run -e JVM_OPTS="-Djavax.net.ssl.trustStore=/opt/vinyldns/conf/trustStore.jks" ...
+```
## Additional JVM parameters
-Additional JVM parameters can be added to `/opt/docker/conf/application.ini`
+
+Additional JVM parameters can be added to the `JVM_OPTS` environment variable
diff --git a/modules/portal/.gitignore b/modules/portal/.gitignore
index d788b9954..843786a95 100644
--- a/modules/portal/.gitignore
+++ b/modules/portal/.gitignore
@@ -4,13 +4,18 @@ __pycache__
/func_test/.virtualenv
node_modules/
public/bower_components/
-public/javascripts/
-public/stylesheets/
public/test_frameworks/
-public/custom/views.vinyl.js
package-lock.json
release.version
private
-public/gentelella
.bloop
.metals
+
+public/js/*
+!public/js/custom.js
+
+public/css/*
+!public/css/theme-overrides.css
+!public/css/vinyldns.css
+
+public/fonts
diff --git a/modules/portal/Gruntfile.js b/modules/portal/Gruntfile.js
index eb3ef53e8..b541d112e 100644
--- a/modules/portal/Gruntfile.js
+++ b/modules/portal/Gruntfile.js
@@ -1,88 +1,133 @@
-/*global module:false*/
-module.exports = function (grunt) {
+module.exports = function(grunt) {
- // Project configuration.
- grunt.initConfig({
- // Metadata.
- pkg: grunt.file.readJSON('package.json'),
- copy: {
- main: {
- files: [
- // includes files within path and its sub-directories
- { expand: true, flatten: true, src: ['node_modules/jquery/dist/jquery.min.js'], dest: 'public/javascripts' },
- { expand: true, flatten: true, src: ['node_modules/angular/angular.min.js'], dest: 'public/javascripts' },
- { expand: true, flatten: true, src: ['node_modules/angular-animate/angular-animate.min.js'], dest: 'public/javascripts' },
- { expand: true, flatten: true, src: ['node_modules/angular-bootstrap/ui-bootstrap.min.js'], dest: 'public/javascripts' },
- { expand: true, flatten: true, src: ['node_modules/bootstrap/dist/js/bootstrap.min.js'], dest: 'public/javascripts' },
- { expand: true, flatten: true, src: ['node_modules/angular-ui-router/release/angular-ui-router.min.js'], dest: 'public/javascripts' },
- { expand: true, flatten: true, src: ['node_modules/bootstrap/dist/css/bootstrap.min.css'], dest: 'public/stylesheets' },
- { expand: true, flatten: true, src: ['node_modules/font-awesome/css/font-awesome.min.css'], dest: 'public/stylesheets' },
- { expand: true, flatten: true, src: ['node_modules/moment/min/moment.min.js'], dest: 'public/javascripts' },
- { expand: true, cwd: 'node_modules/gentelella', dest: 'public/gentelella', src: '**'},
- { expand: true, flatten: true, src: ['public/custom/**/*.js', '!public/custom/**/*.spec.js'], dest: 'public/javascripts' },
- { expand: true, flatten: true, src: ['public/custom/**/*.css'], dest: 'public/stylesheets' }
- ]
- },
- unit: {
- files: [
- { expand: true, flatten: true, src: ['node_modules/angular-mocks/angular-mocks.js'], dest: 'public/test_frameworks' },
- { expand: true, flatten: true, src: ['node_modules/jasmine-jquery/lib/jasmine-jquery.js'], dest: 'public/test_frameworks' },
- ]
- }
- },
- injector: {
- local_dependencies: {
- files: {
- 'app/views/main.scala.html': [
- 'public/javascripts/moment.min.js',
- 'public/gentelella/vendors/jquery/dist/jquery.min.js',
- 'public/gentelella/vendors/bootstrap/dist/js/bootstrap.min.js',
- 'public/gentelella/vendors/bootstrap-daterangepicker/daterangepicker.js',
- 'public/javascripts/ui-bootstrap.min.js',
- 'public/javascripts/angular.min.js',
- 'public/lib/**/*.module.js',
- 'public/lib/**/*.js',
- 'public/app.js',
- 'public/gentelella/build/js/custom.js',
- 'public/js/custom.js',
- '!public/lib/**/*.spec.js'
- ]
- }
- }
- },
- karma: {
- unit: {
- configFile: 'karma.conf.js'
- }
- },
- clean: {
- js: ['public/javascripts/*'],
- css: ['public/stylesheets/*'],
- unit: ['public/test_frameworks/*'],
- gentelella: ['public/gentelella/*']
- },
- ngtemplates: {
- 'views.vinyl': {
- src: 'public/custom/**/*.html',
- dest: 'public/custom/views.vinyl.js',
- options: {
- standalone: true,
- quotes: 'single',
- url: function (url) { return url.replace('public/custom/', ''); }
- }
- }
- }
- });
+ const license = `/*
+* Copyright 2018 Comcast Cable Communications Management, LLC
+*
+* 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.
+*/`;
- grunt.loadNpmTasks('grunt-contrib-copy');
- grunt.loadNpmTasks('grunt-injector');
- grunt.loadNpmTasks('grunt-contrib-clean');
- grunt.loadNpmTasks('grunt-angular-templates');
- grunt.loadNpmTasks('grunt-karma');
- grunt.loadNpmTasks('grunt-mocha-phantomjs');
+ grunt.loadNpmTasks('grunt-contrib-copy');
+ grunt.loadNpmTasks('grunt-contrib-clean');
+ grunt.loadNpmTasks('grunt-karma');
+ grunt.loadNpmTasks('grunt-mocha-phantomjs');
+ grunt.loadNpmTasks('grunt-contrib-concat');
- // Default task
- grunt.registerTask('default', ['clean', 'ngtemplates', 'copy:main', 'injector']);
- // Unit tests
- grunt.registerTask('unit', ['default', 'ngtemplates', 'copy:unit', 'karma:unit', 'clean:unit']);
+ // Project configuration.
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('package.json'),
+
+ copy: {
+ // Collect all of the javascript and CSS files that we need (we'll combine them later)
+ main: {
+ files: [
+ {expand: true, flatten: true, src: ['node_modules/angular/angular.min.js'], dest: 'public/js'},
+ {expand: true, flatten: true, src: ['node_modules/bootstrap/dist/js/bootstrap.min.js'], dest: 'public/js'},
+ {expand: true, flatten: true, src: ['node_modules/jquery/dist/jquery.min.js'], dest: 'public/js'},
+ {expand: true, flatten: true, src: ['node_modules/moment/min/moment.min.js'], dest: 'public/js'},
+
+ {expand: true, flatten: true, src: ['node_modules/bootstrap/dist/css/bootstrap.min.css'], dest: 'public/css'},
+ {expand: true, flatten: true, src: ['node_modules/font-awesome/css/font-awesome.min.css'], dest: 'public/css'},
+
+ // We're picking just the resources we need from the gentelella UI framework and temporarily storing them in mapped/ui/
+ {expand: true, flatten: true, cwd: 'node_modules/gentelella', dest: 'mapped/ui', src: '**/jquery.{smartWizard,mCustomScrollbar.concat.min,dataTables.min,mousewheel.min}.js'},
+ {expand: true, flatten: true, cwd: 'node_modules/gentelella', dest: 'mapped/ui', src: '**/bootstrap-daterangepicker/daterangepicker.js'},
+ {expand: true, flatten: true, cwd: 'node_modules/gentelella', dest: 'mapped/ui', src: '**/build/css/custom.min.css'},
+ {expand: true, flatten: true, cwd: 'node_modules/gentelella', dest: 'mapped/ui', src: '**/{daterangepicker,animate.min}.css'},
+ {expand: true, flatten: true, cwd: 'node_modules/gentelella', dest: 'public/fonts', src: '**/fonts/*.{woff,woff2,ttf}'},
+
+ {expand: true, flatten: true, src: ['public/custom/**/*.js', '!public/custom/**/*.spec.js'], dest: 'public/js'},
+ {expand: true, flatten: true, src: ['public/custom/**/*.css'], dest: 'public/css'},
+ ],
+ },
+ // Unit test files
+ unit: {
+ files: [
+ {expand: true, flatten: true, src: ['node_modules/angular-mocks/angular-mocks.js'], dest: 'public/test_frameworks'},
+ {expand: true, flatten: true, src: ['node_modules/jasmine-jquery/lib/jasmine-jquery.js'], dest: 'public/test_frameworks'},
+ ],
+ },
+ },
+
+ // Unit test configuration
+ karma: {
+ unit: {
+ configFile: 'karma.conf.js',
+ },
+ },
+
+ // Combine multiple files to make it easier to import and use them
+ concat: {
+ options: {
+ sourceMap: true,
+ },
+ css: {
+ files: {
+ 'public/css/ui.css': ['mapped/ui/*.css'],
+ },
+ },
+ vinyldns: {
+ options: {
+ banner: license,
+ separator: ';\n',
+ process: (src, filepath) => {
+ return '/* Source: ' + filepath + '*/\n' +
+ src.replace(/(^|\n)[ \t]*('use strict'|"use strict");?\s*/g, '$1').replace(/\/\*.+?\*\//gs, '').replace(/\n{2,}/g, '\n');
+ },
+ },
+ files: {
+ 'public/js/vinyldns.js': [
+ 'public/lib/**/*.module.js',
+ 'public/lib/**/*.js',
+ '!public/lib/**/*.spec.js',
+ ],
+ },
+ },
+ ui_javascript: {
+ options: {
+ separator: ';\n',
+ process: (src, filepath) => {
+ return '/* Source: ' + filepath + ' */\n' +
+ src.replace(/(^|\n)[ \t]*('use strict'|"use strict");?\s*/g, '$1');
+ },
+ },
+ files: {
+ 'public/js/ui.js': ['mapped/ui/**/*.js'],
+ },
+ },
+ ui_css: {
+ options: {
+ separator: '\n',
+ process: (src, filepath) => {
+ return '/* Source: ' + filepath + ' */\n' + src;
+ },
+ },
+ files: {
+ 'public/css/ui.css': ['mapped/ui/**/*.css'],
+ },
+ },
+ },
+
+ clean: {
+ js: ['public/js/*', '!public/js/custom.js'],
+ css: ['public/css/*', '!public/css/{theme-overrides,vinyldns}.css'],
+ mapped: ['mapped/'],
+ fonts: ['public/fonts'],
+ unit: ['public/test_frameworks/*'],
+ },
+ });
+
+ // Default task
+ grunt.registerTask('default', ['clean', 'copy:main', 'concat', 'clean:mapped']);
+ // Unit tests
+ grunt.registerTask('unit', ['default', 'copy:unit', 'karma:unit', 'clean:unit']);
};
diff --git a/modules/portal/README.md b/modules/portal/README.md
index faa7fb02a..b1ccca194 100644
--- a/modules/portal/README.md
+++ b/modules/portal/README.md
@@ -1,19 +1,24 @@
# VinylDNS Portal
-Supplies a UI for and offers authentication into Vinyl, a DNSaaS offering.
+
+Supplies a UI for and offers authentication into VinylDNS.
# Running Unit Tests
+
First, startup sbt: `sbt`.
Next, you can run all tests by simply running `test`, or you can run an individual test by running `test-only *MySpec`
# Running Frontend Tests
+
The front end tests can be run from the `test/portal/fuctional` directory by simply running `make`.
# Building Locally
1. You must have npm, if you don't have npm, follow instructions here .
-2. Run `npm install` to install all dependencies, this includes those needed for testing. If you just want to run the portal then `npm install --production` would suffice
-3. You must have grunt, if you don't have grunt, run `npm install -g grunt`. Then run `grunt default` from the root of the portal project
+2. Run `npm install` to install all dependencies, this includes those needed for testing. If you just want to run the
+ portal then `npm install --production` would suffice
+3. You must have grunt, if you don't have grunt, run `npm install -g grunt`. Then run `grunt default` from the root of
+ the portal project
4. Create a local.conf file in the portal conf folder for your settings if desired.
5. Follow the instructions for building vinyl locally on the vinyl readme
6. Start vinyl with `sbt run`. Vinyl will start on localhost on port 9000.
@@ -21,20 +26,25 @@ The front end tests can be run from the `test/portal/fuctional` directory by sim
8. In a web browser go to localhost:9001
# Working locally
-Often times as a developer you want to work with the portal locally in a "real" setting against your own LDAP
-server. If your LDAP server requires SSL certs, you will need to create a trust store (or register the
-SSL certs on your local machine). If you create a trust store, you will need to make the trust store
-available so that you can start the portal locally and test.
+
+Often times as a developer you want to work with the portal locally in a "real" setting against your own LDAP server. If
+your LDAP server requires SSL certs, you will need to create a trust store (or register the SSL certs on your local
+machine). If you create a trust store, you will need to make the trust store available so that you can start the portal
+locally and test.
1. Create a trust store and save your certs.
-1. Pass the trust store in when you start sbt. This can be on the command line like...
-`sbt -Djavax.net.ssl.trustStore="./private/trustStore.jks"`
+1. Pass the trust store in when you start sbt. This can be on the command line like...
+ `sbt -Djavax.net.ssl.trustStore="./private/trustStore.jks"`
# Updating the trustStore Certificates
-When some event causes the LDAP lookup to fail because of SSL certificate issues, follow
-the following steps to update the trustStore with the new certificates.
-- Get the new certificate with `openssl s_client -connect :`. This will display the certificate on the screen.
-- Copy everything from `-----BEGIN CERTIFICATE-----` to `-----END CERTIFICATE-----` including the begin and end markers to the clipboard.
+
+When some event causes the LDAP lookup to fail because of SSL certificate issues, follow the following steps to update
+the `trustStore` with the new certificates.
+
+- Get the new certificate with `openssl s_client -connect :`. This will display the certificate on
+ the screen.
+- Copy everything from `-----BEGIN CERTIFICATE-----` to `-----END CERTIFICATE-----` including the begin and end markers
+ to the clipboard.
- Open a new file in your favorite text editor
- Paste the clipboard contents into the file
- Save the file and give it a name to be used in the next steps. (ex. `new-ad-ssl-cert.pem`)
diff --git a/modules/portal/app/views/groups/groupDetail.scala.html b/modules/portal/app/views/groups/groupDetail.scala.html
index 1e62fae2c..e7c3862d8 100644
--- a/modules/portal/app/views/groups/groupDetail.scala.html
+++ b/modules/portal/app/views/groups/groupDetail.scala.html
@@ -109,9 +109,7 @@
}
@plugins = {
-
-
-
+
}
@main(rootAccountName)("MembershipController")("Group")(content)(plugins)
diff --git a/modules/portal/app/views/groups/groups.scala.html b/modules/portal/app/views/groups/groups.scala.html
index 0815d216d..76d57f5f2 100644
--- a/modules/portal/app/views/groups/groups.scala.html
+++ b/modules/portal/app/views/groups/groups.scala.html
@@ -266,9 +266,7 @@
}
@plugins = {
-
-
-
+
}
@main(rootAccountName)("GroupsController")("Groups")(content)(plugins)
diff --git a/modules/portal/app/views/login.scala.html b/modules/portal/app/views/login.scala.html
index b1d0e5168..9b402ec6e 100644
--- a/modules/portal/app/views/login.scala.html
+++ b/modules/portal/app/views/login.scala.html
@@ -13,8 +13,9 @@
-
-
+
+
+
diff --git a/modules/portal/app/views/main.scala.html b/modules/portal/app/views/main.scala.html
index 32542466f..64c088544 100644
--- a/modules/portal/app/views/main.scala.html
+++ b/modules/portal/app/views/main.scala.html
@@ -4,7 +4,7 @@
-
+
@pageHeader | VinylDNS
@@ -12,16 +12,14 @@
-
+
-
-
-
-
-
+
+
+
+
-
@@ -97,8 +95,7 @@
@header(rootAccountName)(request)
@pageContent
-