You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by oc...@apache.org on 2021/02/02 18:10:58 UTC
[trafficcontrol] branch master updated: Add ort integration
testing. (#5298)
This is an automated email from the ASF dual-hosted git repository.
ocket8888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new 9902027 Add ort integration testing. (#5298)
9902027 is described below
commit 9902027971323ce3ce3f9aa3aad543a072cb2caa
Author: John J. Rushford <jr...@apache.org>
AuthorDate: Tue Feb 2 11:10:44 2021 -0700
Add ort integration testing. (#5298)
---
LICENSE | 4 +-
traffic_ops_ort/testing/README.md | 102 +
traffic_ops_ort/testing/docker/db_init/Dockerfile | 42 +
traffic_ops_ort/testing/docker/db_init/dbInit.sh | 30 +
traffic_ops_ort/testing/docker/docker-compose.yml | 101 +
traffic_ops_ort/testing/docker/ort_test/Dockerfile | 52 +
.../testing/docker/ort_test/Ort-test.repo | 22 +
traffic_ops_ort/testing/docker/ort_test/run.sh | 82 +
.../testing/docker/ort_test/systemctl.sh | 53 +
.../testing/docker/traffic_ops/Dockerfile | 62 +
.../docker/traffic_ops/profile.origin.traffic_ops | 18 +
traffic_ops_ort/testing/docker/traffic_ops/run.sh | 278 ++
.../testing/docker/traffic_vault/Dockerfile | 63 +
.../testing/docker/traffic_vault/functions | 707 +++
.../testing/docker/traffic_vault/run.sh | 126 +
.../testing/docker/traffic_vault/sslkeys.xml | 55 +
traffic_ops_ort/testing/docker/variables.env | 37 +
.../testing/docker/yumserver/Dockerfile | 33 +
traffic_ops_ort/testing/docker/yumserver/run.sh | 24 +
.../testing/docker/yumserver/test-rpms/README.md | 23 +
.../ort-tests/baseline-configs/astats.config | 5 +
.../baseline-configs/hdr_rw_first_ds-top.config | 2 +
.../ort-tests/baseline-configs/hosting.config | 2 +
.../ort-tests/baseline-configs/parent.config | 5 +
.../ort-tests/baseline-configs/records.config | 23 +
.../ort-tests/baseline-configs/remap.config | 3 +
.../ort-tests/baseline-configs/storage.config | 2 +
.../ort-tests/baseline-configs/volume.config | 3 +
.../testing/ort-tests/conf/docker-edge-cache.conf | 38 +
.../testing/ort-tests/conf/edge-host.conf | 38 +
traffic_ops_ort/testing/ort-tests/config/config.go | 283 ++
traffic_ops_ort/testing/ort-tests/t3c_mode_test.go | 159 +
traffic_ops_ort/testing/ort-tests/tc-fixtures.json | 4664 ++++++++++++++++++++
.../testing/ort-tests/tcdata/cachegroups.go | 116 +
.../ort-tests/tcdata/cachegroups_parameters.go | 103 +
.../tcdata/cachegroupsdeliveryservices.go | 153 +
.../testing/ort-tests/tcdata/cdnfederations.go | 67 +
traffic_ops_ort/testing/ort-tests/tcdata/cdns.go | 60 +
.../testing/ort-tests/tcdata/coordinates.go | 55 +
.../tcdata/deliveryservice_request_comments.go | 66 +
.../ort-tests/tcdata/deliveryservice_requests.go | 64 +
.../testing/ort-tests/tcdata/deliveryservices.go | 90 +
.../deliveryservices_required_capabilities.go | 212 +
.../ort-tests/tcdata/deliveryservicesregexes.go | 106 +
.../testing/ort-tests/tcdata/divisions.go | 56 +
.../ort-tests/tcdata/federation_resolvers.go | 118 +
.../testing/ort-tests/tcdata/federation_users.go | 165 +
.../testing/ort-tests/tcdata/fixtures.go | 43 +
.../testing/ort-tests/tcdata/origins.go | 56 +
.../testing/ort-tests/tcdata/parameters.go | 89 +
.../testing/ort-tests/tcdata/phys_locations.go | 59 +
.../testing/ort-tests/tcdata/profile_parameters.go | 104 +
.../testing/ort-tests/tcdata/profiles.go | 142 +
.../testing/ort-tests/tcdata/regions.go | 89 +
traffic_ops_ort/testing/ort-tests/tcdata/roles.go | 77 +
.../testing/ort-tests/tcdata/servercapabilities.go | 50 +
.../ort-tests/tcdata/servercheckextension.go | 125 +
.../testing/ort-tests/tcdata/serverchecks.go | 85 +
.../testing/ort-tests/tcdata/servers.go | 143 +
.../ort-tests/tcdata/serverservercapability.go | 286 ++
.../testing/ort-tests/tcdata/servicecategories.go | 61 +
.../testing/ort-tests/tcdata/session.go | 55 +
.../testing/ort-tests/tcdata/staticdnsentries.go | 59 +
.../testing/ort-tests/tcdata/statuses.go | 62 +
.../testing/ort-tests/tcdata/steeringtargets.go | 145 +
traffic_ops_ort/testing/ort-tests/tcdata/tcdata.go | 74 +
.../testing/ort-tests/tcdata/tenants.go | 91 +
traffic_ops_ort/testing/ort-tests/tcdata/todb.go | 376 ++
.../testing/ort-tests/tcdata/topologies.go | 77 +
traffic_ops_ort/testing/ort-tests/tcdata/types.go | 101 +
traffic_ops_ort/testing/ort-tests/tcdata/user.go | 90 +
.../testing/ort-tests/tcdata/withobjs.go | 115 +
.../testing/ort-tests/traffic_ops_ort_test.go | 117 +
traffic_ops_ort/testing/ort-tests/util/util.go | 95 +
.../github.com/kelseyhightower/envconfig/LICENSE | 0
.../kelseyhightower/envconfig/MAINTAINERS | 0
.../github.com/kelseyhightower/envconfig/README.md | 0
.../github.com/kelseyhightower/envconfig/doc.go | 0
.../github.com/kelseyhightower/envconfig/env_os.go | 0
.../kelseyhightower/envconfig/env_syscall.go | 0
.../kelseyhightower/envconfig/envconfig.go | 0
.../envconfig/envconfig_1.8_test.go | 0
.../kelseyhightower/envconfig/envconfig_test.go | 0
.../kelseyhightower/envconfig/testdata/custom.txt | 0
.../envconfig/testdata/default_list.txt | 0
.../envconfig/testdata/default_table.txt | 0
.../kelseyhightower/envconfig/testdata/fault.txt | 0
.../github.com/kelseyhightower/envconfig/usage.go | 0
.../kelseyhightower/envconfig/usage_test.go | 0
89 files changed, 11436 insertions(+), 2 deletions(-)
diff --git a/LICENSE b/LICENSE
index ebfc84d..7ae9bb8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -382,8 +382,8 @@ The riak-go-client component is used under the Apache license:
./vendor/github.com/basho/riak-go-client/LICENSE
The envconfig component is used under the MIT license:
-@traffic_ops/vendor/github.com/kelseyhightower/envconfig/*
-./traffic_ops/vendor/github.com/kelseyhightower/envconfig/LICENSE
+@vendor/github.com/kelseyhightower/envconfig/*
+./vendor/github.com/kelseyhightower/envconfig/LICENSE
The govalidator component is used under the MIT license:
@vendor/github.com/asaskevich/govalidator/*
diff --git a/traffic_ops_ort/testing/README.md b/traffic_ops_ort/testing/README.md
new file mode 100644
index 0000000..6d3bc16
--- /dev/null
+++ b/traffic_ops_ort/testing/README.md
@@ -0,0 +1,102 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+
+# Traffic Ops ORT Tests
+
+The ORT tests are used to validate the ORT tools used with a
+release of Traffic Ops. The tests ensure that the ORT tools
+are able to communicate with Traffic Ops, install required
+packages and generate the correct ATS configuration files on
+a Trafficserver cache.
+
+The first thing you need do is to provide the Traffic Ops and
+Traffic Ops ORT RPM files for the build you wish to test using
+this framework. This test environment provides the necessary
+Docker containers used to support and execute the tests when
+given the necessary RPM's. If you choose to not use the provided
+Docker containers you will need to provide the following resources:
+
+ - A running Traffic Ops with the installed release to be tested
+ - A running Postgres SQL database which is loaded with the proper
+ test data for the Traffic Ops release.
+ - An Apache Traffic Server host that has the installed release of
+ ORT to be tested against the release of Traffic Ops.
+ - A yum server configured to provide the test rpm's herein.
+ - A Traffic vault server.
+
+# Directory layout
+
+ - trafficcontrol/traffic_ops_ort/testing/docker: has all the
+ necessary files for running the test Docker containers.
+ - trafficcontrol/traffic_ops_ort/testing/ort-tests: this directory.
+ contains all the go files used to run the ORT tests.
+
+# Setup.
+
+ 1. Build the Traffic Ops and Traffic Ops ORT RPM's that you wish
+ to test. See the top level 'build' directory for building
+ instructions.
+ 2. Copy the Traffic Ops RPM to docker/trafffic_ops/traffic_ops.rpm
+ (NOTE: Use the file name 'traffic_ops.rpm')
+ 3. Copy the Traffic Ops ORT rpm to docker/ort_test/traffic_ops_ort.rpm
+ (NOTE: Use the file name 'traffic_ops_ort.rpm'
+ 4. Copy the recent copy of riak-2.2.3-1.el7.centos.x86_64.rpm to
+ docker/traffic_vault/riak-2.2.3-1.el7.centos.x86_64.rpm
+ 5. Copy an Apache Trafficserver rpm to
+ docker/yumserver/test-rpms/trafficserver-$VERSION.$COMMIT-HASH.el7.x86_64.rpm
+ You will need to edit and adjust the trafficserver package value in
+ ort-tests/tc-fixtures.json to match the $VERSION.$COMMIT-HASH used in the name
+ of your RPM. Search for '8.0.8-19.77cb23a' in the ort-tests/tc-fixtures.json
+ and change the value to match the RPM version you choose to use.
+ For example, the current value in tc-fixtures.json is '8.0.8-19.77cb23a' and
+ therefore the rpm file expected in 'docker/yumserver/test-rpms' is
+ 'trafficserver-8.0.8-19.77cb23a.el7.x86_64.rpm'.
+ 6. The container Docker files have the usernames and passwords used in the various
+ containers ie, postgresql db, traffic_ops, and traffic_ops_ort. The usernames
+ and passwords passed to the 't3c' executable in in the
+ ort-tests/conf/docker-edge-cache.conf file. Make sure that the usernames/passwords
+ in the Docker files match those in the t3c configuration file.
+ An example ort-tests/conf/edge-cache.conf file is provided should you choose to
+ use your own Traffic Ops and Postgresql environment.
+ 7. Build the Docker images and run the ort test:
+ ```
+ cd trafficcontrol/traffic_ops_ort/testing/docker
+ docker-compose build
+ docker-compose run ort_test
+ ```
+ After some time, test results should be available at
+ 'ort-tests/test.log'
+
+ If you wish to run the tests manually use 'docker ps' to obtain the container id for
+ the ort_test host and then:
+
+ ```
+ docker exec -it $ort_test /bin/bash -l
+ cd /ort-tests
+ go test -cfg=conf/docker-edge-cache.conf
+ ```
+
+ If you wish to run the tests manually using your own environment, create a config
+ file with the necessary login information in the 'conf' directory and then rerun
+ the tests using your config file. WARNING: the traffic ops database will be dropped
+ and initialized using the data in tc-fixtures.json and then the tests are run.
+ DO NOT USE a production Traffic Ops database with these test scripts.
+
+
+
diff --git a/traffic_ops_ort/testing/docker/db_init/Dockerfile b/traffic_ops_ort/testing/docker/db_init/Dockerfile
new file mode 100644
index 0000000..fdc1da6
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/db_init/Dockerfile
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+############################################################
+# Dockerfile to initialized Traffic Ops Database container
+# Based on CentOS 7.2
+############################################################
+
+FROM centos/systemd
+
+RUN yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
+
+RUN yum -y install \
+ postgresql96 \
+ nmap-ncat \
+ cpanminus && \
+ yum clean all
+
+ENV POSTGRES_HOME $POSTGRES_HOME
+ENV PGPASSWORD $PGPASSWORD
+ENV DB_USERNAME $DB_USERNAME
+ENV DB_NAME $DB_NAME
+ENV DB_USER_PASS $DB_USER_PASS
+ENV DB_SERVER $DB_SERVER
+ENV DB_PORT $DB_PORT
+
+ADD db_init/dbInit.sh /
+CMD /dbInit.sh
diff --git a/traffic_ops_ort/testing/docker/db_init/dbInit.sh b/traffic_ops_ort/testing/docker/db_init/dbInit.sh
new file mode 100755
index 0000000..f4392d4
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/db_init/dbInit.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+############################################################
+# Script for creating the database user account for traffic
+# ops.
+# Used while the Docker Image is initializing itself
+############################################################
+
+while ! nc $DB_SERVER $DB_PORT </dev/null; do # &>/dev/null; do
+ echo "waiting for $DB_SERVER:$DB_PORT"
+ sleep 3
+done
+psql -h $DB_SERVER -U postgres -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_USER_PASS'"
+createdb $DB_NAME -h $DB_SERVER -U postgres --owner $DB_USER
diff --git a/traffic_ops_ort/testing/docker/docker-compose.yml b/traffic_ops_ort/testing/docker/docker-compose.yml
new file mode 100644
index 0000000..d744f68
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/docker-compose.yml
@@ -0,0 +1,101 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+# Build trafficcontrol:
+# Copy the traffic_ops rpm to traffic_ops/traffic_ops.rpm
+# Copy the traffic_ops_ort rpm to ort_test/traffic_ops_ort.rpm
+# Copy an ATS rpm to yumserver/test-rpms and update the
+# ../ort-tests/tc-fixtures.json to match the rpm version
+# string you've chosen
+# Copy the riak-2.2.3-1.el7.centos.x86_64.rpm to traffic_vault/
+#
+# Run: docker-compose build
+# Run: docker-compose run ort_test
+#
+
+---
+version: '2'
+
+volumes:
+ trafficcontrol:
+ traffic_ops:
+ conf:
+
+services:
+ db:
+ image: postgres:9.6.6
+ ports:
+ - "5432:5432"
+
+ db_init:
+ env_file:
+ - variables.env
+ build:
+ context: .
+ dockerfile: db_init/Dockerfile
+ depends_on:
+ - db
+
+ to_server:
+ env_file:
+ - variables.env
+ ports:
+ - "443:443"
+ build:
+ context: .
+ dockerfile: traffic_ops/Dockerfile
+ args:
+ RPM: traffic_ops.rpm
+ volumes:
+ - ../../../GO_VERSION:/GO_VERSION
+ depends_on:
+ - db_init
+
+ traffic_vault:
+ env_file:
+ - variables.env
+ ports:
+ - "8087:8087"
+ - "8088:8088"
+ - "8098:8098"
+ build:
+ context: .
+ dockerfile: traffic_vault/Dockerfile
+ depends_on:
+ - to_server
+
+ ort_test:
+ env_file:
+ - variables.env
+ build:
+ context: .
+ dockerfile: ort_test/Dockerfile
+ depends_on:
+ - yumserver
+ - to_server
+ - traffic_vault
+ volumes:
+ - ../../..:/root/go/src/github.com/apache/trafficcontrol
+
+ yumserver:
+ build:
+ context: .
+ dockerfile: yumserver/Dockerfile
+ depends_on:
+ - db_init
+ volumes:
+ - ./yumserver/test-rpms:/var/www/html/traffic-control/7/x86_64/Packages
diff --git a/traffic_ops_ort/testing/docker/ort_test/Dockerfile b/traffic_ops_ort/testing/docker/ort_test/Dockerfile
new file mode 100644
index 0000000..3704503
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/ort_test/Dockerfile
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+############################################################
+# Dockerfile to build Traffic Server container images
+# as Edges for Traffic Control 1.4
+# Based on CentOS 6.6
+############################################################
+
+# For cache, you may either use (RAM or disk) block devices or disk directories
+# To use RAM block devices, pass them as /dev/ram0 and /dev/ram1 via `docker run --device`
+# To use disk directories, simply don't pass devices, and the container will configure Traffic Server for directories
+
+# Block devices may be created on the native machine with, for example, `modprobe brd`.
+# The recommended minimum size for each block devices is 1G.
+# For example, `sudo modprobe brd rd_size=1048576 rd_nr=2`
+
+FROM centos:7
+MAINTAINER dev@trafficcontrol.apache.org
+
+RUN yum install -y \
+ https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm \
+ epel-release initscripts postgresql96.x86_64 git gcc lua-5.1.4-15.el7 lua-devel-5.1.4-15.el7 \
+ ImageMagick-c++-devel
+
+ARG RPM=traffic_ops_ort.rpm
+ADD ort_test/$RPM /
+RUN yum install -y /$(basename $RPM)
+
+RUN sed -i 's/HOME\/bin/HOME\/bin:\/usr\/local\/go\/bin:/g' /root/.bash_profile
+RUN echo "GOPATH=/root/go; export GOPATH" >> /root/.bash_profile
+RUN mkdir /root/go
+
+EXPOSE 80 443
+ADD ort_test/run.sh /
+ADD ort_test/Ort-test.repo /etc/yum.repos.d
+ADD ort_test/systemctl.sh /
+
+ENTRYPOINT /run.sh
diff --git a/traffic_ops_ort/testing/docker/ort_test/Ort-test.repo b/traffic_ops_ort/testing/docker/ort_test/Ort-test.repo
new file mode 100644
index 0000000..ef416ef
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/ort_test/Ort-test.repo
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+[traffic-control]
+name=traffic-control
+enabled=1
+gpgcheck=0
+baseurl=http://yumserver/traffic-control/7/x86_64/
diff --git a/traffic_ops_ort/testing/docker/ort_test/run.sh b/traffic_ops_ort/testing/docker/ort_test/run.sh
new file mode 100755
index 0000000..a87065d
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/ort_test/run.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+# wait period to insure all containers are up and running.
+WAIT="60"
+
+#
+# this seems to wake up the to container.
+#
+function ping_to {
+ /opt/ort/t3c \
+ "--traffic-ops-insecure=true" \
+ "--traffic-ops-timeout-milliseconds=3000" \
+ "--traffic-ops-user=$TO_ADMIN_USER" \
+ "--traffic-ops-password=$TO_ADMIN_PASS" \
+ "--traffic-ops-url=$TO_URI" \
+ "--cache-host-name=atlanta-edge-03" \
+ "--log-location-error=stderr" \
+ "--log-location-info=stderr" \
+ "--log-location-debug=stderr" \
+ "--run-mode=badass"
+}
+
+set -x
+GOPATH=/root/go; export GOPATH
+PATH=$PATH:/usr/local/go/bin:; export PATH
+TERM=xterm; export TERM
+
+# setup some convienient links
+/bin/ln -s /root/go/src/github.com/apache/trafficcontrol /trafficcontrol
+/bin/ln -s /trafficcontrol/traffic_ops_ort/testing/ort-tests /ort-tests
+
+if [ -f /trafficcontrol/GO_VERSION ]; then
+ go_version=$(cat /trafficcontrol/GO_VERSION) && \
+ curl -Lo go.tar.gz https://dl.google.com/go/go${go_version}.linux-amd64.tar.gz && \
+ tar -C /usr/local -xvzf go.tar.gz && \
+ ln -s /usr/local/go/bin/go /usr/bin/go && \
+ rm go.tar.gz
+else
+ echo "no GO_VERSION file, unable to install go"
+ exit 0
+fi
+
+# fetch dependent packages for tests
+go get golang.org/x/crypto/scrypt
+go get golang.org/x/net/publicsuffix
+
+if [ -f /systemctl.sh ]; then
+ mv /bin/systemctl /bin/systemctl.save
+ cp /systemctl.sh /bin/systemctl
+ chmod 0755 /bin/systemctl
+fi
+
+cd /ort-tests
+echo "Sleeping for $WAIT seconds to ensure all containers have initialized" >> test.log
+sleep $WAIT
+echo "Running tests" >> test.log
+
+# wake up the to_server
+ping_to
+sleep 2
+
+(touch test.log && tail -f test.log)&
+go test -cfg=conf/docker-edge-cache.conf 2>&1 >> test.log
+
diff --git a/traffic_ops_ort/testing/docker/ort_test/systemctl.sh b/traffic_ops_ort/testing/docker/ort_test/systemctl.sh
new file mode 100755
index 0000000..c4b8720
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/ort_test/systemctl.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+# This is a work around for testing t3c which uses systemctl.
+# systemctl does not work in a container very well so this script
+# replaces systemctl in the container and always returns a
+# sucessful result to t3c.
+
+USAGE="\nsystemctl COMMAND NAME\n"
+
+if [ -z $1 ] || [ -z $2 ]; then
+ echo -e $USAGE
+ exit 0
+else
+ COMMAND=$1
+ NAME=$2
+fi
+
+if [ "$2" != "trafficserver" ]; then
+ echo -e "\nFailed to start ${NAME}.service: Unit not found.n"
+ exit 0
+fi
+
+case $COMMAND in
+ enable)
+ ;;
+ restart)
+ ;;
+ status)
+ ;;
+ start)
+ ;;
+ stop)
+ ;;
+esac
+
+exit 0
diff --git a/traffic_ops_ort/testing/docker/traffic_ops/Dockerfile b/traffic_ops_ort/testing/docker/traffic_ops/Dockerfile
new file mode 100644
index 0000000..5780b1c
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/traffic_ops/Dockerfile
@@ -0,0 +1,62 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+############################################################
+# Dockerfile to build Traffic Ops container images
+# Based on CentOS 7.2
+############################################################
+
+# Example Build and Run:
+# docker network create cdnet
+# docker build --rm --tag traffic_ops:1.7.0 --build-arg=RPM=http://traffic-control-cdn.net/downloads/1.7.0/RELEASE-1.7.0/traffic_ops-1.7.0-3908.5b77f60f.x86_64.rpm traffic_ops
+#
+# docker run --name my-traffic-ops-mysql --hostname my-traffic-ops-mysql --net cdnet --env MYSQL_ROOT_PASSWORD=secretrootpass --detach mysql:5.5
+#
+# docker run --name my-traffic-ops --hostname my-traffic-ops --net cdnet --publish 443:443 --env MYSQL_IP=my-traffic-ops-mysql --env MYSQL_PORT=3306 --env MYSQL_ROOT_PASS=secretrootpass --env MYSQL_TRAFFIC_OPS_PASS=supersecretpassword --env ADMIN_USER=superroot --env ADMIN_PASS=supersecreterpassward --env CERT_COUNTRY=US --env CERT_STATE=Colorado --env CERT_CITY=Denver --env CERT_COMPANY=NotComcast --env TRAFFIC_VAULT_PASS=marginallylesssecret --env DOMAIN=cdnet --detach traffic_ops:1.5.1
+
+FROM centos/systemd
+MAINTAINER dev@trafficcontrol.apache.org
+
+RUN yum install -y \
+ https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm \
+ initscripts epel-release perl-Crypt-ScryptKDF perl cpanminus perl-Test-CPAN-Meta perl-DBIx-Connector
+
+RUN cpanm Carton
+
+# Override RPM arg to use a different one using --build-arg RPM=... Can be local file or http://...
+ARG RPM=traffic_ops.rpm
+ADD traffic_ops/$RPM /
+RUN yum install -y /$(basename $RPM)
+
+# once installed, remove rpm to lower image size
+RUN rm /$(basename $RPM)
+
+RUN POSTGRES_HOME=/usr/pgsql-9.6 cd /opt/traffic_ops/app && carton
+
+RUN export PERL5LIB=/opt/traffic_ops/app/local/lib/perl5/:/opt/traffic_ops/install/lib/ \
+ && export TERM=xterm \
+ && export USER=root
+
+# fixes an 'Invalid Argument' bug; TODO diagnose , fix, & remove
+RUN cp /opt/traffic_ops/app/bin/traffic_ops_golang{,.new} && mv /opt/traffic_ops/app/bin/traffic_ops_golang{.new,}
+
+EXPOSE 443
+WORKDIR /opt/traffic_ops/app
+ENV MOJO_MODE production
+ADD traffic_ops/profile.origin.traffic_ops /
+ADD traffic_ops/run.sh /
+CMD /run.sh
diff --git a/traffic_ops_ort/testing/docker/traffic_ops/profile.origin.traffic_ops b/traffic_ops_ort/testing/docker/traffic_ops/profile.origin.traffic_ops
new file mode 100644
index 0000000..f655f89
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/traffic_ops/profile.origin.traffic_ops
@@ -0,0 +1,18 @@
+{
+ "parameters": [
+ {
+ "config_file": "CRConfig.json",
+ "name": "domain_name",
+ "value": "{{.Domain}}"
+ },
+ {
+ "config_file": "parent.config",
+ "name": "weight",
+ "value": "1.0"
+ }
+ ],
+ "profile": {
+ "description": "Multi site origin profile 1",
+ "name": "ORG1_CDN1"
+ }
+}
diff --git a/traffic_ops_ort/testing/docker/traffic_ops/run.sh b/traffic_ops_ort/testing/docker/traffic_ops/run.sh
new file mode 100755
index 0000000..4253dbd
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/traffic_ops/run.sh
@@ -0,0 +1,278 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+# Script for running the Dockerfile for Traffic Ops.
+# The Dockerfile sets up a Docker image which can be used for any new Traffic Ops container;
+# This script, which should be run when the container is run (it's the ENTRYPOINT), will configure the container.
+#
+# The following environment variables must be set, ordinarily by `docker run -e` arguments:
+# DB_SERVER
+# DB_PORT
+# DB_ROOT_PASS
+# DB_USER
+# DB_USER_PASS
+# DB_NAME
+# TO_ADMIN_USER
+# TO_ADMIN_PASS
+# CERT_COUNTRY
+# CERT_STATE
+# CERT_CITY
+# CERT_COMPANY
+# TO_DOMAIN
+# TRAFFIC_VAULT_PASS
+
+# Check that env vars are set
+envvars=( DB_SERVER DB_PORT DB_ROOT_PASS DB_USER DB_USER_PASS TO_ADMIN_USER TO_ADMIN_PASS CERT_COUNTRY CERT_STATE CERT_CITY CERT_COMPANY TO_DOMAIN)
+for v in $envvars
+do
+ if [[ -z $$v ]]; then echo "$v is unset"; exit 1; fi
+done
+
+start() {
+ service traffic_ops start
+ exec tail -f /var/log/traffic_ops/traffic_ops.log
+}
+
+init() {
+ local postinstall_input_file="postinstall-input.json"
+ cat > "$postinstall_input_file" <<- ENDOFMESSAGE
+{
+ "/opt/traffic_ops/app/conf/production/database.conf":[
+ {
+ "Database type":"Pg",
+ "config_var":"type"
+ },
+ {
+ "Database name":"$DB_NAME",
+ "config_var":"dbname"
+ },
+ {
+ "Database server hostname IP or FQDN":"$DB_SERVER",
+ "config_var":"hostname"
+ },
+ {
+ "Database port number":"$DB_PORT",
+ "config_var":"port"
+ },
+ {
+ "Traffic Ops database user":"$DB_USER",
+ "config_var":"user"
+ },
+ {
+ "Traffic Ops database password":"$DB_USER_PASS",
+ "config_var":"password",
+ "hidden":"1"
+ }
+ ],
+ "/opt/traffic_ops/app/db/dbconf.yml":[
+ {
+ "Database server root (admin) user":"postgres",
+ "config_var":"pgUser"
+ },
+ {
+ "Database server admin password":"$DB_ROOT_PASS",
+ "config_var":"pgPassword",
+ "hidden":"1"
+ },
+ {
+ "Download Maxmind Database?":"yes",
+ "config_var":"maxmind"
+ }
+ ],
+ "/opt/traffic_ops/app/conf/cdn.conf":[
+ {
+ "Generate a new secret?":"yes",
+ "config_var":"genSecret"
+ },
+ {
+ "Port to serve on?": "443",
+ "config_var": "port"
+ },
+ {
+ "Number of workers?": "12",
+ "config_var":"workers"
+ },
+ {
+ "Traffic Ops url?": "https://$TO_HOSTNAME",
+ "config_var": "base_url"
+ },
+ {
+ "Number of secrets to keep?":"1",
+ "config_var":"keepSecrets"
+ }
+ ],
+ "/opt/traffic_ops/app/conf/ldap.conf":[
+ {
+ "Do you want to set up LDAP?":"no",
+ "config_var":"setupLdap"
+ },
+ {
+ "LDAP server hostname":"",
+ "config_var":"host"
+ },
+ {
+ "LDAP Admin DN":"",
+ "config_var":"admin_dn"
+ },
+ {
+ "LDAP Admin Password":"",
+ "config_var":"admin_pass",
+ "hidden":"1"
+ },
+ {
+ "LDAP Search Base":"",
+ "config_var":"search_base"
+ }
+ ],
+ "/opt/traffic_ops/install/data/json/users.json":[
+ {
+ "Administration username for Traffic Ops":"$TO_ADMIN_USER",
+ "config_var":"tmAdminUser"
+ },
+ {
+ "Password for the admin user":"$TO_ADMIN_PASS",
+ "config_var":"tmAdminPw",
+ "hidden":"1"
+ }
+ ],
+ "/opt/traffic_ops/install/data/profiles/":[
+ {
+ "Add custom profiles?":"no",
+ "config_var":"custom_profiles"
+ }
+ ],
+ "/opt/traffic_ops/install/data/json/openssl_configuration.json":[
+ {
+ "Do you want to generate a certificate?":"yes",
+ "config_var":"genCert"
+ },
+ {
+ "Country Name (2 letter code)":"$CERT_COUNTRY",
+ "config_var":"country"
+ },
+ {
+ "State or Province Name (full name)":"$CERT_STATE",
+ "config_var":"state"
+ },
+ {
+ "Locality Name (eg, city)":"$CERT_CITY",
+ "config_var":"locality"
+ },
+ {
+ "Organization Name (eg, company)":"$CERT_COMPANY",
+ "config_var":"company"
+ },
+ {
+ "Organizational Unit Name (eg, section)":"",
+ "config_var":"org_unit"
+ },
+ {
+ "Common Name (eg, your name or your server's hostname)":"$TO_HOSTNAME",
+ "config_var":"common_name"
+ },
+ {
+ "RSA Passphrase":"passphrase",
+ "config_var":"rsaPassword",
+ "hidden":"1"
+ }
+ ],
+ "/opt/traffic_ops/install/data/json/profiles.json":[
+ {
+ "Traffic Ops url":"https://$TO_HOSTNAME",
+ "config_var":"tm.url"
+ },
+ {
+ "Human-readable CDN Name. (No whitespace, please)":"cdn",
+ "config_var":"cdn_name"
+ },
+ {
+ "Health Polling Interval (milliseconds)":"8000",
+ "config_var":"health_polling_int"
+ },
+ {
+ "DNS sub-domain for which your CDN is authoritative":"$TO_HOSTNAME.$TO_DOMAIN",
+ "config_var":"dns_subdomain"
+ },
+ {
+ "TLD SOA admin":"traffic_ops",
+ "config_var":"soa_admin"
+ },
+ {
+ "TrafficServer Drive Prefix":"/dev/ram",
+ "config_var":"driver_prefix"
+ },
+ {
+ "TrafficServer RAM Drive Prefix":"/dev/ram",
+ "config_var":"ram_drive_prefix"
+ },
+ {
+ "TrafficServer RAM Drive Letters (comma separated)":"1",
+ "config_var":"ram_drive_letters"
+ },
+ {
+ "Health Threshold Load Average":"25",
+ "config_var":"health_thresh_load_avg"
+ },
+ {
+ "Health Threshold Available Bandwidth in Kbps":"1750000",
+ "config_var":"health_thresh_kbps"
+ },
+ {
+ "Traffic Server Health Connection Timeout (milliseconds)":"2000",
+ "config_var":"health_connect_timeout"
+ }
+ ]
+}
+ENDOFMESSAGE
+
+cat > /opt/traffic_ops/app/conf/production/riak.conf << EOM
+{
+ "user": "riakuser",
+ "password": "$RIAK_USER_PASS",
+ "MaxTLSVersion": "1.1",
+ "tlsConfig": {
+ "insecureSkipVerify": true
+ }
+}
+EOM
+
+ # TODO determine if term, user are necessary
+ export TERM=xterm && export USER=root && /opt/traffic_ops/install/bin/postinstall -cfile "$postinstall_input_file"
+
+ # Only listen on IPv4, not IPv6, because Docker doesn't provide a v6 interface by default. See http://mojolicious.org/perldoc/Mojo/Server/Daemon#listen
+ sed -i -e 's#https://\[::\]#https://127\.0\.0\.1#' /opt/traffic_ops/app/conf/cdn.conf
+ service traffic_ops restart
+
+}
+
+if [ -f /GO_VERSION ]; then
+ go_version=$(cat /GO_VERSION) && \
+ curl -Lo go.tar.gz https://dl.google.com/go/go${go_version}.linux-amd64.tar.gz && \
+ tar -C /usr/local -xvzf go.tar.gz && \
+ ln -s /usr/local/go/bin/go /usr/bin/go && \
+ rm go.tar.gz
+else
+ echo "no GO_VERSION file, unable to install go"
+ exit 0
+fi
+/opt/traffic_ops/install/bin/install_goose.sh
+
+(cd /opt/traffic_ops/app && db/admin --env=production reset)
+source /etc/environment
+if [ -z "$INITIALIZED" ]; then init; fi
+start
diff --git a/traffic_ops_ort/testing/docker/traffic_vault/Dockerfile b/traffic_ops_ort/testing/docker/traffic_vault/Dockerfile
new file mode 100644
index 0000000..754166f
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/traffic_vault/Dockerfile
@@ -0,0 +1,63 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+############################################################
+# Dockerfile to build Riak container images
+# as Traffic Vault for Traffic Control 1.6.0
+# Based on CentOS 6.6
+############################################################
+
+FROM centos:7
+MAINTAINER dev@trafficcontrol.apache.org
+
+ARG TV_ADMIN_PASS
+
+# Install openssl
+RUN yum install -y openssl
+
+# Install the initscripts
+RUN yum -y install initscripts
+
+# Install curl which is used to configure the riak search schema.
+RUN yum -y install curl
+
+# On CentOS/RedHat/Fedora (recommended)
+RUN yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
+
+# Install Riak
+ADD traffic_vault/riak-2.2.3-1.el7.centos.x86_64.rpm /
+RUN rpm -i /riak-2.2.3-1.el7.centos.x86_64.rpm
+
+# Set the Riak certs in the config (this cert+key will be created in the run.sh script
+RUN sed -i -- 's/## ssl.certfile = $(platform_etc_dir)\/cert.pem/ssl.certfile = \/etc\/riak\/certs\/server.crt/g' /etc/riak/riak.conf
+RUN sed -i -- 's/## ssl.keyfile = $(platform_etc_dir)\/key.pem/ssl.keyfile = \/etc\/riak\/certs\/server.key/g' /etc/riak/riak.conf
+RUN sed -i -- 's/## ssl.cacertfile = $(platform_etc_dir)\/cacertfile.pem/ssl.cacertfile = \/etc\/riak\/certs\/ca-bundle.crt/g' /etc/riak/riak.conf
+
+RUN sed -i -- "s/nodename = riak@127.0.0.1/nodename = riak@0.0.0.0/g" /etc/riak/riak.conf
+RUN sed -i -- "s/listener.http.internal = 127.0.0.1:8098/listener.http.internal = 0.0.0.0:8098/g" /etc/riak/riak.conf
+RUN sed -i -- "s/listener.protobuf.internal = 127.0.0.1:8087/listener.protobuf.internal = 0.0.0.0:8087/g" /etc/riak/riak.conf
+RUN sed -i -- "s/## listener.https.internal = 127.0.0.1:8098/listener.https.internal = 0.0.0.0:8088/g" /etc/riak/riak.conf
+
+RUN sed -i -- "s/search = off/search = on/g" /etc/riak/riak.conf
+
+RUN mkdir /etc/riak/certs
+
+RUN echo "tls_protocols.tlsv1.1 = on" >> /etc/riak/riak.conf
+
+EXPOSE 8098 8087 8088
+ADD traffic_vault/run.sh /
+ADD traffic_vault/sslkeys.xml /
+ENTRYPOINT /run.sh
diff --git a/traffic_ops_ort/testing/docker/traffic_vault/functions b/traffic_ops_ort/testing/docker/traffic_vault/functions
new file mode 100644
index 0000000..5ae8ba2
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/traffic_vault/functions
@@ -0,0 +1,707 @@
+# -*-Shell-script-*-
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+# functions This file contains functions to be used by most or all
+# shell scripts in the /etc/init.d directory.
+#
+
+TEXTDOMAIN=initscripts
+
+# Make sure umask is sane
+umask 022
+
+# Set up a default search path.
+PATH="/sbin:/usr/sbin:/bin:/usr/bin"
+export PATH
+
+if [ $PPID -ne 1 -a -z "$SYSTEMCTL_SKIP_REDIRECT" ] && \
+ [ -d /run/systemd/system ] ; then
+ case "$0" in
+ /etc/init.d/*|/etc/rc.d/init.d/*)
+ _use_systemctl=1
+ ;;
+ esac
+fi
+
+systemctl_redirect () {
+ local s
+ local prog=${1##*/}
+ local command=$2
+ local options=""
+
+ case "$command" in
+ start)
+ s="Starting $prog (via systemctl): "
+ ;;
+ stop)
+ s="Stopping $prog (via systemctl): "
+ ;;
+ reload|try-reload)
+ s="Reloading $prog configuration (via systemctl): "
+ ;;
+ restart|try-restart|condrestart)
+ s="Restarting $prog (via systemctl): "
+ ;;
+ esac
+
+ if [ -n "$SYSTEMCTL_IGNORE_DEPENDENCIES" ] ; then
+ options="--ignore-dependencies"
+ fi
+
+ if ! systemctl show "$prog.service" > /dev/null 2>&1 || \
+ systemctl show -p LoadState "$prog.service" | grep -q 'not-found' ; then
+ action $"Reloading systemd: " /bin/systemctl daemon-reload
+ fi
+
+ action "$s" /bin/systemctl $options $command "$prog.service"
+}
+
+# Get a sane screen width
+[ -z "${COLUMNS:-}" ] && COLUMNS=80
+
+if [ -z "${CONSOLETYPE:-}" ]; then
+ if [ -c "/dev/stderr" -a -r "/dev/stderr" ]; then
+ CONSOLETYPE="$(/sbin/consoletype < /dev/stderr 2>/dev/null)"
+ else
+ CONSOLETYPE="serial"
+ fi
+fi
+
+if [ -z "${NOLOCALE:-}" ] && [ -z "${LANGSH_SOURCED:-}" ] && \
+ [ -f /etc/sysconfig/i18n -o -f /etc/locale.conf ] ; then
+ . /etc/profile.d/lang.sh 2>/dev/null
+ # avoid propagating LANGSH_SOURCED any further
+ unset LANGSH_SOURCED
+fi
+
+# Read in our configuration
+if [ -z "${BOOTUP:-}" ]; then
+ if [ -f /etc/sysconfig/init ]; then
+ . /etc/sysconfig/init
+ else
+ # This all seem confusing? Look in /etc/sysconfig/init,
+ # or in /usr/share/doc/initscripts-*/sysconfig.txt
+ BOOTUP=color
+ RES_COL=60
+ MOVE_TO_COL="echo -en \\033[${RES_COL}G"
+ SETCOLOR_SUCCESS="echo -en \\033[1;32m"
+ SETCOLOR_FAILURE="echo -en \\033[1;31m"
+ SETCOLOR_WARNING="echo -en \\033[1;33m"
+ SETCOLOR_NORMAL="echo -en \\033[0;39m"
+ LOGLEVEL=1
+ fi
+ if [ "$CONSOLETYPE" = "serial" ]; then
+ BOOTUP=serial
+ MOVE_TO_COL=
+ SETCOLOR_SUCCESS=
+ SETCOLOR_FAILURE=
+ SETCOLOR_WARNING=
+ SETCOLOR_NORMAL=
+ fi
+fi
+
+# Check if any of $pid (could be plural) are running
+checkpid() {
+ local i
+
+ for i in $* ; do
+ [ -d "/proc/$i" ] && return 0
+ done
+ return 1
+}
+
+__kill_pids_term_kill_checkpids() {
+ local base_stime=$1
+ shift 1
+ local pid=
+ local pids=$*
+ local remaining=
+ local stat=
+ local stime=
+
+ for pid in $pids ; do
+ [ ! -e "/proc/$pid" ] && continue
+ read -r line < "/proc/$pid/stat" 2> /dev/null
+
+ stat=($line)
+ stime=${stat[21]}
+
+ [ -n "$stime" ] && [ "$base_stime" -lt "$stime" ] && continue
+ remaining+="$pid "
+ done
+
+ echo "$remaining"
+ [ -n "$remaining" ] && return 1
+
+ return 0
+}
+
+__kill_pids_term_kill() {
+ local try=0
+ local delay=3;
+ local pid=
+ local stat=($(< /proc/self/stat))
+ local base_stime=${stat[21]}
+
+ if [ "$1" = "-d" ]; then
+ delay=$2
+ shift 2
+ fi
+
+ local kill_list=$*
+
+ kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
+
+ [ -z "$kill_list" ] && return 0
+
+ kill -TERM $kill_list >/dev/null 2>&1
+ usleep 100000
+
+ kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
+ if [ -n "$kill_list" ] ; then
+ while [ $try -lt $delay ] ; do
+ sleep 1
+ kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
+ [ -z "$kill_list" ] && break
+ let try+=1
+ done
+ if [ -n "$kill_list" ] ; then
+ kill -KILL $kill_list >/dev/null 2>&1
+ usleep 100000
+ kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
+ fi
+ fi
+
+ [ -n "$kill_list" ] && return 1
+ return 0
+}
+
+# __proc_pids {program} [pidfile]
+# Set $pid to pids from /var/run* for {program}. $pid should be declared
+# local in the caller.
+# Returns LSB exit code for the 'status' action.
+__pids_var_run() {
+ local base=${1##*/}
+ local pid_file=${2:-/var/run/$base.pid}
+ local pid_dir=$(/usr/bin/dirname $pid_file > /dev/null)
+ local binary=$3
+
+ [ -d "$pid_dir" -a ! -r "$pid_dir" ] && return 4
+
+ pid=
+ if [ -f "$pid_file" ] ; then
+ local line p
+
+ [ ! -r "$pid_file" ] && return 4 # "user had insufficient privilege"
+ while : ; do
+ read line
+ [ -z "$line" ] && break
+ for p in $line ; do
+ if [ -z "${p//[0-9]/}" ] && [ -d "/proc/$p" ] ; then
+ if [ -n "$binary" ] ; then
+ local b=$(readlink /proc/$p/exe | sed -e 's/\s*(deleted)$//')
+ [ "$b" != "$binary" ] && continue
+ fi
+ pid="$pid $p"
+ fi
+ done
+ done < "$pid_file"
+
+ if [ -n "$pid" ]; then
+ return 0
+ fi
+ return 1 # "Program is dead and /var/run pid file exists"
+ fi
+ return 3 # "Program is not running"
+}
+
+# Output PIDs of matching processes, found using pidof
+__pids_pidof() {
+ pidof -c -m -o $$ -o $PPID -o %PPID -x "$1" || \
+ pidof -c -m -o $$ -o $PPID -o %PPID -x "${1##*/}"
+}
+
+
+# A function to start a program.
+daemon() {
+ # Test syntax.
+ local gotbase= force= nicelevel corelimit
+ local pid base= user= nice= bg= pid_file=
+ local cgroup=
+ nicelevel=0
+ while [ "$1" != "${1##[-+]}" ]; do
+ case $1 in
+ '')
+ echo $"$0: Usage: daemon [+/-nicelevel] {program}" "[arg1]..."
+ return 1
+ ;;
+ --check)
+ base=$2
+ gotbase="yes"
+ shift 2
+ ;;
+ --check=?*)
+ base=${1#--check=}
+ gotbase="yes"
+ shift
+ ;;
+ --user)
+ user=$2
+ shift 2
+ ;;
+ --user=?*)
+ user=${1#--user=}
+ shift
+ ;;
+ --pidfile)
+ pid_file=$2
+ shift 2
+ ;;
+ --pidfile=?*)
+ pid_file=${1#--pidfile=}
+ shift
+ ;;
+ --force)
+ force="force"
+ shift
+ ;;
+ [-+][0-9]*)
+ nice="nice -n $1"
+ shift
+ ;;
+ *)
+ echo $"$0: Usage: daemon [+/-nicelevel] {program}" "[arg1]..."
+ return 1
+ ;;
+ esac
+ done
+
+ # Save basename.
+ [ -z "$gotbase" ] && base=${1##*/}
+
+ # See if it's already running. Look *only* at the pid file.
+ __pids_var_run "$base" "$pid_file"
+
+ [ -n "$pid" -a -z "$force" ] && return
+
+ # make sure it doesn't core dump anywhere unless requested
+ corelimit="ulimit -S -c ${DAEMON_COREFILE_LIMIT:-0}"
+
+ # if they set NICELEVEL in /etc/sysconfig/foo, honor it
+ [ -n "${NICELEVEL:-}" ] && nice="nice -n $NICELEVEL"
+
+ # if they set CGROUP_DAEMON in /etc/sysconfig/foo, honor it
+ if [ -n "${CGROUP_DAEMON}" ]; then
+ if [ ! -x /bin/cgexec ]; then
+ echo -n "Cgroups not installed"; warning
+ echo
+ else
+ cgroup="/bin/cgexec";
+ for i in $CGROUP_DAEMON; do
+ cgroup="$cgroup -g $i";
+ done
+ fi
+ fi
+
+ # Echo daemon
+ [ "${BOOTUP:-}" = "verbose" -a -z "${LSB:-}" ] && echo -n " $base"
+
+ # And start it up.
+ if [ -z "$user" ]; then
+ $cgroup $nice /bin/bash -c "$corelimit >/dev/null 2>&1 ; $*"
+ else
+ $cgroup $nice runuser -s /bin/bash $user -c "$corelimit >/dev/null 2>&1 ; $*"
+ fi
+
+ [ "$?" -eq 0 ] && success $"$base startup" || failure $"$base startup"
+}
+
+# A function to stop a program.
+killproc() {
+ local RC killlevel= base pid pid_file= delay try binary=
+
+ RC=0; delay=3; try=0
+ # Test syntax.
+ if [ "$#" -eq 0 ]; then
+ echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
+ return 1
+ fi
+ if [ "$1" = "-p" ]; then
+ pid_file=$2
+ shift 2
+ fi
+ if [ "$1" = "-b" ]; then
+ if [ -z $pid_file ]; then
+ echo $"-b option can be used only with -p"
+ echo $"Usage: killproc -p pidfile -b binary program"
+ return 1
+ fi
+ binary=$2
+ shift 2
+ fi
+ if [ "$1" = "-d" ]; then
+ delay=$(echo $2 | awk -v RS=' ' -v IGNORECASE=1 '{if($1!~/^[0-9.]+[smhd]?$/) exit 1;d=$1~/s$|^[0-9.]*$/?1:$1~/m$/?60:$1~/h$/?60*60:$1~/d$/?24*60*60:-1;if(d==-1) exit 1;delay+=d*$1} END {printf("%d",delay+0.5)}')
+ if [ "$?" -eq 1 ]; then
+ echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
+ return 1
+ fi
+ shift 2
+ fi
+
+
+ # check for second arg to be kill level
+ [ -n "${2:-}" ] && killlevel=$2
+
+ # Save basename.
+ base=${1##*/}
+
+ # Find pid.
+ __pids_var_run "$1" "$pid_file" "$binary"
+ RC=$?
+ if [ -z "$pid" ]; then
+ if [ -z "$pid_file" ]; then
+ pid="$(__pids_pidof "$1")"
+ else
+ [ "$RC" = "4" ] && { failure $"$base shutdown" ; return $RC ;}
+ fi
+ fi
+
+ # Kill it.
+ if [ -n "$pid" ] ; then
+ [ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
+ if [ -z "$killlevel" ] ; then
+ __kill_pids_term_kill -d $delay $pid
+ RC=$?
+ [ "$RC" -eq 0 ] && success $"$base shutdown" || failure $"$base shutdown"
+ # use specified level only
+ else
+ if checkpid $pid; then
+ kill $killlevel $pid >/dev/null 2>&1
+ RC=$?
+ [ "$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
+ elif [ -n "${LSB:-}" ]; then
+ RC=7 # Program is not running
+ fi
+ fi
+ else
+ if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
+ RC=7 # Program is not running
+ else
+ failure $"$base shutdown"
+ RC=0
+ fi
+ fi
+
+ # Remove pid file if any.
+ if [ -z "$killlevel" ]; then
+ rm -f "${pid_file:-/var/run/$base.pid}"
+ fi
+ return $RC
+}
+
+# A function to find the pid of a program. Looks *only* at the pidfile
+pidfileofproc() {
+ local pid
+
+ # Test syntax.
+ if [ "$#" = 0 ] ; then
+ echo $"Usage: pidfileofproc {program}"
+ return 1
+ fi
+
+ __pids_var_run "$1"
+ [ -n "$pid" ] && echo $pid
+ return 0
+}
+
+# A function to find the pid of a program.
+pidofproc() {
+ local RC pid pid_file=
+
+ # Test syntax.
+ if [ "$#" = 0 ]; then
+ echo $"Usage: pidofproc [-p pidfile] {program}"
+ return 1
+ fi
+ if [ "$1" = "-p" ]; then
+ pid_file=$2
+ shift 2
+ fi
+ fail_code=3 # "Program is not running"
+
+ # First try "/var/run/*.pid" files
+ __pids_var_run "$1" "$pid_file"
+ RC=$?
+ if [ -n "$pid" ]; then
+ echo $pid
+ return 0
+ fi
+
+ [ -n "$pid_file" ] && return $RC
+ __pids_pidof "$1" || return $RC
+}
+
+status() {
+ local base pid lock_file= pid_file= binary=
+
+ # Test syntax.
+ if [ "$#" = 0 ] ; then
+ echo $"Usage: status [-p pidfile] {program}"
+ return 1
+ fi
+ if [ "$1" = "-p" ]; then
+ pid_file=$2
+ shift 2
+ fi
+ if [ "$1" = "-l" ]; then
+ lock_file=$2
+ shift 2
+ fi
+ if [ "$1" = "-b" ]; then
+ if [ -z $pid_file ]; then
+ echo $"-b option can be used only with -p"
+ echo $"Usage: status -p pidfile -b binary program"
+ return 1
+ fi
+ binary=$2
+ shift 2
+ fi
+ base=${1##*/}
+
+ if [ "$_use_systemctl" = "1" ]; then
+ systemctl status ${0##*/}.service
+ ret=$?
+ # LSB daemons that dies abnormally in systemd looks alive in systemd's eyes due to RemainAfterExit=yes
+ # lets adjust the reality a little bit
+ if systemctl show -p ActiveState ${0##*/}.service | grep -q '=active$' && \
+ systemctl show -p SubState ${0##*/}.service | grep -q '=exited$' ; then
+ ret=3
+ fi
+ return $ret
+ fi
+
+ # First try "pidof"
+ __pids_var_run "$1" "$pid_file" "$binary"
+ RC=$?
+ if [ -z "$pid_file" -a -z "$pid" ]; then
+ pid="$(__pids_pidof "$1")"
+ fi
+ if [ -n "$pid" ]; then
+ echo $"${base} (pid $pid) is running..."
+ return 0
+ fi
+
+ case "$RC" in
+ 0)
+ echo $"${base} (pid $pid) is running..."
+ return 0
+ ;;
+ 1)
+ echo $"${base} dead but pid file exists"
+ return 1
+ ;;
+ 4)
+ echo $"${base} status unknown due to insufficient privileges."
+ return 4
+ ;;
+ esac
+ if [ -z "${lock_file}" ]; then
+ lock_file=${base}
+ fi
+ # See if /var/lock/subsys/${lock_file} exists
+ if [ -f /var/lock/subsys/${lock_file} ]; then
+ echo $"${base} dead but subsys locked"
+ return 2
+ fi
+ echo $"${base} is stopped"
+ return 3
+}
+
+echo_success() {
+ [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+ echo -n "["
+ [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
+ echo -n $" OK "
+ [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+ echo -n "]"
+ echo -ne "\r"
+ return 0
+}
+
+echo_failure() {
+ [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+ echo -n "["
+ [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
+ echo -n $"FAILED"
+ [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+ echo -n "]"
+ echo -ne "\r"
+ return 1
+}
+
+echo_passed() {
+ [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+ echo -n "["
+ [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
+ echo -n $"PASSED"
+ [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+ echo -n "]"
+ echo -ne "\r"
+ return 1
+}
+
+echo_warning() {
+ [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
+ echo -n "["
+ [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
+ echo -n $"WARNING"
+ [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
+ echo -n "]"
+ echo -ne "\r"
+ return 1
+}
+
+# Inform the graphical boot of our current state
+update_boot_stage() {
+ if [ -x /bin/plymouth ]; then
+ /bin/plymouth --update="$1"
+ fi
+ return 0
+}
+
+# Log that something succeeded
+success() {
+ [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_success
+ return 0
+}
+
+# Log that something failed
+failure() {
+ local rc=$?
+ [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_failure
+ [ -x /bin/plymouth ] && /bin/plymouth --details
+ return $rc
+}
+
+# Log that something passed, but may have had errors. Useful for fsck
+passed() {
+ local rc=$?
+ [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_passed
+ return $rc
+}
+
+# Log a warning
+warning() {
+ local rc=$?
+ [ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_warning
+ return $rc
+}
+
+# Run some action. Log its output.
+action() {
+ local STRING rc
+
+ STRING=$1
+ echo -n "$STRING "
+ shift
+ "$@" && success $"$STRING" || failure $"$STRING"
+ rc=$?
+ echo
+ return $rc
+}
+
+# returns OK if $1 contains $2
+strstr() {
+ [ "${1#*$2*}" = "$1" ] && return 1
+ return 0
+}
+
+# Check whether file $1 is a backup or rpm-generated file and should be ignored
+is_ignored_file() {
+ case "$1" in
+ *~ | *.bak | *.orig | *.rpmnew | *.rpmorig | *.rpmsave)
+ return 0
+ ;;
+ esac
+ return 1
+}
+
+# Evaluate shvar-style booleans
+is_true() {
+ case "$1" in
+ [tT] | [yY] | [yY][eE][sS] | [tT][rR][uU][eE] | 1)
+ return 0
+ ;;
+ esac
+ return 1
+}
+
+# Evaluate shvar-style booleans
+is_false() {
+ case "$1" in
+ [fF] | [nN] | [nN][oO] | [fF][aA][lL][sS][eE] | 0)
+ return 0
+ ;;
+ esac
+ return 1
+}
+
+# Apply sysctl settings, including files in /etc/sysctl.d
+apply_sysctl() {
+ if [ -x /lib/systemd/systemd-sysctl ]; then
+ /lib/systemd/systemd-sysctl
+ else
+ for file in /usr/lib/sysctl.d/*.conf ; do
+ is_ignored_file "$file" && continue
+ [ -f /run/sysctl.d/${file##*/} ] && continue
+ [ -f /etc/sysctl.d/${file##*/} ] && continue
+ test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
+ done
+ for file in /run/sysctl.d/*.conf ; do
+ is_ignored_file "$file" && continue
+ [ -f /etc/sysctl.d/${file##*/} ] && continue
+ test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
+ done
+ for file in /etc/sysctl.d/*.conf ; do
+ is_ignored_file "$file" && continue
+ test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
+ done
+ sysctl -e -p /etc/sysctl.conf >/dev/null 2>&1
+ fi
+}
+
+# A sed expression to filter out the files that is_ignored_file recognizes
+__sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
+
+if [ "$_use_systemctl" = "1" ]; then
+ if [ "x$1" = xstart -o \
+ "x$1" = xstop -o \
+ "x$1" = xrestart -o \
+ "x$1" = xreload -o \
+ "x$1" = xtry-restart -o \
+ "x$1" = xforce-reload -o \
+ "x$1" = xcondrestart ] ; then
+
+ systemctl_redirect $0 $1
+ exit $?
+ fi
+fi
+
+strstr "$(cat /proc/cmdline)" "rc.debug" && set -x
+return 0
+
diff --git a/traffic_ops_ort/testing/docker/traffic_vault/run.sh b/traffic_ops_ort/testing/docker/traffic_vault/run.sh
new file mode 100755
index 0000000..0dcdc95
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/traffic_vault/run.sh
@@ -0,0 +1,126 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+# Script for running the Dockerfile for Traffic Vault.
+# The Dockerfile sets up a Docker image which can be used for any new container;
+# This script, which should be run when the container is run (it's the ENTRYPOINT), will configure the container.
+#
+# The following environment variables must be set (ordinarily by `docker run -e` arguments):
+# TV_ADMIN_PASS
+# RIAK_USER_PASS
+# CERT_COUNTRY
+# CERT_STATE
+# CERT_CITY
+# CERT_COMPANY
+# TO_URI
+# TO_USER
+# TO_PASS
+# TV_DOMAIN
+# IP
+# GATEWAY
+# CREATE_TO_DB_ENTRY (If set to yes, create the TO db entry for this server if set to no, assume it it already there)
+
+start() {
+ /etc/init.d/riak restart
+ #exec tail -f /var/log/riak/console.log
+ touch /var/log/messages
+ tail -f /var/log/messages
+}
+
+init() {
+ TMP_TO_COOKIE="$(curl -v -s -k -X POST --data '{ "u":"'"$TO_USER"'", "p":"'"$TO_PASS"'" }' $TO_URI/api/1.2/user/login 2>&1 | grep 'Set-Cookie' | sed -e 's/.*mojolicious=\(.*\); expires.*/\1/')"
+ echo "Got Cookie: $TMP_TO_COOKIE"
+# curl -v -k -X POST -H "Cookie: mojolicious=$TMP_TO_COOKIE" -F "filename=profile.traffic_vault.traffic_ops" -F "profile_to_import=@/profile.traffic_vault.traffic_ops" $TO_URI/profile/doImport
+
+ # \todo figure out a better way to get the IP, domain (Docker network name), gateway
+ TMP_IP=$IP
+ TMP_DOMAIN=$TV_DOMAIN
+ TMP_GATEWAY=$GATEWAY
+
+ echo "Got IP: $TMP_IP"
+ echo "Got Domain: $TMP_DOMAIN"
+ echo "Got Gateway: $TMP_GATEWAY"
+
+ if [ "$CREATE_TO_DB_ENTRY" = "YES" ] ; then
+ TMP_CACHEGROUP_ID="$(curl -s -k -X GET -H "Cookie: mojolicious=$TMP_TO_COOKIE" $TO_URI/api/1.2/cachegroups.json | python -c 'import json,sys;obj=json.load(sys.stdin);match=[x["id"] for x in obj["response"] if x["name"]=="mid-east"]; print match[0]')"
+ echo "Got cachegroup ID: $TMP_CACHEGROUP_ID"
+
+ TMP_SERVER_TYPE_ID="$(curl -s -k -X GET -H "Cookie: mojolicious=$TMP_TO_COOKIE" $TO_URI/api/1.2/types.json | python -c 'import json,sys;obj=json.load(sys.stdin);match=[x["id"] for x in obj["response"] if x["name"]=="RIAK"]; print match[0]')"
+ echo "Got server type ID: $TMP_SERVER_TYPE_ID"
+
+ TMP_SERVER_PROFILE_ID="$(curl -s -k -X GET -H "Cookie: mojolicious=$TMP_TO_COOKIE" $TO_URI/api/1.2/profiles.json | python -c 'import json,sys;obj=json.load(sys.stdin);match=[x["id"] for x in obj["response"] if x["name"]=="RIAK_ALL"]; print match[0]')"
+ echo "Got server profile ID: $TMP_SERVER_PROFILE_ID"
+
+ TMP_PHYS_LOCATION_ID="$(curl -s -k -X GET -H "Cookie: mojolicious=$TMP_TO_COOKIE" $TO_URI/api/1.2/phys_locations.json | python -c 'import json,sys;obj=json.load(sys.stdin);match=[x["id"] for x in obj["response"] if x["name"]=="plocation-nyc-1"]; print match[0]')"
+ echo "Got phys location ID: $TMP_PHYS_LOCATION_ID"
+
+ TMP_CDN_ID="$(curl -s -k -X GET -H "Cookie: mojolicious=$TMP_TO_COOKIE" $TO_URI/api/1.2/cdns.json | python -c 'import json,sys;obj=json.load(sys.stdin);match=[x["id"] for x in obj["response"] if x["name"]=="cdn"]; print match[0]')"
+ echo "Got cdn ID: $TMP_CDN_ID"
+
+ curl -v -k -X POST -H "Cookie: mojolicious=$TMP_TO_COOKIE" --data-urlencode "host_name=$HOSTNAME" --data-urlencode "domain_name=$TMP_DOMAIN" --data-urlencode "interface_name=eth0" --data-urlencode "ip_address=$TMP_IP" --data-urlencode "ip_netmask=255.255.0.0" --data-urlencode "ip_gateway=$TMP_GATEWAY" --data-urlencode "interface_mtu=9000" --data-urlencode "cdn=$TMP_CDN_ID" --data-urlencode "cachegroup=$TMP_CACHEGROUP_ID" --data-urlencode "phys_location=$TMP_PHYS_LOCATION_ID" --data-url [...]
+
+ fi
+
+ TMP_SERVER_ID="$(curl -s -k -X GET -H "Cookie: mojolicious=$TMP_TO_COOKIE" $TO_URI/api/1.2/servers.json | python -c 'import json,sys;obj=json.load(sys.stdin);match=[x["id"] for x in obj["response"] if x["hostName"]=="'"$HOSTNAME"'"]; print match[0]')"
+ echo "Got server ID: $TMP_SERVER_ID"
+
+ curl -v -k -H "Content-Type: application/x-www-form-urlencoded" -H "Cookie: mojolicious=$TMP_TO_COOKIE" -X POST --data-urlencode "id=$TMP_SERVER_ID" --data-urlencode "status=ONLINE" $TO_URI/server/updatestatus
+
+ openssl req -newkey rsa:2048 -nodes -keyout /etc/riak/certs/server.key -x509 -days 365 -out /etc/riak/certs/server.crt -subj "/C=$CERT_COUNTRY/ST=$CERT_STATE/L=$CERT_CITY/O=$CERT_COMPANY"
+ cp /etc/riak/certs/server.crt /etc/riak/certs/ca-bundle.crt
+
+ /etc/init.d/riak restart
+ riak-admin security enable
+ riak-admin security add-group admins
+ riak-admin security add-group keysusers
+ riak-admin security add-user admin password=$TV_ADMIN_PASS groups=admins
+ riak-admin security add-user riakuser password=$RIAK_USER_PASS groups=keysusers
+ riak-admin security add-source riakuser 0.0.0.0/0 password
+ riak-admin security add-source admin 0.0.0.0/0 password
+ riak-admin security grant riak_kv.list_buckets,riak_kv.list_keys,riak_kv.get,riak_kv.put,riak_kv.delete on any to admins
+ riak-admin security grant riak_kv.get,riak_kv.put,riak_kv.delete on default ssl to keysusers
+ riak-admin security grant riak_kv.get,riak_kv.put,riak_kv.delete on default dnssec to keysusers
+ riak-admin security grant riak_kv.get,riak_kv.put,riak_kv.delete on default url_sig_keys to keysusers
+
+ # Setting up Riak search permissions.
+ riak-admin security grant search.admin on schema to admin
+ riak-admin security grant search.admin on index to admin
+ riak-admin security grant search.query on index to admin
+ riak-admin security grant search.query on index sslkeys to admin
+ riak-admin security grant search.query on index to riakuser
+ riak-admin security grant search.query on index sslkeys to riakuser
+ riak-admin security grant riak_core.set_bucket on any to admin
+ echo "INITIALIZED=1" >> /etc/environment
+
+ # Add the search schema
+
+ (cd / && curl --tlsv1.1 --tls-max 1.1 -kvsX PUT "https://admin:$TV_ADMIN_PASS@localhost:8088/search/schema/sslkeys" -H "Content-Type: application/xml" -d @sslkeys.xml)
+
+ # Add the search index
+ curl --tlsv1.1 --tls-max 1.1 -kvsX PUT "https://admin:$TV_ADMIN_PASS@localhost:8088/search/index/sslkeys" -H 'Content-Type: application/json' -d '{"schema":"sslkeys"}'
+
+ # Add Index to bucket association for 'sslkeys'
+ curl --tlsv1.1 --tls-max 1.1 -kvs -XPUT "https://admin:$TV_ADMIN_PASS@localhost:8088/buckets/ssl/props" -H'content-type:application/json' -d'{"props":{"search_index":"sslkeys"}}'
+}
+
+# sleeping to wait and make sure traffic ops is up on to_server.
+sleep 30
+
+source /etc/environment
+if [ -z "$INITIALIZED" ]; then init; fi
+start
diff --git a/traffic_ops_ort/testing/docker/traffic_vault/sslkeys.xml b/traffic_ops_ort/testing/docker/traffic_vault/sslkeys.xml
new file mode 100644
index 0000000..245b8bc
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/traffic_vault/sslkeys.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+
+<schema name="schedule" version="1.5">
+ <fields>
+ <field name="cdn" type="string" indexed="true" stored="true" />
+ <field name="deliveryservice" type="string" indexed="true" stored="true" />
+ <field name="hostname" type="string" indexed="true" stored="true" />
+ <field name="certificate.crt" type="string" indexed="false" stored="true" />
+ <field name="certificate.key" type="string" indexed="false" stored="true" />
+
+ <!-- All of these fields are required by Riak Search -->
+ <field name="_yz_id" type="_yz_str" indexed="true" stored="true" multiValued="false" required="true"/>
+ <field name="_yz_ed" type="_yz_str" indexed="true" stored="false" multiValued="false"/>
+ <field name="_yz_pn" type="_yz_str" indexed="true" stored="false" multiValued="false"/>
+ <field name="_yz_fpn" type="_yz_str" indexed="true" stored="false" multiValued="false"/>
+ <field name="_yz_vtag" type="_yz_str" indexed="true" stored="false" multiValued="false"/>
+ <field name="_yz_rk" type="_yz_str" indexed="true" stored="true" multiValued="false"/>
+ <field name="_yz_rt" type="_yz_str" indexed="true" stored="true" multiValued="false"/>
+ <field name="_yz_rb" type="_yz_str" indexed="true" stored="true" multiValued="false"/>
+ <field name="_yz_err" type="_yz_str" indexed="true" stored="false" multiValued="false"/>
+
+ <!--catch all field-->
+ <dynamicField name="*" type="ignored" />
+
+ </fields>
+
+ <uniqueKey>_yz_id</uniqueKey>
+
+ <types>
+ <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
+ <!-- YZ String: Used for non-analyzed fields -->
+ <fieldType name="_yz_str" class="solr.StrField" sortMissingLast="true" />
+ <!-- Used for the catch all field -->
+ <fieldtype name="ignored" stored="false" indexed="false" multiValued="true" class="solr.StrField" />
+ </types>
+</schema>
diff --git a/traffic_ops_ort/testing/docker/variables.env b/traffic_ops_ort/testing/docker/variables.env
new file mode 100644
index 0000000..368b297
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/variables.env
@@ -0,0 +1,37 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+CERT_COUNTRY=US
+CERT_STATE=Colorado
+CERT_CITY=Denver
+CERT_COMPANY=NotComcast
+POSTGRES_HOME=/usr/pgsql-9.6
+PGPASSWORD=secretrootpass
+DB_NAME=traffic_ops
+DB_PORT=5432
+DB_ROOT_PASS=null
+DB_USER=traffic_ops
+DB_USER_PASS=twelve
+DB_SERVER=db
+RIAK_USER_PASS=tvsecret
+TO_ADMIN_USER=admin
+TO_ADMIN_PASS=twelve
+TO_HOSTNAME=to_server
+TO_DOMAIN=trafficops_default
+TO_URI=https://to_server:443
+TV_ADMIN_PASS=tvsecret
+TV_DOMAIN=local
diff --git a/traffic_ops_ort/testing/docker/yumserver/Dockerfile b/traffic_ops_ort/testing/docker/yumserver/Dockerfile
new file mode 100644
index 0000000..254b515
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/yumserver/Dockerfile
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+############################################################
+# Dockerfile to build Traffic Server container images
+# as Edges for Traffic Control 1.4
+# Based on CentOS 6.6
+############################################################
+
+FROM centos:7
+MAINTAINER dev@trafficcontrol.apache.org
+
+RUN yum install -y httpd createrepo yum-utils
+
+RUN mkdir -p /var/www/html/traffic-control/7/x86_64/Packages
+RUN sed -i -e 's/#ServerName www.example.com:80/ServerName www.example.com:80/g' /etc/httpd/conf/httpd.conf
+
+EXPOSE 80
+ADD yumserver/run.sh /
+ENTRYPOINT /run.sh
diff --git a/traffic_ops_ort/testing/docker/yumserver/run.sh b/traffic_ops_ort/testing/docker/yumserver/run.sh
new file mode 100755
index 0000000..1379735
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/yumserver/run.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+/usr/sbin/httpd
+
+createrepo /var/www/html/traffic-control/7/x86_64
+
+tail -f /var/log/httpd/access_log
diff --git a/traffic_ops_ort/testing/docker/yumserver/test-rpms/README.md b/traffic_ops_ort/testing/docker/yumserver/test-rpms/README.md
new file mode 100644
index 0000000..266e2d9
--- /dev/null
+++ b/traffic_ops_ort/testing/docker/yumserver/test-rpms/README.md
@@ -0,0 +1,23 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+
+# Test rpms
+
+Drop ATS test rpms here. t3c will utilize yum to install the
+ATS rpm found here as part of the integration testing.
diff --git a/traffic_ops_ort/testing/ort-tests/baseline-configs/astats.config b/traffic_ops_ort/testing/ort-tests/baseline-configs/astats.config
new file mode 100644
index 0000000..7b2f58e
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/baseline-configs/astats.config
@@ -0,0 +1,5 @@
+# DO NOT EDIT - Generated for ATS_EDGE_TIER_CACHE by () on Fri Nov 13 18:49:10 UTC 2020
+allow_ip6=::1/128,fc01:9400:1000:8::/64
+allow_ip=127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
+path=_astats
+record_types=122
diff --git a/traffic_ops_ort/testing/ort-tests/baseline-configs/hdr_rw_first_ds-top.config b/traffic_ops_ort/testing/ort-tests/baseline-configs/hdr_rw_first_ds-top.config
new file mode 100644
index 0000000..a1ca67a
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/baseline-configs/hdr_rw_first_ds-top.config
@@ -0,0 +1,2 @@
+# DO NOT EDIT - Generated for atlanta-edge-03 by () on Fri Nov 13 18:49:10 UTC 2020
+first header rewrite
diff --git a/traffic_ops_ort/testing/ort-tests/baseline-configs/hosting.config b/traffic_ops_ort/testing/ort-tests/baseline-configs/hosting.config
new file mode 100644
index 0000000..a5baff0
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/baseline-configs/hosting.config
@@ -0,0 +1,2 @@
+# DO NOT EDIT - Generated for atlanta-edge-03 by () on Fri Nov 13 18:49:10 UTC 2020
+hostname=* volume=1
diff --git a/traffic_ops_ort/testing/ort-tests/baseline-configs/parent.config b/traffic_ops_ort/testing/ort-tests/baseline-configs/parent.config
new file mode 100644
index 0000000..0bdecd0
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/baseline-configs/parent.config
@@ -0,0 +1,5 @@
+# DO NOT EDIT - Generated for atlanta-edge-03 by atstccfg/0.2 from https://to_server:443 ips (172.28.0.5:443) on 2021-01-13T16:46:07.704055764Z
+# ds 'ds-top' topology 'mso-topology'
+dest_domain=origin.topology.example.net port=80 parent="atlanta-mid-16.ga.atlanta.kabletown.net:80|0.999" round_robin=consistent_hash go_direct=false qstring=ignore
+# ds '' topology ''
+dest_domain=. parent="atlanta-mid-16.ga.atlanta.kabletown.net:80|0.999;" round_robin=consistent_hash go_direct=false
diff --git a/traffic_ops_ort/testing/ort-tests/baseline-configs/records.config b/traffic_ops_ort/testing/ort-tests/baseline-configs/records.config
new file mode 100644
index 0000000..04a7a71
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/baseline-configs/records.config
@@ -0,0 +1,23 @@
+# DO NOT EDIT - Generated for ATS_EDGE_TIER_CACHE by () on Fri Nov 13 18:49:10 UTC 2020
+CONFIG proxy.config.admin.user_id STRING ats
+CONFIG proxy.config.body_factory.template_sets_dir STRING /opt/trafficserver/etc/trafficserver/body_factory
+CONFIG proxy.config.config_dir STRING /opt/trafficserver/etc/trafficserver
+CONFIG proxy.config.diags.debug.enabled INT 1
+CONFIG proxy.config.dns.round_robin_nameservers INT 0
+CONFIG proxy.config.exec_thread.autoconfig INT 0
+CONFIG proxy.config.http.cache.required_headers INT 0
+CONFIG proxy.config.http.connect_attempts_timeout INT 10
+CONFIG proxy.config.http.enable_http_stats INT 1
+CONFIG proxy.config.http.insert_response_via_str INT 3
+CONFIG proxy.config.http.parent_proxy.retry_time INT 60
+CONFIG proxy.config.http.parent_proxy_routing_enable INT 1
+CONFIG proxy.config.http.server_ports STRING 80 80:ipv6
+CONFIG proxy.config.http.slow.log.threshold INT 10000
+CONFIG proxy.config.http.transaction_active_timeout_in INT 0
+CONFIG proxy.config.log.logfile_dir STRING /var/log/trafficserver
+CONFIG proxy.config.log.max_space_mb_for_logs INT 512
+CONFIG proxy.config.log.max_space_mb_headroom INT 50
+CONFIG proxy.config.proxy_name STRING atlanta-edge-03.ga.atlanta.kabletown.net
+CONFIG proxy.config.reverse_proxy.enabled INT 0
+CONFIG proxy.config.url_remap.remap_required INT 0
+LOCAL proxy.local.outgoing_ip_to_bind STRING 127.0.0.13
diff --git a/traffic_ops_ort/testing/ort-tests/baseline-configs/remap.config b/traffic_ops_ort/testing/ort-tests/baseline-configs/remap.config
new file mode 100644
index 0000000..b28b2f3
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/baseline-configs/remap.config
@@ -0,0 +1,3 @@
+# DO NOT EDIT - Generated for atlanta-edge-03 by () on Fri Nov 13 18:49:10 UTC 2020
+map http://atlanta-edge-03.ds-top.test.cdn1.net/ http://origin.topology.example.net/ @plugin=header_rewrite.so @pparam=dscp/set_dscp_40.config @plugin=header_rewrite.so @pparam=hdr_rw_first_ds-top.config @plugin=cachekey.so @pparam=--separator= @pparam=--remove-all-params=true @pparam=--remove-path=true @pparam=--capture-prefix-uri=/^([^?]*)/$1/ # topology 'mso-topology'
+map https://atlanta-edge-03.ds-top.test.cdn1.net/ http://origin.topology.example.net/ @plugin=header_rewrite.so @pparam=dscp/set_dscp_40.config @plugin=header_rewrite.so @pparam=hdr_rw_first_ds-top.config @plugin=cachekey.so @pparam=--separator= @pparam=--remove-all-params=true @pparam=--remove-path=true @pparam=--capture-prefix-uri=/^([^?]*)/$1/ # topology 'mso-topology'
diff --git a/traffic_ops_ort/testing/ort-tests/baseline-configs/storage.config b/traffic_ops_ort/testing/ort-tests/baseline-configs/storage.config
new file mode 100644
index 0000000..a680c88
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/baseline-configs/storage.config
@@ -0,0 +1,2 @@
+# DO NOT EDIT - Generated for ATS_EDGE_TIER_CACHE by () on Fri Nov 13 18:49:10 UTC 2020
+/var/trafficserver/cache volume=1
diff --git a/traffic_ops_ort/testing/ort-tests/baseline-configs/volume.config b/traffic_ops_ort/testing/ort-tests/baseline-configs/volume.config
new file mode 100644
index 0000000..8718379
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/baseline-configs/volume.config
@@ -0,0 +1,3 @@
+# DO NOT EDIT - Generated for ATS_EDGE_TIER_CACHE by () on Fri Nov 13 18:49:10 UTC 2020
+# TRAFFIC OPS NOTE: This is running with forced volumes - the size is irrelevant
+volume=1 scheme=http size=100%
diff --git a/traffic_ops_ort/testing/ort-tests/conf/docker-edge-cache.conf b/traffic_ops_ort/testing/ort-tests/conf/docker-edge-cache.conf
new file mode 100644
index 0000000..d06370c
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/conf/docker-edge-cache.conf
@@ -0,0 +1,38 @@
+{
+ "default": {
+ "logLocations": {
+ "debug": "stdout",
+ "error": "stdout",
+ "event": "stdout",
+ "info": "stdout",
+ "warning": "stdout"
+ },
+ "session": {
+ "timeoutInSecs": 60
+ },
+ "includeSystemTests": false
+ },
+ "use_ims": true,
+ "trafficOps": {
+ "URL": "https://to_server:443",
+ "password": "twelve",
+ "users": {
+ "disallowed": "disallowed",
+ "operations": "operations",
+ "admin": "admin",
+ "federation": "federation",
+ "portal": "portal",
+ "readOnly": "readOnly",
+ "extension": "extension"
+ }
+ },
+ "trafficOpsDB": {
+ "dbname": "traffic_ops",
+ "description": "Test database to_test",
+ "hostname": "db",
+ "password": "twelve",
+ "port": "5432",
+ "type": "Pg",
+ "user": "traffic_ops"
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/conf/edge-host.conf b/traffic_ops_ort/testing/ort-tests/conf/edge-host.conf
new file mode 100644
index 0000000..09b0c38
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/conf/edge-host.conf
@@ -0,0 +1,38 @@
+{
+ "default": {
+ "logLocations": {
+ "debug": "stdout",
+ "error": "stdout",
+ "event": "stdout",
+ "info": "stdout",
+ "warning": "stdout"
+ },
+ "session": {
+ "timeoutInSecs": 60
+ },
+ "includeSystemTests": false
+ },
+ "use_ims": true,
+ "trafficOps": {
+ "URL": "https://localhost:443",
+ "password": "twelve",
+ "users": {
+ "disallowed": "disallowed",
+ "operations": "operations",
+ "admin": "admin",
+ "federation": "federation",
+ "portal": "portal",
+ "readOnly": "readOnly",
+ "extension": "extension"
+ }
+ },
+ "trafficOpsDB": {
+ "dbname": "traffic_ops",
+ "description": "Test database to_test",
+ "hostname": "localhost",
+ "password": "twelve",
+ "port": "5432",
+ "type": "Pg",
+ "user": "traffic_ops"
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/config/config.go b/traffic_ops_ort/testing/ort-tests/config/config.go
new file mode 100644
index 0000000..d136614
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/config/config.go
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 config provides tools to load and validate configuration data for
+// Traffic Ops API tests.
+package config
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "reflect"
+ "strings"
+
+ log "github.com/apache/trafficcontrol/lib/go-log"
+ "github.com/kelseyhightower/envconfig"
+)
+
+// Config reflects the structure of the test-to-api.conf file
+type Config struct {
+ TrafficOps TrafficOps `json:"trafficOps"`
+ TrafficOpsDB TrafficOpsDB `json:"trafficOpsDB"`
+ Default Default `json:"default"`
+ UseIMS bool `json:"use_ims"`
+}
+
+// TrafficOps - config section
+type TrafficOps struct {
+ // URL - The point to the Traffic Ops instance being tested
+ URL string `json:"URL" envconfig:"TO_URL"`
+
+ // UserPassword - The Traffic Ops test user password hitting the API
+ UserPassword string `json:"password" envconfig:"TO_USER_PASSWORD"`
+
+ // User - The Traffic Ops Users
+ Users Users `json:"users"`
+
+ // Insecure - ignores insecure ssls certs that were self-generated
+ Insecure bool `json:"sslInsecure" envconfig:"SSL_INSECURE"`
+}
+
+// Users "users" section of the test-to-api.conf file
+type Users struct {
+
+ // DisallowedUser - The Traffic Ops Disallowed user
+ Disallowed string `json:"disallowed" envconfig:"TO_USER_DISALLOWED"`
+
+ // ReadOnly - The Traffic Ops Read Only user
+ ReadOnly string `json:"readOnly" envconfig:"TO_USER_READ_ONLY"`
+
+ // Operations - The Traffic Ops Operations user
+ Operations string `json:"operations" envconfig:"TO_USER_OPERATIONS"`
+
+ // AdminUser - The Traffic Ops Admin user
+ Admin string `json:"admin" envconfig:"TO_USER_ADMIN"`
+
+ // PortalUser - The Traffic Ops Portal user
+ Portal string `json:"portal" envconfig:"TO_USER_PORTAL"`
+
+ // FederationUser - The Traffic Ops Federation user
+ Federation string `json:"federation" envconfig:"TO_USER_FEDERATION"`
+
+ // Extension - The Traffic Ops Extension user
+ Extension string `json:"extension" envconfig:"TO_USER_EXTENSION"`
+}
+
+// TrafficOpsDB - config section
+type TrafficOpsDB struct {
+ // Name - Traffic Ops Database name where the test data will be setup
+ Name string `json:"dbname" envconfig:"TODB_NAME"`
+
+ // Hostname - Traffic Ops Database hostname where Postgres is running
+ Hostname string `json:"hostname" envconfig:"TODB_HOSTNAME"`
+
+ // User - database user that Traffic Ops is using to point to the 'to_test' database
+ User string `json:"user" envconfig:"TODB_USER"`
+
+ // Password - database password for the User above
+ Password string `json:"password" envconfig:"TODB_PASSWORD"`
+
+ // Port - Postgres port running that has the to_test schema
+ Port string `json:"port" envconfig:"TODB_PORT"`
+
+ // DBType - will be 'Pg' by default but tells the Golang database driver
+ // the database type
+ DBType string `json:"type" envconfig:"TODB_TYPE"`
+
+ // SSL - Flag that tells the database driver that the Postgres instances has TLS enabled
+ SSL bool `json:"ssl" envconfig:"TODB_SSL"`
+
+ // Description - database description
+ Description string `json:"description" envconfig:"TODB_DESCRIPTION"`
+}
+
+// Default - config section
+type Default struct {
+ Session Session `json:"session"`
+ Log Locations `json:"logLocations"`
+ IncludeSystemTests bool `json:"includeSystemTests"`
+}
+
+// Session - config section
+type Session struct {
+ TimeoutInSecs int `json:"timeoutInSecs" envconfig:"SESSION_TIMEOUT_IN_SECS"`
+}
+
+// Locations - reflects the structure of the database.conf file
+type Locations struct {
+ Debug string `json:"debug"`
+ Event string `json:"event"`
+ Error string `json:"error"`
+ Info string `json:"info"`
+ Warning string `json:"warning"`
+}
+
+// LoadConfig - reads the config file into the Config struct
+func LoadConfig(confPath string) (Config, error) {
+ var cfg Config
+
+ confBytes, err := ioutil.ReadFile(confPath)
+ if err != nil {
+ return cfg, fmt.Errorf("failed to read CDN configuration: %v", err)
+ }
+
+ err = json.Unmarshal(confBytes, &cfg)
+ if err != nil {
+ return cfg, fmt.Errorf("failed to parse configuration from '%s': %v", confPath, err)
+ }
+
+ if err := validate(confPath, cfg); err != nil {
+ return cfg, fmt.Errorf("failed to validate configuration:\n%v", err)
+ }
+
+ if err := envconfig.Process("traffic-ops-client-tests", &cfg); err != nil {
+ return cfg, fmt.Errorf("failed to parse configuration from environment: %v", err)
+ }
+
+ return cfg, nil
+}
+
+type multiError []error
+
+func (me multiError) Error() string {
+ var sb strings.Builder
+ for _, e := range me {
+ fmt.Fprintln(&sb, e)
+ }
+ return sb.String()
+}
+
+// validate all required fields in the config.
+func validate(confPath string, config Config) error {
+ var errs multiError
+
+ var f string
+ f = "TrafficOps"
+ toTag, ok := getStructTag(config, f)
+ if !ok {
+ errs = append(errs, fmt.Errorf("'%s' must be configured in %s", toTag, confPath))
+ }
+
+ if config.TrafficOps.URL == "" {
+ f = "URL"
+ tag, ok := getStructTag(config.TrafficOps, f)
+ if !ok {
+ errs = append(errs, fmt.Errorf("cannot lookup structTag: %s", f))
+ }
+ errs = append(errs, fmt.Errorf("'%s.%s' must be configured in %s", toTag, tag, confPath))
+ }
+
+ if config.TrafficOps.Users.Disallowed == "" {
+ f = "Disallowed"
+ tag, ok := getStructTag(config.TrafficOps.Users, f)
+ if !ok {
+ errs = append(errs, fmt.Errorf("cannot lookup structTag: %s", f))
+ }
+ errs = append(errs, fmt.Errorf("'%s.%s' must be configured in %s", toTag, tag, confPath))
+ }
+
+ if config.TrafficOps.Users.ReadOnly == "" {
+ f = "ReadOnly"
+ tag, ok := getStructTag(config.TrafficOps.Users, f)
+ if !ok {
+ errs = append(errs, fmt.Errorf("cannot lookup structTag: %s", f))
+ }
+ errs = append(errs, fmt.Errorf("'%s.%s' must be configured in %s", toTag, tag, confPath))
+ }
+
+ if config.TrafficOps.Users.Operations == "" {
+ f = "Operations"
+ tag, ok := getStructTag(config.TrafficOps.Users, f)
+ if !ok {
+ errs = append(errs, fmt.Errorf("cannot lookup structTag: %s", f))
+ }
+ errs = append(errs, fmt.Errorf("'%s.%s' must be configured in %s", toTag, tag, confPath))
+ }
+
+ if config.TrafficOps.Users.Admin == "" {
+ f = "Admin"
+ tag, ok := getStructTag(config.TrafficOps.Users, f)
+ if !ok {
+ errs = append(errs, fmt.Errorf("cannot lookup structTag: %s", f))
+ }
+ errs = append(errs, fmt.Errorf("'%s.%s' must be configured in %s", toTag, tag, confPath))
+ }
+
+ if config.TrafficOps.Users.Portal == "" {
+ f = "Portal"
+ tag, ok := getStructTag(config.TrafficOps.Users, f)
+ if !ok {
+ errs = append(errs, fmt.Errorf("cannot lookup structTag: %s", f))
+ }
+ errs = append(errs, fmt.Errorf("'%s.%s' must be configured in %s", toTag, tag, confPath))
+ }
+
+ if config.TrafficOps.Users.Federation == "" {
+ f = "Federation"
+ tag, ok := getStructTag(config.TrafficOps.Users, f)
+ if !ok {
+ errs = append(errs, fmt.Errorf("cannot lookup structTag: %s", f))
+ }
+ errs = append(errs, fmt.Errorf("'%s.%s' must be configured in %s", toTag, tag, confPath))
+ }
+
+ if len(errs) > 0 {
+ return errs
+ }
+ return nil
+}
+
+func getStructTag(thing interface{}, fieldName string) (string, bool) {
+ var tag string
+ var ok bool
+ t := reflect.TypeOf(thing)
+ if t != nil {
+ if f, ok := t.FieldByName(fieldName); ok {
+ tag = f.Tag.Get("json")
+ return tag, ok
+ }
+ }
+ return tag, ok
+}
+
+// ErrorLog - critical messages
+func (c Config) ErrorLog() log.LogLocation {
+ return log.LogLocation(c.Default.Log.Error)
+}
+
+// WarningLog - warning messages
+func (c Config) WarningLog() log.LogLocation {
+ return log.LogLocation(c.Default.Log.Warning)
+}
+
+// InfoLog - information messages
+func (c Config) InfoLog() log.LogLocation {
+ return log.LogLocation(c.Default.Log.Info)
+}
+
+// DebugLog - troubleshooting messages
+func (c Config) DebugLog() log.LogLocation {
+ return log.LogLocation(c.Default.Log.Debug)
+}
+
+// EventLog - access.log high level transactions
+func (c Config) EventLog() log.LogLocation {
+ return log.LogLocation(c.Default.Log.Event)
+}
diff --git a/traffic_ops_ort/testing/ort-tests/t3c_mode_test.go b/traffic_ops_ort/testing/ort-tests/t3c_mode_test.go
new file mode 100644
index 0000000..4958043
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/t3c_mode_test.go
@@ -0,0 +1,159 @@
+package orttest
+
+/*
+ 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.
+*/
+
+import (
+ "bytes"
+ "errors"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/testing/ort-tests/tcdata"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/testing/ort-tests/util"
+ "os"
+ "os/exec"
+ "testing"
+ "time"
+)
+
+var (
+ base_line_dir = "baseline-configs"
+ test_config_dir = "/opt/trafficserver/etc/trafficserver"
+
+ testFiles = [8]string{
+ "astats.config",
+ "hdr_rw_first_ds-top.config",
+ "hosting.config",
+ "parent.config",
+ "records.config",
+ "remap.config",
+ "storage.config",
+ "volume.config",
+ }
+)
+
+func TestT3cBadassAndSyncDs(t *testing.T) {
+ t.Logf("------------- Starting TestT3cBadassAndSyncDs ---------------")
+ tcd.WithObjs(t, []tcdata.TCObj{
+ tcdata.CDNs, tcdata.Types, tcdata.Tenants, tcdata.Parameters,
+ tcdata.Profiles, tcdata.ProfileParameters, tcdata.Statuses,
+ tcdata.Divisions, tcdata.Regions, tcdata.PhysLocations,
+ tcdata.CacheGroups, tcdata.Servers, tcdata.Topologies,
+ tcdata.DeliveryServices}, func() {
+
+ // run badass and check config files.
+ err := t3c_update("atlanta-edge-03", "badass")
+ if err != nil {
+ t.Fatalf("ERROR: t3c badass failed: %v\n", err)
+ }
+ for _, v := range testFiles {
+ bfn := base_line_dir + "/" + v
+ if !util.FileExists(bfn) {
+ t.Fatalf("ERROR: missing baseline config file, %s, needed for tests", bfn)
+ }
+ tfn := test_config_dir + "/" + v
+ if !util.FileExists(tfn) {
+ t.Fatalf("ERROR: missing the expected config file, %s", tfn)
+ }
+
+ result, err := util.DiffFiles(bfn, tfn)
+ if err != nil || !result {
+ t.Fatalf("ERROR: the contents of '%s' does not match those in %s",
+ tfn, bfn)
+ }
+ }
+
+ time.Sleep(time.Second * 5)
+
+ t.Logf("------------------------ running SYNCDS Test ------------------")
+ // remove the remap.config in preparation for running syncds
+ remap := test_config_dir + "/remap.config"
+ err = os.Remove(remap)
+ if err != nil {
+ t.Fatalf("ERROR: unable to remove %s\n", remap)
+ }
+ // prepare for running syncds.
+ err = setQueueUpdateStatus("atlanta-edge-03", "true")
+ if err != nil {
+ t.Fatalf("ERROR: queue updates failed: %v\n", err)
+ }
+
+ // remap.config is removed and atlanta-edge-03 should have
+ // queue updates enabled. run t3c to verify a new remap.config
+ // is pulled down.
+ err = t3c_update("atlanta-edge-03", "syncds")
+ if err != nil {
+ t.Fatalf("ERROR: t3c syncds failed: %v\n", err)
+ }
+ if !util.FileExists(remap) {
+ t.Fatalf("ERROR: syncds failed to pull down %s\n", remap)
+ }
+ t.Logf("------------------------ end SYNCDS Test ------------------")
+
+ })
+ t.Logf("------------- End of TestT3cBadassAndSyncDs ---------------")
+}
+
+func setQueueUpdateStatus(host_name string, update string) error {
+ args := []string{
+ "--dir=/opt/trafficserver/etc/traffficserver",
+ "--traffic-ops-insecure",
+ "--traffic-ops-timeout-milliseconds=30000",
+ "--traffic-ops-disable-proxy=true",
+ "--traffic-ops-user=" + tcd.Config.TrafficOps.Users.Admin,
+ "--traffic-ops-password=" + tcd.Config.TrafficOps.UserPassword,
+ "--traffic-ops-url=" + tcd.Config.TrafficOps.URL,
+ "--cache-host-name=" + host_name,
+ "--log-location-error=stdout",
+ "--log-location-info=stdout",
+ "--log-location-warning=stdout",
+ "--set-queue-status=" + update,
+ "--set-reval-status=false",
+ }
+ cmd := exec.Command("/opt/ort/atstccfg", args...)
+ var out bytes.Buffer
+ var errOut bytes.Buffer
+ cmd.Stdout = &out
+ cmd.Stderr = &errOut
+ err := cmd.Run()
+ if err != nil {
+ return errors.New(err.Error() + ": " + "stdout: " + out.String() + " stderr: " + errOut.String())
+ }
+ return nil
+}
+
+func t3c_update(host string, run_mode string) error {
+ args := []string{
+ "--traffic-ops-insecure=true",
+ "--dispersion=0",
+ "--login-dispersion=0",
+ "--traffic-ops-timeout-milliseconds=3000",
+ "--traffic-ops-user=" + tcd.Config.TrafficOps.Users.Admin,
+ "--traffic-ops-password=" + tcd.Config.TrafficOps.UserPassword,
+ "--traffic-ops-url=" + tcd.Config.TrafficOps.URL,
+ "--cache-host-name=" + host,
+ "--log-location-error=test.log",
+ "--log-location-info=test.log",
+ "--log-location-debug=test.log",
+ "--run-mode=" + run_mode,
+ }
+ cmd := exec.Command("/opt/ort/t3c", args...)
+ var out bytes.Buffer
+ var errOut bytes.Buffer
+ cmd.Stdout = &out
+ cmd.Stderr = &errOut
+ err := cmd.Run()
+ if err != nil {
+ return errors.New(err.Error() + ": " + "stdout: " + out.String() + " stderr: " + errOut.String())
+ }
+ return nil
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tc-fixtures.json b/traffic_ops_ort/testing/ort-tests/tc-fixtures.json
new file mode 100644
index 0000000..3d65f47
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tc-fixtures.json
@@ -0,0 +1,4664 @@
+{
+ "asns": [
+ {
+ "asn": 8888,
+ "cachegroupName": "originCachegroup"
+ },
+ {
+ "asn": 9999,
+ "cachegroupName": "multiOriginCachegroup"
+ }
+ ],
+ "cachegroups": [
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "originCachegroup",
+ "shortName": "og1",
+ "typeName": "ORG_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "multiOriginCachegroup",
+ "shortName": "mog1",
+ "typeName": "ORG_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "parentCachegroup",
+ "shortName": "pg1",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "parentCachegroup2",
+ "shortName": "pg2",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "secondaryCachegroup",
+ "shortName": "sg1",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "cachegroup1",
+ "parentCachegroupName": "parentCachegroup",
+ "secondaryParentCachegroupName": "secondaryCachegroup",
+ "shortName": "cg1",
+ "localizationMethods": [
+ "CZ",
+ "DEEP_CZ",
+ "GEO"
+ ],
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "fallback1",
+ "parentCachegroupName": "parentCachegroup",
+ "secondaryParentCachegroupName": "secondaryCachegroup",
+ "shortName": "fb1",
+ "localizationMethods": [
+ "CZ",
+ "DEEP_CZ",
+ "GEO"
+ ],
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "fallback2",
+ "parentCachegroupName": "parentCachegroup",
+ "secondaryParentCachegroupName": "secondaryCachegroup",
+ "shortName": "fb2",
+ "localizationMethods": [
+ "CZ",
+ "DEEP_CZ",
+ "GEO"
+ ],
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "fallback3",
+ "parentCachegroupName": "parentCachegroup",
+ "secondaryParentCachegroupName": "secondaryCachegroup",
+ "shortName": "fb3",
+ "localizationMethods": [
+ "CZ",
+ "DEEP_CZ",
+ "GEO"
+ ],
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 24.1234,
+ "longitude": -121.1234,
+ "name": "cachegroup2",
+ "parentCachegroupName": "secondaryCachegroup",
+ "secondaryParentCachegroupName": "parentCachegroup",
+ "shortName": "cg2",
+ "typeName": "EDGE_LOC",
+ "fallbacks": [
+ "fallback1",
+ "fallback2",
+ "fallback3"
+ ]
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "cachegroup3",
+ "parentCachegroupName": "parentCachegroup",
+ "secondaryParentCachegroupName": "secondaryCachegroup",
+ "shortName": "cg3",
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "edge-parent1",
+ "shortName": "ep1",
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "has-edge-parent1",
+ "parentCachegroupName": "edge-parent1",
+ "shortName": "hep1",
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-edge-cg-01",
+ "shortName": "te1",
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-edge-cg-02",
+ "shortName": "te2",
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-mid-cg-01",
+ "shortName": "tm1",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-mid-cg-02",
+ "shortName": "tm2",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-mid-cg-03",
+ "shortName": "tm3",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-mid-cg-04",
+ "shortName": "tm4",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-mid-cg-05",
+ "shortName": "tm5",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-mid-cg-06",
+ "shortName": "tm6",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "topology-mid-cg-07",
+ "shortName": "tm7",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "dtrc1",
+ "shortName": "dtrc1",
+ "typeName": "MID_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "dtrc2",
+ "shortName": "dtrc2",
+ "typeName": "EDGE_LOC"
+ },
+ {
+ "latitude": 0,
+ "longitude": 0,
+ "name": "dtrc3",
+ "shortName": "dtrc3",
+ "typeName": "EDGE_LOC"
+ }
+ ],
+ "cdns": [
+ {
+ "dnssecEnabled": false,
+ "domainName": "test.cdn1.net",
+ "name": "cdn1"
+ },
+ {
+ "dnssecEnabled": false,
+ "domainName": "test.cdn2.net",
+ "name": "cdn2"
+ },
+ {
+ "dnssecEnabled": false,
+ "domainName": "test.cdn3.net",
+ "name": "cdn3"
+ },
+ {
+ "dnssecEnabled": false,
+ "domainName": "test.cdn4.net",
+ "name": "cdn4"
+ },
+ {
+ "dnssecEnabled": false,
+ "domainName": "test.bar.net",
+ "name": "bar"
+ }
+ ],
+ "deliveryServiceRequestComments": [
+ {
+ "value": "this is comment one"
+ },
+ {
+ "value": "this is comment two"
+ },
+ {
+ "value": "this is comment three"
+ },
+ {
+ "value": "this is comment four"
+ }
+ ],
+ "deliveryServiceRequests": [
+ {
+ "changeType": "create",
+ "deliveryService": {
+ "active": true,
+ "cdnName": "cdn1",
+ "ccrDnsTtl": 30,
+ "deepCachingType": "NEVER",
+ "displayName": "Good Kabletown CDN",
+ "dscp": 1,
+ "geoLimit": 1,
+ "geoProvider": 1,
+ "initialDispersion": 1,
+ "logsEnabled": true,
+ "longDesc": "long desc",
+ "regionalGeoBlocking": true,
+ "routingName": "goodroute",
+ "tenant": "tenant1",
+ "type": "HTTP",
+ "xmlId": "test-ds1"
+ },
+ "status": "draft"
+ },
+ {
+ "changeType": "create",
+ "deliveryService": {
+ "active": true,
+ "cdnName": "cdn1",
+ "ccrDnsTtl": 30,
+ "deepCachingType": "NEVER",
+ "displayName": "Bad Tenant",
+ "dscp": 0,
+ "geoLimit": 0,
+ "geoProvider": 0,
+ "initialDispersion": 3,
+ "logsEnabled": false,
+ "longDesc": "long desc",
+ "regionalGeoBlocking": false,
+ "tenant": "root",
+ "type": "HTTP",
+ "xmlId": "test-ds2"
+ },
+ "status": "draft"
+ },
+ {
+ "changeType": "create",
+ "deliveryService": {
+ "ccrDnsTtl": 30,
+ "deepCachingType": "NEVER",
+ "displayName": "Bad Test Case CDN",
+ "dscp": 0,
+ "geoLimit": 0,
+ "geoProvider": 1,
+ "infoUrl": "xxx",
+ "initialDispersion": 1,
+ "logsEnabled": true,
+ "longDesc": "long desc",
+ "orgServerFqdn": "xxx",
+ "regionalGeoBlocking": true,
+ "routingName": "x routing",
+ "tenant": "tenant1",
+ "type": "HTTP",
+ "xmlId": "test-ds3"
+ },
+ "status": "draft"
+ },
+ {
+ "changeType": "update",
+ "deliveryService": {
+ "active": false,
+ "cdnName": "cdn1",
+ "ccrDnsTtl": 30,
+ "deepCachingType": "NEVER",
+ "displayName": "Testing transitions",
+ "dscp": 3,
+ "geoLimit": 1,
+ "geoProvider": 1,
+ "initialDispersion": 1,
+ "logsEnabled": true,
+ "longDesc": "long desc",
+ "regionalGeoBlocking": true,
+ "routingName": "goodroute",
+ "tenant": "tenant1",
+ "type": "HTTP",
+ "xmlId": "test-transitions"
+ },
+ "status": "draft"
+ }
+ ],
+ "deliveryServices": [
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "cacheUrl1",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": [],
+ "deepCachingType": "NEVER",
+ "displayName": "ds1DisplayName",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": "edgeHeader1\nedgeHeader2",
+ "exampleURLs": [
+ "http://ccr.ds1.example.net",
+ "https://ccr.ds1.example.net"
+ ],
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "d s 1",
+ "longDesc1": "ds1",
+ "longDesc2": "ds1",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds1\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "edgeHeaderRewrite": "edgeRewrite1\nedgeHeader2",
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://origin.example.net",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": "rr1\nrr2",
+ "regionalGeoBlocking": false,
+ "remapText": "@plugin=tslua.so @pparam=/opt/trafficserver/etc/trafficserver/remapPlugin1.lua",
+ "routingName": "ccr-ds1",
+ "signed": false,
+ "signingAlgorithm": "url_sig",
+ "sslKeyVersion": 2,
+ "tenant": "tenant1",
+ "tenantName": "tenant1",
+ "type": "HTTP",
+ "xmlId": "ds1",
+ "anonymousBlockingEnabled": true
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "cacheUrl2",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": ["fmt", "limit", "somethingelse"],
+ "deepCachingType": "NEVER",
+ "displayName": "d s 1",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": "edgeRewrite1\nedgeHeader2",
+ "exampleURLs": [
+ "http://ccr.ds2.example.net",
+ "https://ccr.ds2x.example.net"
+ ],
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "d s 1",
+ "longDesc1": "ds2",
+ "longDesc2": "ds2",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds2\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "maxOriginConnections": -1,
+ "midHeaderRewrite": "midHeader1\nmidHeader2",
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://origin.ds2.example.net",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": "rr1\nrr2",
+ "regionalGeoBlocking": false,
+ "remapText": "@plugin=tslua.so @pparam=/opt/trafficserver/etc/trafficserver/ds2plugin.lua",
+ "routingName": "ccr-ds2",
+ "signed": false,
+ "signingAlgorithm": "url_sig",
+ "sslKeyVersion": 2,
+ "tenant": "tenant2",
+ "tenantName": "tenant2",
+ "type": "HTTP_LIVE",
+ "xmlId": "ds2",
+ "anonymousBlockingEnabled": true
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "cacheUrl3",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": null,
+ "deepCachingType": "NEVER",
+ "displayName": "d s 1",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": "edgeRewrite1\nedgeHeader2",
+ "exampleURLs": [
+ "http://ccr.ds3.example.net",
+ "https://ccr.ds3x.example.net"
+ ],
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "d s 3",
+ "longDesc1": "ds3",
+ "longDesc2": "ds3",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds3\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "maxOriginConnections": 0,
+ "midHeaderRewrite": "midHeader1\nmidHeader2",
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://origin.ds3.example.net",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": "rr1\nrr2",
+ "regionalGeoBlocking": false,
+ "remapText": "@plugin=tslua.so @pparam=/opt/trafficserver/etc/trafficserver/ds3plugin.lua",
+ "routingName": "ccr-ds3",
+ "signed": false,
+ "signingAlgorithm": "url_sig",
+ "sslKeyVersion": 2,
+ "tenant": "tenant3",
+ "tenantName": "tenant3",
+ "type": "HTTP_LIVE",
+ "xmlId": "ds3",
+ "anonymousBlockingEnabled": true
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "deepCachingType": "NEVER",
+ "displayName": "anymap-ds",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": "",
+ "exampleURLs": [],
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "",
+ "longDesc1": "",
+ "longDesc2": "",
+ "matchList": [],
+ "maxDnsAnswers": 0,
+ "maxOriginConnections": 1,
+ "midHeaderRewrite": "",
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://example.com",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": "",
+ "regionalGeoBlocking": false,
+ "remapText": "map some raw remap text",
+ "routingName": "",
+ "signed": false,
+ "signingAlgorithm": "url_sig",
+ "sslKeyVersion": 2,
+ "tenant": "tenant3",
+ "tenantName": "tenant3",
+ "type": "ANY_MAP",
+ "xmlId": "anymap-ds",
+ "anonymousBlockingEnabled": true
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "cacheUrl1",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": ["a", "b", "c"],
+ "consistentHashRegex": "foo",
+ "deepCachingType": "ALWAYS",
+ "displayName": "ds-test-minor-versions",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": "edgeRewrite1\nedgeHeader2",
+ "fqPacingRate": 42,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "logsEnabled": false,
+ "longDesc": "d s 1",
+ "longDesc1": "ds1",
+ "longDesc2": "ds1",
+ "maxDnsAnswers": 0,
+ "maxOriginConnections": 1000,
+ "midHeaderRewrite": "midHeader1\nmidHeader2",
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://origin-test-minor-version.example.net",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": "rr1\nrr2",
+ "regionalGeoBlocking": false,
+ "remapText": "@plugin=tslua.so @pparam=/opt/trafficserver/etc/trafficserver/remapPlugin1.lua",
+ "routingName": "cdn",
+ "signed": true,
+ "signingAlgorithm": "url_sig",
+ "sslKeyVersion": 2,
+ "tenantId": 1,
+ "tenant": "root",
+ "trRequestHeaders": "X-Foo\nX-Bar",
+ "trResponseHeaders": "Access-Control-Allow-Origin: *\nContent-Type: text/html; charset=utf-8",
+ "type": "HTTP_LIVE",
+ "xmlId": "ds-test-minor-versions",
+ "anonymousBlockingEnabled": true
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "cacheUrl1",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": [],
+ "deepCachingType": "NEVER",
+ "displayName": "ds1DisplayName",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": "edgeRewrite1\nedgeHeader2",
+ "exampleURLs": [
+ "http://ccr.msods1.example.net",
+ "https://ccr.msods1.example.net"
+ ],
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "mso DS 1",
+ "longDesc1": "msods1",
+ "longDesc2": "msods1",
+ "matchList": [
+ {
+ "pattern": ".*\\.msods1\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "midHeaderRewrite": "midHeader1\nmidHeader2",
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": true,
+ "orgServerFqdn": "http://origin.example.net",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": "rr1\nrr2",
+ "regionalGeoBlocking": false,
+ "remapText": "@plugin=tslua.so @pparam=/opt/trafficserver/etc/trafficserver/remapPlugin1.lua",
+ "routingName": "ccr-msods1",
+ "signed": false,
+ "signingAlgorithm": "url_sig",
+ "sslKeyVersion": 2,
+ "tenant": "tenant1",
+ "tenantName": "tenant1",
+ "type": "HTTP_LIVE",
+ "xmlId": "msods1",
+ "anonymousBlockingEnabled": true
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "cacheUrl1",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": [],
+ "deepCachingType": "NEVER",
+ "displayName": "ds1natDisplayName",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": "edgeRewrite1\nedgeHeader2",
+ "exampleURLs": [
+ "http://ccr.ds1nat.example.net",
+ "https://ccr.ds1nat.example.net"
+ ],
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "d s 1",
+ "longDesc1": "ds1nat",
+ "longDesc2": "ds1nat",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds1nat\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "midHeaderRewrite": "midHeader1\nmidHeader2",
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://origin.example.net",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": "rr1\nrr2",
+ "regionalGeoBlocking": false,
+ "remapText": "@plugin=tslua.so @pparam=/opt/trafficserver/etc/trafficserver/remapPlugin1.lua",
+ "routingName": "ccr-ds1nat",
+ "signed": false,
+ "signingAlgorithm": "url_sig",
+ "sslKeyVersion": 2,
+ "tenant": "tenant1",
+ "tenantName": "tenant1",
+ "type": "HTTP_LIVE_NATNL",
+ "xmlId": "ds1nat",
+ "anonymousBlockingEnabled": true
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": [],
+ "deepCachingType": "NEVER",
+ "displayName": "ds-with-topology",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": null,
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "d s top",
+ "longDesc1": "ds top",
+ "longDesc2": "ds-top",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds-top\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "midHeaderRewrite": null,
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://origin.topology.example.net",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 1,
+ "rangeRequestHandling": 0,
+ "regexRemap": null,
+ "regionalGeoBlocking": false,
+ "remapText": null,
+ "routingName": "cdn",
+ "signed": false,
+ "signingAlgorithm": null,
+ "sslKeyVersion": 0,
+ "tenant": "tenant1",
+ "tenantName": "tenant1",
+ "type": "HTTP_LIVE_NATNL",
+ "xmlId": "ds-top",
+ "anonymousBlockingEnabled": false,
+ "topology": "mso-topology",
+ "firstHeaderRewrite": "first header rewrite",
+ "innerHeaderRewrite": "inner header rewrite",
+ "lastHeaderRewrite": "last header rewrite"
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": [],
+ "deepCachingType": "NEVER",
+ "displayName": "ds-top-req-cap",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": null,
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "",
+ "longDesc1": "",
+ "longDesc2": "",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds-top-req-cap\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "midHeaderRewrite": null,
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://example.org",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 0,
+ "qstringIgnore": 0,
+ "rangeRequestHandling": 0,
+ "regexRemap": null,
+ "regionalGeoBlocking": false,
+ "remapText": null,
+ "routingName": "cdn",
+ "signed": false,
+ "signingAlgorithm": null,
+ "sslKeyVersion": 0,
+ "tenant": "tenant1",
+ "tenantName": "tenant1",
+ "topology": "top-for-ds-req",
+ "type": "HTTP",
+ "xmlId": "ds-top-req-cap",
+ "anonymousBlockingEnabled": false
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": [],
+ "deepCachingType": "NEVER",
+ "displayName": "ds-top-req-cap2",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": null,
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "",
+ "longDesc1": "",
+ "longDesc2": "",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds-top-req-cap2\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "midHeaderRewrite": null,
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": "http://example.org",
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 0,
+ "qstringIgnore": 0,
+ "rangeRequestHandling": 0,
+ "regexRemap": null,
+ "regionalGeoBlocking": false,
+ "remapText": null,
+ "routingName": "cdn",
+ "signed": false,
+ "signingAlgorithm": null,
+ "sslKeyVersion": 0,
+ "tenant": "tenant1",
+ "tenantName": "tenant1",
+ "topology": "top-for-ds-req2",
+ "type": "HTTP",
+ "xmlId": "ds-top-req-cap2",
+ "anonymousBlockingEnabled": false
+ },
+ {
+ "active": true,
+ "cdnName": "cdn1",
+ "cacheurl": "",
+ "ccrDnsTtl": 3600,
+ "checkPath": "",
+ "consistentHashQueryParams": [],
+ "deepCachingType": "NEVER",
+ "displayName": "ds-client-steering",
+ "dnsBypassCname": null,
+ "dnsBypassIp": "",
+ "dnsBypassIp6": "",
+ "dnsBypassTtl": 30,
+ "dscp": 40,
+ "edgeHeaderRewrite": null,
+ "fqPacingRate": 0,
+ "geoLimit": 0,
+ "geoLimitCountries": "",
+ "geoLimitRedirectURL": null,
+ "geoProvider": 0,
+ "globalMaxMbps": 0,
+ "globalMaxTps": 0,
+ "httpBypassFqdn": "",
+ "infoUrl": "TBD",
+ "initialDispersion": 1,
+ "ipv6RoutingEnabled": true,
+ "lastUpdated": "2018-04-06 16:48:51+00",
+ "logsEnabled": false,
+ "longDesc": "d s client-steering",
+ "longDesc1": "ds client-steering",
+ "longDesc2": "ds-client-steering",
+ "matchList": [
+ {
+ "pattern": ".*\\.ds-client-steering\\..*",
+ "setNumber": 0,
+ "type": "HOST_REGEXP"
+ }
+ ],
+ "maxDnsAnswers": 0,
+ "midHeaderRewrite": null,
+ "missLat": 41.881944,
+ "missLong": -87.627778,
+ "multiSiteOrigin": false,
+ "orgServerFqdn": null,
+ "originShield": null,
+ "profileDescription": null,
+ "profileName": null,
+ "protocol": 2,
+ "qstringIgnore": 0,
+ "rangeRequestHandling": 0,
+ "regexRemap": null,
+ "regionalGeoBlocking": false,
+ "remapText": null,
+ "routingName": "cdn",
+ "signed": false,
+ "signingAlgorithm": null,
+ "sslKeyVersion": 0,
+ "tenant": "tenant1",
+ "tenantName": "tenant1",
+ "type": "CLIENT_STEERING",
+ "xmlId": "ds-client-steering",
+ "anonymousBlockingEnabled": false
+ }
+ ],
+ "deliveryServicesRegexes": [
+ {
+ "dsName": "ds1",
+ "typeName": "HOST_REGEXP",
+ "setNumber": 1,
+ "pattern" : ".*"
+ },
+ {
+ "dsName": "ds1",
+ "typeName": "HOST_REGEXP",
+ "setNumber": 2,
+ "pattern" : "\\d+"
+ },
+ {
+ "dsName": "ds2",
+ "typeName": "HOST_REGEXP",
+ "setNumber": 1,
+ "pattern" : ".*"
+ },
+ {
+ "dsName": "ds1",
+ "typeName": "HOST_REGEXP",
+ "setNumber": 3,
+ "pattern" : ""
+ }
+ ],
+ "deliveryservicesRequiredCapabilities": [
+ {
+ "xmlID": "ds1",
+ "RequiredCapability": "foo"
+ },
+ {
+ "xmlID": "ds2",
+ "RequiredCapability": "bar"
+ },
+ {
+ "xmlID": "msods1",
+ "RequiredCapability": "bar"
+ }
+ ],
+ "topologyBasedDeliveryServicesRequiredCapabilities": [
+ {
+ "xmlID": "ds-top-req-cap",
+ "RequiredCapability": "ram"
+ },
+ {
+ "xmlID": "ds-top-req-cap",
+ "RequiredCapability": "disk"
+ },
+ {
+ "xmlID": "ds-top-req-cap2",
+ "RequiredCapability": "ram"
+ }
+ ],
+ "divisions": [
+ {
+ "name": "division1"
+ },
+ {
+ "name": "cdn-div2"
+ }
+ ],
+ "federations": [
+ {
+ "cname": "the.cname.com.",
+ "ttl": 48,
+ "description": "the description"
+ },
+ {
+ "cname": "booya.com.",
+ "ttl": 34,
+ "description": "fooya"
+ }
+ ],
+ "federation_resolvers": [
+ {
+ "ipAddress": "1.2.3.4",
+ "type": "RESOLVE4",
+ "id": 1
+ },
+ {
+ "ipAddress": "0.0.0.0/12",
+ "type": "RESOLVE4",
+ "id": 2
+ },
+ {
+ "ipAddress": "dead::babe",
+ "type": "RESOLVE6",
+ "id": 3
+ },
+ {
+ "ipAddress": "::f1d0:f00d/123",
+ "type": "RESOLVE6",
+ "id": 4
+ }
+ ],
+ "coordinates": [
+ {
+ "latitude": 1.1,
+ "longitude": 2.2,
+ "name": "coordinate1"
+ },
+ {
+ "latitude": 3.3,
+ "longitude": 4.4,
+ "name": "coordinate2"
+ },
+ {
+ "latitude": 5.5,
+ "longitude": 6.6,
+ "name": "abc-coordinate"
+ }
+ ],
+ "origins": [
+ {
+ "name": "origin1",
+ "cachegroup": "originCachegroup",
+ "deliveryService": "ds1",
+ "fqdn": "origin1.example.com",
+ "ipAddress": "1.2.3.4",
+ "ip6Address": "dead:beef:cafe::42",
+ "port": 1234,
+ "protocol": "http",
+ "tenant": "tenant1"
+ },
+ {
+ "name": "origin2",
+ "cachegroup": "originCachegroup",
+ "deliveryService": "ds2",
+ "fqdn": "origin2.example.com",
+ "ipAddress": "5.6.7.8",
+ "ip6Address": "cafe::42",
+ "port": 5678,
+ "protocol": "https",
+ "tenant": "tenant1"
+ }
+ ],
+ "parameters": [
+ {
+ "configFile": "rascal.properties",
+ "lastUpdated": "2018-01-19T19:01:21.455131+00:00",
+ "name": "health.threshold.loadavg",
+ "secure": false,
+ "value": "25.0"
+ },
+ {
+ "configFile": "rascal.properties",
+ "lastUpdated": "2018-01-19T19:01:21.472279+00:00",
+ "name": "health.threshold.availableBandwidthInKbps",
+ "secure": false,
+ "value": ">1750000"
+ },
+ {
+ "configFile": "rascal.properties",
+ "lastUpdated": "2018-01-19T19:01:21.489534+00:00",
+ "name": "history.count",
+ "secure": false,
+ "value": "30"
+ },
+ {
+ "configFile": "records.config",
+ "lastUpdated": "2018-01-19T19:01:21.434425+00:00",
+ "name": "CONFIG proxy.config.allocator.enable_reclaim",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "records.config",
+ "lastUpdated": "2018-01-19T19:01:21.435957+00:00",
+ "name": "CONFIG proxy.config.allocator.max_overage",
+ "secure": false,
+ "value": "INT 3"
+ },
+ {
+ "configFile": "records.config",
+ "lastUpdated": "2018-01-19T19:01:21.437496+00:00",
+ "name": "CONFIG proxy.config.diags.show_location",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "records.config",
+ "lastUpdated": "2018-01-19T19:01:21.439033+00:00",
+ "name": "CONFIG proxy.config.http.cache.allow_empty_doc",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "records.config",
+ "lastUpdated": "2018-01-19T19:01:21.440502+00:00",
+ "name": "LOCAL proxy.config.cache.interim.storage",
+ "secure": false,
+ "value": "STRING NULL"
+ },
+ {
+ "configFile": "records.config",
+ "lastUpdated": "2018-01-19T19:01:21.441933+00:00",
+ "name": "CONFIG proxy.config.http.parent_proxy.file",
+ "secure": false,
+ "value": "STRING parent.config"
+ },
+ {
+ "configFile": "logs_xml.config",
+ "lastUpdated": "2018-01-19T19:01:21.461206+00:00",
+ "name": "LogFormat.Name",
+ "secure": false,
+ "value": "custom_ats_2"
+ },
+ {
+ "configFile": "logs_xml.config",
+ "lastUpdated": "2018-01-19T19:01:21.462772+00:00",
+ "name": "LogObject.Format",
+ "secure": false,
+ "value": "custom_ats_2"
+ },
+ {
+ "configFile": "logs_xml.config",
+ "lastUpdated": "2018-01-19T19:01:21.464259+00:00",
+ "name": "LogObject.Filename",
+ "secure": false,
+ "value": "custom_ats_2"
+ },
+ {
+ "configFile": "records.config",
+ "lastUpdated": "2018-01-19T19:01:21.467349+00:00",
+ "name": "CONFIG proxy.config.cache.control.filename",
+ "secure": false,
+ "value": "STRING cache.config"
+ },
+ {
+ "configFile": "plugin.config",
+ "lastUpdated": "2018-01-19T19:01:21.469075+00:00",
+ "name": "regex_revalidate.so",
+ "secure": false,
+ "value": "--config regex_revalidate.config"
+ },
+ {
+ "configFile": "records.config",
+ "lastUpdated": "2018-01-19T19:01:21.49285+00:00",
+ "name": "CONFIG proxy.config.hostdb.storage_size",
+ "secure": false,
+ "value": "INT 33554432"
+ },
+ {
+ "configFile": "regex_revalidate.config",
+ "lastUpdated": "2018-01-19T19:01:21.496195+00:00",
+ "name": "maxRevalDurationDays",
+ "secure": false,
+ "value": "90"
+ },
+ {
+ "configFile": "package",
+ "lastUpdated": "2018-01-19T19:01:21.499423+00:00",
+ "name": "trafficserver",
+ "secure": false,
+ "value": "5.3.2-765.f4354b9.el7.centos.x86_64"
+ },
+ {
+ "configFile": "global",
+ "lastUpdated": "2018-01-19T19:01:21.501151+00:00",
+ "name": "use_tenancy",
+ "secure": false,
+ "value": "1"
+ },
+ {
+ "configFile": "global",
+ "lastUpdated": "2020-04-21T05:19:43.853831+00:00",
+ "name": "tm.instance_name",
+ "secure": false,
+ "value": "Traffic Ops API Tests"
+ }
+ ],
+ "physLocations": [
+ {
+ "address": "1234 mile high circle",
+ "city": "Denver",
+ "comments": null,
+ "email": null,
+ "lastUpdated": "2018-01-19T21:19:32.081465+00:00",
+ "name": "Denver",
+ "phone": "303-111-1111",
+ "poc": null,
+ "region": "region1",
+ "shortName": "denver",
+ "state": "CO",
+ "zip": "80202"
+ },
+ {
+ "address": "1234 green way",
+ "city": "Boulder",
+ "comments": null,
+ "email": null,
+ "lastUpdated": "2018-01-19T21:19:32.086195+00:00",
+ "name": "Boulder",
+ "phone": "303-222-2222",
+ "poc": null,
+ "region": "region1",
+ "shortName": "boulder",
+ "state": "CO",
+ "zip": "80301"
+ },
+ {
+ "address": "1234 southern way",
+ "city": "Atlanta",
+ "comments": null,
+ "email": null,
+ "lastUpdated": "2018-01-19T21:19:32.089538+00:00",
+ "name": "HotAtlanta",
+ "phone": "404-222-2222",
+ "poc": null,
+ "region": "region1",
+ "shortName": "atlanta",
+ "state": "GA",
+ "zip": "30301"
+ }
+ ],
+ "profiles": [
+ {
+ "cdnName": "cdn1",
+ "description": "Edge Cache - Apache Traffic Server",
+ "name": "ATS_EDGE_TIER_CACHE",
+ "routingDisabled": false,
+ "type": "ATS_PROFILE",
+ "params": [
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.proxy_name",
+ "secure": false,
+ "value": "STRING __HOSTNAME__"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.config_dir",
+ "secure": false,
+ "value": "STRING /opt/trafficserver/etc/trafficserver"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.admin.user_id",
+ "secure": false,
+ "value": "STRING ats"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.server_ports",
+ "secure": false,
+ "value": "STRING 80 80:ipv6"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.insert_response_via_str",
+ "secure": false,
+ "value": "INT 3"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.parent_proxy_routing_enable",
+ "secure": false,
+ "value": "INT 1"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.parent_proxy.retry_time",
+ "secure": false,
+ "value": "INT 60"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.connect_attempts_timeout",
+ "secure": false,
+ "value": "INT 10"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.cache.required_headers",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.enable_http_stats",
+ "secure": false,
+ "value": "INT 1"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.dns.round_robin_nameservers",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.log.max_space_mb_for_logs",
+ "secure": false,
+ "value": "INT 512"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.log.max_space_mb_headroom",
+ "secure": false,
+ "value": "INT 50"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.log.logfile_dir",
+ "secure": false,
+ "value": "STRING /var/log/trafficserver"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.reverse_proxy.enabled",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.diags.debug.enabled",
+ "secure": false,
+ "value": "INT 1"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.slow.log.threshold",
+ "secure": false,
+ "value": "INT 10000"
+ },
+ {
+ "configFile": "cache.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver/"
+ },
+ {
+ "configFile": "hosting.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver/"
+ },
+ {
+ "configFile": "parent.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver/"
+ },
+ {
+ "configFile": "plugin.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver/"
+ },
+ {
+ "configFile": "records.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver/"
+ },
+ {
+ "configFile": "storage.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver/"
+ },
+ {
+ "configFile": "volume.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver/"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.url_remap.remap_required",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "rascal.properties",
+ "name": "health.threshold.queryTime",
+ "secure": false,
+ "value": "1000"
+ },
+ {
+ "configFile": "rascal.properties",
+ "name": "health.polling.url",
+ "secure": false,
+ "value": "http://${hostname}/_astats?application=&inf.name=${interface_name}"
+ },
+ {
+ "configFile": "storage.config",
+ "name": "Disk_Volume",
+ "secure": false,
+ "value": "1"
+ },
+ {
+ "configFile": "rascal.properties",
+ "name": "health.connection.timeout",
+ "secure": false,
+ "value": "2000"
+ },
+ {
+ "configFile": "chkconfig",
+ "name": "trafficserver",
+ "secure": false,
+ "value": "0:off\t1:off\t2:on\t3:on\t4:on\t5:on\t6:off"
+ },
+ {
+ "configFile": "regex_revalidate.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.exec_thread.autoconfig",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "astats.config",
+ "name": "allow_ip",
+ "secure": false,
+ "value": "127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
+ },
+ {
+ "configFile": "astats.config",
+ "name": "allow_ip6",
+ "secure": false,
+ "value": "::1/128,fc01:9400:1000:8::/64"
+ },
+ {
+ "configFile": "astats.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver"
+ },
+ {
+ "configFile": "astats.config",
+ "name": "path",
+ "secure": false,
+ "value": "_astats"
+ },
+ {
+ "configFile": "astats.config",
+ "name": "record_types",
+ "secure": false,
+ "value": "122"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.http.transaction_active_timeout_in",
+ "secure": false,
+ "value": "INT 0"
+ },
+ {
+ "configFile": "records.config",
+ "name": "CONFIG proxy.config.body_factory.template_sets_dir",
+ "secure": false,
+ "value": "STRING /opt/trafficserver/etc/trafficserver/body_factory"
+ },
+ {
+ "configFile": "storage.config",
+ "name": "Drive_Letters",
+ "secure": false,
+ "value": "cache"
+ },
+ {
+ "configFile": "ip_allow.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver"
+ },
+ {
+ "configFile": "storage.config",
+ "name": "Drive_Prefix",
+ "secure": false,
+ "value": "/var/trafficserver/"
+ },
+ {
+ "configFile": "set_dscp_0.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_10.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_12.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_14.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_18.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_20.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_22.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_26.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_28.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_30.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_34.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_36.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_38.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_8.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_16.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_24.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_32.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_40.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_48.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_56.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "set_dscp_37.config",
+ "name": "location",
+ "value": "/opt/trafficserver/etc/trafficserver/dscp"
+ },
+ {
+ "configFile": "package",
+ "lastUpdated": "2018-01-19T19:01:21.499423+00:00",
+ "name": "trafficserver",
+ "secure": true,
+ "value": "8.0.8-19.77cb23a.el7.x86_64"
+ },
+ {
+ "configFile": "remap.config",
+ "name": "location",
+ "secure": false,
+ "value": "/opt/trafficserver/etc/trafficserver"
+ }
+ ]
+ },
+ {
+ "cdnName": "cdn1",
+ "description": "edge1 description",
+ "lastUpdated": "2018-03-02T17:27:11.818418+00:00",
+ "name": "EDGE1",
+ "routing_disabled": false,
+ "type": "ATS_PROFILE"
+ },
+ {
+ "cdnName": "cdn2",
+ "description": "edge2 description",
+ "lastUpdated": "2018-03-02T17:27:11.818418+00:00",
+ "name": "EDGEInCDN2",
+ "routing_disabled": false,
+ "type": "ATS_PROFILE"
+ },
+ {
+ "cdnName": "cdn4",
+ "description": "edge2 description",
+ "lastUpdated": "2018-03-02T17:27:11.818418+00:00",
+ "name": "EDGE2",
+ "routing_disabled": false,
+ "type": "ATS_PROFILE"
+ },
+ {
+ "cdnName": "cdn2",
+ "description": "cdn2 edge description",
+ "name": "CDN2_EDGE",
+ "routing_disabled": false,
+ "type": "ATS_PROFILE"
+ },
+ {
+ "cdnName": "cdn1",
+ "description": "mid description",
+ "lastUpdated": "2018-03-02T17:27:11.80173+00:00",
+ "name": "MID1",
+ "routing_disabled": false,
+ "type": "ATS_PROFILE"
+ },
+ {
+ "cdnName": "cdn2",
+ "description": "mid description",
+ "lastUpdated": "2018-03-02T17:27:11.80173+00:00",
+ "name": "MID2",
+ "routing_disabled": false,
+ "type": "ATS_PROFILE"
+ },
+ {
+ "cdnName": "cdn1",
+ "description": "origin description",
+ "lastUpdated": "2018-03-02T17:27:11.80173+00:00",
+ "name": "ORIGIN1",
+ "routing_disabled": false,
+ "type": "ORG_PROFILE"
+ },
+ {
+ "cdnName": "cdn1",
+ "description": "cdn1 description",
+ "lastUpdated": "2018-03-02T17:27:11.80452+00:00",
+ "name": "CCR1",
+ "routing_disabled": false,
+ "type": "TR_PROFILE"
+ },
+ {
+ "cdnName": "cdn2",
+ "description": "cdn2 description",
+ "lastUpdated": "2018-03-02T17:27:11.807948+00:00",
+ "name": "CCR2",
+ "routing_disabled": false,
+ "type": "TR_PROFILE"
+ },
+ {
+ "cdnName": "cdn1",
+ "description": "rascal description",
+ "lastUpdated": "2018-03-02T17:27:11.813052+00:00",
+ "name": "RASCAL1",
+ "routing_disabled": false,
+ "type": "TM_PROFILE",
+ "params": [
+ {
+ "configFile": "rascal.properties",
+ "name": "health.threshold.queryTime",
+ "secure": false,
+ "value": "1000"
+ },
+ {
+ "configFile": "rascal.properties",
+ "name": "health.polling.url",
+ "secure": false,
+ "value": "http://${hostname}/_astats?application=&inf.name=${interface_name}"
+ },
+ {
+ "configFile": "rascal-config.txt",
+ "lastUpdated": "2018-01-19T19:01:21.472279+00:00",
+ "name": "peers.polling.interval",
+ "secure": false,
+ "value": "60"
+ },
+ {
+ "configFile": "rascal-config.txt",
+ "lastUpdated": "2018-01-19T19:01:21.472279+00:00",
+ "name": "health.polling.interval",
+ "secure": false,
+ "value": "30"
+ }
+ ]
+ },
+ {
+ "cdnName": "cdn1",
+ "description": "mso origin description",
+ "lastUpdated": "2018-03-02T17:27:11.80173+00:00",
+ "name": "MSO",
+ "routing_disabled": false,
+ "type": "ORG_PROFILE"
+ },
+ {
+ "cdnName": "cdn2",
+ "description": "cdn2 mid description",
+ "name": "CDN2_MID",
+ "routing_disabled": false,
+ "type": "ATS_PROFILE"
+ }
+ ],
+ "regions": [
+ {
+ "divisionName": "division1",
+ "name": "region1"
+ },
+ {
+ "divisionName": "cdn-div2",
+ "name": "cdn-region2"
+ }
+ ],
+ "roles": [
+ {
+ "name": "new_admin",
+ "description": "super-user 2",
+ "privLevel": 30,
+ "capabilities": [
+ "all-read",
+ "all-write",
+ "cdn-read"
+ ]
+ },
+ {
+ "name": "bad_admin",
+ "description": "super-user 3",
+ "privLevel": 30,
+ "capabilities": [
+ "all-read",
+ "all-write",
+ "invalid-capability"
+ ]
+ }
+ ],
+ "servers": [
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-edge-01",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.21/30",
+ "gateway": "127.0.0.21",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:8::1/64",
+ "gateway": "2345:1234:12:8::1",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "atlanta-edge-01\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn2",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "cdn2-test-edge",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "0.0.0.0/0",
+ "gateway": "0.0.0.0",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 1500,
+ "name": "eth0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGEInCDN2",
+ "rack": "",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "",
+ "xmppPasswd": ""
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "guid": null,
+ "hostName": "influxdb02",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.11/22",
+ "gateway": "127.0.0.11",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:8::2/64",
+ "gateway": "2345:1234:12:8::2",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 1500,
+ "name": "eth1"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 8086,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "",
+ "xmppPasswd": ""
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-router-01",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.12/30",
+ "gateway": "127.0.0.1",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:8::3/64",
+ "gateway": "2345:1234:12:8::3",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "atlanta-router-01\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup2",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-edge-03",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:12:2::4/64",
+ "gateway": "2345:1234:12:2::4",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.13/30",
+ "gateway": "127.0.0.1",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "ATS_EDGE_TIER_CACHE",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "atlanta-edge-03\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-edge-14",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:12:8::5/64",
+ "gateway": "2345:1234:12:8::5",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.14/30",
+ "gateway": "127.0.0.1",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "atlanta-edge-14\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-edge-15",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:12:d::6/64",
+ "gateway": "2345:1234:12:d::6",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.15/30",
+ "gateway": "127.0.0.7",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "ipNetmask": "255.255.255.252",
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "atlanta-edge-15\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "parentCachegroup",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-mid-16",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:12:d::7/64",
+ "gateway": "2345:1234:12:d::7",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.16/30",
+ "gateway": "127.0.0.7",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "MID1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false,
+ "xmppId": "atlanta-mid-16\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "parentCachegroup",
+ "cdnName": "cdn2",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-mid-17",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:17:d::7/64",
+ "gateway": "2345:1234:17:d::7",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.17/30",
+ "gateway": "127.0.0.17",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "MID2",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false,
+ "xmppId": "atlanta-mid-17\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-org-1",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:12:d::8/64",
+ "gateway": "2345:1234:12:d::8",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.17/30",
+ "gateway": "127.0.0.17",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "atlanta-org-1\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-org-2",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.18/30",
+ "gateway": "127.0.0.18",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:d::9/64",
+ "gateway": "2345:1234:12:d::9",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "atlanta-org-1\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "ga.atlanta.kabletown.net",
+ "guid": null,
+ "hostName": "atlanta-mid-01",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.2/30",
+ "gateway": "127.0.0.2",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:9::10/64",
+ "gateway": "2345:1234:12:9::10",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false,
+ "xmppId": "atlanta-mid-01\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "guid": null,
+ "hostName": "rascal01",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.4/30",
+ "gateway": "127.0.0.4",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:b::11/64",
+ "gateway": "2345:1234:12:b::11",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "RASCAL1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 81,
+ "type": "RASCAL",
+ "updPending": false,
+ "xmppId": "",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup2",
+ "cdnName": "cdn2",
+ "domainName": "kabletown2.net",
+ "guid": null,
+ "hostName": "edge1-cdn2",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.31/24",
+ "gateway": "127.0.0.4",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:b::13/64",
+ "gateway": "2345:1234:12:b::13",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "CDN2_EDGE",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 81,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "cdnName": "cdn1",
+ "domainName": "docker_default",
+ "guid": null,
+ "hostName": "traffic_vault",
+ "httpsPort": 8087,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.1/22",
+ "gateway": "127.0.0.1",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:b::12/64",
+ "gateway": "2345:1234:12:b::12",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 1500,
+ "name": "eth1"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "ONLINE",
+ "tcpPort": 8088,
+ "type": "RIAK",
+ "updPending": false,
+ "xmppId": "",
+ "xmppPasswd": ""
+ },
+ {
+ "cachegroup": "multiOriginCachegroup",
+ "cdnName": "cdn1",
+ "domainName": "ga.denver.kabletown.net",
+ "guid": null,
+ "hostName": "denver-mso-org-01",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "127.0.0.1/30",
+ "gateway": "127.0.0.1",
+ "serviceAddress": true
+ },
+ {
+ "address": "2345:1234:12:8::20/64",
+ "gateway": "2345:1234:12:8::20",
+ "serviceAddress": false
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "lastUpdated": "2018-03-28T17:30:00.220351+00:00",
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "MSO",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "ORG",
+ "updPending": false,
+ "xmppId": "denver-mso-org-01\\\\@ocdn.kabletown.net",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup3",
+ "cdnName": "cdn1",
+ "domainName": "kabletown2.net",
+ "guid": null,
+ "hostName": "edge1-cdn1-cg3",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "::13/64",
+ "gateway": "2345:1234:12:b::13",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.100/24",
+ "gateway": "127.0.0.4",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 81,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "cachegroup3",
+ "cdnName": "cdn1",
+ "domainName": "kabletown2.net",
+ "guid": null,
+ "hostName": "edge2-cdn1-cg3",
+ "httpsPort": 443,
+ "iloIpAddress": "",
+ "iloIpGateway": "",
+ "iloIpNetmask": "",
+ "iloPassword": "",
+ "iloUsername": "",
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "::14/64",
+ "gateway": "2345:1234:12:b::13",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.101/24",
+ "gateway": "127.0.0.4",
+ "serviceAddress": true
+ }
+ ],
+ "maxBandwidth": null,
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "mgmtIpAddress": "",
+ "mgmtIpGateway": "",
+ "mgmtIpNetmask": "",
+ "offlineReason": null,
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "routerHostName": "",
+ "routerPortName": "",
+ "status": "REPORTED",
+ "tcpPort": 81,
+ "type": "EDGE",
+ "updPending": false,
+ "xmppId": "",
+ "xmppPasswd": "X"
+ },
+ {
+ "cachegroup": "topology-edge-cg-01",
+ "cdnName": "cdn1",
+ "domainName": "edge-01.forked-topology.kabletown.net",
+ "hostName": "topology-edge-01",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:12:2::4/64",
+ "gateway": "2345:1234:12:2::4",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.19/30",
+ "gateway": "127.0.0.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-edge-cg-02",
+ "cdnName": "cdn1",
+ "domainName": "edge-02.forked-topology.kabletown.net",
+ "hostName": "topology-edge-02",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:12:2::4/64",
+ "gateway": "2345:1234:12:2::4",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.20/30",
+ "gateway": "127.0.0.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-mid-cg-04",
+ "cdnName": "cdn1",
+ "domainName": "mid-04.forked-topology.kabletown.net",
+ "hostName": "topology-mid-04",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2345:1234:12:2::4/64",
+ "gateway": "2345:1234:12:2::4",
+ "serviceAddress": false
+ },
+ {
+ "address": "127.0.0.13/30",
+ "gateway": "127.0.0.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "MID1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc1",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-mid-01",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::2/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.2/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "MID1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc1",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-mid-02",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::3/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.3/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "MID1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc1",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-mid-03",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::4/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.4/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "MID1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc2",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-edge-01",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::5/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.5/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc2",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-edge-02",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::6/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.6/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc2",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-edge-03",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::7/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.7/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc3",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-edge-04",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::8/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.8/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc3",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-edge-05",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::9/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.9/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc3",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-edge-06",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::10/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.10/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc2",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-edge-07",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::11/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.11/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_EDGE",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc3",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-edge-08",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.12/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_EDGE",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "dtrc1",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "dtrc-mid-04",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::13/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.13/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "cachegroup3",
+ "cdnName": "cdn1",
+ "domainName": "kabletown.net",
+ "hostName": "edgeInCachegroup3",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.13/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "EDGE1",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "parentCachegroup",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInParentCachegroup",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.14/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "secondaryCachegroup",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInSecondaryCachegroup",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.15/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "fallback1",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "edgeInFallback1",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.16/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_EDGE",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "fallback2",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "edgeInFallback2",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.17/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_EDGE",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "parentCachegroup2",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInParentCachegroup2",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.18/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-edge-cg-01",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "edgeInTopologyEdgeCg01",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.19/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_EDGE",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-edge-cg-02",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "edgeInTopologyEdgeCg02",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.20/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_EDGE",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "EDGE",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-mid-cg-01",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInTopologyMidCg01",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.21/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-mid-cg-02",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInTopologyMidCg02",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.22/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-mid-cg-03",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInTopologyMidCg03",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.23/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-mid-cg-04",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInTopologyMidCg04",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.24/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-mid-cg-05",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInTopologyMidCg05",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.25/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-mid-cg-06",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInTopologyMidCg06",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.26/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ },
+ {
+ "cachegroup": "topology-mid-cg-07",
+ "cdnName": "cdn2",
+ "domainName": "kabletown.net",
+ "hostName": "midInTopologyMidCg07",
+ "httpsPort": 443,
+ "interfaces": [
+ {
+ "ipAddresses": [
+ {
+ "address": "2001:db8:dead:beef::12/64",
+ "gateway": "2001:db8:dead:beef::1",
+ "serviceAddress": false
+ },
+ {
+ "address": "192.0.2.27/24",
+ "gateway": "192.0.2.1",
+ "serviceAddress": true
+ }
+ ],
+ "monitor": true,
+ "mtu": 9000,
+ "name": "bond0"
+ }
+ ],
+ "physLocation": "Denver",
+ "profile": "CDN2_MID",
+ "rack": "RR 119.02",
+ "revalPending": false,
+ "status": "REPORTED",
+ "tcpPort": 80,
+ "type": "MID",
+ "updPending": false
+ }
+ ],
+ "serverCapabilities": [
+ {
+ "name": "foo"
+ },
+ {
+ "name": "bar"
+ },
+ {
+ "name": "ram"
+ },
+ {
+ "name": "disk"
+ },
+ {
+ "name": "asdf"
+ }
+ ],
+ "serverServerCapabilities": [
+ {
+ "serverHostName": "atlanta-edge-03",
+ "serverCapability": "foo"
+ },
+ {
+ "serverHostName": "atlanta-edge-03",
+ "serverCapability": "bar"
+ },
+ {
+ "serverHostName": "dtrc-mid-01",
+ "serverCapability": "ram"
+ },
+ {
+ "serverHostName": "dtrc-mid-01",
+ "serverCapability": "disk"
+ },
+ {
+ "serverHostName": "dtrc-mid-02",
+ "serverCapability": "ram"
+ },
+ {
+ "serverHostName": "dtrc-mid-02",
+ "serverCapability": "disk"
+ },
+ {
+ "serverHostName": "dtrc-edge-01",
+ "serverCapability": "ram"
+ },
+ {
+ "serverHostName": "dtrc-edge-01",
+ "serverCapability": "disk"
+ },
+ {
+ "serverHostName": "dtrc-edge-01",
+ "serverCapability": "asdf"
+ },
+ {
+ "serverHostName": "dtrc-edge-02",
+ "serverCapability": "ram"
+ },
+ {
+ "serverHostName": "dtrc-edge-02",
+ "serverCapability": "disk"
+ },
+ {
+ "serverHostName": "dtrc-edge-04",
+ "serverCapability": "ram"
+ },
+ {
+ "serverHostName": "dtrc-edge-04",
+ "serverCapability": "disk"
+ },
+ {
+ "serverHostName": "dtrc-edge-05",
+ "serverCapability": "ram"
+ },
+ {
+ "serverHostName": "dtrc-edge-05",
+ "serverCapability": "disk"
+ },
+ {
+ "serverHostName": "dtrc-edge-07",
+ "serverCapability": "asdf"
+ },
+ {
+ "serverHostName": "dtrc-edge-08",
+ "serverCapability": "asdf"
+ },
+ {
+ "serverHostName": "dtrc-mid-04",
+ "serverCapability": "asdf"
+ }
+ ],
+ "serviceCategories": [
+ {
+ "name": "serviceCategory1"
+ },
+ {
+ "name": "barServiceCategory2"
+ }
+ ],
+ "staticdnsentries": [
+ {
+ "address": "192.168.0.1",
+ "cachegroup": "cachegroup2",
+ "deliveryservice": "ds1",
+ "host": "host2",
+ "type": "A_RECORD",
+ "ttl": 10
+ },
+ {
+ "address": "this.is.a.hostname.",
+ "cachegroup": "cachegroup1",
+ "deliveryservice": "ds1",
+ "host": "host1",
+ "type": "CNAME_RECORD",
+ "ttl": 0
+ },
+ {
+ "address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
+ "cachegroup": "cachegroup2",
+ "deliveryservice": "ds1",
+ "host": "host3",
+ "ttl": 10,
+ "type": "AAAA_RECORD"
+ }
+ ],
+ "statuses": [
+ {
+ "description": "Edge: Puts server in CCR config file in this state, but CCR will never route traffic to it. Mid: Server will not be included in parent.config files for its edge caches",
+ "name": "OFFLINE"
+ },
+ {
+ "description": "Edge: Puts server in CCR config file in this state, and CCR will always route traffic to it. Mid: Server will be included in parent.config files for its edges",
+ "name": "ONLINE"
+ },
+ {
+ "description": "Edge: Puts server in CCR config file in this state, and CCR will adhere to the health protocol. Mid: N/A for now",
+ "name": "REPORTED"
+ },
+ {
+ "description": "Temporary down. Edge: XMPP client will send status OFFLINE to CCR, otherwise similar to REPORTED. Mid: Server will not be included in parent.config files for its edge caches",
+ "name": "ADMIN_DOWN"
+ },
+ {
+ "description": "Edge: 12M will not include caches in this state in CCR config files. Mid: N/A for now",
+ "name": "CCR_IGNORE"
+ },
+ {
+ "description": "Pre Production. Not active in any configuration.",
+ "name": "PRE_PROD"
+ },
+ {
+ "name": "TEST_NULL_DESCRIPTION"
+ }
+ ],
+ "tenants": [
+ {
+ "active": true,
+ "name": "tenant1",
+ "parentName": "root"
+ },
+ {
+ "active": false,
+ "name": "tenant2",
+ "parentName": "tenant1"
+ },
+ {
+ "active": true,
+ "name": "tenant3",
+ "parentName": "tenant2"
+ },
+ {
+ "active": true,
+ "name": "tenant4",
+ "parentName": "root"
+ }
+ ],
+ "topologies": [
+ {
+ "name": "mso-topology",
+ "description": "a multi-site origin topology",
+ "nodes": [
+ {
+ "cachegroup": "multiOriginCachegroup",
+ "parents": []
+ },
+ {
+ "cachegroup": "parentCachegroup",
+ "parents": [0]
+ },
+ {
+ "cachegroup": "cachegroup2",
+ "parents": [1]
+ }
+ ]
+ },
+ {
+ "name": "another-topology",
+ "description": "another topology",
+ "nodes": [
+ {
+ "cachegroup": "parentCachegroup",
+ "parents": []
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "parents": [
+ 0
+ ]
+ },
+ {
+ "cachegroup": "secondaryCachegroup",
+ "parents": []
+ },
+ {
+ "cachegroup": "cachegroup2",
+ "parents": [
+ 2
+ ]
+ }
+ ]
+ },
+ {
+ "name": "secondary-parents",
+ "description": "A topology with secondary parents",
+ "nodes": [
+ {
+ "cachegroup": "parentCachegroup",
+ "parent": "",
+ "secParent": "",
+ "parents": []
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "parent": "parentCachegroup",
+ "secParent": "secondaryCachegroup",
+ "parents": [
+ 0,
+ 2
+ ]
+ },
+ {
+ "cachegroup": "secondaryCachegroup",
+ "parent": "",
+ "secParent": "",
+ "parents": []
+ },
+ {
+ "cachegroup": "fallback1",
+ "parent": "secondaryCachegroup",
+ "secParent": "parentCachegroup",
+ "parents": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "cachegroup": "fallback2",
+ "parent": "secondaryCachegroup",
+ "secParent": "parentCachegroup",
+ "parents": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ {
+ "name": "4-tiers",
+ "description": "A 4-tier topology",
+ "nodes": [
+ {
+ "cachegroup": "parentCachegroup",
+ "parents": []
+ },
+ {
+ "cachegroup": "parentCachegroup2",
+ "parents": [
+ 0
+ ]
+ },
+ {
+ "cachegroup": "cachegroup1",
+ "parents": [
+ 1
+ ]
+ },
+ {
+ "cachegroup": "secondaryCachegroup",
+ "parents": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "cachegroup": "fallback1",
+ "parents": [
+ 3
+ ]
+ }
+ ]
+ },
+ {
+ "name": "forked-topology",
+ "description": "This topology stems from 2 ancestors",
+ "nodes": [
+ {
+ "cachegroup": "topology-edge-cg-01",
+ "parents": [
+ 2
+ ]
+ },
+ {
+ "cachegroup": "topology-edge-cg-02",
+ "parents": [
+ 6
+ ]
+ },
+ {
+ "cachegroup": "topology-mid-cg-01",
+ "parents": [
+ 3
+ ]
+ },
+ {
+ "cachegroup": "topology-mid-cg-02",
+ "parents": [
+ 4
+ ]
+ },
+ {
+ "cachegroup": "topology-mid-cg-03",
+ "parents": [
+ 5
+ ]
+ },
+ {
+ "cachegroup": "topology-mid-cg-04",
+ "parents": []
+ },
+ {
+ "cachegroup": "topology-mid-cg-05",
+ "parents": [
+ 7
+ ]
+ },
+ {
+ "cachegroup": "topology-mid-cg-06",
+ "parents": [
+ 8
+ ]
+ },
+ {
+ "cachegroup": "topology-mid-cg-07",
+ "parents": []
+ }
+ ]
+ },
+ {
+ "name": "top-for-ds-req",
+ "description": "a topology",
+ "nodes": [
+ {
+ "cachegroup": "dtrc1",
+ "parents": []
+ },
+ {
+ "cachegroup": "dtrc2",
+ "parents": [0]
+ },
+ {
+ "cachegroup": "dtrc3",
+ "parents": [0]
+ }
+ ]
+ },
+ {
+ "name": "top-for-ds-req2",
+ "description": "a topology",
+ "nodes": [
+ {
+ "cachegroup": "dtrc1",
+ "parents": []
+ },
+ {
+ "cachegroup": "dtrc2",
+ "parents": [0]
+ }
+ ]
+ }
+ ],
+ "types": [
+ {
+ "description": "Host header regular expression",
+ "lastUpdated": "2018-03-02T19:13:46.788583+00:00",
+ "name": "HOST_REGEXP",
+ "useInTable": "regex"
+ },
+ {
+ "description": "DNS Content routing, RAM cache, National",
+ "lastUpdated": "2018-03-02T19:13:46.792319+00:00",
+ "name": "DNS_LIVE_NATNL",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "Other CDN (CDS-IS, Akamai, etc)",
+ "lastUpdated": "2018-03-02T19:13:46.793921+00:00",
+ "name": "OTHER_CDN",
+ "useInTable": "server"
+ },
+ {
+ "description": "Client-Controlled Steering Delivery Service",
+ "lastUpdated": "2018-03-02T19:13:46.795291+00:00",
+ "name": "CLIENT_STEERING",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "influxdb type",
+ "lastUpdated": "2018-03-02T19:13:46.796707+00:00",
+ "name": "INFLUXDB",
+ "useInTable": "server"
+ },
+ {
+ "description": "riak type",
+ "lastUpdated": "2018-03-02T19:13:46.798008+00:00",
+ "name": "RIAK",
+ "useInTable": "server"
+ },
+ {
+ "description": "Origin",
+ "lastUpdated": "2018-03-02T19:13:46.799404+00:00",
+ "name": "ORG",
+ "useInTable": "server"
+ },
+ {
+ "description": "HTTP Content routing cache in RAM ",
+ "lastUpdated": "2018-03-02T19:13:46.800738+00:00",
+ "name": "HTTP_LIVE",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "Active Directory User",
+ "lastUpdated": "2018-03-02T19:13:46.802044+00:00",
+ "name": "ACTIVE_DIRECTORY",
+ "useInTable": "tm_user"
+ },
+ {
+ "description": "federation type resolve4",
+ "lastUpdated": "2018-03-02T19:13:46.803471+00:00",
+ "name": "RESOLVE4",
+ "useInTable": "federation"
+ },
+ {
+ "description": "Static DNS A entry",
+ "lastUpdated": "2018-03-02T19:13:46.804776+00:00",
+ "name": "A_RECORD",
+ "useInTable": "staticdnsentry"
+ },
+ {
+ "description": "Local User",
+ "lastUpdated": "2018-03-02T19:13:46.806035+00:00",
+ "name": "LOCAL",
+ "useInTable": "tm_user"
+ },
+ {
+ "description": "Weighted steering target",
+ "lastUpdated": "2018-03-02T19:13:46.80748+00:00",
+ "name": "STEERING_WEIGHT",
+ "useInTable": "steering_target"
+ },
+ {
+ "description": "HTTP Content routing, RAM cache, National",
+ "lastUpdated": "2018-03-02T19:13:46.808911+00:00",
+ "name": "HTTP_LIVE_NATNL",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "Ops hosts for management",
+ "lastUpdated": "2018-03-02T19:13:46.810576+00:00",
+ "name": "TOOLS_SERVER",
+ "useInTable": "server"
+ },
+ {
+ "description": "Path regular expression",
+ "lastUpdated": "2018-03-02T19:13:46.812049+00:00",
+ "name": "PATH_REGEXP",
+ "useInTable": "regex"
+ },
+ {
+ "description": "Static DNS CNAME entry",
+ "lastUpdated": "2018-03-02T19:13:46.813461+00:00",
+ "name": "CNAME_RECORD",
+ "useInTable": "staticdnsentry"
+ },
+ {
+ "description": "Kabletown Content Router",
+ "lastUpdated": "2018-03-02T19:13:46.814833+00:00",
+ "name": "CCR",
+ "useInTable": "server"
+ },
+ {
+ "description": "Origin Cachegroup",
+ "lastUpdated": "2018-03-02T19:13:46.816199+00:00",
+ "name": "ORG_LOC",
+ "useInTable": "cachegroup"
+ },
+ {
+ "description": "Mid Cachegroup",
+ "lastUpdated": "2018-03-02T19:13:46.816199+00:00",
+ "name": "MID_LOC",
+ "useInTable": "cachegroup"
+ },
+ {
+ "description": "Edge Cache",
+ "lastUpdated": "2018-03-02T19:13:46.817689+00:00",
+ "name": "EDGE",
+ "useInTable": "server"
+ },
+ {
+ "description": "Ordered steering target",
+ "lastUpdated": "2018-03-02T19:13:46.81913+00:00",
+ "name": "STEERING_ORDER",
+ "useInTable": "steering_target"
+ },
+ {
+ "description": "DNS Content Routing",
+ "lastUpdated": "2018-03-02T19:13:46.820528+00:00",
+ "name": "DNS",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "federation type resolve6",
+ "lastUpdated": "2018-03-02T19:13:46.822161+00:00",
+ "name": "RESOLVE6",
+ "useInTable": "federation"
+ },
+ {
+ "description": "Static DNS AAAA entry",
+ "lastUpdated": "2018-03-02T19:13:46.823506+00:00",
+ "name": "AAAA_RECORD",
+ "useInTable": "staticdnsentry"
+ },
+ {
+ "description": "HTTP Content Routing, no caching",
+ "lastUpdated": "2018-03-02T19:13:46.824798+00:00",
+ "name": "HTTP_NO_CACHE",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "any_map type",
+ "lastUpdated": "2018-03-02T19:13:46.826411+00:00",
+ "name": "ANY_MAP",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "Steering Delivery Service",
+ "lastUpdated": "2018-03-02T19:13:46.827779+00:00",
+ "name": "STEERING",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "Edge Cachegroup",
+ "lastUpdated": "2018-03-02T19:13:46.829249+00:00",
+ "name": "EDGE_LOC",
+ "useInTable": "cachegroup"
+ },
+ {
+ "description": "HTTP Content routing cache ",
+ "lastUpdated": "2018-03-02T19:13:46.830862+00:00",
+ "name": "HTTP",
+ "useInTable": "deliveryservice"
+ },
+ {
+ "description": "Mid Tier Cache",
+ "lastUpdated": "2018-03-02T19:13:46.832327+00:00",
+ "name": "MID",
+ "useInTable": "server"
+ },
+ {
+ "description": "Traffic Monitor (Rascal)",
+ "lastUpdated": "2018-03-02T19:13:46.832327+00:00",
+ "name": "RASCAL",
+ "useInTable": "server"
+ }
+ ],
+ "users": [
+ {
+ "addressLine1": "address of admin",
+ "addressLine2": "",
+ "city": "Anywhere",
+ "company": "Comcast",
+ "country": "USA",
+ "email": "admin@example.com",
+ "fullName": "Fred the admin",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "810-555-9876",
+ "postalCode": "55443",
+ "publicSshKey": "",
+ "role": 4,
+ "stateOrProvince": "LA",
+ "tenant": "root",
+ "token": "test",
+ "uid": 0,
+ "username": "adminuser"
+ },
+ {
+ "addressLine1": "address of disallowed",
+ "addressLine2": "place",
+ "city": "somewhere",
+ "company": "else",
+ "country": "UK",
+ "email": "disallowed@example.com",
+ "fullName": "Me me",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "",
+ "postalCode": "",
+ "publicSshKey": "",
+ "registrationSent": "",
+ "role": 1,
+ "stateOrProvince": "",
+ "tenant": "tenant1",
+ "token": "quest",
+ "uid": 0,
+ "username": "disalloweduser"
+ },
+ {
+ "addressLine1": "address of readonly",
+ "addressLine2": "place",
+ "city": "somewhere",
+ "company": "else",
+ "country": "UK",
+ "email": "readonly@example.com",
+ "fullName": "Readonly User",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "",
+ "postalCode": "",
+ "publicSshKey": "",
+ "registrationSent": "",
+ "role": 2,
+ "stateOrProvince": "",
+ "tenant": "tenant1",
+ "uid": 0,
+ "username": "readonlyuser"
+ },
+ {
+ "addressLine1": "address of admin",
+ "addressLine2": "",
+ "city": "Anywhere",
+ "company": "Comcast",
+ "country": "USA",
+ "email": "tenant3user@example.com",
+ "fullName": "Fred the admin",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "810-555-9876",
+ "postalCode": "55443",
+ "publicSshKey": "",
+ "role": 4,
+ "stateOrProvince": "LA",
+ "tenant": "tenant3",
+ "uid": 0,
+ "username": "tenant3user"
+ },
+ {
+ "addressLine1": "address of admin",
+ "addressLine2": "",
+ "city": "Anywhere",
+ "company": "Comcast",
+ "country": "USA",
+ "email": "tenant4user@example.com",
+ "fullName": "Fred the admin",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "810-555-9876",
+ "postalCode": "55443",
+ "publicSshKey": "",
+ "role": 4,
+ "stateOrProvince": "LA",
+ "tenant": "tenant4",
+ "uid": 0,
+ "username": "tenant4user"
+ },
+ {
+ "addressLine1": "address of ops",
+ "addressLine2": "place",
+ "city": "somewhere",
+ "company": "else",
+ "country": "UK",
+ "email": "ops@example.com",
+ "fullName": "Operations User",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "",
+ "postalCode": "",
+ "publicSshKey": "",
+ "registrationSent": "",
+ "role": 3,
+ "stateOrProvince": "",
+ "tenant": "root",
+ "uid": 0,
+ "username": "opsuser"
+ },
+ {
+ "addressLine1": "address of steering",
+ "addressLine2": "place",
+ "city": "somewhere",
+ "company": "else",
+ "country": "UK",
+ "email": "steering@example.com",
+ "fullName": "Steering User",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "",
+ "postalCode": "",
+ "publicSshKey": "",
+ "registrationSent": "",
+ "role": 6,
+ "stateOrProvince": "",
+ "tenant": "root",
+ "uid": 0,
+ "username": "steering"
+ }
+ ],
+ "steeringTargets": [
+ {
+ "deliveryService": "ds1",
+ "target": "ds2",
+ "value": 42,
+ "type": "STEERING_WEIGHT"
+ }
+ ],
+ "servercheck_extensions": [
+ {
+ "name": "ILO_PING",
+ "version": "1.0.0",
+ "info_url": "-",
+ "script_file": "ToPingCheck.pl",
+ "isactive": 1,
+ "description": "",
+ "servercheck_short_name": "ILO",
+ "type": "CHECK_EXTENSION_BOOL"
+ },
+ {
+ "name": "ORT_ERROR_COUNT",
+ "version": "1.0.0",
+ "info_url": "-",
+ "script_file": "ToORTCheck.pl",
+ "isactive": 1,
+ "description": "",
+ "servercheck_short_name": "ORT",
+ "type": "CHECK_EXTENSION_NUM"
+ }
+ ],
+ "serverchecks": [
+ {
+ "servercheck_short_name": "ILO",
+ "host_name": "atlanta-edge-01",
+ "value": 1
+ },
+ {
+ "servercheck_short_name": "ORT",
+ "host_name": "atlanta-edge-01",
+ "value": 13
+ }
+ ],
+ "invalidationJobs": [
+ {
+ "deliveryService": "ds1",
+ "regex": "/.*",
+ "startTime": 4117118271000,
+ "ttl": "121m"
+ },
+ {
+ "deliveryService": "ds1",
+ "regex": "/foo",
+ "startTime": 4117118271000,
+ "ttl": 2160
+ },
+ {
+ "deliveryService": "ds2",
+ "regex": "\\/some-path?.+\\.jpg",
+ "startTime": "2100-06-19T13:57:51-06:00",
+ "ttl": 2.1
+ }
+ ],
+ "statsSummaries": [
+ {
+ "cdnName": "cdn1",
+ "deliveryServiceName": "all",
+ "statName": "daily_maxgbps",
+ "statValue": 5,
+ "summaryTime": "2019-01-01T00:00:00-06:00"
+ },
+ {
+ "cdnName": "cdn1",
+ "deliveryServiceName": "all",
+ "statName": "daily_bytesserved",
+ "statValue": 1000,
+ "summaryTime": "2019-01-01T00:00:00-06:00"
+ }
+ ],
+ "capabilities": [
+ {
+ "name": "test",
+ "description": "quest"
+ },
+ {
+ "name": "foo",
+ "description": "bar"
+ }
+ ]
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/cachegroups.go b/traffic_ops_ort/testing/ort-tests/tcdata/cachegroups.go
new file mode 100644
index 0000000..2f15f3f
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/cachegroups.go
@@ -0,0 +1,116 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+func (r *TCData) CreateTestCacheGroups(t *testing.T) {
+
+ var err error
+ var resp *tc.CacheGroupDetailResponse
+
+ for _, cg := range r.TestData.CacheGroups {
+
+ resp, _, err = TOSession.CreateCacheGroupNullable(cg)
+ if err != nil {
+ t.Errorf("could not CREATE cachegroups: %v, request: %v", err, cg)
+ continue
+ }
+
+ // Testing 'join' fields during create
+ if cg.ParentName != nil && resp.Response.ParentName == nil {
+ t.Error("Parent cachegroup is null in response when it should have a value")
+ }
+ if cg.SecondaryParentName != nil && resp.Response.SecondaryParentName == nil {
+ t.Error("Secondary parent cachegroup is null in response when it should have a value\n")
+ }
+ if cg.Type != nil && resp.Response.Type == nil {
+ t.Error("Type is null in response when it should have a value\n")
+ }
+ if resp.Response.LocalizationMethods == nil {
+ t.Error("Localization methods are null")
+ }
+ if resp.Response.Fallbacks == nil {
+ t.Error("Fallbacks are null")
+ }
+
+ }
+}
+
+func (r *TCData) DeleteTestCacheGroups(t *testing.T) {
+ var parentlessCacheGroups []tc.CacheGroupNullable
+
+ // delete the edge caches.
+ for _, cg := range r.TestData.CacheGroups {
+ // Retrieve the CacheGroup by name so we can get the id for the Update
+ resp, _, err := TOSession.GetCacheGroupNullableByName(*cg.Name)
+ if err != nil {
+ t.Errorf("cannot GET CacheGroup by name: %v - %v", *cg.Name, err)
+ }
+ cg = resp[0]
+
+ // Cachegroups that are parents (usually mids but sometimes edges)
+ // need to be deleted only after the children cachegroups are deleted.
+ if cg.ParentCachegroupID == nil && cg.SecondaryParentCachegroupID == nil {
+ parentlessCacheGroups = append(parentlessCacheGroups, cg)
+ continue
+ }
+ if len(resp) > 0 {
+ respCG := resp[0]
+ _, _, err := TOSession.DeleteCacheGroupByID(*respCG.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE CacheGroup by name: '%s' %v", *respCG.Name, err)
+ }
+ // Retrieve the CacheGroup to see if it got deleted
+ cgs, _, err := TOSession.GetCacheGroupNullableByName(*cg.Name)
+ if err != nil {
+ t.Errorf("error deleting CacheGroup by name: %s", err.Error())
+ }
+ if len(cgs) > 0 {
+ t.Errorf("expected CacheGroup name: %s to be deleted", *cg.Name)
+ }
+ }
+ }
+
+ // now delete the parentless cachegroups
+ for _, cg := range parentlessCacheGroups {
+ // Retrieve the CacheGroup by name so we can get the id for the Update
+ resp, _, err := TOSession.GetCacheGroupNullableByName(*cg.Name)
+ if err != nil {
+ t.Errorf("cannot GET CacheGroup by name: %v - %v", *cg.Name, err)
+ }
+ if len(resp) > 0 {
+ respCG := resp[0]
+ _, _, err := TOSession.DeleteCacheGroupByID(*respCG.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE CacheGroup by name: '%s' %v", *respCG.Name, err)
+ }
+
+ // Retrieve the CacheGroup to see if it got deleted
+ cgs, _, err := TOSession.GetCacheGroupNullableByName(*cg.Name)
+ if err != nil {
+ t.Errorf("error deleting CacheGroup name: %s", err.Error())
+ }
+ if len(cgs) > 0 {
+ t.Errorf("expected CacheGroup name: %s to be deleted", *cg.Name)
+ }
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/cachegroups_parameters.go b/traffic_ops_ort/testing/ort-tests/tcdata/cachegroups_parameters.go
new file mode 100644
index 0000000..8ef5509
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/cachegroups_parameters.go
@@ -0,0 +1,103 @@
+/*
+
+ 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 tcdata
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+func (r *TCData) CreateTestCacheGroupParameters(t *testing.T) {
+ // Get Cache Group to assign parameter to
+ firstCacheGroup := r.TestData.CacheGroups[0]
+ cacheGroupResp, _, err := TOSession.GetCacheGroupNullableByName(*firstCacheGroup.Name)
+ if err != nil {
+ t.Errorf("cannot GET Cache Group by name: %v - %v", firstCacheGroup.Name, err)
+ }
+ if cacheGroupResp == nil {
+ t.Fatal("Cache Groups response should not be nil")
+ }
+
+ // Get Parameter to assign to Cache Group
+ firstParameter := r.TestData.Parameters[0]
+ paramResp, _, err := TOSession.GetParameterByName(firstParameter.Name)
+ if err != nil {
+ t.Errorf("cannot GET Parameter by name: %v - %v", firstParameter.Name, err)
+ }
+ if paramResp == nil {
+ t.Fatal("Parameter response should not be nil")
+ }
+
+ // Assign Parameter to Cache Group
+ cacheGroupID := cacheGroupResp[0].ID
+ parameterID := paramResp[0].ID
+ resp, _, err := TOSession.CreateCacheGroupParameter(*cacheGroupID, parameterID)
+ if err != nil {
+ t.Errorf("could not CREATE cache group parameter: %v", err)
+ }
+ if resp == nil {
+ t.Fatal("Cache Group Parameter response should not be nil")
+ }
+ r.TestData.CacheGroupParameterRequests = append(r.TestData.CacheGroupParameterRequests, resp.Response...)
+}
+
+func (r *TCData) DeleteTestCacheGroupParameters(t *testing.T) {
+ for _, cgp := range r.TestData.CacheGroupParameterRequests {
+ DeleteTestCacheGroupParameter(t, cgp)
+ }
+}
+
+func DeleteTestCacheGroupParameter(t *testing.T, cgp tc.CacheGroupParameterRequest) {
+
+ delResp, _, err := TOSession.DeleteCacheGroupParameter(cgp.CacheGroupID, cgp.ParameterID)
+ if err != nil {
+ t.Fatalf("cannot DELETE Parameter by cache group: %v - %v", err, delResp)
+ }
+
+ // Retrieve the Cache Group Parameter to see if it got deleted
+ queryParams := fmt.Sprintf("?parameterId=%d", cgp.ParameterID)
+
+ parameters, _, err := TOSession.GetCacheGroupParametersByQueryParams(cgp.CacheGroupID, queryParams)
+ if err != nil {
+ t.Errorf("error deleting Parameter name: %s", err.Error())
+ }
+ if parameters == nil {
+ t.Fatal("Cache Group Parameters response should not be nil")
+ }
+ if len(parameters) > 0 {
+ t.Errorf("expected Parameter: %d to be to be disassociated from Cache Group: %d", cgp.ParameterID, cgp.CacheGroupID)
+ }
+
+ // Attempt to delete it again and it should return an error now
+ _, _, err = TOSession.DeleteCacheGroupParameter(cgp.CacheGroupID, cgp.ParameterID)
+ if err == nil {
+ t.Error("expected error when deleting unassociated cache group parameter")
+ }
+
+ // Attempt to delete using a non existing cache group
+ _, _, err = TOSession.DeleteCacheGroupParameter(-1, cgp.ParameterID)
+ if err == nil {
+ t.Error("expected error when deleting cache group parameter with non existing cache group")
+ }
+
+ // Attempt to delete using a non existing parameter
+ _, _, err = TOSession.DeleteCacheGroupParameter(cgp.CacheGroupID, -1)
+ if err == nil {
+ t.Error("expected error when deleting cache group parameter with non existing parameter")
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/cachegroupsdeliveryservices.go b/traffic_ops_ort/testing/ort-tests/tcdata/cachegroupsdeliveryservices.go
new file mode 100644
index 0000000..ffe6d5d
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/cachegroupsdeliveryservices.go
@@ -0,0 +1,153 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "net/http"
+ "net/url"
+ "testing"
+)
+
+// TODO this is the name hard-coded in the create servers test; change to be dynamic
+// TODO this test assumes that a CDN named "cdn1" exists, has at least one Delivery Service, and also
+// assumes that ALL SERVERS IN "cachegroup3" ARE EDGE-TIER CACHE SERVERS IN "cdn1". If that EVER changes,
+// this WILL break.
+const TestEdgeServerCacheGroupName = "cachegroup3"
+
+func (r *TCData) CreateTestCachegroupsDeliveryServices(t *testing.T) {
+ dss, _, err := TOSession.GetDeliveryServiceServers()
+ if err != nil {
+ t.Fatalf("cannot GET DeliveryServiceServers: %v", err)
+ }
+ if len(dss.Response) > 0 {
+ t.Fatalf("cannot test cachegroups delivery services: expected no initial delivery service servers, actual %v", len(dss.Response))
+ }
+
+ dses, _, err := TOSession.GetDeliveryServicesV30WithHdr(nil, nil)
+ if err != nil {
+ t.Fatalf("cannot GET DeliveryServices: %v - %v", err, dses)
+ }
+
+ clientCGs, _, err := TOSession.GetCacheGroupNullableByName(TestEdgeServerCacheGroupName)
+ if err != nil {
+ t.Fatalf("getting cachegroup: %v", err)
+ }
+ if len(clientCGs) != 1 {
+ t.Fatalf("getting cachegroup expected 1, got %v", len(clientCGs))
+ }
+
+ clientCG := clientCGs[0]
+
+ if clientCG.ID == nil {
+ t.Fatalf("Cachegroup has a nil ID")
+ }
+ cgID := *clientCG.ID
+
+ dsIDs := []int{}
+ topologyDsIDs := []int{}
+ for _, ds := range dses {
+ if *ds.CDNName == "cdn1" && ds.Topology == nil {
+ dsIDs = append(dsIDs, *ds.ID)
+ } else if *ds.CDNName == "cdn1" && ds.Topology != nil {
+ topologyDsIDs = append(topologyDsIDs, *ds.ID)
+ }
+ }
+ if len(dsIDs) < 1 {
+ t.Fatal("No Delivery Services found in CDN 'cdn1', cannot continue.")
+ }
+
+ if len(topologyDsIDs) < 1 {
+ t.Fatal("No Topology-based Delivery Services found in CDN 'cdn1', cannot continue.")
+ }
+
+ _, reqInf, err := TOSession.SetCachegroupDeliveryServices(cgID, topologyDsIDs)
+ if err == nil {
+ t.Fatal("assigning Topology-based delivery service to cachegroup - expected: error, actual: nil")
+ }
+ if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
+ t.Fatalf("assigning Topology-based delivery service to cachegroup - expected: 400-level status code, actual: %d", reqInf.StatusCode)
+ }
+
+ resp, _, err := TOSession.SetCachegroupDeliveryServices(cgID, dsIDs)
+ if err != nil {
+ t.Fatalf("setting cachegroup delivery services returned error: %v", err)
+ }
+ if len(resp.Response.ServerNames) == 0 {
+ t.Fatal("setting cachegroup delivery services returned success, but no servers set")
+ }
+
+ // Note this second post of the same cg-dses specifically tests a previous bug, where the query
+ // failed if any servers with location parameters were already assigned, due to a foreign key
+ // violation. See https://github.com/apache/trafficcontrol/pull/3199
+ resp, _, err = TOSession.SetCachegroupDeliveryServices(cgID, dsIDs)
+ if err != nil {
+ t.Fatalf("setting cachegroup delivery services returned error: %v", err)
+ }
+ if len(resp.Response.ServerNames) == 0 {
+ t.Fatal("setting cachegroup delivery services returned success, but no servers set")
+ }
+
+ params := url.Values{}
+ for _, serverName := range resp.Response.ServerNames {
+ params.Set("hostName", string(serverName))
+ resp, _, err := TOSession.GetServers(¶ms)
+ if err != nil {
+ t.Fatalf("getting server: %v", err)
+ }
+ servers := resp
+ if len(servers) != 1 {
+ t.Fatalf("getting servers: expected 1 got %v", len(servers))
+ }
+ server := servers[0]
+ serverID := server.ID
+
+ serverDSes, _, err := TOSession.GetDeliveryServicesByServer(serverID)
+
+ for _, dsID := range dsIDs {
+ found := false
+ for _, serverDS := range serverDSes {
+ if *serverDS.ID == int(dsID) {
+ found = true
+ break
+ }
+ }
+ if !found {
+ t.Errorf("post succeeded, but didn't assign delivery service %v to server", dsID)
+ }
+ }
+ }
+}
+
+func (r *TCData) DeleteTestCachegroupsDeliveryServices(t *testing.T) {
+ dss, _, err := TOSession.GetDeliveryServiceServersN(1000000)
+ if err != nil {
+ t.Errorf("cannot GET DeliveryServiceServers: %v", err)
+ }
+ for _, ds := range dss.Response {
+ _, _, err := TOSession.DeleteDeliveryServiceServer(*ds.DeliveryService, *ds.Server)
+ if err != nil {
+ t.Errorf("deleting delivery service servers: " + err.Error() + "\n")
+ }
+ }
+
+ dss, _, err = TOSession.GetDeliveryServiceServers()
+ if err != nil {
+ t.Errorf("cannot GET DeliveryServiceServers: %v", err)
+ }
+ if len(dss.Response) > 0 {
+ t.Errorf("deleting delivery service servers: delete succeeded, expected empty subsequent get, actual %v", len(dss.Response))
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/cdnfederations.go b/traffic_ops_ort/testing/ort-tests/tcdata/cdnfederations.go
new file mode 100644
index 0000000..b207dca
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/cdnfederations.go
@@ -0,0 +1,67 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "encoding/json"
+ "testing"
+)
+
+var fedIDs []int
+
+func (r *TCData) CreateTestCDNFederations(t *testing.T) {
+
+ // Every federation is associated with a cdn
+ for i, f := range r.TestData.Federations {
+
+ // CDNs test data and Federations test data are not naturally parallel
+ if i >= len(r.TestData.CDNs) {
+ break
+ }
+
+ data, _, err := TOSession.CreateCDNFederationByName(f, r.TestData.CDNs[i].Name)
+ if err != nil {
+ t.Errorf("could not POST federations: " + err.Error())
+ }
+ bytes, _ := json.Marshal(data)
+ t.Logf("POST Response: %s\n", bytes)
+
+ // need to save the ids, otherwise the other tests won't be able to reference the federations
+ if data.Response.ID == nil {
+ t.Error("Federation id is nil after posting")
+ } else {
+ fedIDs = append(fedIDs, *data.Response.ID)
+ }
+ }
+}
+
+func (r *TCData) DeleteTestCDNFederations(t *testing.T) {
+
+ for _, id := range fedIDs {
+ resp, _, err := TOSession.DeleteCDNFederationByID("foo", id)
+ if err != nil {
+ t.Errorf("cannot DELETE federation by id: '%d' %v", id, err)
+ }
+ bytes, err := json.Marshal(resp)
+ t.Logf("DELETE Response: %s\n", bytes)
+
+ data, _, err := TOSession.GetCDNFederationsByID("foo", id)
+ if len(data.Response) != 0 {
+ t.Error("expected federation to be deleted")
+ }
+ }
+ fedIDs = nil // reset the global variable for the next test
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/cdns.go b/traffic_ops_ort/testing/ort-tests/tcdata/cdns.go
new file mode 100644
index 0000000..60a03fb
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/cdns.go
@@ -0,0 +1,60 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+func (r *TCData) CreateTestCDNs(t *testing.T) {
+
+ for _, cdn := range r.TestData.CDNs {
+ resp, _, err := TOSession.CreateCDN(cdn)
+ t.Log("Response: ", resp)
+ if err != nil {
+ t.Errorf("could not CREATE cdns: %v", err)
+ }
+ }
+
+}
+
+func (r *TCData) DeleteTestCDNs(t *testing.T) {
+
+ for _, cdn := range r.TestData.CDNs {
+ // Retrieve the CDN by name so we can get the id for the Update
+ resp, _, err := TOSession.GetCDNByName(cdn.Name)
+ if err != nil {
+ t.Errorf("cannot GET CDN by name: %v - %v", cdn.Name, err)
+ }
+ if len(resp) > 0 {
+ respCDN := resp[0]
+
+ _, _, err := TOSession.DeleteCDNByID(respCDN.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE CDN by name: '%s' %v", respCDN.Name, err)
+ }
+
+ // Retrieve the CDN to see if it got deleted
+ cdns, _, err := TOSession.GetCDNByName(cdn.Name)
+ if err != nil {
+ t.Errorf("error deleting CDN name: %s", err.Error())
+ }
+ if len(cdns) > 0 {
+ t.Errorf("expected CDN name: %s to be deleted", cdn.Name)
+ }
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/coordinates.go b/traffic_ops_ort/testing/ort-tests/tcdata/coordinates.go
new file mode 100644
index 0000000..96e51ad
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/coordinates.go
@@ -0,0 +1,55 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+func (r *TCData) CreateTestCoordinates(t *testing.T) {
+ for _, coord := range r.TestData.Coordinates {
+
+ _, _, err := TOSession.CreateCoordinate(coord)
+ if err != nil {
+ t.Errorf("could not CREATE coordinates: %v", err)
+ }
+ }
+}
+
+func (r *TCData) DeleteTestCoordinates(t *testing.T) {
+ for _, coord := range r.TestData.Coordinates {
+ // Retrieve the Coordinate by name so we can get the id for the Update
+ resp, _, err := TOSession.GetCoordinateByName(coord.Name)
+ if err != nil {
+ t.Errorf("cannot GET Coordinate by name: %v - %v", coord.Name, err)
+ }
+ if len(resp) > 0 {
+ respCoord := resp[0]
+ _, _, err := TOSession.DeleteCoordinateByID(respCoord.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE Coordinate by name: '%s' %v", respCoord.Name, err)
+ }
+ // Retrieve the Coordinate to see if it got deleted
+ coords, _, err := TOSession.GetCoordinateByName(coord.Name)
+ if err != nil {
+ t.Errorf("error deleting Coordinate name: %s", err.Error())
+ }
+ if len(coords) > 0 {
+ t.Errorf("expected Coordinate name: %s to be deleted", coord.Name)
+ }
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservice_request_comments.go b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservice_request_comments.go
new file mode 100644
index 0000000..5690bb5
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservice_request_comments.go
@@ -0,0 +1,66 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+func (r *TCData) CreateTestDeliveryServiceRequestComments(t *testing.T) {
+
+ // Retrieve a delivery service request by xmlId so we can get the ID needed to create a dsr comment
+ dsr := r.TestData.DeliveryServiceRequests[0].DeliveryService
+
+ resp, _, err := TOSession.GetDeliveryServiceRequestByXMLID(dsr.XMLID)
+ if err != nil {
+ t.Errorf("cannot GET delivery service request by xml id: %v - %v", dsr.XMLID, err)
+ }
+ if len(resp) != 1 {
+ t.Errorf("found %d delivery service request by xml id, expected %d: %s", len(resp), 1, dsr.XMLID)
+ } else {
+ respDSR := resp[0]
+
+ for _, comment := range r.TestData.DeliveryServiceRequestComments {
+ comment.DeliveryServiceRequestID = respDSR.ID
+ resp, _, err := TOSession.CreateDeliveryServiceRequestComment(comment)
+ if err != nil {
+ t.Errorf("could not CREATE delivery service request comment: %v - %v", err, resp)
+ }
+ }
+ }
+
+}
+
+func (r *TCData) DeleteTestDeliveryServiceRequestComments(t *testing.T) {
+
+ comments, _, _ := TOSession.GetDeliveryServiceRequestComments()
+
+ for _, comment := range comments {
+ _, _, err := TOSession.DeleteDeliveryServiceRequestCommentByID(comment.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE delivery service request comment by id: '%d' %v", comment.ID, err)
+ }
+
+ // Retrieve the delivery service request comment to see if it got deleted
+ comments, _, err := TOSession.GetDeliveryServiceRequestCommentByID(comment.ID)
+ if err != nil {
+ t.Errorf("error deleting delivery service request comment: %s", err.Error())
+ }
+ if len(comments) > 0 {
+ t.Errorf("expected delivery service request comment: %d to be deleted", comment.ID)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservice_requests.go b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservice_requests.go
new file mode 100644
index 0000000..0e929fe
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservice_requests.go
@@ -0,0 +1,64 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+const (
+ dsrGood = 0
+ dsrBadTenant = 1
+ dsrRequired = 2
+ dsrDraft = 3
+)
+
+func (r *TCData) CreateTestDeliveryServiceRequests(t *testing.T) {
+ t.Log("CreateTestDeliveryServiceRequests")
+
+ dsr := r.TestData.DeliveryServiceRequests[dsrGood]
+ respDSR, _, err := TOSession.CreateDeliveryServiceRequest(dsr)
+ t.Log("Response: ", respDSR)
+ if err != nil {
+ t.Errorf("could not CREATE DeliveryServiceRequests: %v", err)
+ }
+
+}
+
+func (r *TCData) DeleteTestDeliveryServiceRequests(t *testing.T) {
+
+ // Retrieve the DeliveryServiceRequest by name so we can get the id for the Update
+ dsr := r.TestData.DeliveryServiceRequests[dsrGood]
+ resp, _, err := TOSession.GetDeliveryServiceRequestByXMLID(dsr.DeliveryService.XMLID)
+ if err != nil {
+ t.Errorf("cannot GET DeliveryServiceRequest by id: %v - %v", dsr.DeliveryService.XMLID, err)
+ }
+ respDSR := resp[0]
+ alert, _, err := TOSession.DeleteDeliveryServiceRequestByID(respDSR.ID)
+ t.Log("Response: ", alert)
+ if err != nil {
+ t.Errorf("cannot DELETE DeliveryServiceRequest by id: %d - %v - %v", respDSR.ID, err, alert)
+ }
+
+ // Retrieve the DeliveryServiceRequest to see if it got deleted
+ dsrs, _, err := TOSession.GetDeliveryServiceRequestByXMLID(dsr.DeliveryService.XMLID)
+ if err != nil {
+ t.Errorf("error deleting DeliveryServiceRequest name: %s", err.Error())
+ }
+ if len(dsrs) > 0 {
+ t.Errorf("expected DeliveryServiceRequest XMLID: %s to be deleted", dsr.DeliveryService.XMLID)
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservices.go b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservices.go
new file mode 100644
index 0000000..3c942ff
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservices.go
@@ -0,0 +1,90 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "net/url"
+ "strconv"
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+func (r *TCData) CreateTestDeliveryServices(t *testing.T) {
+ pl := tc.Parameter{
+ ConfigFile: "remap.config",
+ Name: "location",
+ Value: "/remap/config/location/parameter/",
+ }
+ _, _, err := TOSession.CreateParameter(pl)
+ if err != nil {
+ t.Errorf("cannot create parameter: %v", err)
+ }
+ for _, ds := range r.TestData.DeliveryServices {
+ _, _, err = TOSession.CreateDeliveryServiceV30(ds)
+ if err != nil {
+ t.Errorf("could not CREATE delivery service '%s': %v", *ds.XMLID, err)
+ }
+ }
+}
+
+func (r *TCData) DeleteTestDeliveryServices(t *testing.T) {
+ dses, _, err := TOSession.GetDeliveryServicesV30WithHdr(nil, nil)
+ if err != nil {
+ t.Errorf("cannot GET deliveryservices: %v", err)
+ }
+ for _, testDS := range r.TestData.DeliveryServices {
+ var ds tc.DeliveryServiceNullableV30
+ found := false
+ for _, realDS := range dses {
+ if realDS.XMLID != nil && *realDS.XMLID == *testDS.XMLID {
+ ds = realDS
+ found = true
+ break
+ }
+ }
+ if !found {
+ t.Errorf("DeliveryService not found in Traffic Ops: %v", *ds.XMLID)
+ continue
+ }
+
+ delResp, err := TOSession.DeleteDeliveryService(strconv.Itoa(*ds.ID))
+ if err != nil {
+ t.Errorf("cannot DELETE DeliveryService by ID: %v - %v", err, delResp)
+ continue
+ }
+
+ // Retrieve the Server to see if it got deleted
+ params := url.Values{}
+ params.Set("id", strconv.Itoa(*ds.ID))
+ foundDS, _, err := TOSession.GetDeliveryServicesV30WithHdr(nil, params)
+ if err != nil {
+ t.Errorf("Unexpected error deleting Delivery Service '%s': %v", *ds.XMLID, err)
+ }
+ if len(foundDS) > 0 {
+ t.Errorf("expected Delivery Service: %s to be deleted, but %d exist with same ID (#%d)", *ds.XMLID, len(foundDS), *ds.ID)
+ }
+ }
+
+ // clean up parameter created in CreateTestDeliveryServices()
+ params, _, err := TOSession.GetParameterByNameAndConfigFile("location", "remap.config")
+ for _, param := range params {
+ deleted, _, err := TOSession.DeleteParameterByID(param.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE parameter by ID (%d): %v - %v", param.ID, err, deleted)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservices_required_capabilities.go b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservices_required_capabilities.go
new file mode 100644
index 0000000..6a75229
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservices_required_capabilities.go
@@ -0,0 +1,212 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
+)
+
+func (r *TCData) CreateTestTopologyBasedDeliveryServicesRequiredCapabilities(t *testing.T) {
+ for _, td := range r.TestData.TopologyBasedDeliveryServicesRequiredCapabilities {
+
+ c := tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: helperGetDeliveryServiceID(t, td.XMLID),
+ RequiredCapability: td.RequiredCapability,
+ }
+
+ _, _, err := TOSession.CreateDeliveryServicesRequiredCapability(c)
+ if err != nil {
+ t.Fatalf("cannot create delivery service required capability: %v", err)
+ }
+ }
+
+ invalid := tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: helperGetDeliveryServiceID(t, util.StrPtr("ds-top-req-cap")),
+ RequiredCapability: util.StrPtr("asdf"),
+ }
+ _, reqInf, err := TOSession.CreateDeliveryServicesRequiredCapability(invalid)
+ if err == nil {
+ t.Fatal("when adding delivery service required capability to a delivery service with a topology that " +
+ "doesn't have cachegroups with at least one server with the required capabilities - expected: error, actual: nil")
+ }
+ if reqInf.StatusCode != http.StatusBadRequest {
+ t.Fatalf("when adding delivery service required capability to a delivery service with a topology that "+
+ "doesn't have cachegroups with at least one server with the required capabilities - expected status code: "+
+ "%d, actual: %d", http.StatusBadRequest, reqInf.StatusCode)
+ }
+}
+
+func (r *TCData) CreateTestDeliveryServicesRequiredCapabilities(t *testing.T) {
+ data := r.TestData.DeliveryServicesRequiredCapabilities
+ if len(data) == 0 {
+ t.Fatal("there must be at least one test ds required capability defined")
+ }
+ ds1 := helperGetDeliveryServiceID(t, data[0].XMLID)
+ amDS := helperGetDeliveryServiceID(t, util.StrPtr("anymap-ds"))
+ testCases := []struct {
+ description string
+ capability tc.DeliveryServicesRequiredCapability
+ }{
+ {
+ description: fmt.Sprintf("re-assign a deliveryservice to a required capability; deliveryServiceID: %d, requiredCapability: %s", *ds1, *data[0].RequiredCapability),
+ capability: tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: ds1,
+ RequiredCapability: data[0].RequiredCapability,
+ },
+ },
+ {
+ description: fmt.Sprintf("assign a deliveryservice to a required capability with no delivery service id; deliveryServiceID: 0, requiredCapability: %s", *data[0].RequiredCapability),
+ capability: tc.DeliveryServicesRequiredCapability{
+ RequiredCapability: data[0].RequiredCapability,
+ },
+ },
+ {
+ description: fmt.Sprintf("assign a deliveryservice to a required capability with no requiredCapability; deliveryServiceID: %d, requiredCapability: 0", *ds1),
+ capability: tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: ds1,
+ },
+ },
+ {
+ description: fmt.Sprintf("assign a deliveryservice to a required capability with an invalid required capability; deliveryServiceID: %d, requiredCapability: bogus", *ds1),
+ capability: tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: ds1,
+ RequiredCapability: util.StrPtr("bogus"),
+ },
+ },
+ {
+ description: fmt.Sprintf("assign a deliveryservice to a required capability with an invalid delivery service id; deliveryServiceID: -1, requiredCapability: %s", *data[0].RequiredCapability),
+ capability: tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: util.IntPtr(-1),
+ RequiredCapability: data[0].RequiredCapability,
+ },
+ },
+ {
+ description: "assign a deliveryservice to a required capability with an invalid deliveryservice type",
+ capability: tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: amDS,
+ RequiredCapability: data[0].RequiredCapability,
+ },
+ },
+ }
+
+ // Assign all required capability to delivery services listed in `tc-fixtures.json`.
+ for _, td := range r.TestData.DeliveryServicesRequiredCapabilities {
+ var dsID int
+ if td.DeliveryServiceID != nil {
+ dsID = *td.DeliveryServiceID
+ }
+
+ var capability string
+ if td.RequiredCapability != nil {
+ capability = *td.RequiredCapability
+ }
+
+ t.Run(fmt.Sprintf("assign a deliveryservice to a required capability; deliveryServiceID: %d, requiredCapability: %s", dsID, capability), func(t *testing.T) {
+ cap := tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: helperGetDeliveryServiceID(t, td.XMLID),
+ RequiredCapability: td.RequiredCapability,
+ }
+
+ _, _, err := TOSession.CreateDeliveryServicesRequiredCapability(cap)
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+ })
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.description, func(t *testing.T) {
+ _, _, err := TOSession.CreateDeliveryServicesRequiredCapability(tc.capability)
+ if err == nil {
+ t.Fatalf("%s; expected err", tc.description)
+ }
+ })
+ }
+}
+
+func (r *TCData) DeleteTestDeliveryServicesRequiredCapabilities(t *testing.T) {
+ // Get Required Capabilities to delete them
+ capabilities, _, err := TOSession.GetDeliveryServicesRequiredCapabilitiesWithHdr(nil, nil, nil, nil)
+ if err != nil {
+ t.Fatalf(err.Error())
+ }
+ if len(capabilities) < 1 {
+ t.Fatal("no delivery services returned")
+ }
+
+ type testCase struct {
+ description string
+ capability tc.DeliveryServicesRequiredCapability
+ err string
+ }
+
+ testCases := []testCase{
+ testCase{
+ description: fmt.Sprintf("delete a deliveryservices required capability with an invalid delivery service id; deliveryServiceID: -1, requiredCapability: %s", *capabilities[0].RequiredCapability),
+ capability: tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: util.IntPtr(-1),
+ RequiredCapability: capabilities[0].RequiredCapability,
+ },
+ err: "no deliveryservice.RequiredCapability with that key found",
+ },
+ testCase{
+ description: fmt.Sprintf("delete a deliveryservices required capability with an invalid required capability; deliveryServiceID: %d, requiredCapability: bogus", *capabilities[0].DeliveryServiceID),
+ capability: tc.DeliveryServicesRequiredCapability{
+ DeliveryServiceID: capabilities[0].DeliveryServiceID,
+ RequiredCapability: util.StrPtr("bogus"),
+ },
+ err: "no deliveryservice.RequiredCapability with that key found",
+ },
+ }
+
+ for _, c := range capabilities {
+ t := testCase{
+ description: fmt.Sprintf("delete a deliveryservices required capability; deliveryServiceID: %d, requiredCapability: %s", *c.DeliveryServiceID, *c.RequiredCapability),
+ capability: c,
+ }
+ testCases = append(testCases, t)
+ }
+
+ for _, c := range testCases {
+ t.Run(c.description, func(t *testing.T) {
+ _, _, err := TOSession.DeleteDeliveryServicesRequiredCapability(*c.capability.DeliveryServiceID, *c.capability.RequiredCapability)
+ if err != nil && !strings.Contains(err.Error(), c.err) {
+ t.Fatalf("%s; got err= %s; expected err= %s", c.description, err, c.err)
+ }
+ })
+ }
+}
+
+func helperGetDeliveryServiceID(t *testing.T, xmlID *string) *int {
+ t.Helper()
+ if xmlID == nil {
+ t.Fatal("xml id must not be nil")
+ }
+ ds, _, err := TOSession.GetDeliveryServiceByXMLIDNullableWithHdr(*xmlID, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(ds) < 1 {
+ t.Fatalf("cannot GET deliveyservice by xml id: %v. Response did not include record.", *xmlID)
+ }
+ return ds[0].ID
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservicesregexes.go b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservicesregexes.go
new file mode 100644
index 0000000..d34aa45
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/deliveryservicesregexes.go
@@ -0,0 +1,106 @@
+/*
+
+ 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 tcdata
+
+import (
+ "fmt"
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "testing"
+)
+
+func (r *TCData) CreateTestDeliveryServicesRegexes(t *testing.T) {
+ db, err := r.OpenConnection()
+ if err != nil {
+ t.Fatal("cannot open db")
+ }
+ defer func() {
+ err := db.Close()
+ if err != nil {
+ t.Errorf("unable to close connection to db, error: %v", err)
+ }
+ }()
+
+ dbRegexInsertTemplate := "INSERT INTO regex (pattern, type) VALUES ('%v', '%v');"
+ dbRegexQueryTemplate := "SELECT id FROM regex order by id desc limit 1;"
+ dbDSRegexInsertTemplate := "INSERT INTO deliveryservice_regex (deliveryservice, regex, set_number) VALUES ('%v', '%v', '%v');"
+
+ for i, regex := range r.TestData.DeliveryServicesRegexes {
+ loadDSRegexIDs(t, ®ex)
+
+ err = execSQL(db, fmt.Sprintf(dbRegexInsertTemplate, regex.Pattern, regex.Type))
+ if err != nil {
+ t.Fatalf("unable to create regex: %v", err)
+ }
+
+ row := db.QueryRow(dbRegexQueryTemplate)
+ err = row.Scan(®ex.ID)
+ if err != nil {
+ t.Fatalf("unable to query regex: %v", err)
+ }
+
+ err = execSQL(db, fmt.Sprintf(dbDSRegexInsertTemplate, regex.DSID, regex.ID, regex.SetNumber))
+ if err != nil {
+ t.Fatalf("unable to create ds regex %v", err)
+ }
+
+ r.TestData.DeliveryServicesRegexes[i] = regex
+ }
+}
+
+func loadDSRegexIDs(t *testing.T, test *tc.DeliveryServiceRegexesTest) {
+ dsTypes, _, err := TOSession.GetTypeByName(test.TypeName)
+ if err != nil {
+ t.Fatalf("unable to get type by name %v: %v", test.TypeName, err)
+ }
+ if len(dsTypes) < 1 {
+ t.Fatalf("could not find any types by name %v", test.TypeName)
+ }
+ test.Type = dsTypes[0].ID
+
+ dses, _, err := TOSession.GetDeliveryServiceByXMLIDNullable(test.DSName)
+ if err != nil {
+ t.Fatalf("unable to ds by xmlid %v: %v", test.DSName, err)
+ }
+ if len(dses) != 1 {
+ t.Fatalf("unable to find ds by xmlid %v", test.DSName)
+ }
+ test.DSID = *dses[0].ID
+}
+
+func (r *TCData) DeleteTestDeliveryServicesRegexes(t *testing.T) {
+ db, err := r.OpenConnection()
+ if err != nil {
+ t.Fatal("cannot open db")
+ }
+ defer func() {
+ err := db.Close()
+ if err != nil {
+ t.Errorf("unable to close connection to db, error: %v", err)
+ }
+ }()
+
+ for _, regex := range r.TestData.DeliveryServicesRegexes {
+ err = execSQL(db, fmt.Sprintf("DELETE FROM deliveryservice_regex WHERE deliveryservice = '%v' and regex ='%v';", regex.DSID, regex.ID))
+ if err != nil {
+ t.Fatalf("unable to delete deliveryservice_regex by regex %v and ds %v: %v", regex.ID, regex.DSID, err)
+ }
+
+ err := execSQL(db, fmt.Sprintf("DELETE FROM regex WHERE Id = '%v';", regex.ID))
+ if err != nil {
+ t.Fatalf("unable to delete regex %v: %v", regex.ID, err)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/divisions.go b/traffic_ops_ort/testing/ort-tests/tcdata/divisions.go
new file mode 100644
index 0000000..e30171e
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/divisions.go
@@ -0,0 +1,56 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+func (r *TCData) CreateTestDivisions(t *testing.T) {
+ for _, division := range r.TestData.Divisions {
+ resp, _, err := TOSession.CreateDivision(division)
+ t.Log("Response: ", resp)
+ if err != nil {
+ t.Errorf("could not CREATE division: %v", err)
+ }
+ }
+}
+
+func (r *TCData) DeleteTestDivisions(t *testing.T) {
+
+ for _, division := range r.TestData.Divisions {
+ // Retrieve the Division by name so we can get the id
+ resp, _, err := TOSession.GetDivisionByName(division.Name)
+ if err != nil {
+ t.Errorf("cannot GET Division by name: %v - %v", division.Name, err)
+ }
+ respDivision := resp[0]
+
+ delResp, _, err := TOSession.DeleteDivisionByID(respDivision.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE Division by division: %v - %v", err, delResp)
+ }
+
+ // Retrieve the Division to see if it got deleted
+ divisionResp, _, err := TOSession.GetDivisionByName(division.Name)
+ if err != nil {
+ t.Errorf("error deleting Division division: %s", err.Error())
+ }
+ if len(divisionResp) > 0 {
+ t.Errorf("expected Division : %s to be deleted", division.Name)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/federation_resolvers.go b/traffic_ops_ort/testing/ort-tests/tcdata/federation_resolvers.go
new file mode 100644
index 0000000..e89a841
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/federation_resolvers.go
@@ -0,0 +1,118 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
+)
+
+func (r *TCData) CreateTestFederationResolvers(t *testing.T) {
+ for _, fr := range r.TestData.FederationResolvers {
+ if fr.Type == nil {
+ t.Fatal("testData Federation Resolver has nil Type")
+ }
+
+ tid, _, err := TOSession.GetTypeByName(*fr.Type)
+ if err != nil {
+ t.Fatalf("Couldn't get an ID for type %s", *fr.Type)
+ }
+ if len(tid) != 1 {
+ t.Fatalf("Expected exactly one Type by name %s, got %d", *fr.Type, len(tid))
+ }
+
+ fr.TypeID = util.UIntPtr(uint(tid[0].ID))
+
+ alerts, _, err := TOSession.CreateFederationResolver(fr)
+ if err != nil {
+ t.Fatalf("failed to create Federation resolver %+v: %v\n\talerts: %+v", fr, err, alerts)
+ }
+ for _, a := range alerts.Alerts {
+ if a.Level != tc.SuccessLevel.String() {
+ t.Errorf("Unexpected %s creating a federation resolver: %s", a.Level, a.Text)
+ } else {
+ t.Logf("Received expected success creating federation resolver: %s", a.Text)
+ }
+ }
+ }
+
+ var invalidFR tc.FederationResolver
+ alerts, _, err := TOSession.CreateFederationResolver(invalidFR)
+ if err == nil {
+ t.Error("Expected an error creating a bad Federation Resolver, but didn't get one")
+ }
+ for _, a := range alerts.Alerts {
+ if a.Level == tc.SuccessLevel.String() {
+ t.Errorf("Unexpected success creating a bad Federation Resolver: %s", a.Text)
+ } else {
+ t.Logf("Received expected %s creating federation resolver: %s", a.Level, a.Text)
+ }
+ }
+
+ invalidFR.TypeID = util.UIntPtr(1)
+ invalidFR.IPAddress = util.StrPtr("not a valid IP address")
+ alerts, _, err = TOSession.CreateFederationResolver(invalidFR)
+ if err == nil {
+ t.Error("Expected an error creating a bad Federation Resolver, but didn't get one")
+ }
+ for _, a := range alerts.Alerts {
+ if a.Level == tc.SuccessLevel.String() {
+ t.Errorf("Unexpected success creating a bad Federation Resolver: %s", a.Text)
+ } else {
+ t.Logf("Received expected %s creating a bad federation resolver: %s", a.Level, a.Text)
+ }
+ }
+}
+
+func (r *TCData) DeleteTestFederationResolvers(t *testing.T) {
+ frs, _, err := TOSession.GetFederationResolvers()
+ if err != nil {
+ t.Errorf("Unexpected error getting Federation Resolvers: %v", err)
+ }
+ if len(frs) < 1 {
+ t.Fatal("Found no Federation Resolvers to delete")
+ }
+ for _, fr := range frs {
+ if fr.ID == nil {
+ t.Fatalf("Malformed Federation Resolver: %+v", fr)
+ }
+ alerts, _, err := TOSession.DeleteFederationResolver(*fr.ID)
+ if err != nil {
+ t.Fatalf("failed to delete Federation Resolver %+v: %v\n\talerts: %+v", fr, err, alerts)
+ }
+ for _, a := range alerts.Alerts {
+ if a.Level != tc.SuccessLevel.String() {
+ t.Errorf("Unexpected %s deleting a federation resolver: %s", a.Level, a.Text)
+ } else {
+ t.Logf("Received expected success deleting federation resolver: %s", a.Text)
+ }
+ }
+ }
+
+ alerts, _, err := TOSession.DeleteFederationResolver(0)
+ if err == nil {
+ t.Error("Expected an error deleting a non-existent Federation Resolver, but didn't get one")
+ }
+ for _, a := range alerts.Alerts {
+ if a.Level == tc.SuccessLevel.String() {
+ t.Errorf("Unexpected success deleting a non-existent Federation Resolver: %s", a.Text)
+ } else {
+ t.Logf("Received expected %s deleting a non-existent federation resolver: %s", a.Level, a.Text)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/federation_users.go b/traffic_ops_ort/testing/ort-tests/tcdata/federation_users.go
new file mode 100644
index 0000000..1815d2e
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/federation_users.go
@@ -0,0 +1,165 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+func (r *TCData) CreateTestFederationUsers(t *testing.T) {
+ if len(r.TestData.Federations) == 0 {
+ t.Error("no federations test data")
+ }
+
+ fedID := fedIDs[0]
+
+ // Get Users
+ users, _, err := TOSession.GetUsers()
+ if err != nil {
+ t.Fatalf("getting users: " + err.Error())
+ }
+ if len(users) < 3 {
+ t.Fatal("need > 3 users to create federation users")
+ }
+
+ u1 := users[0].ID
+ u2 := users[1].ID
+ u3 := users[2].ID
+
+ // Associate one user to federation
+ _, _, err = TOSession.CreateFederationUsers(fedID, []int{*u1}, false)
+ if err != nil {
+ t.Fatalf("assigning users %v to federation %v: %v", []int{*u1}, fedID, err.Error())
+ }
+
+ fedUsers, _, err := TOSession.GetFederationUsers(fedID)
+ if err != nil {
+ t.Fatalf("gettings users for federation %v: %v", fedID, err.Error())
+ }
+ if len(fedUsers) != 1 {
+ t.Errorf("federation users expected 1, actual: %+v", len(fedUsers))
+ }
+
+ // Associate two users to federation and replace first one
+ _, _, err = TOSession.CreateFederationUsers(fedID, []int{*u2, *u3}, true)
+ if err != nil {
+ t.Fatalf("assigning users %v to federation %v: %v", []int{*u2, *u3}, fedID, err.Error())
+ }
+
+ fedUsers, _, err = TOSession.GetFederationUsers(fedID)
+ if err != nil {
+ t.Fatalf("gettings users for federation %v: %v", fedID, err.Error())
+ }
+ if len(fedUsers) != 2 {
+ t.Errorf("federation users expected 2, actual: %+v", len(fedUsers))
+ }
+
+ // Associate one more user to federation
+ _, _, err = TOSession.CreateFederationUsers(fedID, []int{*u1}, false)
+ if err != nil {
+ t.Fatalf("assigning users %v to federation %v: %v", []int{*u1}, fedID, err.Error())
+ }
+
+ fedUsers, _, err = TOSession.GetFederationUsers(fedID)
+ if err != nil {
+ t.Fatalf("gettings users for federation %v: %v", fedID, err.Error())
+ }
+ if len(fedUsers) != 3 {
+ t.Errorf("federation users expected 2, actual: %+v", len(fedUsers))
+ }
+}
+
+func (r *TCData) CreateTestValidFederationUsers(t *testing.T) {
+ if len(r.TestData.Federations) == 0 {
+ t.Error("no federations test data")
+ }
+
+ fedID := fedIDs[0]
+
+ // Get Users
+ users, _, err := TOSession.GetUsers()
+ if err != nil {
+ t.Fatalf("getting users: " + err.Error())
+ }
+ if len(users) == 0 {
+ t.Fatal("need at least 1 user to test invalid federation user create")
+ }
+
+ // Associate with invalid federdation id
+ _, _, err = TOSession.CreateFederationUsers(fedID, []int{*users[0].ID}, false)
+ if err == nil {
+ t.Error("expected to get error back from associating non existent federation id")
+ }
+}
+func (r *TCData) CreateTestInvalidFederationUsers(t *testing.T) {
+ if len(r.TestData.Federations) == 0 {
+ t.Error("no federations test data")
+ }
+
+ fedID := fedIDs[0]
+
+ // Get Users
+ users, _, err := TOSession.GetUsers()
+ if err != nil {
+ t.Fatalf("getting users: " + err.Error())
+ }
+ if len(users) == 0 {
+ t.Fatal("need at least 1 user to test invalid federation user create")
+ }
+
+ // Associate with invalid federdation id
+ _, _, err = TOSession.CreateFederationUsers(-1, []int{*users[0].ID}, false)
+ if err == nil {
+ t.Error("expected to get error back from associating non existent federation id")
+ }
+
+ // Associate with invalid user id
+ _, _, err = TOSession.CreateFederationUsers(fedID, []int{-1}, false)
+ if err == nil {
+ t.Error("expected to get error back from associating non existent user id")
+ }
+}
+
+func (r *TCData) DeleteTestFederationUsers(t *testing.T) {
+ if len(r.TestData.Federations) == 0 {
+ t.Error("no federations test data")
+ }
+
+ fedID := fedIDs[0]
+
+ fedUsers, _, err := TOSession.GetFederationUsers(fedID)
+ if err != nil {
+ t.Fatalf("gettings users for federation %v: %v", fedID, err.Error())
+ }
+ if len(fedUsers) != 3 {
+ t.Errorf("federation users expected 3, actual: %+v", len(fedUsers))
+ }
+
+ for _, fedUser := range fedUsers {
+ _, _, err = TOSession.DeleteFederationUser(fedID, *fedUser.ID)
+ if err != nil {
+ t.Fatalf("deleting user %v from federation %v: %v", *fedUser.ID, fedID, err.Error())
+ }
+ }
+
+ fedUsers, _, err = TOSession.GetFederationUsers(fedID)
+ if err != nil {
+ t.Fatalf("gettings users for federation %v: %v", fedID, err.Error())
+ }
+ if len(fedUsers) != 0 {
+ t.Errorf("federation users expected 0, actual: %+v", len(fedUsers))
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/fixtures.go b/traffic_ops_ort/testing/ort-tests/tcdata/fixtures.go
new file mode 100644
index 0000000..24ce0bd
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/fixtures.go
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 tcdata
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "os"
+
+ "github.com/apache/trafficcontrol/lib/go-log"
+)
+
+// LoadFixtures ...
+func (r *TCData) LoadFixtures(fixturesPath string) {
+
+ f, err := ioutil.ReadFile(fixturesPath)
+ if err != nil {
+ log.Errorf("Cannot unmarshal fixtures json %s", err)
+ os.Exit(1)
+ }
+ err = json.Unmarshal(f, &r.TestData)
+ if err != nil {
+ log.Errorf("Cannot unmarshal fixtures json %v", err)
+ os.Exit(1)
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/origins.go b/traffic_ops_ort/testing/ort-tests/tcdata/origins.go
new file mode 100644
index 0000000..ce6e3e8
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/origins.go
@@ -0,0 +1,56 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+func (r *TCData) CreateTestOrigins(t *testing.T) {
+ // loop through origins, assign FKs and create
+ for _, origin := range r.TestData.Origins {
+ _, _, err := TOSession.CreateOrigin(origin)
+ if err != nil {
+ t.Errorf("could not CREATE origins: %v", err)
+ }
+ }
+}
+
+func (r *TCData) DeleteTestOrigins(t *testing.T) {
+ for _, origin := range r.TestData.Origins {
+ resp, _, err := TOSession.GetOriginByName(*origin.Name)
+ if err != nil {
+ t.Errorf("cannot GET Origin by name: %v - %v", *origin.Name, err)
+ }
+ if len(resp) > 0 {
+ respOrigin := resp[0]
+
+ delResp, _, err := TOSession.DeleteOriginByID(*respOrigin.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE Origin by ID: %v - %v", err, delResp)
+ }
+
+ // Retrieve the Origin to see if it got deleted
+ org, _, err := TOSession.GetOriginByName(*origin.Name)
+ if err != nil {
+ t.Errorf("error deleting Origin name: %s", err.Error())
+ }
+ if len(org) > 0 {
+ t.Errorf("expected Origin name: %s to be deleted", *origin.Name)
+ }
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/parameters.go b/traffic_ops_ort/testing/ort-tests/tcdata/parameters.go
new file mode 100644
index 0000000..061dec1
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/parameters.go
@@ -0,0 +1,89 @@
+/*
+
+ 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 tcdata
+
+import (
+ "sync"
+ "testing"
+
+ tc "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+func (r *TCData) CreateTestParameters(t *testing.T) {
+
+ for _, pl := range r.TestData.Parameters {
+ resp, _, err := TOSession.CreateParameter(pl)
+ t.Log("Response: ", resp)
+ if err != nil {
+ t.Errorf("could not CREATE parameters: %v", err)
+ }
+ }
+
+}
+
+func (r *TCData) DeleteTestParametersParallel(t *testing.T) {
+
+ var wg sync.WaitGroup
+ for _, pl := range r.TestData.Parameters {
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ DeleteTestParameter(t, pl)
+ }()
+
+ }
+ wg.Wait()
+}
+
+func (r *TCData) DeleteTestParameters(t *testing.T) {
+
+ for _, pl := range r.TestData.Parameters {
+ DeleteTestParameter(t, pl)
+ }
+}
+
+func DeleteTestParameter(t *testing.T, pl tc.Parameter) {
+
+ // Retrieve the Parameter by name so we can get the id for the Update
+ resp, _, err := TOSession.GetParameterByNameAndConfigFile(pl.Name, pl.ConfigFile)
+ if err != nil {
+ t.Errorf("cannot GET Parameter by name: %v - %v", pl.Name, err)
+ }
+
+ if len(resp) == 0 {
+ // TODO This fails for the ProfileParameters test; determine a way to check this, even for ProfileParameters
+ // t.Errorf("DeleteTestParameter got no params for %+v %+v", pl.Name, pl.ConfigFile)
+ } else if len(resp) > 1 {
+ // TODO figure out why this happens, and be more precise about deleting things where created.
+ // t.Errorf("DeleteTestParameter params for %+v %+v expected 1, actual %+v", pl.Name, pl.ConfigFile, len(resp))
+ }
+ for _, respParameter := range resp {
+ delResp, _, err := TOSession.DeleteParameterByID(respParameter.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE Parameter by name: %v - %v", err, delResp)
+ }
+
+ // Retrieve the Parameter to see if it got deleted
+ pls, _, err := TOSession.GetParameterByID(pl.ID)
+ if err != nil {
+ t.Errorf("error deleting Parameter name: %s", err.Error())
+ }
+ if len(pls) > 0 {
+ t.Errorf("expected Parameter Name: %s and ConfigFile: %s to be deleted", pl.Name, pl.ConfigFile)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/phys_locations.go b/traffic_ops_ort/testing/ort-tests/tcdata/phys_locations.go
new file mode 100644
index 0000000..907a44f
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/phys_locations.go
@@ -0,0 +1,59 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+func (r *TCData) CreateTestPhysLocations(t *testing.T) {
+ for _, pl := range r.TestData.PhysLocations {
+ resp, _, err := TOSession.CreatePhysLocation(pl)
+ t.Log("Response: ", resp)
+ if err != nil {
+ t.Errorf("could not CREATE physlocations: %v", err)
+ }
+ }
+
+}
+
+func (r *TCData) DeleteTestPhysLocations(t *testing.T) {
+
+ for _, cdn := range r.TestData.PhysLocations {
+ // Retrieve the PhysLocation by name so we can get the id for the Update
+ resp, _, err := TOSession.GetPhysLocationByName(cdn.Name)
+ if err != nil {
+ t.Errorf("cannot GET PhysLocation by name: %v - %v", cdn.Name, err)
+ }
+ if len(resp) > 0 {
+ respPhysLocation := resp[0]
+
+ _, _, err := TOSession.DeletePhysLocationByID(respPhysLocation.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE PhysLocation by name: '%s' %v", respPhysLocation.Name, err)
+ }
+
+ // Retrieve the PhysLocation to see if it got deleted
+ cdns, _, err := TOSession.GetPhysLocationByName(cdn.Name)
+ if err != nil {
+ t.Errorf("error deleting PhysLocation name: %s", err.Error())
+ }
+ if len(cdns) > 0 {
+ t.Errorf("expected PhysLocation name: %s to be deleted", cdn.Name)
+ }
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/profile_parameters.go b/traffic_ops_ort/testing/ort-tests/tcdata/profile_parameters.go
new file mode 100644
index 0000000..cc4fdc9
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/profile_parameters.go
@@ -0,0 +1,104 @@
+/*
+
+ 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 tcdata
+
+import (
+ "fmt"
+ "sync"
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+const queryParamFormat = "?profileId=%d¶meterId=%d"
+
+func (r *TCData) CreateTestProfileParameters(t *testing.T) {
+
+ firstProfile := r.TestData.Profiles[0]
+ profileResp, _, err := TOSession.GetProfileByName(firstProfile.Name)
+ if err != nil {
+ t.Errorf("cannot GET Profile by name: %v - %v", firstProfile.Name, err)
+ }
+
+ firstParameter := r.TestData.Parameters[0]
+ paramResp, _, err := TOSession.GetParameterByName(firstParameter.Name)
+ if err != nil {
+ t.Errorf("cannot GET Parameter by name: %v - %v", firstParameter.Name, err)
+ }
+
+ profileID := profileResp[0].ID
+ parameterID := paramResp[0].ID
+
+ pp := tc.ProfileParameter{
+ ProfileID: profileID,
+ ParameterID: parameterID,
+ }
+ resp, _, err := TOSession.CreateProfileParameter(pp)
+ t.Log("Response: ", resp)
+ if err != nil {
+ t.Errorf("could not CREATE profile parameters: %v", err)
+ }
+
+}
+
+func (r *TCData) DeleteTestProfileParametersParallel(t *testing.T) {
+
+ var wg sync.WaitGroup
+ for _, pp := range r.TestData.ProfileParameters {
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ DeleteTestProfileParameter(t, pp)
+ }()
+
+ }
+ wg.Wait()
+}
+
+func (r *TCData) DeleteTestProfileParameters(t *testing.T) {
+
+ for _, pp := range r.TestData.ProfileParameters {
+ DeleteTestProfileParameter(t, pp)
+ }
+}
+
+func DeleteTestProfileParameter(t *testing.T, pp tc.ProfileParameter) {
+
+ queryParams := fmt.Sprintf(queryParamFormat, pp.ProfileID, pp.ParameterID)
+ // Retrieve the PtofileParameter by profile so we can get the id for the Update
+ resp, _, err := TOSession.GetProfileParameterByQueryParams(queryParams)
+ if err != nil {
+ t.Errorf("cannot GET Parameter by profile: %v - %v", pp.Profile, err)
+ }
+ if len(resp) > 0 {
+ respPP := resp[0]
+
+ delResp, _, err := TOSession.DeleteParameterByProfileParameter(respPP.ProfileID, respPP.ParameterID)
+ if err != nil {
+ t.Errorf("cannot DELETE Parameter by profile: %v - %v", err, delResp)
+ }
+
+ // Retrieve the Parameter to see if it got deleted
+ pps, _, err := TOSession.GetProfileParameterByQueryParams(queryParams)
+ if err != nil {
+ t.Errorf("error deleting Parameter name: %s", err.Error())
+ }
+ if len(pps) > 0 {
+ t.Errorf("expected Parameter Name: %s and ConfigFile: %s to be deleted", pp.Profile, pp.Parameter)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/profiles.go b/traffic_ops_ort/testing/ort-tests/tcdata/profiles.go
new file mode 100644
index 0000000..184f647
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/profiles.go
@@ -0,0 +1,142 @@
+/*
+
+ 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 tcdata
+
+import (
+ "strings"
+ "testing"
+
+ tc "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+// CreateBadProfiles ensures that profiles can't be created with bad values
+func (r *TCData) CreateBadProfiles(t *testing.T) {
+
+ // blank profile
+ prs := []tc.Profile{
+ tc.Profile{Type: "", Name: "", Description: "", CDNID: 0},
+ tc.Profile{Type: "ATS_PROFILE", Name: "badprofile", Description: "description", CDNID: 0},
+ tc.Profile{Type: "ATS_PROFILE", Name: "badprofile", Description: "", CDNID: 1},
+ tc.Profile{Type: "ATS_PROFILE", Name: "", Description: "description", CDNID: 1},
+ tc.Profile{Type: "", Name: "badprofile", Description: "description", CDNID: 1},
+ }
+
+ for _, pr := range prs {
+ resp, _, err := TOSession.CreateProfile(pr)
+
+ if err == nil {
+ t.Errorf("Creating bad profile succeeded: %+v\nResponse is %+v", pr, resp)
+ }
+ }
+}
+
+func (r *TCData) CreateTestProfiles(t *testing.T) {
+
+ for _, pr := range r.TestData.Profiles {
+ resp, _, err := TOSession.CreateProfile(pr)
+
+ t.Log("Response: ", resp)
+ if err != nil {
+ t.Errorf("could not CREATE profiles with name: %s %v", pr.Name, err)
+ }
+ profiles, _, err := TOSession.GetProfileByName(pr.Name)
+ if err != nil {
+ t.Errorf("could not GET profile with name: %s %v", pr.Name, err)
+ }
+ if len(profiles) == 0 {
+ t.Errorf("could not GET profile %+v: not found", pr)
+ }
+ profileID := profiles[0].ID
+
+ for _, param := range pr.Parameters {
+ if param.Name == nil || param.Value == nil || param.ConfigFile == nil {
+ t.Errorf("invalid parameter specification: %+v", param)
+ continue
+ }
+ _, _, err := TOSession.CreateParameter(tc.Parameter{Name: *param.Name, Value: *param.Value, ConfigFile: *param.ConfigFile})
+ if err != nil {
+ // ok if already exists
+ if !strings.Contains(err.Error(), "already exists") {
+ t.Errorf("could not CREATE parameter %+v: %s", param, err.Error())
+ continue
+ }
+ }
+ p, _, err := TOSession.GetParameterByNameAndConfigFileAndValue(*param.Name, *param.ConfigFile, *param.Value)
+ if err != nil {
+ t.Errorf("could not GET parameter %+v: %s", param, err.Error())
+ }
+ if len(p) == 0 {
+ t.Errorf("could not GET parameter %+v: not found", param)
+ }
+ _, _, err = TOSession.CreateProfileParameter(tc.ProfileParameter{ProfileID: profileID, ParameterID: p[0].ID})
+ if err != nil {
+ t.Errorf("could not CREATE profile_parameter %+v: %s", param, err.Error())
+ }
+ }
+
+ }
+}
+
+func (r *TCData) DeleteTestProfiles(t *testing.T) {
+
+ for _, pr := range r.TestData.Profiles {
+ // Retrieve the Profile by name so we can get the id for the Update
+ resp, _, err := TOSession.GetProfileByName(pr.Name)
+ if err != nil {
+ t.Errorf("cannot GET Profile by name: %s - %v", pr.Name, err)
+ continue
+ }
+ if len(resp) == 0 {
+ t.Errorf("cannot GET Profile by name: not found - %s", pr.Name)
+ continue
+ }
+
+ profileID := resp[0].ID
+ // query by name does not retrieve associated parameters. But query by id does.
+ resp, _, err = TOSession.GetProfileByID(profileID)
+ if err != nil {
+ t.Errorf("cannot GET Profile by id: %v - %v", err, resp)
+ }
+ // delete any profile_parameter associations first
+ // the parameter is what's being deleted, but the delete is cascaded to profile_parameter
+ for _, param := range resp[0].Parameters {
+ _, _, err := TOSession.DeleteParameterByID(*param.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE parameter with parameterID %d: %s", *param.ID, err.Error())
+ }
+ }
+ delResp, _, err := TOSession.DeleteProfileByID(profileID)
+ if err != nil {
+ t.Errorf("cannot DELETE Profile by name: %v - %v", err, delResp)
+ }
+ //time.Sleep(1 * time.Second)
+
+ // Retrieve the Profile to see if it got deleted
+ prs, _, err := TOSession.GetProfileByName(pr.Name)
+ if err != nil {
+ t.Errorf("error deleting Profile name: %s", err.Error())
+ }
+ if len(prs) > 0 {
+ t.Errorf("expected Profile Name: %s to be deleted", pr.Name)
+ }
+
+ // Attempt to export Profile
+ _, _, err = TOSession.ExportProfile(profileID)
+ if err == nil {
+ t.Errorf("expected Profile: %s to be nil on export", pr.Name)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/regions.go b/traffic_ops_ort/testing/ort-tests/tcdata/regions.go
new file mode 100644
index 0000000..099a2ca
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/regions.go
@@ -0,0 +1,89 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "strings"
+ "testing"
+)
+
+func (r *TCData) CreateTestRegions(t *testing.T) {
+
+ for _, region := range r.TestData.Regions {
+ resp, _, err := TOSession.CreateRegion(region)
+ t.Log("Response: ", resp)
+ if err != nil {
+ t.Errorf("could not CREATE region: %v", err)
+ }
+ }
+}
+
+func (r *TCData) DeleteTestRegionsByName(t *testing.T) {
+ for _, region := range r.TestData.Regions {
+ delResp, _, err := TOSession.DeleteRegion(nil, ®ion.Name)
+ if err != nil {
+ t.Errorf("cannot DELETE Region by name: %v - %v", err, delResp)
+ }
+
+ deleteLog, _, err := TOSession.GetLogsByLimit(1)
+ if err != nil {
+ t.Fatalf("unable to get latest audit log entry")
+ }
+ if len(deleteLog) != 1 {
+ t.Fatalf("log entry length - expected: 1, actual: %d", len(deleteLog))
+ }
+ if !strings.Contains(*deleteLog[0].Message, region.Name) {
+ t.Errorf("region deletion audit log entry - expected: message containing region name '%s', actual: %s", region.Name, *deleteLog[0].Message)
+ }
+
+ // Retrieve the Region to see if it got deleted
+ regionResp, _, err := TOSession.GetRegionByName(region.Name)
+ if err != nil {
+ t.Errorf("error deleting Region region: %s", err.Error())
+ }
+ if len(regionResp) > 0 {
+ t.Errorf("expected Region : %s to be deleted", region.Name)
+ }
+ }
+
+ r.CreateTestRegions(t)
+}
+
+func (r *TCData) DeleteTestRegions(t *testing.T) {
+
+ for _, region := range r.TestData.Regions {
+ // Retrieve the Region by name so we can get the id
+ resp, _, err := TOSession.GetRegionByName(region.Name)
+ if err != nil {
+ t.Errorf("cannot GET Region by name: %v - %v", region.Name, err)
+ }
+ respRegion := resp[0]
+
+ delResp, _, err := TOSession.DeleteRegionByID(respRegion.ID)
+ if err != nil {
+ t.Errorf("cannot DELETE Region by region: %v - %v", err, delResp)
+ }
+
+ // Retrieve the Region to see if it got deleted
+ regionResp, _, err := TOSession.GetRegionByName(region.Name)
+ if err != nil {
+ t.Errorf("error deleting Region region: %s", err.Error())
+ }
+ if len(regionResp) > 0 {
+ t.Errorf("expected Region : %s to be deleted", region.Name)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/roles.go b/traffic_ops_ort/testing/ort-tests/tcdata/roles.go
new file mode 100644
index 0000000..1826bb6
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/roles.go
@@ -0,0 +1,77 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+const (
+ roleGood = 0
+ roleInvalidCap = 1
+ roleNeedCap = 2
+ roleBadPrivLevel = 3
+)
+
+func (r *TCData) CreateTestRoles(t *testing.T) {
+ expectedAlerts := []tc.Alerts{tc.Alerts{[]tc.Alert{tc.Alert{"role was created.", "success"}}}, tc.Alerts{[]tc.Alert{tc.Alert{"can not add non-existent capabilities: [invalid-capability]", "error"}}}, tc.Alerts{[]tc.Alert{tc.Alert{"role was created.", "success"}}}}
+ for i, role := range r.TestData.Roles {
+ var alerts tc.Alerts
+ alerts, _, status, err := TOSession.CreateRole(role)
+ t.Log("Status Code: ", status)
+ t.Log("Response: ", alerts)
+ if err != nil {
+ t.Logf("error: %v", err)
+ //t.Errorf("could not CREATE role: %v", err)
+ }
+ if !reflect.DeepEqual(alerts, expectedAlerts[i]) {
+ t.Errorf("got alerts: %v but expected alerts: %v", alerts, expectedAlerts[i])
+ }
+ }
+}
+
+func (r *TCData) DeleteTestRoles(t *testing.T) {
+
+ role := r.TestData.Roles[roleGood]
+ // Retrieve the Role by name so we can get the id
+ resp, _, status, err := TOSession.GetRoleByName(*role.Name)
+ t.Log("Status Code: ", status)
+ if err != nil {
+ t.Errorf("cannot GET Role by name: %v - %v", role.Name, err)
+ }
+ respRole := resp[0]
+
+ delResp, _, status, err := TOSession.DeleteRoleByID(*respRole.ID)
+ t.Log("Status Code: ", status)
+
+ if err != nil {
+ t.Errorf("cannot DELETE Role by role: %v - %v", err, delResp)
+ }
+
+ // Retrieve the Role to see if it got deleted
+ roleResp, _, status, err := TOSession.GetRoleByName(*role.Name)
+ t.Log("Status Code: ", status)
+
+ if err != nil {
+ t.Errorf("error deleting Role role: %s", err.Error())
+ }
+ if len(roleResp) > 0 {
+ t.Errorf("expected Role : %s to be deleted", *role.Name)
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/servercapabilities.go b/traffic_ops_ort/testing/ort-tests/tcdata/servercapabilities.go
new file mode 100644
index 0000000..3177f03
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/servercapabilities.go
@@ -0,0 +1,50 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+)
+
+func (r *TCData) CreateTestServerCapabilities(t *testing.T) {
+
+ for _, sc := range r.TestData.ServerCapabilities {
+ resp, _, err := TOSession.CreateServerCapability(sc)
+ if err != nil {
+ t.Errorf("could not CREATE server capability: %v", err)
+ }
+ t.Log("Response: ", resp)
+ }
+
+}
+
+func (r *TCData) DeleteTestServerCapabilities(t *testing.T) {
+
+ for _, sc := range r.TestData.ServerCapabilities {
+ delResp, _, err := TOSession.DeleteServerCapability(sc.Name)
+ if err != nil {
+ t.Errorf("cannot DELETE server capability: %v - %v", err, delResp)
+ }
+
+ serverCapability, _, err := TOSession.GetServerCapability(sc.Name)
+ if err == nil {
+ t.Errorf("expected error trying to GET deleted server capability: %s, actual: nil", sc.Name)
+ }
+ if serverCapability != nil {
+ t.Errorf("expected nil trying to GET deleted server capability: %s, actual: non-nil", sc.Name)
+ }
+ }
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/servercheckextension.go b/traffic_ops_ort/testing/ort-tests/tcdata/servercheckextension.go
new file mode 100644
index 0000000..c14d53c
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/servercheckextension.go
@@ -0,0 +1,125 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+ "time"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
+)
+
+func (r *TCData) CreateTestServerCheckExtensions(t *testing.T) {
+ toReqTimeout := time.Second * time.Duration(r.Config.Default.Session.TimeoutInSecs)
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword)
+
+ for _, ext := range r.TestData.ServerCheckExtensions {
+ resp, _, err := TOSession.CreateServerCheckExtension(ext)
+ t.Logf("Response: %v %v", *ext.Name, resp)
+ if err != nil {
+ t.Errorf("could not create to_extension %v: %v", ext.Name, err)
+ }
+ }
+
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword)
+}
+
+func (r *TCData) CreateTestInvalidServerCheckExtensions(t *testing.T) {
+ toReqTimeout := time.Second * time.Duration(r.Config.Default.Session.TimeoutInSecs)
+ // Fail Attempt to Create ServerCheckExtension as non extension user
+ _, _, err := TOSession.CreateServerCheckExtension(r.TestData.ServerCheckExtensions[0])
+ if err == nil {
+ t.Error("expected to receive error with non extension user")
+ }
+
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword)
+
+ // Attempt to create another valid ServerCheckExtension and it should fail as there is no open slots
+ toExt := tc.ServerCheckExtensionNullable{
+ Name: util.StrPtr("MEM_CHECKER"),
+ Version: util.StrPtr("3.0.3"),
+ InfoURL: util.StrPtr("-"),
+ ScriptFile: util.StrPtr("mem.py"),
+ ServercheckShortName: util.StrPtr("MC"),
+ Type: util.StrPtr("CHECK_EXTENSION_MEM"),
+ }
+ _, _, err = TOSession.CreateServerCheckExtension(toExt)
+ if err == nil {
+ t.Error("expected to receive error with no open slots left")
+ }
+
+ // Attempt to create a TO Extension with an invalid type
+ toExt.Type = util.StrPtr("INVALID_TYPE")
+ _, _, err = TOSession.CreateServerCheckExtension(toExt)
+ if err == nil {
+ t.Error("expected to receive error with invalid TO extension type")
+ }
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword)
+
+}
+
+func (r *TCData) DeleteTestServerCheckExtensions(t *testing.T) {
+ toReqTimeout := time.Second * time.Duration(r.Config.Default.Session.TimeoutInSecs)
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword)
+
+ extensions, _, err := TOSession.GetServerCheckExtensions()
+ if err != nil {
+ t.Fatalf("could not get to_extensions: %v", err)
+ }
+
+ ids := []int{}
+ for _, ext := range r.TestData.ServerCheckExtensions {
+ found := false
+ for _, respTOExt := range extensions.Response {
+ if *ext.Name == *respTOExt.Name {
+ ids = append(ids, *respTOExt.ID)
+ found = true
+ continue
+ }
+ }
+ if !found {
+ t.Errorf("expected to find to_extension %v", *ext.Name)
+ }
+ }
+
+ for _, id := range ids {
+ resp, _, err := TOSession.DeleteServerCheckExtension(id)
+ t.Logf("Response: %v %v", id, resp)
+ if err != nil {
+ t.Errorf("cannot delete to_extension: %v - %v", id, err)
+ }
+ }
+ extensions, _, err = TOSession.GetServerCheckExtensions()
+ if err != nil {
+ t.Fatalf("could not get to_extensions: %v", err)
+ }
+
+ for _, ext := range r.TestData.ServerCheckExtensions {
+ found := false
+ for _, respTOExt := range extensions.Response {
+ if *ext.Name == *respTOExt.Name {
+ found = true
+ continue
+ }
+ }
+ if found {
+ t.Errorf("to_extension %v should have been deleted", *ext.Name)
+ }
+ }
+
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword)
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/serverchecks.go b/traffic_ops_ort/testing/ort-tests/tcdata/serverchecks.go
new file mode 100644
index 0000000..33cbee1
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/serverchecks.go
@@ -0,0 +1,85 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "testing"
+ "time"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
+)
+
+func (r *TCData) CreateTestServerChecks(t *testing.T) {
+ toReqTimeout := time.Second * time.Duration(r.Config.Default.Session.TimeoutInSecs)
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword)
+
+ for _, servercheck := range r.TestData.Serverchecks {
+ resp, _, err := TOSession.InsertServerCheckStatus(servercheck)
+ t.Logf("Response: %v host_name %v check %v", *servercheck.HostName, *servercheck.Name, resp)
+ if err != nil {
+ t.Errorf("could not CREATE servercheck: %v", err)
+ }
+ }
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword)
+}
+
+func (r *TCData) CreateTestInvalidServerChecks(t *testing.T) {
+ toReqTimeout := time.Second * time.Duration(r.Config.Default.Session.TimeoutInSecs)
+
+ _, _, err := TOSession.InsertServerCheckStatus(r.TestData.Serverchecks[0])
+ if err == nil {
+ t.Error("expected to receive error with non extension user")
+ }
+
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword)
+
+ invalidServerCheck := tc.ServercheckRequestNullable{
+ Name: util.StrPtr("BOGUS"),
+ Value: util.IntPtr(1),
+ ID: util.IntPtr(-1),
+ HostName: util.StrPtr("bogus_hostname"),
+ }
+
+ // Attempt to create a ServerCheck with invalid server ID
+ _, _, err = TOSession.InsertServerCheckStatus(invalidServerCheck)
+ if err == nil {
+ t.Error("expected to receive error with invalid id")
+ }
+
+ invalidServerCheck.ID = nil
+ // Attempt to create a ServerCheck with invalid host name
+ _, _, err = TOSession.InsertServerCheckStatus(invalidServerCheck)
+ if err == nil {
+ t.Error("expected to receive error with invalid host name")
+ }
+
+ // get valid name to get past host check
+ invalidServerCheck.Name = r.TestData.Serverchecks[0].Name
+
+ // Attempt to create a ServerCheck with invalid servercheck name
+ _, _, err = TOSession.InsertServerCheckStatus(invalidServerCheck)
+ if err == nil {
+ t.Error("expected to receive error with invalid servercheck name")
+ }
+ r.SwitchSession(toReqTimeout, r.Config.TrafficOps.URL, r.Config.TrafficOps.Users.Extension, r.Config.TrafficOps.UserPassword, r.Config.TrafficOps.Users.Admin, r.Config.TrafficOps.UserPassword)
+}
+
+// Need to define no-op function as TCObj interface expects a delete function
+// There is no delete path for serverchecks
+func (r *TCData) DeleteTestServerChecks(t *testing.T) {
+ return
+}
diff --git a/traffic_ops_ort/testing/ort-tests/tcdata/servers.go b/traffic_ops_ort/testing/ort-tests/tcdata/servers.go
new file mode 100644
index 0000000..bfdb15f
--- /dev/null
+++ b/traffic_ops_ort/testing/ort-tests/tcdata/servers.go
@@ -0,0 +1,143 @@
+package tcdata
+
+/*
+
+ 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.
+*/
+
+import (
+ "net/url"
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-util"
+)
+
+func (r *TCData) CreateTestServers(t *testing.T) {
+ // loop through servers, assign FKs and create
+ for _, server := range r.TestData.Servers {
+ if server.HostName == nil {
+ t.Errorf("found server with nil hostname: %+v", server)
+ continue
+ }
+ resp, _, err := TOSession.CreateServerWithHdr(server, nil)
+ t.Log("Response: ", *server.HostName, " ", resp)
+ if err != nil {
+ t.Errorf("could not CREATE servers: %v", err)
+ }
+ }
+}
+
+func (r *TCData) CreateTestBlankFields(t *testing.T) {
+ serverResp, _, err := TOSession.GetServersWithHdr(nil, nil)
+ if err != nil {
+ t.Fatalf("couldnt get servers: %v", err)
+ }
+ if len(serverResp.Response) < 1 {
+ t.Fatal("expected at least one server")
+ }
+ server := serverResp.Response[0]
+ originalHost := server.HostName
... 2048 lines suppressed ...