2
0
mirror of https://github.com/VinylDNS/vinyldns synced 2025-08-22 02:02:14 +00:00
- Move away from using multiple images for "quickstart" and instead use a single "integration" image which provides all of the dependencies

- Update `docker-up-vinyldns.sh` to support the new `integration` image
- Update `remove-vinyl-containers.sh` to more cleanly.. clean up
- Update `verify.sh` to more reliably run `sbt` targets
- Update `build/docker/api/application.conf` to allow for overrides and default to the `vinyldns-integration` image
- Update `build/docker/portal/application.conf` to allow overrides and use `vinyldns-integration` image
  - Update `build/docker/portal/Dockerfile` to use `vinyldns/build:base-build-portal` to reduce need to download dependencies over and over
- Update `api/assembly` sbt target to output to `assembly` rather than some deeply nested folder in `**/target`
- Update documentation to reflect changes

- Move `docker/` directory to `quickstart/` to reduce confusion with the `build/docker` directory
- Move `bin/` to `utils/` since the files are binaries

- Add `.dockerignore` to root
This commit is contained in:
Emerle, Ryan 2021-10-20 09:07:19 -04:00
parent 07b683cbd0
commit a075c3c35e
217 changed files with 461 additions and 873 deletions

View File

@ -7,9 +7,9 @@
**/.idea/
**/.bsp
**/*cache*
**/*.png
**/.git
**/Dockerfile
**/*.dockerignore
**/.github
**/_template
img/

View File

@ -5,7 +5,7 @@ on:
pull_request:
branches: ['*']
push:
branches: ['master']
branches: ['master','main']
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -140,4 +140,4 @@ jobs:
path: ~/.sbt
key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
- name: Func tests
run: ./bin/func-test-portal.sh && ./bin/func-test-api-travis.sh
run: ./utils/func-test-portal.sh && ./utils/func-test-api.sh

4
.gitignore vendored
View File

@ -31,8 +31,8 @@ tmp.out
.vscode
project/metals.sbt
.bsp
docker/data
quickstart/data
**/.virtualenv
**/.venv*
**/*cache*
**/assembly/

View File

