A RESTful API to manage DNS entries using the Bluecat Proteus API Client.
# Basic API information
GET '/ping'
GET '/version'
GET '/'
# Custom search based on type and filters
GET '/:account/search?type=XXX&filters=XXX'
# Manage entities by ID
GET '/:account/id/:id
DELETE '/:account/id/:id
# Manage Zones
GET '/:account/zones'
GET '/:account/zones/:id'
# Manage DNS records
GET '/:account/records?type=(HostRecord|AliasRecord|ExternalHostRecord)'
POST '/:account/records'
GET '/:account/records/:id'
PUT '/:account/records/:id'
DELETE '/:account/records/:id'
# Manage Networks
GET '/:account/networks'
GET '/:account/networks/:id'
# Manage IP addresses
POST '/:account/ips'
GET '/:account/ips/:ip
PUT '/:account/ips/:ip
DELETE '/:account/ips/:ip'
GET '/:account/ips/cidrs'
# Manage MAC addresses
POST '/:account/macs'
GET '/:account/macs/:mac'
PUT '/:account/macs'
The API uses the "X-Auth-Token" HTTP header to authenticate all requests (GET, POST, DELETE) using a simple token.
The client submits a valid bcrypted token in the header with each request (see Examples below).
To generate a token for use by the API, you can use uuidgen
, store that in the config.yml file, and bcrypt it
for use by the client, e.g.
Run uuidgen, record that value in keepass and update the auth_token password parameter in jenkins. Use toker to bcrypt hash the uuid for use in the client's header.
UUID=$(uuidgen)
echo "UUID: ${UUID}"
HASH=$(./toker hash "${UUID}")
echo "HASH: ${HASH}"
Warning - 20210113: wasabi gem has a bug in parsing XML/SOAP since 3.6.0. We are holding back wasabi gem to 3.5.0 which still works: savonrb/wasabi#99
Requirements:
rbenv
bundler
Setup:
# Clone repository and install Ruby version specified
git clone git@git.yale.edu:spinup/dns-api.git ./dns-api
cd dns-api
rbenv install $(cat .ruby-version)
# Clean environment of all PROTEUS_ environment variables
while IFS= read -r result; do unset ${result%%=*}; done < <(env | grep PROTEUS_)
# Create configuration file from erb template
export PROTEUS_API_X_AUTH_TOKEN=$(uuidgen)
echo "For testing copy and execute the following in a separate shell:"
echo "export CLIENT_BCRYPT_X_AUTH_TOKEN=$(toker hash ${PROTEUS_API_X_AUTH_TOKEN})"
echo "Supply the following X-Auth-Token value in the http header: ${CLIENT_BCRYPT_X_AUTH_TOKEN}"
export PROTEUS_URL=<replace_with_bluecat_management url>
export PROTEUS_USER=<replace_with_bluecat_api_username>
export PROTEUS_PASS=<replace_with_bluecat_api_username_password>
export PROTEUS_VIEWID=<replace_with_bluecat_api_username_viewid_from_portal>
# app.rb will load these values from the environment into config.yml.erb
# Run application
bundle install
bundle exec shotgun
The app will run and be ready to receive requests at localhost:9393
. Modifications to the code, will trigger a reload by shotgun
.
To begin testing, launch a separate shell session.
# use the bcrypted hash of the UUID created earlier
# export CLIENT_BCRYPT_X_AUTH_TOKEN=$(toker hash ${PROTEUS_API_X_AUTH_TOKEN})"
# verify unprotected routes
curl http://localhost:9393/v1/dns/ping
# You should get a `pong` back.
curl http://localhost:9393/v1/dns/version
# You should `{"version":"<api-version-number>"}
# verify authorization
curl http://localhost:9393/
# You should get "Invalid token".
curl -H "X-Auth-Token:${CLIENT_BCRYPT_X_AUTH_TOKEN}" http://localhost:9393/
# You should get "Requested resource not found!"
No errors logged by the api running in developement shell session logstream in stdout
.
To test your code:
# Code lint
bundle exec rubocop
# Execute unit tests
bundle exec rake
You can use Dockerfile.local
to run the app locally in a container:
# Setup environment as before
while IFS= read -r result; do unset ${result%%=*}; done < <(env | grep PROTEUS_)
export PROTEUS_API_X_AUTH_TOKEN=$(uuidgen)
export PROTEUS_URL=<replace_with_bluecat_management url>
export PROTEUS_USER=<replace_with_bluecat_api_username>
export PROTEUS_PASS=<replace_with_bluecat_api_username_password>
export PROTEUS_VIEWID=<replace_with_bluecat_api_username_viewid_from_portal>
docker build -f docker/Dockerfile.local . -t "localhost/dns-api"
# Pass these values into running container environment
docker run -e PROTEUS_API_X_AUTH_TOKEN=${PROTEUS_API_X_AUTH_TOKEN} \
-e PROTEUS_URL=${PROTEUS_URL} \
-e PROTEUS_USER=${PROTEUS_USER} \
-e PROTEUS_PASS=${PROTEUS_PASS} \
-e PROTEUS_VIEWID=${PROTEUS_VIEWID} \
-p 8080:8080 "localhost/dns-api"
# Optionally tag with commit hash
# docker tag "localhost/dns-api" "localhost/dns-api:$(git log -1 --pretty=%h)"
Open a second shell. The previous curl
commands for testing may be used with 8080
substituting for 9393
.
# verify unprotected routes
curl http://localhost:8080/v1/dns/ping
# You should get a `pong` back.
curl http://localhost:8080/v1/dns/version
# You should `{"version":"<api-version-number>"}
# verify authorization
curl http://localhost:8080/
# You should get "Invalid token".
curl -H "X-Auth-Token:${CLIENT_BCRYPT_X_AUTH_TOKEN}" http://localhost:8080/
# You should get "Requested resource not found!"
# Stopping the docker container
docker kill $(docker ps -f 'ancestor=localhost/dns-api' -q)
A docker image for deployment to enterprise infrastructure may be created by using the providedDockerfile
. A continuous integration tool such as Jenkins manages the necssary configuration values to build the container. (These values are pushed to an encrypted Amazon S3 container blob decrypted at build time.)
# Construct payload
# Specify user-defined fields for Proteus Bluecat
export PROTEUS_UDF="machine_type=virtual machine|description=BAM test object; ToBeDeleted|phone=2038675309|location=Other|reg_by=NetId|reg_date=1981-11-16 00:00:00|user_name=NetId"
read -r -d '' PROTEUS_HOST_PAYLOAD <<-EOF
{
"hostname": "<fqdn>",
"cidr": "<subnet_cidr_for_new_ipaddress>",
"reverse": true,
"properties": "${PROTEUS_UDF}"
}
EOF
export PROTEUS_HOST_PAYLOAD
curl -H "X-Auth-Token: ${CLIENT_BCRYPT_X_AUTH_TOKEN}" \
-H "Content-Type: application/json" \
-X 'POST' \
-d "${PROTEUS_HOST_PAYLOAD}" \
'http://localhost:9393//v1/dns/bam-dev/ips'
A MAC address create (POST) request has only one required value (mac
).
If the optional parameter macpool
is submitted, the MAC address will be created and associated with the specified MAC Pool.
A MAC address create request may look like this (replacing values in <....>
):
# Construct payload
# Specify user-defined fields for Proteus Bluecat
export PROTEUS_UDF="machine_type=virtual machine|description=BAM test object; ToBeDeleted|phone=2038675309|location=Other|reg_by=NetId|reg_date=1981-11-16 00:00:00|user_name=NetId"
read -r -d '' PROTEUS_MAC_PAYLOAD <<-EOF
{
"mac": "<mac_address>",
"macpool": <optional_integer_value_of_macpool_object>,
"properties": "${PROTEUS_UDF}"
}
EOF
export PROTEUS_MAC_PAYLOAD
curl -H "X-Auth-Token: ${CLIENT_BCRYPT_X_AUTH_TOKEN}" \
-H "Content-Type: application/json" \
-X 'POST' \
-d "${PROTEUS_MAC_PAYLOAD}" \
'http://localhost:9393//v1/dns/bam-dev/macs'
- E Camden Fisher (camden.fisher@yale.edu)
- Tenyo Grozev (tenyo.grozev@yale.edu)
- Jose Andrade (jose.andrade@yale.edu)
- Vincent Balbarin (vincent.balbarin@yale.edu)
- Darryl Wisneski (darryl.wisneski@yale.edu)
The contents of this repository are covered under a GNU Affero General Public License.
Copyright, 2017, Yale University