@ -7,19 +7,31 @@
- [Running VinylDNS Locally](#running-vinyldns-locally)
- [Testing](#testing)
## Developer Requirements
## Developer Requirements (Local)
- Scala 2.12
- sbt 1+
- Java 8 (at least u162)
- Python 2.7
- virtualenv
- Docker
- curl
- npm
- grunt
- Scala 2.12
- sbt 1.4+
Make sure that you have the requirements installed before proceeding.
- curl
- docker
- docker-compose
- GNU Make 3.82+
- grunt
- npm
- Python 3.5+
## Developer Requirements (Docker)
Since almost everything can be run with Docker and GNU Make, if you don't want to setup a local development environment,
then you simply need:
- `Docker` v19.03+ _(earlier versions may work fine)_
- `Docker Compose` v2.0+ _(earlier versions may work fine)_
- `GNU Make` v3.82+
- `Bash` 3.2+
- Basic utilities: `awk`, `sed`, `curl`, `grep`, etc may be needed for scripts
## Project Layout
@ -135,10 +147,12 @@ README. However, VinylDNS can also be run in the foreground.
### Starting the API Server
Before starting the API service, you can start the dependencies for local development:
```
cd test/api/integration
make build && make run-bg
```
This will start a container running in the background with necessary prerequisites.
Once the prerequisites are running, you can start up sbt by running `sbt` from the root directory.
@ -147,16 +161,21 @@ Once the prerequisites are running, you can start up sbt by running `sbt` from t
* `reStart` to start up the API server
* Wait until you see the message `VINYLDNS SERVER STARTED SUCCESSFULLY` before working with the server
* To stop the VinylDNS server, run `reStop` from the api project
* To stop the dependent Docker containers, change to the root project `project root`, then run `dockerComposeStop` from
the API project
* To stop the dependent Docker containers: `utils/clean-vinyldns-containers.sh`
See the [API Configuration Guide](https://www.vinyldns.io/operator/config-api) for information regarding API
configuration.
### Starting the Portal
To run the portal locally, you _first_ have to start up the VinylDNS API Server (see instructions above). Once that is
done, in the same `sbt` session or a different one, go to `project portal` and then execute `;preparePortal; run`.
To run the portal locally, you _first_ have to start up the VinylDNS API Server:
```
utils/quickstart-vinyldns.sh
```
Once that is done, in the same `sbt` session or a different one, go to `project portal` and then
execute `;preparePortal; run`.
See the [Portal Configuration Guide](https://www.vinyldns.io/operator/config-portal) for information regarding portal
configuration.
@ -220,7 +239,7 @@ You can run all unit and integration tests for the api and portal by running `sb
When adding new features, you will often need to write new functional tests that black box / regression test the API.
- The API functional tests are written in Python and live under `test/api/functional`.
The Portal functional tests are written in JavaScript and live under `test/portal/functional`.
- The Portal functional tests are written in JavaScript and live under `test/portal/functional`.
#### Running Functional Tests
@ -229,6 +248,7 @@ To run functional tests you can simply execute the following command:
```
make build && make run
```
During iterative test development, you can use `make run-local` which will mount the current functional tests in the
container, allowing for easier test development.
@ -236,13 +256,11 @@ Additionally, you can pass `--interactive` to `make run` or `make run-local` to
From there you can run tests with the `/functional_test/run.sh` command. This allows for finer-grained control over the
test execution process as well as easier inspection of logs.
##### API Functional Tests
You can run a specific test by name by running `make run -- -k <name of test function>`. Any arguments after
`make run --` will be passed to the test runner [`test/api/functional/run.sh`](test/api/functional/run.sh).
#### Setup
We use [pytest](https://docs.pytest.org/en/latest/) for python tests. It is helpful that you browse the documentation so

View File

@ -79,7 +79,7 @@ running the release
1. Follow [Docker Content Trust](#docker-content-trust) to setup a notary delegation for yourself
1. Follow [Sonatype Credentials](#sonatype-credentials) to setup the sonatype pgp signing key on your local
1. Make sure you're logged in to Docker with `docker login`
1. Run `bin/release.sh` _Note: the arg "skip-tests" will skip unit, integration and functional testing before a release_
1. Run `utils/release.sh` _Note: the arg "skip-tests" will skip unit, integration and functional testing before a release_
1. You will be asked to confirm the version which originally comes from `version.sbt`. _NOTE: if the version ends with
`SNAPSHOT`, then the docker latest tag won't be applied and the core module will only be published to the sonatype
staging repo._

View File

@ -48,9 +48,9 @@ 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 `./bin/docker-up-vinyldns.sh`. This will start up the api at `localhost:9000` and the portal at `localhost:9001`
1. Run `./utils/quickstart-vinyldns.sh`. This will start up the api at `localhost:9000` and the portal at `localhost:9001`
1. See [Developer Guide](DEVELOPER_GUIDE.md#loading-test-data) for how to load a test DNS zone
1. To stop the local setup, run `./bin/remove-vinyl-containers.sh`.
1. To stop the local setup, run `./utils/clean-vinyldns-containers.sh`.
There exist several clients at <https://github.com/vinyldns> that can be used to make API requests, using the endpoint `http://localhost:9000`
@ -72,7 +72,7 @@ TTL = 300, IP Addressess = 1.1.1.1`
1. Upon connecting to a zone for the first time, a zone sync is executed to provide VinylDNS a copy of the records in the zone
1. Changes made via VinylDNS are made against the DNS backend, you do not need to sync the zone further to push those changes out
1. If changes to the zone are made outside of VinylDNS, then the zone will have to be re-synced to give VinylDNS a copy of those records
1. If you wish to modify the url used in the creation process from `http://localhost:9000`, to say `http://vinyldns.yourdomain.com:9000`, you can modify the `bin/.env` file before execution.
1. If you wish to modify the url used in the creation process from `http://localhost:9000`, to say `http://vinyldns.yourdomain.com:9000`, you can modify the `utils/.env` file before execution.
1. A similar `docker/.env.quickstart` can be modified to change the default ports for the Portal and API. You must also modify their config files with the new port: https://www.vinyldns.io/operator/config-portal & https://www.vinyldns.io/operator/config-api
## Code of Conduct

View File

@ -1,2 +0,0 @@
VINYLDNS_API_URL=http://localhost:9000
VINYLDNS_PORTAL_URL=http://localhost:9001

View File

@ -1,113 +0,0 @@
#!/usr/bin/env bash
#####################################################################################################
# Starts up the api, portal, and dependent services via
# docker-compose. The api will be available on localhost:9000 and the
# portal will be on localhost:9001
#
# Relevant overrides can be found at ./.env and ../docker/.env
#
# Options:
# -t, --timeout seconds: overwrite ping timeout, default of 60
# -a, --api-only: only starts up vinyldns-api and its dependencies, excludes vinyldns-portal
# -c, --clean: re-pull vinyldns/api and vinyldns/portal images from docker hub
# -v, --version tag: overwrite vinyldns/api and vinyldns/portal docker tags
#####################################################################################################
function wait_for_url {
echo "pinging ${URL} ..."
DATA=""
RETRY="$TIMEOUT"
while [ "$RETRY" -gt 0 ]
do
DATA=$(curl -I -s "${URL}" -o /dev/null -w "%{http_code}")
if [ $? -eq 0 ]
then
echo "Succeeded in connecting to ${URL}!"
break
else
echo "Retrying" >&2
let RETRY-=1
sleep 1
if [ "$RETRY" -eq 0 ]
then
echo "Exceeded retries waiting for ${URL} to be ready, failing"
exit 1
fi
fi
done
}
function usage {
printf "usage: docker-up-vinyldns.sh [OPTIONS]\n\n"
printf "starts up a local VinylDNS installation using docker compose\n\n"
printf "options:\n"
printf "\t-t, --timeout seconds: overwrite ping timeout of 60\n"
printf "\t-a, --api-only: do not start up vinyldns-portal\n"
printf "\t-c, --clean: re-pull vinyldns/api and vinyldns/portal images from docker hub\n"
printf "\t-v, --version tag: overwrite vinyldns/api and vinyldns/portal docker tags\n"
}
function clean_images {
if (( $CLEAN == 1 )); then
echo "cleaning docker images..."
docker rmi vinyldns/api:$VINYLDNS_VERSION
docker rmi vinyldns/portal:$VINYLDNS_VERSION
fi
}
function wait_for_api {
echo "Waiting for api..."
URL="$VINYLDNS_API_URL"
wait_for_url
}
function wait_for_portal {
# check if portal was skipped
if [ "$SERVICE" != "api" ]; then
echo "Waiting for portal..."
URL="$VINYLDNS_PORTAL_URL"
wait_for_url
fi
}
# initial var setup
DIR=$( cd $(dirname $0) ; pwd -P )
TIMEOUT=60
DOCKER_COMPOSE_CONFIG="${DIR}/../docker/docker-compose-quick-start.yml"
# empty service starts up all docker services in compose file
SERVICE=""
# when CLEAN is set to 1, existing docker images are deleted so they are re-pulled
CLEAN=0
# default to latest for docker versions
export VINYLDNS_VERSION=latest
# source env before parsing args so vars can be overwritten
set -a # Required in order to source docker/.env
# Source customizable env files
source "$DIR"/.env
source "$DIR"/../docker/.env
# parse args
while [ "$1" != "" ]; do
case "$1" in
-t | --timeout ) TIMEOUT="$2"; shift;;
-a | --api-only ) SERVICE="api";;
-c | --clean ) CLEAN=1;;
-v | --version ) export VINYLDNS_VERSION=$2; shift;;
* ) usage; exit;;
esac
shift
done
clean_images
echo "timeout is set to ${TIMEOUT}"
echo "vinyldns version is set to '${VINYLDNS_VERSION}'"
echo "Starting vinyldns and all dependencies in the background..."
docker-compose -f "$DOCKER_COMPOSE_CONFIG" up -d ${SERVICE}
wait_for_api
wait_for_portal

View File

@ -1,30 +0,0 @@
#!/usr/bin/env bash
#
# The local vinyldns setup used for testing relies on the
# following docker images:
# mysql:5.7
# s12v/elasticmq:0.13.8
# vinyldns/bind9
# vinyldns/api
# vinyldns/portal
# rroemhild/test-openldap
# localstack/localstack
#
# This script with kill and remove containers associated
# with these names and/or tags
#
# Note: this will not remove the actual images from your
# machine, just the running containers
IDS=$(docker ps -a | grep -e 'mysql:5.7' -e 's12v/elasticmq:0.13.8' -e 'vinyldns' -e 'flaviovs/mock-smtp' -e 'localstack/localstack' -e 'rroemhild/test-openldap' | awk '{print $1}')
echo "killing..."
echo $(echo "$IDS" | xargs -I {} docker kill {})
echo
echo "removing..."
echo $(echo "$IDS" | xargs -I {} docker rm -v {})
echo
echo "pruning network..."
docker network prune -f

View File

@ -47,7 +47,7 @@ lazy val sharedSettings = Seq(
lazy val testSettings = Seq(
parallelExecution in Test := true,
parallelExecution in IntegrationTest := false,
fork in IntegrationTest := false,
fork in IntegrationTest := true,
testOptions in Test += Tests.Argument("-oDNCXEPQRMIK", "-l", "SkipCI"),
logBuffered in Test := false,
// Hide stack traces in tests
@ -67,13 +67,11 @@ lazy val apiSettings = Seq(
)
lazy val apiAssemblySettings = Seq(
assemblyJarName in assembly := "vinyldns.jar",
assemblyOutputPath in assembly := file("assembly/vinyldns.jar"),
test in assembly := {},
mainClass in assembly := Some("vinyldns.api.Boot"),
mainClass in reStart := Some("vinyldns.api.Boot"),
// there are some odd things from dnsjava including update.java and dig.java that we don't use
assemblyMergeStrategy in assembly := {
case "update.class" | "dig.class" => MergeStrategy.discard
case PathList("scala", "tools", "nsc", "doc", "html", "resource", "lib", "index.js") =>
MergeStrategy.discard
case PathList("scala", "tools", "nsc", "doc", "html", "resource", "lib", "template.js") =>
@ -153,6 +151,7 @@ lazy val coreBuildSettings = Seq(
// to write a crypto plugin so that we fall back to a noarg constructor
scalacOptions ++= scalacOptionsByV(scalaVersion.value).filterNot(_ == "-Ywarn-unused:params")
) ++ pbSettings
lazy val corePublishSettings = Seq(
publishMavenStyle := true,
publishArtifact in Test := false,
@ -266,11 +265,11 @@ lazy val portal = (project in file("modules/portal"))
},
checkJsHeaders := {
import scala.sys.process._
"./bin/add-license-headers.sh -d=modules/portal/public/lib -f=js -c" !
"./utils/add-license-headers.sh -d=modules/portal/public/lib -f=js -c" !
},
createJsHeaders := {
import scala.sys.process._
"./bin/add-license-headers.sh -d=modules/portal/public/lib -f=js" !
"./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"

View File

@ -9,11 +9,17 @@ vinyldns {
settings = {
name = "vinyldns"
name = ${?JDBC_DB_NAME}
driver = "org.mariadb.jdbc.Driver"
migration-url = "jdbc:mariadb://vinyldns-mysql:3306/?user=root&password=pass"
url = "jdbc:mariadb://vinyldns-mysql:3306/vinyldns?user=root&password=pass"
driver = ${?JDBC_DRIVER}
migration-url = "jdbc:mariadb://vinyldns-integration:19002/?user=root&password=pass"
migration-url = ${?JDBC_MIGRATION_URL}
url = "jdbc:mariadb://vinyldns-integration:19002/vinyldns?user=root&password=pass"
url = ${?JDBC_URL}
user = "root"
user = ${?JDBC_USER}
password = "pass"
password = ${?JDBC_PASSWORD}
# see https://github.com/brettwooldridge/HikariCP
connection-timeout-millis = 1000
@ -50,11 +56,17 @@ vinyldns {
# these must be overridden to use MYSQL for production use
# assumes a docker or mysql instance running locally
name = "vinyldns"
name = ${?JDBC_DB_NAME}
driver = "org.mariadb.jdbc.Driver"
migration-url = "jdbc:mariadb://vinyldns-mysql:3306/?user=root&password=pass"
url = "jdbc:mariadb://vinyldns-mysql:3306/vinyldns?user=root&password=pass"
driver = ${?JDBC_DRIVER}
migration-url = "jdbc:mariadb://vinyldns-integration:19002/?user=root&password=pass"
migration-url = ${?JDBC_MIGRATION_URL}
url = "jdbc:mariadb://vinyldns-integration:19002/vinyldns?user=root&password=pass"
url = ${?JDBC_URL}
user = "root"
user = ${?JDBC_USER}
password = "pass"
password = ${?JDBC_PASSWORD}
# see https://github.com/brettwooldridge/HikariCP
connection-timeout-millis = 1000
idle-timeout = 10000
@ -89,15 +101,21 @@ vinyldns {
defaultZoneConnection {
name = "vinyldns."
keyName = "vinyldns."
keyName = ${?DEFAULT_DNS_KEY_NAME}
key = "nzisn+4G2ldMn0q1CV3vsg=="
primaryServer = "vinyldns-bind9"
key = ${?DEFAULT_DNS_KEY_SECRET}
primaryServer = "vinyldns-integration:19001"
primaryServer = ${?DEFAULT_DNS_ADDRESS}
}
defaultTransferConnection {
name = "vinyldns."
keyName = "vinyldns."
keyName = ${?DEFAULT_DNS_KEY_NAME}
key = "nzisn+4G2ldMn0q1CV3vsg=="
primaryServer = "vinyldns-bind9"
key = ${?DEFAULT_DNS_KEY_SECRET}
primaryServer = "vinyldns-integration:19001"
primaryServer = ${?DEFAULT_DNS_ADDRESS}
}
backends = [
@ -106,14 +124,20 @@ vinyldns {
zone-connection {
name = "vinyldns."
key-name = "vinyldns."
key-name = ${?DEFAULT_DNS_KEY_NAME}
key = "nzisn+4G2ldMn0q1CV3vsg=="
primary-server = "vinyldns-bind9"
key = ${?DEFAULT_DNS_KEY_SECRET}
primary-server = "vinyldns-integration:19001"
primary-server = ${?DEFAULT_DNS_ADDRESS}
}
transfer-connection {
name = "vinyldns."
key-name = "vinyldns."
key-name = ${?DEFAULT_DNS_KEY_NAME}
key = "nzisn+4G2ldMn0q1CV3vsg=="
primary-server = "vinyldns-bind9"
key = ${?DEFAULT_DNS_KEY_SECRET}
primary-server = "vinyldns-integration:19001"
primary-server = ${?DEFAULT_DNS_ADDRESS}
}
}
]

View File

@ -1,4 +1,4 @@
FROM hseeberger/scala-sbt:11.0.8_1.3.13_2.11.12 as builder
FROM vinyldns/build:base-build-portal as builder
ARG BRANCH=master
ARG VINYLDNS_VERSION
@ -8,16 +8,6 @@ RUN git clone -b ${BRANCH} --single-branch --depth 1 https://github.com/vinyldns
# The default jvmopts are huge, meant for running everything, use a paired down version
COPY .jvmopts /vinyldns
# Needed for preparePortal
RUN apt-get update \
&& apt-get install -y \
apt-transport-https \
curl \
gnupg \
&& curl -sL https://deb.nodesource.com/setup_12.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g grunt-cli
RUN cd /vinyldns ; sbt "set version in ThisBuild := \"${VINYLDNS_VERSION}\"" portal/preparePortal universal:packageZipTarball
FROM adoptopenjdk/openjdk11:jdk-11.0.8_10-alpine

View File

@ -21,7 +21,8 @@ LDAP {
securityAuthentication = "simple"
# Note: The following assumes a purely docker setup, using container_name = vinyldns-ldap
providerUrl = "ldap://vinyldns-ldap:389"
providerUrl = "ldap://vinyldns-ldap:19004"
providerUrl = ${?LDAP_PROVIDER_URL}
}
# This is only needed if keeping vinyldns user store in sync with ldap (to auto lock out users who left your
@ -41,7 +42,9 @@ http.port = 9000
data-stores = ["mysql"]
portal.vinyldns.backend.url = "http://vinyldns-api:9000"
portal.vinyldns.backend.url = "http://vinyldns-integration:9000"
portal.vinyldns.backend.url = ${?API_URL}
# 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
@ -53,10 +56,14 @@ mysql {
# assumes a docker or mysql instance running locally
name = "vinyldns"
driver = "org.mariadb.jdbc.Driver"
migration-url = "jdbc:mariadb://vinyldns-mysql:3306/?user=root&password=pass"
url = "jdbc:mariadb://vinyldns-mysql:3306/vinyldns?user=root&password=pass"
migration-url = "jdbc:mariadb://vinyldns-integration:19002/?user=root&password=pass"
migration-url = ${?JDBC_MIGRATION_URL}
url = "jdbc:mariadb://vinyldns-integration:19002/vinyldns?user=root&password=pass"
url = ${?JDBC_URL}
user = "root"
user = ${?JDBC_USER}
password = "pass"
password = ${?JDBC_PASSWORD}
# see https://github.com/brettwooldridge/HikariCP
connection-timeout-millis = 1000
idle-timeout = 10000

View File

@ -1,17 +0,0 @@
REST_PORT=9000
# Do not use quotes around the environment variables.
MYSQL_ROOT_PASSWORD=pass
# This is required as mysql is currently locked down to localhost
MYSQL_ROOT_HOST=%
# Host URL for queue
QUEUE_HOST=vinyldns-elasticmq
# portal settings
PORTAL_PORT=9001
PLAY_HTTP_SECRET_KEY=change-this-for-prod
VINYLDNS_BACKEND_URL=http://vinyldns-api:9000
SQS_ENDPOINT=http://vinyldns-localstack:19007
MYSQL_ENDPOINT=vinyldns-mysql:3306
USER_TABLE_NAME=users
USER_CHANGE_TABLE_NAME=userChange
TEST_LOGIN=true

View File

@ -1,17 +0,0 @@
REST_PORT=9000
# Do not use quotes around the environment variables.
MYSQL_ROOT_PASSWORD=pass
# This is required as mysql is currently locked down to localhost
MYSQL_ROOT_HOST=%
# Host URL for queue
QUEUE_HOST=vinyldns-elasticmq
# portal settings
PORTAL_PORT=9001
PLAY_HTTP_SECRET_KEY=change-this-for-prod
VINYLDNS_BACKEND_URL=http://vinyldns-api:9000
SQS_ENDPOINT=http://vinyldns-localstack:19007
MYSQL_ENDPOINT=vinyldns-mysql:3306
USER_TABLE_NAME=users
USER_CHANGE_TABLE_NAME=userChange
TEST_LOGIN=true

View File

@ -1,5 +0,0 @@
.DS_Store
.dockerignore
.git
.gitignore
classes

View File

@ -1,17 +0,0 @@
FROM adoptopenjdk/openjdk11:jdk-11.0.7_10-alpine
RUN apk add --update --no-cache netcat-openbsd bash
# install the jar onto the server, asserts this Dockerfile is copied to target/scala-2.12 after a build
COPY vinyldns.jar /app/vinyldns-server.jar
COPY run.sh /app/run.sh
RUN chmod a+x /app/run.sh
COPY docker.conf /app/docker.conf
EXPOSE 9000
# set the entry point for the container to start vinyl, specify the config resource
ENTRYPOINT ["/app/run.sh"]

View File

@ -1,333 +0,0 @@
################################################################################################################
# This configuration is only used by docker. Environment variables are required in order to start
# up a docker cluster appropriately, so most of the values are passed in here. Defaults assume a local docker compose
# for vinyldns running.
# SQS_ENDPOINT is the SQS endpoint
# SQS_QUEUE_NAME is the queue name for the SQS queue
# SQS_REGION is the service region where the SQS queue lives (e.g. us-east-1)
# AWS_ACCESS_KEY is the AWS access key
# AWS_SECRET_ACCESS_KEY is the AWS secret access key
# JDBC_MIGRATION_URL - the URL for migations in the SQL database
# JDBC_URL - the full URL to the SQL database
# JDBC_USER - the SQL database user
# JDBC_PASSWORD - the SQL database password
# DEFAULT_DNS_ADDRESS - the server (and port if not 53) of the default DNS server
# DEFAULT_DNS_KEY_NAME - the default key name used to connect to the default DNS server
# DEFAULT_DNS_KEY_SECRET - the default key secret used to connect to the default DNS server
################################################################################################################
vinyldns {
# configured backend providers
backend {
# Use "default" when dns backend legacy = true
# otherwise, use the id of one of the connections in any of your backends
default-backend-id = "default"
# this is where we can save additional backends
backend-providers = [
{
class-name = "vinyldns.route53.backend.Route53BackendProviderLoader"
settings = {
backends = [
{
id = "r53",
access-key = "test",
access-key = ${?AWS_ACCESS_KEY_ID}
secret-key = "test",
secret-key = ${?AWS_SECRET_ACCESS_KEY},
service-endpoint = "http://vinyldns-localstack:19009",
service-endpoint = ${?AWS_ROUTE53_ENDPOINT},
signing-region = "us-east-1"
signing-region = ${?AWS_DEFAULT_REGION}
}
]
}
},
{
class-name = "vinyldns.api.backend.dns.DnsBackendProviderLoader"
settings = {
legacy = false
backends = [
{
id = "default"
zone-connection = {
name = "vinyldns."
key-name = "vinyldns."
key-name = ${?DEFAULT_DNS_KEY_NAME}
key = "nzisn+4G2ldMn0q1CV3vsg=="
key = ${?DEFAULT_DNS_KEY_SECRET}
primary-server = "vinyldns-bind9"
primary-server = ${?DEFAULT_DNS_ADDRESS}
}
transfer-connection = {
name = "vinyldns."
key-name = "vinyldns."
key-name = ${?DEFAULT_DNS_KEY_NAME}
key = "nzisn+4G2ldMn0q1CV3vsg=="
key = ${?DEFAULT_DNS_KEY_SECRET}
primary-server = "vinyldns-bind9"
primary-server = ${?DEFAULT_DNS_ADDRESS}
},
tsig-usage = "always"
},
{
id = "func-test-backend"
zone-connection = {
name = "vinyldns."
key-name = "vinyldns."
key-name = ${?DEFAULT_DNS_KEY_NAME}
key = "nzisn+4G2ldMn0q1CV3vsg=="
key = ${?DEFAULT_DNS_KEY_SECRET}
primary-server = "vinyldns-bind9"
primary-server = ${?DEFAULT_DNS_ADDRESS}
}
transfer-connection = {
name = "vinyldns."
key-name = "vinyldns."
key-name = ${?DEFAULT_DNS_KEY_NAME}
key = "nzisn+4G2ldMn0q1CV3vsg=="
key = ${?DEFAULT_DNS_KEY_SECRET}
primary-server = "vinyldns-bind9"
primary-server = ${?DEFAULT_DNS_ADDRESS}
},
tsig-usage = "always"
}
]
}
}
]
}
queue {
class-name = "vinyldns.sqs.queue.SqsMessageQueueProvider"
messages-per-poll = 10
polling-interval = 250.millis
settings {
# AWS access key and secret.
access-key = "test"
access-key = ${?AWS_ACCESS_KEY}
secret-key = "test"
secret-key = ${?AWS_SECRET_ACCESS_KEY}
# Regional endpoint to make your requests (eg. 'us-west-2', 'us-east-1', etc.). This is the region where your queue is housed.
signing-region = "us-east-1"
signing-region = ${?SQS_REGION}
# Endpoint to access queue
service-endpoint = "http://vinyldns-localstack:19007/"
service-endpoint = ${?SQS_ENDPOINT}
# Queue name. Should be used in conjunction with service endpoint, rather than using a queue url which is subject to change.
queue-name = "vinyldns"
queue-name = ${?SQS_QUEUE_NAME}
}
}
rest {
host = "0.0.0.0"
port = 9000
}
sync-delay = 10000
approved-name-servers = [
"172.17.42.1.",
"ns1.parent.com."
"ns1.parent.com1."
"ns1.parent.com2."
"ns1.parent.com3."
"ns1.parent.com4."
]
crypto {
type = "vinyldns.core.crypto.NoOpCrypto"
}
data-stores = ["mysql"]
mysql {
settings {
# JDBC Settings, these are all values in scalikejdbc-config, not our own
# these must be overridden to use MYSQL for production use
# assumes a docker or mysql instance running locally
name = "vinyldns"
driver = "org.mariadb.jdbc.Driver"
migration-url = "jdbc:mariadb://vinyldns-mysql:3306/?user=root&password=pass"
migration-url = ${?JDBC_MIGRATION_URL}
url = "jdbc:mariadb://vinyldns-mysql:3306/vinyldns?user=root&password=pass"
url = ${?JDBC_URL}
user = "root"
user = ${?JDBC_USER}
password = "pass"
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 = []
batch-change-limit = 1000
# FQDNs / IPs that cannot be modified via VinylDNS
# regex-list used for all record types except PTR
# ip-list used exclusively for PTR records
high-value-domains = {
regex-list = [
"high-value-domain.*" # for testing
]
ip-list = [
# using reverse zones in the vinyldns/bind9 docker image for testing
"192.0.2.252",
"192.0.2.253",
"fd69:27cc:fe91:0:0:0:0:ffff",
"fd69:27cc:fe91:0:0:0:ffff:0"
]
}
# FQDNs / IPs / zone names that require manual review upon submission in batch change interface
# domain-list used for all record types except PTR
# ip-list used exclusively for PTR records
manual-review-domains = {
domain-list = [
"needs-review.*"
]
ip-list = [
"192.0.1.254",
"192.0.1.255",
"192.0.2.254",
"192.0.2.255",
"192.0.3.254",
"192.0.3.255",
"192.0.4.254",
"192.0.4.255",
"fd69:27cc:fe91:0:0:0:ffff:1",
"fd69:27cc:fe91:0:0:0:ffff:2",
"fd69:27cc:fe92:0:0:0:ffff:1",
"fd69:27cc:fe92:0:0:0:ffff:2",
"fd69:27cc:fe93:0:0:0:ffff:1",
"fd69:27cc:fe93:0:0:0:ffff:2",
"fd69:27cc:fe94:0:0:0:ffff:1",
"fd69:27cc:fe94:0:0:0:ffff:2"
]
zone-name-list = [
"zone.requires.review."
"zone.requires.review1."
"zone.requires.review2."
"zone.requires.review3."
"zone.requires.review4."
]
}
# FQDNs / IPs that cannot be modified via VinylDNS
# regex-list used for all record types except PTR
# ip-list used exclusively for PTR records
high-value-domains = {
regex-list = [
"high-value-domain.*" # for testing
]
ip-list = [
# using reverse zones in the vinyldns/bind9 docker image for testing
"192.0.1.252",
"192.0.1.253",
"192.0.2.252",
"192.0.2.253",
"192.0.3.252",
"192.0.3.253",
"192.0.4.252",
"192.0.4.253",
"fd69:27cc:fe91:0:0:0:0:ffff",
"fd69:27cc:fe91:0:0:0:ffff:0",
"fd69:27cc:fe92:0:0:0:0:ffff",
"fd69:27cc:fe92:0:0:0:ffff:0",
"fd69:27cc:fe93:0:0:0:0:ffff",
"fd69:27cc:fe93:0:0:0:ffff:0",
"fd69:27cc:fe94:0:0:0:0:ffff",
"fd69:27cc:fe94:0:0:0:ffff:0"
]
}
# types of unowned records that users can access in shared zones
shared-approved-types = ["A", "AAAA", "CNAME", "PTR", "TXT"]
manual-batch-review-enabled = true
scheduled-changes-enabled = true
multi-record-batch-change-enabled = true
global-acl-rules = [
{
group-ids: ["global-acl-group-id"],
fqdn-regex-list: [".*shared[0-9]{1}."]
},
{
group-ids: ["another-global-acl-group"],
fqdn-regex-list: [".*ok[0-9]{1}."]
}
]
}
akka {
loglevel = "INFO"
loggers = ["akka.event.slf4j.Slf4jLogger"]
logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
logger-startup-timeout = 30s
actor {
provider = "akka.actor.LocalActorRefProvider"
}
}
akka.http {
server {
# The time period within which the TCP binding process must be completed.
# Set to `infinite` to disable.
bind-timeout = 5s
# Show verbose error messages back to the client
verbose-error-messages = on
}
parsing {
# Spray doesn't like the AWS4 headers
illegal-header-warnings = on
}
}

View File

@ -1,12 +0,0 @@
<configuration>
<!-- Test configuration, log to console so we can get the docker logs -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d [test] %-5p | \(%logger{4}:%line\) | %msg %n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>

View File

@ -1,41 +0,0 @@
#!/usr/bin/env bash
# gets the docker-ized ip address, sets it to an environment variable
export APP_HOST=`ip addr show eth0 | grep 'inet ' | awk '{print $2}' | cut -f1 -d'/'`
export MYSQL_ADDRESS="vinyldns-mysql"
export MYSQL_PORT=3306
export JDBC_USER=root
export JDBC_PASSWORD=pass
export JDBC_URL="jdbc:mariadb://${MYSQL_ADDRESS}:${MYSQL_PORT}/vinyldns?user=${JDBC_USER}&password=${JDBC_PASSWORD}"
export JDBC_MIGRATION_URL="jdbc:mariadb://${MYSQL_ADDRESS}:${MYSQL_PORT}/?user=${JDBC_USER}&password=${JDBC_PASSWORD}"
# wait until mysql is ready...
echo 'Waiting for MYSQL to be ready...'
DATA=""
RETRY=40
SLEEP_DURATION=1
while [ "$RETRY" -gt 0 ]
do
DATA=$(nc -vzw1 ${MYSQL_ADDRESS} ${MYSQL_PORT})
if [ $? -eq 0 ]
then
break
else
echo "Retrying" >&2
let RETRY-=1
sleep "$SLEEP_DURATION"
if [ "$RETRY" -eq 0 ]
then
echo "Exceeded retries waiting for MYSQL to be ready, failing"
return 1
fi
fi
done
echo "Starting up Vinyl..."
sleep 2
java -Djava.net.preferIPv4Stack=true -Dconfig.file=/app/docker.conf -Dakka.loglevel=INFO -Dlogback.configurationFile=/app/logback.xml -jar /app/vinyldns-server.jar vinyldns.api.Boot

View File

@ -1,68 +0,0 @@
version: "3.0"
services:
mysql:
image: "mysql:5.7"
env_file:
.env.quickstart
container_name: "vinyldns-mysql"
ports:
- "19002:3306"
bind9:
image: "vinyldns/bind9:0.0.5"
env_file:
.env.quickstart
container_name: "vinyldns-bind9"
ports:
- "19001:53/udp"
- "19001:53"
volumes:
- ./bind9/etc:/var/cache/bind/config
- ./bind9/zones:/var/cache/bind/zones
localstack:
image: localstack/localstack:0.10.4
container_name: "vinyldns-localstack"
ports:
- "19006:19006"
- "19007:19007"
- "19009:19009"
environment:
- SERVICES=sns:19006,sqs:19007,route53:19009
- START_WEB=0
- HOSTNAME_EXTERNAL=vinyldns-localstack
ldap:
image: rroemhild/test-openldap
container_name: "vinyldns-ldap"
ports:
- "19008:389"
api:
image: "vinyldns/api:${VINYLDNS_VERSION}"
env_file:
.env.quickstart
container_name: "vinyldns-api"
ports:
- "${REST_PORT}:${REST_PORT}"
volumes:
- ./api/docker.conf:/opt/docker/conf/application.conf
- ./api/logback.xml:/opt/docker/conf/logback.xml
depends_on:
- mysql
- bind9
- localstack
portal:
image: "vinyldns/portal:${VINYLDNS_VERSION}"
env_file:
.env.quickstart
ports:
- "${PORTAL_PORT}:${PORTAL_PORT}"
container_name: "vinyldns-portal"
volumes:
- ./portal/application.ini:/opt/docker/conf/application.ini
- ./portal/application.conf:/opt/docker/conf/application.conf
depends_on:
- api
- ldap

View File

@ -1,41 +0,0 @@
version: "3.0"
services:
mysql:
image: mysql:5.7<skipPull>
env_file:
.env
ports:
- "19002:3306"
bind9:
image: vinyldns/bind9:0.0.5<skipPull>
env_file:
.env
ports:
- "19001:53/udp"
- "19001:53"
volumes:
- ./bind9/etc:/var/cache/bind/config
- ./bind9/zones:/var/cache/bind/zones
localstack:
image: localstack/localstack:0.10.4<skipPull>
ports:
- "19006:19006"
- "19007:19007"
- "19009:19009"
environment:
- SERVICES=sns:19006,sqs:19007,route53:19009
- START_WEB=0
mail:
image: flaviovs/mock-smtp:0.0.2<skipPull>
ports:
- "19025:25"
volumes:
- ./email:/var/lib/mock-smtp
ldap:
image: rroemhild/test-openldap:latest<skipPull>
ports:
- "19008:389"

View File

@ -1,4 +1,3 @@
/*
* Copyright 2018 Comcast Cable Communications Management, LLC
*

View File

@ -22,6 +22,7 @@ import org.flywaydb.core.Flyway
import org.slf4j.LoggerFactory
import scala.collection.JavaConverters._
import scala.util.{Failure, Success, Try}
object MySqlConnector {
@ -44,20 +45,21 @@ object MySqlConnector {
getDataSource(migrationConnectionSettings).map { migrationDataSource =>
logger.info("Running migrations to ready the databases")
val migration = new Flyway()
migration.setDataSource(migrationDataSource)
val placeholders = Map("dbName" -> config.name)
val migration = Flyway
.configure()
.dataSource(migrationDataSource)
.placeholders(placeholders.asJava)
.schemas(config.name)
// flyway changed the default schema table name in v5.0.0
// this allows to revert to an old naming convention if needed
config.migrationSchemaTable.foreach { tableName =>
migration.setTable(tableName)
migration.table(tableName)
}
val placeholders = Map("dbName" -> config.name)
migration.setPlaceholders(placeholders.asJava)
migration.setSchemas(config.name)
// Runs flyway migrations
migration.migrate()
migration.load().migrate()
logger.info("migrations complete")
}
}
@ -85,6 +87,20 @@ object MySqlConnector {
case (k, v) => dsConfig.addDataSourceProperty(k, v)
}
new HikariDataSource(dsConfig)
def retry[T](times: Int, delayMs: Int)(op: => T) =
Iterator
.range(0, times)
.map(_ => Try(op))
.flatMap {
case Success(t) => Some(t)
case Failure(_) =>
logger.warn("failed to startup database connection, retrying..")
Thread.sleep(delayMs)
None
}
.toSeq
.head
retry(60, 1000) { new HikariDataSource(dsConfig) }
}
}

View File

@ -1,4 +1,4 @@
# Vinyl Portal
# VinylDNS Portal
Supplies a UI for and offers authentication into Vinyl, a DNSaaS offering.
# Running Unit Tests
@ -7,18 +7,7 @@ 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 frontend code is tested using Jasmine, spec files are stored in the same directory as the angular js files.
For example, the public/lib/controllers has both the controller files and the specs for those controllers. To run
these tests the command is `grunt unit`
# Running Functional Tests
As of now, we have a functional testing harness that gets things set up, and a single test which tests if the login page
loads successfully. Run the following commands from the vinyl-portal folder as well, we are not using a VM for testing
at this time.
`./run_all_tests.sh` will run the unit tests (`sbt clean coverage test`), and then set up and run the func tests
`./run_func_tests.sh` will only set up and run the func tests
The front end tests can be run from the `test/portal/fuctional` directory by simply running `make`.
# Building Locally
@ -42,8 +31,7 @@ available so that you can start the portal locally and test.
`sbt -Djavax.net.ssl.trustStore="./private/trustStore.jks"`
# Updating the trustStore Certificates
Sometime on or before May 05, 2020 the certificates securing the AD servers will need to be renewed and updated.
When this happens or some other event causes the LDAP lookup to fail because of SSL certificate issues, follow
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 <ldap server>:<port>`. 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.
@ -56,10 +44,3 @@ the following steps to update the trustStore with the new certificates.
- Answer yes to trust the certificate
The trustStore is now updated with the new certificate. You can delete the certificate file it is no longer needed.
# Credits
* [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)
* [htmlunit](http://htmlunit.sourceforge.net/)
* [htmlunit-core-js](https://github.com/HtmlUnit/htmlunit-core-js) - [Mozilla Public License v2.0](https://www.mozilla.org/en-US/MPL/2.0/)

View File

@ -1,32 +0,0 @@
#!/usr/bin/env bash
# allow skipping with env var
if [ "$SKIP_MYSQL_WAIT" -eq "1" ]; then
exit 0
fi
# the mysql address, default to a local docker setup
MYSQL_ADDRESS=${MYSQL_ADDRESS:-vinyldns-mysql}
MYSQL_PORT=${MYSQL_PORT:-3306}
echo "Waiting for MYSQL to be ready on ${MYSQL_ADDRESS}:${MYSQL_PORT}"
DATA=""
RETRY=30
while [ "$RETRY" -gt 0 ]
do
DATA=$(nc -vzw1 "$MYSQL_ADDRESS" "$MYSQL_PORT")
if [ $? -eq 0 ]
then
break
else
echo "Retrying" >&2
let RETRY-=1
sleep .5
if [ "$RETRY" -eq 0 ]
then
echo "Exceeded retries waiting for MYSQL to be ready on ${MYSQL_ADDRESS}:${MYSQL_PORT}, failing"
return 1
fi
fi
done

View File

@ -7,6 +7,6 @@ npm install -f
npm install grunt -g -f
grunt default
$DIR/../../bin/add-license-headers.sh -d=$DIR/public/lib -f=js
$DIR/../../utils/add-license-headers.sh -d=$DIR/public/lib -f=js
cd -

17
quickstart/.env Normal file
View File

@ -0,0 +1,17 @@
REST_PORT=9000
# portal settings
PORTAL_PORT=9001
PLAY_HTTP_SECRET_KEY=change-this-for-prod
VINYLDNS_BACKEND_URL=http://vinyldns-integration:9000
SQS_ENDPOINT=http://vinyldns-integration:19003
MYSQL_ENDPOINT=vinyldns-integration:19002
TEST_LOGIN=true
JDBC_DRIVER=org.mariadb.jdbc.Driver
JDBC_URL=jdbc:mariadb://vinyldns-integration:19002/vinyldns?user=root&password=pass
JDBC_MIGRATION_URL=jdbc:mariadb://vinyldns-integration:19002/?user=root&password=pass
JDBC_USER=root
JDBC_PASSWORD=pass
DEFAULT_DNS_ADDRESS=127.0.0.1:19001

Some files were not shown because too many files have changed in this diff Show More