2
0
mirror of https://github.com/VinylDNS/vinyldns synced 2025-08-22 18:17:07 +00:00
vinyldns/js/search.js
Nicholas Spadaccino 9bb9b68147 updated site
2024-04-24 14:29:40 -04:00

561 lines
259 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// When the user clicks on the search box, we want to toggle the search dropdown
function displayToggleSearch(e) {
e.preventDefault();
e.stopPropagation();
closeDropdownSearch(e);
if (idx === null) {
console.log("Building search index...");
prepareIdxAndDocMap();
console.log("Search index built.");
}
const dropdown = document.querySelector("#search-dropdown-content");
if (dropdown) {
if (!dropdown.classList.contains("show")) {
dropdown.classList.add("show");
}
document.addEventListener("click", closeDropdownSearch);
document.addEventListener("keydown", searchOnKeyDown);
document.addEventListener("keyup", searchOnKeyUp);
}
}
//We want to prepare the index only after clicking the search bar
var idx = null
const docMap = new Map()
function prepareIdxAndDocMap() {
const docs = [
{
"title": "Access the Portal",
"url": "/portal/access.html",
"content": "Access the portal Login The login page is where you provide your account username and password to access VinylDNS. The URL to access VinylDNS varies by instance. Check with your VinylDNS administrators for login information. Logout To logout of VinylDNS select your username in the top right of the portal to reveal the dropdown menu containing the Logout link."
} ,
{
"title": "Approve Batch Change",
"url": "/api/approve-batchchange.html",
"content": "Approve Batch Change Manually approves a batch change in pending review status given the batch change ID, resulting in revalidation and submission for backend processing. Only system administrators (ie. support or super user) can manually review a batch change. In the event that a batch change is approved and still encounters non-fatal errors, it will remain in manual review state until a successful approval (202 Accepted) or rejection (200 OK). Note: If manual review is disabled in the VinylDNS instance, users trying to access this endpoint will encounter a 404 Not Found response since it will not exist. HTTP REQUEST POST /zones/batchrecordchanges/{id}/approve HTTP REQUEST PARAMS name type required? description id string yes Unique identifier assigned to each created batch change. reviewComment string no Optional approval explanation. EXAMPLE HTTP REQUEST { \"reviewComment\": \"Comments are optional.\" } HTTP RESPONSE TYPES Code description 202 OK Batch change is approved and is returned in response body. Batch change is submitted for backend processing. 400 BadRequest Batch change is not in pending approval status. 403 Forbidden User is not a system administrator (ie. support or super user) or is attempting to approve a scheduled batch prior to its scheduled due date. 404 NotFound Batch change does not exist. Since we re-run validations upon successful approval, the create batch error codes still hold, so it is possible to see them as well. HTTP RESPONSE ATTRIBUTES name type description userId string The unique identifier of the user that created the batch change. userName string The username of the user that created the batch change. comments string Conditional: comments about the batch change, if provided. createdTimestamp date-time The timestamp (UTC) when the batch change was created. changes Array of SingleChange Array of single changes within a batch change. A SingleChange can either be a SingleAddChange or a SingleDeleteRRSetChange. status BatchChangeStatus Status of the batch change. id string The unique identifier for this batch change. ownerGroupId string Conditional: Record ownership assignment, if provided. approvalStatus BatchChangeApprovalStatus Whether the batch change is currently awaiting manual review. Will be ManuallyApproved status when approving. reviewerId string Unique identifier for the reviewer of the batch change. reviewerUserName string User name for the reviewer of the batch change. reviewComment string Conditional: Comment from the reviewer of the batch change, if provided. reviewTimestamp date-time The timestamp (UTC) of when the batch change was manually reviewed. EXAMPLE RESPONSE { \"userId\": \"vinyl\", \"userName\": \"vinyl201\", \"comments\": \"\", \"createdTimestamp\": \"2019-07-25T20:08:17Z\", \"changes\": [ { \"changeType\": \"Add\", \"inputName\": \"approve.parent.com.\", \"type\": \"A\", \"ttl\": 7200, \"record\": { \"address\": \"1.1.1.1\" }, \"status\": \"Pending\", \"recordName\": \"approve\", \"zoneName\": \"parent.com.\", \"zoneId\": \"876879e5-293d-4092-99ab-9cbdf50c1636\", \"validationErrors\": [], \"id\": \"a69cad97-994d-41e3-aed2-ec8c86a30ac5\" } ], \"status\": \"PendingProcessing\", \"id\": \"2343fa88-d4da-4377-986a-34ba4e8ca628\", \"ownerGroupId\": \"159a41c5-e67e-4951-b539-05f5ac788139\", \"reviewerId\": \"90c11ffc-5a71-4794-97c6-74d19c81af7d \", \"reviewComment\": \"Good to go!\", \"reviewTimestamp\": \"2019-07-25T20:10:28Z\", \"approvalStatus\": \"ManuallyApproved\" }"
} ,
{
"title": "Authentication",
"url": "/api/auth-mechanism.html",
"content": "API Authentication The API Authentication for VinylDNS is modeled after the AWS Signature Version 4 Signing process. The AWS documentation for it can be found here. Similar to how the AWS Signature Version 4 signing process adds authentication information to AWS requests, VinylDNSs API Authenticator also adds authentication information to every API request. VinylDNS API Authentication Process Retrieve the Authorization HTTP Header (Auth Header) from the HTTP Request Context. Parse the retrieved Auth Header into an AWS String to Sign structure which should be in the form: StringToSign = Algorithm + \\n + RequestDateTime + \\n + CredentialScope + \\n + HashedCanonicalRequest String to Sign Example: AWS4-HMAC-SHA256 20150830T123600Z 20150830/us-east-1/iam/aws4_request f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59 Extract the access key from the Auth Header and search for the account associated with the access key. Validate the signature of the request. Build the authentication information, which essentially contains all the authorized accounts for the signed in user. Authentication Failure Response If any these validations fail, a 401 (Unauthorized) or a 403 (Forbidden) error will be thrown; otherwise unanticipated exceptions will simply bubble out and result as 500s or 503s. If the Auth Header is not found, then a 401 (Unauthorized) error is returned. If the Auth Header cannot be parsed, then a 403 (Forbidden) error is returned. If the access key cannot be found, then a 401 (Unauthorized) error is returned. If the request signature cannot be validated, then a 403 (Forbidden) error is returned."
} ,
{
"title": "Batch Change Errors",
"url": "/api/batchchange-errors.html",
"content": "Batch Change Errors Single Change Errors Non-Fatal Errors Fatal Errors Full-Request Errors SINGLE CHANGE ERRORS Single change errors are errors that get collected at different validation stages and correspond to individual change inputs. Each change can have its own list of one or more errors. Single change errors are grouped into the following stages: Independent input validations: Validate invalid data input formats and values. Record and zone discovery: Resolve record and zone from fully-qualified input name. Dependent context validations: Check for sufficient user access and conflicts with existing records or other submissions within the batch. Since single change errors are collected at different stages, errors at later stages may exist but will not appear unless errors at earlier stages are addressed. An example is that a user may initially get an error about required data missing from the DNS request, and then after correcting the data encounter an issue about a conflicting record already existing in the DNS backend. EXAMPLE ERROR RESPONSE BY CHANGE [ { \"changeType\": \"Add\", \"inputName\": \"good-A.another.example.com.\", \"type\": \"A\", \"ttl\": 200, \"record\": { \"address\": \"1.2.3.4\" } }, { \"changeType\": \"Add\", \"inputName\": \"duplicate.example.com\", \"type\": \"CNAME\", \"ttl\": 200, \"record\": { \"cname\": \"test.example.com.\" }, \"errors\": [ \"Record with name \\\"duplicate.example.com.\\\" is not unique in the batch change. CNAME record cannot use duplicate name.\" ] }, { \"changeType\": \"Add\", \"inputName\": \"duplicate.example.com\", \"type\": \"A\", \"ttl\": 300, \"record\": { \"address\": \"1.2.3.4\" } }, { \"changeType\": \"Add\", \"inputName\": \"bad-ttl-and-invalid-name$.sample.com.\", \"type\": \"A\", \"ttl\": 29, \"record\": { \"address\": \"1.2.3.4\" }, \"errors\": [ \"Failed validation 29, TTL must be between 30 and 2147483647.\", \"Failed validation bad-ttl-and-invalid-name$.sample.com., valid domain names are a series of one or more labels joined by dots and terminate on a dot.\" ] } ] Single Change Errors Single change errors can be further classified as non-fatal or fatal errors. The presence of one or more fatal errors will result in an immediate failure (ie. hard stop) and no changes in the batch will be accepted. The behavior of non-fatal errors depends on whether manual review is configured on: if manual review is disabled, non-fatal errors are treated as fatal errors; if manual review is enabled, batches with only non-fatal errors will enter a pending review state. When non-fatal errors are encountered with manual review enabled, the errors will be saved on the corresponding SingleChanges. The SingleChanges will also have a status of NeedsReview. The following chart provides a breakdown of batch change status outcome based on a combination of manual review configuration and error types present in the batch change: Manual Review Enabled? Errors in Batch? Status Outcome Yes Both fatal and non-fatal Hard stop Yes Fatal only Hard stop Yes Non-fatal only PendingReview Yes No PendingProcessing (will be or is being auto-processed) No Both fatal and non-fatal Hard stop No Fatal only Hard stop No Non-fatal only Failed No No PendingProcessing (will be or is being auto-processed) Note: if a user submits a batch change with allowManualReview set to false, the request will treat the request as though the VinylDNS instance is configured to have manual review disabled. Non-Fatal Errors Zone Discovery Failed Record Requires Manual Review Fatal Errors Invalid Domain Name Invalid Length Invalid Record Type Invalid IPv4 Address Invalid IPv6 Address Invalid IP Address Invalid TTL Invalid Batch Record Type Record Already Exists Record Does Not Exist CNAME Conflict User Is Not Authorized Record Name Not Unique In Batch Change Invalid Record Type In Reverse Zone Missing Owner Group Id Not a Member of Owner Group High Value Domain CNAME Cannot be the Same Name as Zone Name Non-Fatal Errors Zone Discovery Failed Error Message: Zone Discovery Failed: zone for \"<input>\" does not exist in VinylDNS. If zone exists, then it must be connected to in VinylDNS. Details: Given an inputName, VinylDNS will determine the record and zone name for the requested change. For most records, the record names are the same as the zone name (apex), or split at at the first ., so the inputName rname.zone.name.com will be split into record name rname and zone name zone.name.com (or rname.zone.name.com for both the record and zone name if its an apex record). For PTR records, there is logic to determine the appropriate reverse zone from the given IP address. If this logic cannot find a matching zone in VinylDNS, you will see this error. In that case, you need to connect to the zone in VinylDNS. Even if the zone already exists outside of VinylDNS, it has to be added to VinylDNS to modify records. VinylDNS also does not support dotted records for forward zones (eg. record baz.foo.bar. in zone bar.), so encountering this error could indicate that a zone needs to be created outside of VinylDNS and then connected to within VinylDNS. Record Requires Manual Review Error Message: Record set with name <input> requires manual review. Details: Based on a configurable list, VinylDNS will determine if the given inputName requires manual review before it can be processed. Fatal Errors Invalid Domain Name Error Message: Invalid domain name: \"<input>\", valid domain names must be letters, numbers, underscores, and hyphens, joined by dots, and terminate with a dot. Details: Fully qualified domain names, must be comprised of labels, separated by dots. A label is a combination of letters, digits, underscores, and hyphens. They must also be absolute, which means they end with a dot. Syntax: <domain> ::= <subdomain> | \" \" <subdomain> ::= <label> | <subdomain> \".\" <label> <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ] <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str> <let-dig-hyp> ::= <let-dig> | \"-\" <let-dig> ::= <letter> | <digit> <letter> ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case <digit> ::= any one of the ten digits 0 through 9 More info can be found at: RFC 1035, DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION, Section 2.3.1. Preferred name syntax Invalid Length Error Message: Invalid length: \"<input>\", length needs to be between <minLengthInclusive> and <maxLengthInclusive> characters. Details: The length of the input did not fit in the range in [minLengthInclusive, maxLengthInclusive]. Invalid Record Type Error Message: Invalid record type: \"<input>\", valid record types include <valid record types>. Details: The record type input must match one of the valid record types. Not all DNS record types are currently supported. Invalid IPv4 Address Error Message: Invalid IPv4 address: \"<input>\" Details: The IPv4 address input is not a valid IPv4 address. Accepted inputs must be in dotted-decimal notation, with four groups of three decimal digits, separated by periods. Leading zeros in groups can be omitted. Range: 0.0.0.0 - 255.255.255.255 Examples: 1.1.1.1 10.234.0.62 Invalid IPv6 Address Error Message: Invalid IPv6 address: \"<input>\". Details: The IPv6 address input is not a valid IPv6 address. Accepted inputs must be eight groups of four hexadecimal digits, separated by colons. Leading zeros in groups can be emitted. Consecutive groups of all zeros can be replaced by a double colon. Range: 0000:0000:0000:0000:0000:0000:0000:0000 - ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff Examples: 2001:0db8:0000:0000:0000:ff00:0042:8329 2001:0db8::ff00:0042:8329 2001:db8::ff00:42:8329 Invalid IP Address Error Message: Invalid IP address: \"<input>\". Details: The IP address input is not a valid IPv4 or IPv6 address. Invalid TTL Error Message: Invalid TTL: \"<input>\", must be a number between 30 and 2147483647. Details: Time-to-live must be a number in the range [30, 2147483647]. Invalid Batch Record Type Error Message: Invalid Batch Record Type: \"<input>\", valid record types for batch changes include <valid record types>. Details: The DNS record type is not currently supported for batch changes. Record Already Exists Error Message: Record \"<input>\" Already Exists: cannot add an existing record; to update it, issue a DeleteRecordSet then an Add. Details: A record with the given name already exists, and cannot be duplicated for the given type. Record Does Not Exist Error Message: Record \"<input>\" Does Not Exist: cannot delete a record that does not exist. Details: A record with the given name could not be found in VinylDNS. If the record exists in DNS, then you should sync the zone for that record to bring VinylDNS up to date with what is in the DNS backend. CNAME Conflict Error Message: CNAME conflict: CNAME record names must be unique. Existing record with name \"<name>\" and type \"<type>\" conflicts with this record. Details: A CNAME record with the given name already exists. CNAME records must have unique names. User Is Not Authorized Error Message: User \"<user>\" is not authorized. Details: User must either be in the admin group for the zone being changed, or have an ACL rule. Record Name Not Unique In Batch Change Error Message: Record \"<name>\" Name Not Unique In Batch Change: cannot have multiple \"<type>\" records with the same name. Details: Certain record types do not allow multiple records with the same name. If you get this error, it means you have illegally input two or more records with the same name and one of these types. Invalid Record Type In Reverse Zone Error Message: Invalid Record Type In Reverse Zone: record with name \"<name>\" and type \"<type>\" is not allowed in a reverse zone. Details: Not all record types are allowed in a DNS reverse zone. The given type is not supported. Missing Owner Group Id Error Message: Zone \"<zone name>\" is a shared zone, so owner group ID must be specified for record \"<record name>\". Details: You are trying to create a new record or update an existing unowned record in a shared zone. This requires a record owner group ID in the batch change. Not a Member of Owner Group Error Message: User \"<user name>\" must be a member of group \"<group ID>\" to apply this group to batch changes. Details: You must be a member of the group you are assigning for record ownership in the batch change. High Value Domain Error Message: Record Name \"<record name>\" is configured as a High Value Domain, so it cannot be modified. Details: You are trying to create a record with a name that is not permitted in VinylDNS. The list of high value domains is specific to each VinylDNS instance. You should reach out to your VinylDNS administrators for more information. CNAME at the Zone Apex is not Allowed Error Message: CNAME cannot be the same name as zone \"<zone_name>\". Details: CNAME records cannot be @ or the same name as the zone. FULL-REQUEST ERRORS Fail-request errors cause the batch change processing to abort immediately upon encounter. Invalid Batch Change Input Batch Change Not Found Malformed JSON Errors 1. INVALID BATCH CHANGE INPUT HTTP RESPONSE CODE Code description 400 Bad Request - There is a top-level issue with batch change, aborting batch processing. There are a series of different error messages that can be returned with this error code. EXAMPLE ERROR MESSAGES: Batch change contained no changes. Batch change must have at least one change, up to a maximum of <limit> changes. Cannot request more than <limit> changes in a single batch change request DETAILS: If there are issues with the batch change input data provided in the batch change request, errors will be returned and batch change validations will abort processing. BATCH CHANGE NOT FOUND HTTP RESPONSE CODE Code description 404 Not Found - batch change not found for specified ID in get batch change request. ERROR MESSAGE: Batch change with id <id> cannot be found DETAILS: The batch ID specified in the get batch change request does not exist. MALFORMED JSON ERRORS DETAILS: If there are issues with the JSON provided in a batch change request, errors will be returned (not in a single change format) and none of the batch change validations will run. EXAMPLE ERROR MESSAGES: { \"errors\": [ \"Missing BatchChangeInput.changes\" ] } { \"errors\": [ \"Missing BatchChangeInput.changes.inputName\", \"Missing BatchChangeInput.changes.type\", \"Missing BatchChangeInput.changes.ttl\" ] } { \"errors\": [ \"Invalid RecordType\"\" ] }"
} ,
{
"title": "Batch Change Model",
"url": "/api/batchchange-model.html",
"content": "Batch Change Model Table of Contents Batch Change Information Batch Change Attributes Single Change Attributes Batch Change Example BATCH CHANGE INFORMATION Batch change is an alternative to submitting individual RecordSet changes and provides the following: The ability to accept multiple changes in a single API call. The ability to include records of multiple record types across multiple zones. Input names are entered as fully-qualified domain names (or IP addresses for PTR records), so users dont have to think in record/zone context. All record validations are processed simultaneously. Fatal errors for any change in the batch will result in a 400 response and none will be applied. Support for manual review if enabled in your VinylDNS instance. Batch change will remain in limbo until a system administrator (ie. support or super user) either rejects it resulting in an immediate failure or approves it resulting in revalidation and submission for processing. Support for notifications when a batch change is rejected or implemented. A batch change consists of multiple single changes which can be a combination of SingleAddChanges and SingleDeleteRRSetChanges. Note: In the portal batch change is referred to as DNS Change. To update an existing record, you must delete the record first and add the record again with the updated changes. Batch changes are also susceptible to the following restrictions: Current supported record types for batch change are: A, AAAA, CNAME, and PTR. Batch change requests must contain at least one change. The maximum number of single changes within a batch change depends on the instance of VinylDNS. Contact your VinylDNS administrators to find the batch change limit for your instance. Access permissions will follow existing rules (admin group or ACL access). Note that an update (delete and add of the same record name, zone and record type combination) requires Write access. BATCH CHANGE ATTRIBUTES name type description userId string The unique identifier of the user that created the batch change. userName string The username of the user that created the batch change. comments string Optional comments about the batch change. createdTimestamp date-time The timestamp (UTC) when the batch change was created. changes Array of SingleChange Array of single changes within a batch change. A SingleChange can either be a SingleAddChange or a SingleDeleteRRSetChange. status BatchChangeStatus - PendingProcessing - at least one change in batch has not finished processing- Complete - all changes have been processed successfully- Failed - all changes failed during processing- PartialFailure - some changes have failed and the rest were successful- PendingReview - one or more changes requires manual approval/rejection by a system administrator (ie. super or support user) to proceed- Rejected - the batch change was rejected by a system administrator (ie. super or support user) and no changes were applied- Scheduled - the batch change is scheduled for a later date at which time it needs to be approved to proceed.- Cancelled - the PendingReview batch change was cancelled by its creator before review. id string The unique identifier for this batch change. ownerGroupId string Record ownership assignment. Required if any records in the batch change are in shared zones and are new or unowned. approvalStatus BatchChangeApprovalStatus Whether the batch change is currently awaiting manual review. Can be one of AutoApproved, PendingReview, ManuallyApproved, Rejected, or Cancelled. reviewerId string Optional unique identifier for the reviewer of the batch change. Required if batch change was manually rejected or approved. reviewerUserName string Optional user name for the reviewer of the batch change. Required if batch change was manually rejected or approved. reviewComment string Optional comment for the reviewer of the batch change. Only applicable if batch change was manually rejected or approved. reviewTimestamp date-time Optional timestamp (UTC) of when the batch change was manually reviewed. Required if batch change was manually rejected or approved. scheduledTime date-time Optional requested date and time to process the batch change. cancelledTimestamp date-time Optional date and time a batch change was cancelled by its creator. SINGLE CHANGE ATTRIBUTES A successful batch change response consists of a corresponding SingleAddChange or SingleDeleteRRSetChange for each batch change input. See the batch change create page for details on constructing a batch change request. SingleAddChange name type description changeType ChangeInputType Type of change input. Can either be an Add or DeleteRecordSet. See more details about behavior of changeType interaction. inputName string The fully-qualified domain name of the record which was provided in the create batch request. type RecordType Type of DNS record, supported records for batch changes are currently: A, AAAA, CNAME, and PTR. ttl long The time-to-live in seconds. record RecordData The data added for this record, which varies by record type. status SingleChangeStatus Status for this change. Can be one of: Pending, Complete, Failed, NeedsReview or Rejected. recordName string The name of the record. Record names for the apex will be match the zone name (including terminating dot). zoneName string The name of the zone. zoneId string The unique identifier for the zone. systemMessage string Conditional: Returns system message relevant to corresponding batch change input. recordChangeId string Conditional: The unique identifier for the record change; only returned on successful batch creation. recordSetId string Conditional: The unique identifier for the record set; only returned on successful batch creation, validationErrors Array of BatchChangeError Array containing any validation errors associated with this SingleAddChange. Note: These will only exist on NeedsReview or Rejected SingleChanges id string The unique identifier for this change. SingleDeleteRRSetChange name type description changeType ChangeInputType Type of change input. Can either be an Add or DeleteRecordSet. See more details about behavior of changeType interaction. inputName string The fully-qualified domain name of the record which was provided in the create batch request. type RecordType Type of DNS record, supported records for batch changes are currently: A, AAAA, CNAME, and PTR. record RecordData Optional. The data deleted for this record, which varies by record type. If not provided, the entire DNS recordset was deleted. status SingleChangeStatus Status for this change. Can be one of: Pending, Complete, Failed, NeedsReview or Rejected. recordName string The name of the record. Record names for the apex will be match the zone name (including terminating dot). zoneName string The name of the zone. zoneId string The unique identifier for the zone. systemMessage string Conditional: Returns system message relevant to corresponding batch change input. recordChangeId string Conditional: The unique identifier for the record change; only returned on successful batch creation. recordSetId string Conditional: The unique identifier for the record set; only returned on successful batch creation, validationErrors Array of BatchChangeError Array containing any validation errors associated with this SingleDeleteRRSetChange. Note: These will only exist on NeedsReview or Rejected SingleChanges id string The unique identifier for this change. ChangeType Values There are two valid changeTypes for a SingleChange: Add and DeleteRecordSet changeTypes can be used independently or combined to achieve the desired behavior described below. Create a new DNS record: Add with record data Delete an entire record set: 1. DeleteRecordSet without specifying existing record data or 2. DeleteRecordSet for each entry of the DNS record Delete a single entry from DNS record with multiple entries: DeleteRecordSet specifying existing record data Update an existing record set: 1. DeleteRecordSet specifying existing record data (single entry delete) or not specifying record data (full delete) and 2. Add with record data BATCH CHANGE EXAMPLE Successful batch change response example with a SingleAddChange and a SingleDeleteRRSetChange. { \"userId\": \"vinyl\", \"userName\": \"vinyl201\", \"comments\": \"this is optional\", \"createdTimestamp\": \"2018-05-08T18:46:34Z\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\" \"changes\": [ { \"changeType\": \"Add\", \"inputName\": \"recordName.zoneName.\", \"type\": \"A\", \"ttl\": 3600, \"record\": { \"address\": \"1.1.1.1\" }, \"status\": \"Complete\", \"recordName\": \"recordName\", \"zoneName\": \"zoneName.\", \"zoneId\": \"8f8f649f-998e-4428-a029-b4ba5f5bd4ca\", \"recordChangeId\": \"4754ac4c-5f81-11e8-9c2d-fa7ae01bbebc\", \"recordSetId\": \"4754b084-5f81-11e8-9c2d-fa7ae01bbebc\", \"validationErrors\": [], \"id\": \"17350028-b2b8-428d-9f10-dbb518a0364d\" }, { \"changeType\": \"DeleteRecordSet\", \"inputName\": \"recordName.zoneName.\", \"type\": \"AAAA\", \"status\": \"Complete\", \"recordName\": \"recordName\", \"zoneName\": \"zoneName.\", \"zoneId\": \"9cbdd3ac-9752-4d56-9ca0-6a1a14fc5562\", \"recordChangeId\": \"4754b322-5f81-11e8-9c2d-fa7ae01bbebc\", \"recordSetId\": \"4754b084-5f81-11e8-9c2d-fa7ae01bbebc\", \"validationErrors\": [], \"id\": \"c29d33e4-9bee-4417-a99b-6e815fdeb748\" }, { \"changeType\": \"DeleteRecordSet\", \"inputName\": \"anotherRecordName.zoneName.\", \"type\": \"A\", \"record\": { \"address\": \"1.1.1.1\" }, \"status\": \"Complete\", \"recordName\": \"recordName\", \"zoneName\": \"zoneName.\", \"zoneId\": \"9cbdd3ac-9752-4d56-9ca0-6a1a14fc5562\", \"recordChangeId\": \"9c449026-cffe-4379-beb7-217b8a31aadd\", \"recordSetId\": \"e68776ab-f56f-41bf-a03e-c288b9469b53\", \"validationErrors\": [], \"id\": \"e68776ab-f56f-41bf-a03e-c288b9469b53\" } ], \"status\": \"Complete\", \"id\": \"937191c4-b1fd-4ab5-abb4-9553a65b44ab\", \"approvalStatus\": \"AutoApproved\" }"
} ,
{
"title": "Cancel Batch Change",
"url": "/api/cancel-batchchange.html",
"content": "Cancel Batch Change Cancels a batch change that is PendingReview. Only the user who created the batch change can cancel it. Note: If manual review is disabled in the VinylDNS instance, users trying to access this endpoint will encounter a 404 Not Found response since it will not exist. HTTP REQUEST POST /zones/batchrecordchanges/{id}/cancel HTTP REQUEST PARAMS name type required? description id string yes Unique identifier assigned to each created batch change. HTTP RESPONSE TYPES Code description 200 OK - The batch change is returned in response body. 403 Forbidden - The user does not have the access required to perform the action. 404 Not Found - Batch change not found. HTTP RESPONSE ATTRIBUTES See Batch Change Model attributes"
} ,
{
"title": "API Configuration Guide",
"url": "/operator/config-api.html",
"content": "API Configuration Guide Note: ALL configuration assumes a vinyldns namespace. For example, sqs settings would be under vinyldns.sqs. Configuration Configuration Overview Configuration API Server Queue Configuration Database Configuration Cryptography Zone Connections Additional Configuration Settings Full Example Config There are a lot of configuration settings in VinylDNS. So much so that it may seem overwhelming to configure vinyldns to your environment. This document describes the configuration settings, highlighting the settings you are most likely to change. All the configuration settings are captured at the end. It is important to note that the api and portal have different configuration. We will review the configuration for each separately. Configuration Overview How do we config? All configuration is done using Typesafe Config. It provides a means to specifying default configurations, and overriding the configured values in a number of ways: The default configuration provides “safe” default values for all configuration. This makes it possible for you to only change the configuration values that you need to, and assume the default for the rest. This can typically be found in a file named reference.conf. The Typesafe Config library manages populating unspecified values for you automatically. You can override the reference.conf file by providing your own application.conf file when the system starts up. We will review how to do that in the sections that follow. You can override individual configuration properties when the application starts up using standard jvm arguments. For example, you can specify -Dmy.config.value=42, and that will override both application.conf and reference.conf (defaults) You can further override configuration properties with environment variables. The Typesafe Config provides special syntax that allows you to use environment variables. You can make the environment variable optional (meaning use it if it is there) or required (fail to start up without the environment variable). We will illustrate use of environment variables in this guide. Using Environment Variables We strongly recommend that you use environment variables in particular for secrets. Laying down environment variables in a flat file is a security vulnerability for your installation. To demonstrate environment variable usage, here is a following snippet… queue.settings { access-key = ${AWS_ACCESS_KEY} secret-key = ${AWS_SECRET_ACCESS_KEY} signing-region = ${SQS_REGION} service-endpoint = ${SQS_SERVICE_ENDPOINT} queue-name = ${SQS_QUEUE_NAME} } In the example, if any of the values in ${xxx} are not found in the environment, the application will not start up! Configuring API Server The API configuration has a lot of values, the important ones reviewed here. There are several configuration settings that are specific to your environment. The most important configuration is around your system dependencies. Presently, these are your settings for: AWS SQS MySQL Queue Configuration VinylDNS supports both SQS and MySQL queue implementations. There are a couple of implementation-dependent settings that need to be specified: messages-per-poll: Number of messages retrieved in a single queue receive request. Valid values are 1 through 10 ( default). polling-interval: Interval to delay between each poll for messages. If using SQS, be sure to follow the AWS SQS Setup Guide first to get the values you need to configure here. If using MySQL, follow the MySQL Setup Guide first to get the values you need to configure here. The following in a sample SQS config: vinyldns { queue { class-name = \"vinyldns.sqs.queue.SqsMessageQueueProvider\" messages-per-poll = 10 polling-interval = 250.millis # connection information to SQS settings { # AWS access key and secret. access-key = \"x\" secret-key = \"x\" # Regional endpoint to make your requests (eg. 'us-west-2', 'us-east-1', etc.). This is the region where your queue is housed. signing-region = \"x\" # Endpoint to access queue service-endpoint = \"http://vinyldns-elasticmq:9324/\" # Queue name. Should be used in conjunction with service endpoint, rather than using a queue url which is subject to change. queue-name = \"vinyldns\" } } } The following is a sample MySQL queue config: queue { class-name = \"vinyldns.mysql.queue.MySqlMessageQueueProvider\" polling-interval = 250.millis messages-per-poll = 10 max-retries = 50 # Override max retries; default = 100 settings = { name = \"vinyldns\" driver = \"org.mariadb.jdbc.Driver\" migration-url = \"jdbc:mariadb://localhost:19004/?user=root&password=pass\" url = \"jdbc:mariadb://localhost:19004/vinyldns?user=root&password=pass\" user = \"root\" password = \"pass\" # see https://github.com/brettwooldridge/HikariCP connection-timeout-millis = 1000 idle-timeout = 10000 max-lifetime = 30000 maximum-pool-size = 5 minimum-idle = 0 my-sql-properties = { cachePrepStmts=true prepStmtCacheSize=250 prepStmtCacheSqlLimit=2048 rewriteBatchedStatements=true } } } Database Configuration VinylDNS supports a MySQL database. You can enable all repos in a single backend, or have a mix of the two. For each backend, you need to configure the table(s) that should be loaded. If using MySQL, follow the MySQL Setup Guide first to get the values you need to configure here. vinyldns { # this list should include only the datastores being used by your instance data-stores = [\"mysql\"] mysql { # this is the path to the mysql provider. This should not be edited # from the default in reference.conf class-name = \"vinyldns.mysql.repository.MySqlDataStoreProvider\" settings { # the name of the database, recommend to leave this as is name = \"vinyldns\" # the jdbc driver, recommended to leave this as is driver = \"org.mariadb.jdbc.Driver\" # the URL used to create the schema, typically this will be without the \"database\" name migration-url = \"jdbc:mariadb://localhost:19002/?user=root&password=pass\" # the main connection URL url = \"jdbc:mariadb://localhost:19002/vinyldns?user=root&password=pass\" # the user to connect to MySQL user = \"root\" # the password to connect to MySQL password = \"pass\" ## see https://github.com/brettwooldridge/HikariCP for more detail on the following fields # the maximum number of connections to scale the connection pool to maximum-pool-size = 20 # the maximum number of milliseconds to wait for a connection from the connection pool connection-timeout-millis = 1000 # the minimum number of idle connections that HikariCP tries to maintain in the pool minimum-idle = 10 # the maximum number of milliseconds that a connection is can sit idle in the pool idle-timeout = 10000 # The max lifetime of a connection in a pool. Should be several seconds shorter than the database imposed connection time limit max-lifetime = 600000 # controls whether JMX MBeans are registered register-mbeans = true # my-sql-properties allows you to include any additional mysql performance settings you want. # Note that the properties within my-sql-properties must be camel case! # see https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration for guidance my-sql-properties { prepStmtCacheSize = 300 prepStmtCacheSqlLimit = 2048 cachePrepStmts = true useServerPrepStmts = true rewriteBatchedStatements = true } } repositories { # all repositories with config sections here will be enabled in mysql zone { # no additional settings for repositories enabled in mysql } batch-change { } user { } record-set { } record-set-cache { } } } } Cryptography Settings VinylDNS uses symmetric cryptography in order to encrypt/decrypt sensitive information in the system. This includes TSIG keys and user secrets. Cryptography is used in both the portal as well as the api. Cryptography is pluggable, meaning you can bring your own crypto with you. All that is required is to provide an implementation of CryptoAlgebra using a crypto library of choice. The default implementation is NoOpCrypto, which does not do any encryption (not recommended for production). VinylDNS provides a cryptography implementation called JavaCrypto that you can use for production. The example that follows illustrates using the provided JavaCrypto. If you create your own implementation, you have to build your jar and make it (and all dependencies) available to the VinylDNS API and the VinylDNS portal. The following are the configuration settings for crypto. Notice here the only thing we see is the type. The type is the fully qualified class name for the CryptoAlgebra you will be using. If your crypto implementation requires additional settings, they will be configured inside the crypto element, adjacent to the type. vinyldns { crypto { type = \"vinyldns.core.crypto.JavaCrypto\" secret = \"8B06A7F3BC8A2497736F1916A123AA40E88217BE9264D8872597EF7A6E5DCE61\" } } Zone Connections VinylDNS has three ways of indicating zone connections: Global default connection applies to all zones unless overridden by one of the following connections. This configuration is required. Backends allows you to specify zone connection information for an individual zone by choosing a pre-configured zone connection. This configuration is optional. Zone level override allows you to specify zone update and transfer connection information for each zone. More information is in the Zone Model. VinylDNS has 2 connections for each zone: The DDNS connection - used for making DDNS updates to the zone The Transfer connection - used for making AXFR requests for zone syncing with the DNS backend VinylDNS also ties in testing network connectivity to the default zone connections primary server into its API health checks. A value for the health check connection timeout in milliseconds can be specified using health-check-timeout; a default value of 10000 will be used if not provided. Global Zone Connections Configuration: vinyldns { # timeout for DNS backend connectivity health check health-check-timeout = 5000 # the DDNS connection information for the default dns backend defaultZoneConnection { # this is not really used, but must be set, usually set to the keyName itself, or a descriptive name if you are interested name = \"vinyldns.\" # the name of the TSIG key keyName = \"vinyldns.\" # the TSIG secret key key = \"nzisn+4G2ldMn0q1CV3vsg==\" # the host name or IP address, note you can add a port if not using the default by settings hostname:port primaryServer = \"ddns1.foo.bar.com\" # the key algorithm to use: HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, HMAC-SHA512 algorithm = \"HMAC-MD5\" } # the AXFR connection information for the default dns backend defaultTransferConnection { name = \"vinyldns.\" keyName = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primaryServer = \"localhost:19001\" algorithm = \"HMAC-MD5\" } } # Zone Connection Data, ID can be specified in a zone to override the global default configuration backends = [ { id = \"test-backend-id\" zone-connection { name = \"vinyldns.\" key-name = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primary-server = \"127.0.0.1:19001\" algorithm = \"HMAC-MD5\" } transfer-connection { name = \"vinyldns.\" key-name = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primary-server = \"127.0.0.1:19001\" algorithm = \"HMAC-MD5\" } } ] Alternate Zone Connections Configuration: Below is an alternate way of setting zone connections configuration instead of using the Global Zone Connections Configuration # configured backend providers backend { # Use \"default\" when dns backend legacy = true # otherwise, use the id of one of the connections in any of your backends default-backend-id = \"default\" # this is where we can save additional backends backend-providers = [ { class-name = \"vinyldns.api.backend.dns.DnsBackendProviderLoader\" settings = { legacy = false backends = [ { id = \"default\" zone-connection = { name = \"vinyldns.\" key-name = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primary-server = \"127.0.0.1:19001\" } transfer-connection = { name = \"vinyldns.\" key-name = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primary-server = \"127.0.0.1:19001\" }, tsig-usage = \"always\" }, { id = \"func-test-backend\" zone-connection = { name = \"vinyldns.\" key-name = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primary-server = \"127.0.0.1:19001\" } transfer-connection = { name = \"vinyldns.\" key-name = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primary-server = \"127.0.0.1:19001\" }, tsig-usage = \"always\" } ] } } ] } Below is an example configuration of backend provider for AWS Route 53, in case we want to use AWS Route 53 as backend. backend { default-backend-id = \"r53\" backend-providers = [ { class-name = \"vinyldns.route53.backend.Route53BackendProviderLoader\" settings = { backends = [ { # AWS access key and secret key. access-key = \"your-access-key\" secret-key = \"your-secret-key\" # Regional endpoint to make your requests (eg. 'us-west-2', 'us-east-1', etc.). This is the region where your queue is housed. signing-region = \"us-east-1\" # Endpoint to access r53 service-endpoint = \"https://route53.amazonaws.com/\" id = \"r53\" } ] } } ] } Make sure to add AWS name servers in Approved Name Servers Config. Additional Configuration Settings Approved Name Servers When running a large DNS installation, allowing users the ability to self-manage zone delegations can lead to a lot of problems when not done properly. Also, allowing delegation to untrusted DNS servers can be a security risk. To “lock down” zone delegation, you can configure name servers that you trust, so zone delegation is controlled. The entries in the list can be host names, IP addresses, or regular expressions. approved-name-servers = [ \"172.17.42.1.\", \"ddns1.foo.bar.\", \".*awsdns.*\" ] Processing Disabled The processing disabled flag can be used if doing a blue/green deployment. When processing is disabled, the VinylDNS engine will not be actively polling the message queue for messages. processing-disabled = false | true Color For blue-green deployments, you can configure the color of the current node. Not applicable to every environment. color = \"green\" Version Version of the application that is deployed. Currently, this is a configuration value. version = \"0.8.0\" Note: You can get installation information including color, version, default key name, and processing-disabled by hitting the status endpoint GET /status Is Zone Sync Schedule Allowed Used while deploying. Should be set to true only on one api server/instance and false on every other api servers/instances. Thus automated sync will be done only once on a single server/instance instead of every api servers/instances. Set it to true while running locally or when we have only a single api server/instance. is-zone-sync-schedule-allowed = true HTTP Host and Port To specify what host and port to bind to when starting up the API server, default is 9000. rest { host = \"0.0.0.0\" port = 9000 } Sync Delay VinylDNS uses a “sync-delay” setting that prevents users from syncing their zones too frequently. The settings is inspected per zone, and is the number of milliseconds since the last sync to wait before allowing another sync for that zone. sync-delay = 10000 Notifiers VinylDNS provides the ability to send notifications via configured notifiers when a batch change is either implemented or rejected. Notifiers in VinylDNS are designed to be pluggable (ie. bring-your-own-implementation), granting users the flexibility to implement their own which can smoothly integrate into their instance. Setup requires a notifiers key which contains all of the configured notifiers that will be used by the running instance. notifiers = [\"email\", \"sns\"] E-mail notifier Configuration for the e-mail notifier appears like the following: email = { # Path to notifier provider implementation class-name = \"vinyldns.api.notifier.email.EmailNotifierProvider\" settings = { # Sender address for e-mail notifications from = \"Sender <do-not-reply@example.sender>\" smtp { # Host SMTP server host = \"example.host\" } } } Note that settings.from and settings.smtp are both required, though the smtp values requirements depend on the specific exchange service that you are interfacing with. Below is an example e-mail notification: AWD Simple Notification Service (SNS) notifier Configuration for the AWS SNS notifier appears like the following: sns { # Path to notifier provider implementation class-name = \"vinyldns.api.notifier.sns.SnsNotifierProvider\" settings { # SNS topic Amazon Resource Name (ARN) topic-arn = \"arn:aws:sns:us-east-1:000000000000:batchChanges\" # AWS access key and secret access-key = \"vinyldnsTest\" secret-key = \"notNeededForSnsLocal\" # Endpoint to access SNS service-endpoint = \"http://127.0.0.1:19006\" # Regional endpoint to make your requests (eg. 'us-west-2', 'us-east-1', etc.). This is the region where your SNS is housed. signing-region = \"us-east-1\" } } Email Domain Configuration This configuration setting determines the valid domains which are allowed in the email fields. The email-domains field accepts a list of valid email domains. Wildcard matching is available; for example, *dummy.com means it will allow any subdomain within dummy.com like test.dummy.com. If the email-domains field is left empty then it will accept any domain name. The number-of-dots field controls the number of dots allowed after the @ symbol in an email. If this config value is left out, it will default to two. valid-email-config { email-domains = [\"test.com\",\"*dummy.com\"] number-of-dots= 2 } Batch Manual Review Enabled Configuration setting that determines whether batch changes with non-fatal errors can be reviewed rather than failing immediately. When enabling manual review, the expectation is that a DNS technician is actively querying and addressing batch change requests that are in a manual review state. If your process flow does not accommodate this expectation, we advise disabling manual review. manual-batch-review-enabled = true Manual Review Domains Configuration setting that determines what Batch Change/DNS Change input names require manual review if manual-batch-review-enabled is set to true. If manual-batch-review-enabled is set to false any input names that match entries in the configured list will be treated as fatal errors. manual-review-domains = { domain-list = [ \"needs-review.*\" ] ip-list = [ \"192.0.2.254\", \"192.0.2.255\", \"fd69:27cc:fe91:0:0:0:ffff:1\", \"fd69:27cc:fe91:0:0:0:ffff:2\" ] zone-name-list = [ \"zone.requires.review.\" ] } Scheduled Batch Changes Enabled Configuration setting that determines if users are able to make Batch Changes with a scheduled time. manual-batch-review-enabled must be enabled as well. If enabled, a VinylDNS administrator cannot approve the Batch Change until after the scheduled time. An administrator could also reject the Batch Change. scheduled-changes-enabled = true IPv6 Zone Discovery Boundaries Configuration setting that determines the range that will be searched for in reverse IPv6 Zone Discovery. This allows you to limit the search for what is appropriate for your organization. For example, min = 2, max = 3 will only search in zones in the form X.X.ip6.arpa. and X.X.X.ip6.arpa.. Note the following constraints: 0 < min <= max <= 32. If your organization only makes zone cuts at one point, you may set min == max. The default values if omitted are min = 5, max = 20. v6-discovery-nibble-boundaries { min = 5 max = 20 } Dotted Hosts Configuration setting that determines the zones, users (either individual or based on group) and record types that are allowed to create dotted hosts. If only all the above are satisfied, one can create a dotted host in VinylDNS. Note the following: Zones defined in the zone must always end with a dot. Eg: comcast.com. Wildcard character * can be used in zone to allow dotted hosts for all zones matching it. Individual users who are allowed to create dotted hosts are added to the user-list using their username. A set of users in a group who are allowed to create dotted hosts are added to the group-list using group name. If the user is either in user-list or group-list, they are allowed to create a dotted host. It is not necessary for the user to be in both user-list and group-list. The record types which are allowed while creating a dotted host is added to the record-types. The number of dots allowed in a record name for a zone is given in dots-limit. If user-list is left empty (user-list = []), no user will be allowed to create dotted hosts unless theyre present in group-list and vice-versa. If both user-list and group-list is left empty no users will be allowed to create dotted hosts in that zone. If record-types is left empty (record-types = []), user cannot create dotted hosts of any record type in that zone. If dots-limit is set to 0 (dots-limit = 0), we cannot create dotted hosts record in that zone. # approved zones, individual users, users in groups, record types and no.of.dots that are allowed for dotted hosts dotted-hosts = { allowed-settings = [ { zone = \"dummy.\" user-list = [\"testuser\"] group-list = [\"dummy-group\"] record-types = [\"AAAA\"] dots-limit = 3 }, { # for wildcard zones. Settings will be applied to all matching zones zone = \"*ent.com.\" user-list = [\"professor\", \"testuser\"] group-list = [\"testing-group\"] record-types = [\"A\", \"CNAME\"] dots-limit = 3 } ] } In the above, the dotted hosts can be created only in the zone dummy. and zones matching *ent.com. (parent.com., child.parent.com.) Also, it must satisfy the allowed users or group users and record type of the respective zone to create a dotted host. For eg, we cant create a dotted host with CNAME record type in the zone dummy. as its not in record-types. And the user professor cant create a dotted host in the zone dummy. as the user is not in user-list or group-list (not part of dummy-group). The config can be left empty as follows if we dont want to use it: dotted-hosts = { allowed-settings = [] } Full Example Config # The default application.conf is not intended to be used in production. It assumes a docker-compose # setup for all of the services. Provide your own application.conf on the docker mount with your # own settings vinyldns { queue { class-name = \"vinyldns.sqs.queue.SqsMessageQueueProvider\" messages-per-poll = 10 polling-interval = 250.millis settings { # AWS access key and secret. access-key = \"x\" secret-key = \"x\" # Regional endpoint to make your requests (eg. 'us-west-2', 'us-east-1', etc.). This is the region where your queue is housed. signing-region = \"x\" # Endpoint to access queue service-endpoint = \"http://localhost:9324/\" # Queue name. Should be used in conjunction with service endpoint, rather than using a queue url which is subject to change. queue-name = \"vinyldns\" } } # host and port the server binds to. This should not be changed rest { host = \"0.0.0.0\" port = 9000 } # The maximum number of records VinylDNS will load when syncing a DNS Zone # this is to prevent possible out of memory errors when loading a Zone # this does not stop the zone from existing in DNS, but you will not be able to manage it in VinylDNS if the number of records exceeds the max max-zone-size = 60000 # the delay between zone syncs so we are not syncing too often sync-delay = 10000 # crypto settings for symmetric cryptography of secrets in the system # Note: for production systems secrets should not live in plain text in a file crypto { type = \"vinyldns.core.crypto.NoOpCrypto\" } # both datastore options are in use data-stores = [\"mysql\"] mysql { class-name = \"vinyldns.mysql.repository.MySqlDataStoreProvider\" settings { name = \"vinyldns\" driver = \"org.mariadb.jdbc.Driver\" migration-url = \"jdbc:mariadb://localhost:19002/?user=root&password=pass\" url = \"jdbc:mariadb://localhost:19002/vinyldns?user=root&password=pass\" user = \"root\" password = \"pass\" maximum-pool-size = 20 minimum-idle = 10 connection-timeout-millis = 1000 idle-timeout = 10000 max-lifetime = 600000 register-mbeans = true my-sql-properties { prepStmtCacheSize = 300 prepStmtCacheSqlLimit = 2048 cachePrepStmts = true useServerPrepStmts = true rewriteBatchedStatements = true } } repositories { zone { } batch-change { } user { } record-set { } record-set-cache { } group { } membership { } group-change { } zone-change { } record-change { } } } # limits for batchchange routing, membership routing , recordset routing , zone routing api { limits { batchchange-routing-max-items-limit = 100 membership-routing-default-max-items = 100 membership-routing-max-items-limit = 1000 membership-routing-max-groups-list-limit = 1500 recordset-routing-default-max-items= 100 zone-routing-default-max-items = 100 zone-routing-max-items-limit = 100 } } # the DDNS connection information for the default dns backend defaultZoneConnection { name = \"vinyldns.\" keyName = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primaryServer = \"localhost:19001\" algorithm = \"HMAC-MD5\" } # the AXFR connection information for the default dns backend defaultTransferConnection { name = \"vinyldns.\" keyName = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primaryServer = \"localhost:19001\" algorithm = \"HMAC-MD5\" } # the max number of changes in a single batch change. Change carefully as this has performance # implications batch-change-limit = 1000 # notifier configuration notifiers = [\"email\", \"sns\"] email = { # Path to notifier provider implementation class-name = \"vinyldns.api.notifier.email.EmailNotifierProvider\" settings = { # Sender address for e-mail notifications from = \"Sender <do-not-reply@example.sender>\" smtp { # Host SMTP server host = \"example.host\" } } # Valid Email Domains valid-email-config { email-domains = [\"test.com\",\"*dummy.com\"] number-of-dots= 2 } sns { # Path to notifier provider implementation class-name = \"vinyldns.api.notifier.sns.SnsNotifierProvider\" settings { # SNS topic Amazon Resource Name (ARN) topic-arn = \"arn:aws:sns:us-east-1:000000000000:batchChanges\" # AWS access key and secret access-key = \"vinyldnsTest\" secret-key = \"notNeededForSnsLocal\" # Endpoint to access SNS service-endpoint = \"http://127.0.0.1:19006\" # Regional endpoint to make your requests (eg. 'us-west-2', 'us-east-1', etc.). This is the region where your SNS is housed. signing-region = \"us-east-1\" } } # approved zones, individual users, users in groups, record types and no.of.dots that are allowed for dotted hosts dotted-hosts = { allowed-settings = [ { zone = \"dummy.\" user-list = [\"testuser\"] group-list = [\"dummy-group\"] record-types = [\"AAAA\"] dots-limit = 3 }, { # for wildcard zones. Settings will be applied to all matching zones zone = \"*ent.com.\" user-list = [\"professor\", \"testuser\"] group-list = [\"testing-group\"] record-types = [\"A\", \"CNAME\"] dots-limit = 3 } ] } # true if you want to enable manual review for non-fatal errors manual-batch-review-enabled = true # true if you want to allow Batch Changes to be scheduled. manual-batch-review-enabled must also be true. scheduled-changes-enabled = true # types of unowned records that users can access in shared zones shared-approved-types = [\"A\", \"AAAA\", \"CNAME\", \"PTR\", \"TXT\"] # FQDNs / IPs that cannot be modified via VinylDNS # regex-list: list of regular expressions matching any FQDN that are not allowed to be modified by this VinylDNS instance # ip-list: list of IP addresses that cannot be modified by this VinylDNS instance high-value-domains = { regex-list = [ \"high-value-domain.*\" ] ip-list = [ \"192.0.2.252\", \"192.0.2.253\", \"fd69:27cc:fe91:0:0:0:0:ffff\", \"fd69:27cc:fe91:0:0:0:ffff:0\" ] } # FQDNS / IPs / zone names that require manual review when submitted through Batch Change/DNS Change # Treated as a fatal error if manual review is not enabled manual-review-domains = { domain-list = [ \"needs-review.*\" ] ip-list = [ \"192.0.2.254\", \"192.0.2.255\", \"fd69:27cc:fe91:0:0:0:ffff:1\", \"fd69:27cc:fe91:0:0:0:ffff:2\" ] zone-name-list = [ \"zone.requires.review.\" ] } # Zone Connection Data backends = [ { id = \"test-backend-id\" zone-connection { name = \"vinyldns.\" key-name = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primary-server = \"127.0.0.1:19001\" algorithm = \"HMAC-MD5\" } transfer-connection { name = \"vinyldns.\" key-name = \"vinyldns.\" key = \"nzisn+4G2ldMn0q1CV3vsg==\" primary-server = \"127.0.0.1:19001\" algorithm = \"HMAC-MD5\" } } ] } # Akka settings, these should not need to be modified unless you know akka http really well. akka { loglevel = \"INFO\" loggers = [\"akka.event.slf4j.Slf4jLogger\"] logging-filter = \"akka.event.slf4j.Slf4jLoggingFilter\" logger-startup-timeout = 30s } akka.http { server { # The time period within which the TCP binding process must be completed. # Set to `infinite` to disable. bind-timeout = 5s # Show verbose error messages back to the client verbose-error-messages = on } parsing { # Don't complain about the / in the AWS SigV4 auth header ignore-illegal-header-for = [\"authorization\"] } } }"
} ,
{
"title": "Portal Configuration Guide",
"url": "/operator/config-portal.html",
"content": "Portal Configuration Guide The portal configuration is much smaller than the API Server. Note: Unlike the API server, not all configuration resides under a vinyldns namespace. Configuration Database Configuration LDAP Cryptography Custom Links Additional Configuration Settings Full Example Config Database Configuration VinylDNS supports a MySQL backend (see API Database Configuration). Follow the MySQL Setup Guide first to get the values you need to configure here. The Portal uses the following tables: user userChanges Note that the user table is shared between the API and the portal, and must be configured with the same values in both configs: vinyldns { # this list should include only the datastores being used by your portal instance (user and userChange repo) data-stores = [\"mysql\"] mysql { # this is the path to the mysql provider. This should not be edited # from the default in reference.conf class-name = \"vinyldns.mysql.repository.MySqlDataStoreProvider\" settings { # the name of the database, recommend to leave this as is name = \"vinyldns\" # the jdbc driver, recommended to leave this as is driver = \"org.mariadb.jdbc.Driver\" # the URL used to create the schema, typically this will be without the \"database\" name migration-url = \"jdbc:mariadb://localhost:19002/?user=root&password=pass\" # the main connection URL url = \"jdbc:mariadb://localhost:19002/vinyldns?user=root&password=pass\" # the user to connect to MySQL user = \"root\" # the password to connect to MySQL password = \"pass\" ## see https://github.com/brettwooldridge/HikariCP for more detail on the following fields # the maximum number of connections to scale the connection pool to maximum-pool-size = 20 # the maximum number of milliseconds to wait for a connection from the connection pool connection-timeout-millis = 1000 # the minimum number of idle connections that HikariCP tries to maintain in the pool minimum-idle = 10 # the maximum number of milliseconds that a connection is can sit idle in the pool idle-timeout = 10000 # The max lifetime of a connection in a pool. Should be several seconds shorter than the database imposed connection time limit max-lifetime = 600000 # controls whether JMX MBeans are registered register-mbeans = true # my-sql-properties allows you to include any additional mysql performance settings you want. # Note that the properties within my-sql-properties must be camel case! # see https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration for guidance my-sql-properties { prepStmtCacheSize = 300 prepStmtCacheSqlLimit = 2048 cachePrepStmts = true useServerPrepStmts = true rewriteBatchedStatements = true } } repositories { # all repositories with config sections here will be enabled in mysql user { # no additional settings for repositories enabled in mysql } } } } LDAP Be sure to follow the LDAP Setup Guide first to get the values you need to configure here. LDAP configuration connects VinylDNS to your Directory where user information is stored. The default value for user sync enabled is false and user sync hours polling interval is 24 (max value). If the hours polling interval is configured higher than 24, 24 hours will be used. LDAP { # The name of the user to connect VinylDNS to LDAP user=\"test\" # The password for the user to connect VinylDNS to LDAP password=\"test\" # The domain for the user connecting VinylDNS to LDAP domain=\"test\" # One or more search bases to find users. If users come from multiple domains, list them here searchBase = [{organization = \"someDomain\", domainName = \"DC=test,DC=test,DC=com\"}, {organization = \"anotherDomain\", domainName = \"DC=test,DC=com\"}] # Connection information to LDAP context { initialContextFactory = \"com.sun.jndi.ldap.LdapCtxFactory\" securityAuthentication = \"simple\" # Set this to point to your LDAP providerUrl = \"ldaps://somedomain.com:9999\" } user-sync { enabled = true # Default value is false hours-polling-interval = 12 # Default value is 24 } } Cryptography Settings The Portal encrypts user secrets at rest using the same mechanism as the API server. Note: It is extremely important that these settings match the API server, otherwise the API server will not be able to decrypt user secrets and your installation will fail! Cryptography is pluggable, meaning you can bring your own crypto with you. All that is required is to provide an implementation of CryptoAlgebra using a crypto library of choice. The default implementation is NoOpCrypto, which does not do any encryption (not recommended for production). The following are the configuration settings for crypto. Notice here the only thing we see is the type. The type is the fully qualified class name for the CryptoAlgebra you will be using. If your crypto implementation requires additional settings, they will be configured inside the crypto element, adjacent to the type. crypto { type = \"vinyldns.core.crypto.JavaCrypto\" secret = \"8B06A7F3BC8A2497736F1916A123AA40E88217BE9264D8872597EF7A6E5DCE61\" } Custom Links Custom links display either on the nav bar once logged in, or on the log in screen. These links are useful to point to internal documentation and procedures. For example, how to raise certain tickets with engineering, or internal slack channels. # an array of links links = [ { # indicates that this link should be display on the sidebar once logged in displayOnSidebar = true # display this link also on the login screen displayOnLoginScreen = true # text to display for the link title = \"API Documentation\" # the hyperlink address being linked to href = \"https://vinyldns.io\" # a fa icon to display icon = \"fa fa-file-text-o\" } ] Additional Configuration Settings Play Secret The play secret must be set to a secret value, and should be an environment variable # See https://www.playframework.com/documentation/latest/ApplicationSecret for more details. play.http.secret.key = \"vinyldnsportal-change-this-for-production\" Play Allowed Hosts Filter Play provides a filter that lets you configure which hosts can access your application. The filter introduces a whitelist of allowed hosts and sends a 400 (Bad Request) response to all requests with a host that do not match the whitelist. # See https://www.playframework.com/documentation/2.8.x/AllowedHostsFilter for more details. # Note: allowed = [\".\"] matches all hosts hence would not be recommended in a production environment. play.filters.hosts { allowed = [\".\"] } Test Login The test login should not be used for production environments. It is useful to tinker with VinylDNS. If this setting is true, then you can login with testuser and testpassword. Logging in using the testuser will not contact LDAP. portal.test_login = false HTTP Port The HTTP Port that the Portal server will bind to http.port=9001 Portal URL Necessary to preview the metadata while sharing the portal link to social media portal.vinyldns.url = \"http://localhost:9001\" Shared Zones Display / Record Owner Selection Necessary to enable shared zones submission and record ownership shared-display-enabled = true Batch Change Limit How many changes are allowable in a single DNS change request batch-change-limit = 1000 Manual Review Enabled Triggers the manual review process for certain DNS requests manual-batch-review-enabled = true Scheduled Changes Allows users to schedule changes to be run sometime in the future scheduled-changes-enabled = true Full Example Config # This is the main configuration file for the application. # ~~~~~ # Secret key # ~~~~~ # The secret key is used to secure cryptographics functions. # # This must be changed for production, but we recommend not changing it in this file. # # See https://www.playframework.com/documentation/latest/ApplicationSecret for more details. play.http.secret.key = \"vinyldnsportal-change-this-for-production\" # See https://www.playframework.com/documentation/2.8.x/AllowedHostsFilter for more details. # Note: allowed = [\".\"] matches all hosts hence would not be recommended in a production environment. play.filters.hosts { allowed = [\".\"] } # The application languages # ~~~~~ play.i18n.langs = [ \"en\" ] portal.vinyldns.backend.url = \"http://vinyldns-api:9000\" portal.vinyldns.url = \"http://localhost:9001\" portal.test_login = false # configuration for the users and groups store data-stores = [\"mysql\"] mysql { class-name = \"vinyldns.mysql.repository.MySqlDataStoreProvider\" settings { name = \"vinyldns\" driver = \"org.mariadb.jdbc.Driver\" migration-url = \"jdbc:mariadb://localhost:19002/?user=root&password=pass\" url = \"jdbc:mariadb://localhost:19002/vinyldns?user=root&password=pass\" user = \"root\" password = \"pass\" maximum-pool-size = 20 minimum-idle = 10 connection-timeout-millis = 1000 idle-timeout = 10000 max-lifetime = 600000 register-mbeans = true my-sql-properties { prepStmtCacheSize = 300 prepStmtCacheSqlLimit = 2048 cachePrepStmts = true useServerPrepStmts = true rewriteBatchedStatements = true } } repositories { user { } } } } play.filters.enabled += \"play.filters.csrf.CSRFFilter\" # Expire session after 10 hours play.http.session.maxAge = 10h # session secure should be false in order to run properly locally, this is set properly on deployment play.http.session.secure = false play.http.session.httpOnly = true # use no-op by default crypto { type = \"vinyldns.core.crypto.NoOpCrypto\" } http.port=9001 links = [ { displayOnSidebar = true displayOnLoginScreen = true title = \"API Documentation\" href = \"https://vinyldns.io\" icon = \"fa fa-file-text-o\" } ]"
} ,
{
"title": "Connect to your Zone",
"url": "/portal/connect-to-zone.html",
"content": "Connect to your Zone Once your zone is setup for use with VinylDNS, you can use the VinylDNS portal to connect to it. If you dont already have an admin group in VinylDNS for your zone select the Groups link in the navigation and create an admin group for your zone. Members of the group will have full access to the zone. See Manage Access for more details. Select the Zones link from the navigation, then click the Connect button. This will show the Connect to a Zone form. Enter the full name of the zone, example “test.sys.example.com” Enter the email distribution list for the zone. This is typically a distribution list email for the team that owns the zone. Select the admin group for the zone. If you do not have any custom TSIG keys, you can leave the connection information empty. If you do have custom TSIG keys, read the section on Understand Connections. Click the Connect button at the bottom of the form. You may have to click the Refresh button from the zone list to see your new zone. If you see error messages, please consult the FAQ."
} ,
{
"title": "Understand Connections",
"url": "/portal/connections.html",
"content": "Understand Connections VinylDNS provides the ability to specify two different connections to the backend DNS servers. The primary connection is used for issuing DNS updates The transfer connection is used for syncing DNS data with VinylDNS If you do not have any keys, then you can leave this information empty. VinylDNS will assume a set of default keys that should provide the access VinylDNS needs to manage your zone. If you have an existing TSIG key that you are using for issuing DDNS updates to DNS, and you wish to continue to use it, you must request that your zone be setup to allow transfers from VinylDNS. Note: If you make any changes outside of VinylDNS they will not be reflected in VinylDNS unless you manually sync the zone. If you have an existing TSIG key that you are using for issuing DDNS updates, and you no longer need the key, please contact your VinylDNS administrators to ensure that the key is revoked and the zone is setup with the default VinylDNS TSIG key. Once your key is revoked, you can leave the connections empty in which case VinylDNS will assume the default keys and they should work."
} ,
{
"title": "Contributing",
"url": "/extra_md/contributing.html",
"content": "Contributing to VinylDNS The following are a set of guidelines for contributing to VinylDNS and its associated repositories. Table of Contents Code of Conduct Issues Working on an Issue Submitting an Issue Discussion Process Pull Requests General Flow Pull Request Requirements Commit Messages Testing Documentation Edits Style Guides License Header Checks Contributor License Agreement Modifying your Pull Request Pull Request Approval Code of Conduct This project and everyone participating in it are governed by the VinylDNS Code Of Conduct. By participating, you agree to this Code. Issues Work on VinylDNS is tracked by GitHub Issues. To contribute to VinylDNS, you can join the discussion on an issue, submit a Pull Request to resolve the issue, or make an issue of your own. VinylDNS issues are generally labeled as bug reports, feature requests, or maintenance requests. Working on an Issue If you would like to contribute to VinylDNS, you can look through good first issue and help wanted issues. We keep a list of these issues around to encourage participation in building the platform. In the issue list, you can chose “ Labels” and choose a specific label to narrow down the issues to review. Beginner issues: only require a few lines of code to complete, rather isolated to one or two files. A good way to get through changing and testing your code, and meet everyone! Help wanted issues: these are more involved than beginner issues, are items that tend to come near the top of our backlog but not necessarily in the current development stream. Besides those issues, you can sort the issue list by number of comments to find one that may be of interest. You do not have to limit yourself to only good first issue or help wanted issues. When resolving an issue, you generally will do so by making a Pull Request, and adding a link to the issue. Before choosing an issue, see if anyone is assigned or has indicated they are working on it (either in comment or via Pull Request). If that is the case, then instead of making a Pull Request of your own, you can help out by reviewing their Pull Request. Submitting an Issue When submitting an issue you will notice there are three issue templates to choose from. Before making any issue, please go search the issue list (open and closed issues) and check to see if a similar issue has been made. If so, we ask that you do not duplicate an issue, but feel free to comment on the existing issue with additional details. Bug report: If you find a bug in the project you can report it with this template and the VinylDNS team will take a look at it. Please be as detailed as possible as it will help us recreate the bug and figure out what exactly is going on. If you are unsure whether what you found is a bug, we encourage you to first pop in our discussion board, and we can help determine if what youre seeing is unexpected behavior, and if it is we will direct to make the bug report. Feature request: Use this template if you have something you wish to be added to the project. Please be detailed when describing why you are requesting the feature, what you want it to do, and alternative solutions you have considered. Discussion Process Some issues may require discussion with the community before proceeding to implementation. This can happen if the issue is a larger change, for example a big refactoring or new feature. The VinylDNS maintainers may label an issue for ** Discussion** in order to solicit more detail before proceeding. If the issue is straightforward and/or well documented, it can be implemented immediately by the submitter. If the submitter is unable to make the changes required to address the issue, the VinylDNS maintainers will prioritize the work in our backlog. Pull Requests Contributions to VinylDNS are generally made via Github Pull Requests. Most Pull Requests are related to an issue, and will have a link to the issue in the Pull Request. General Flow We follow the standard GitHub Flow for taking code contributions. The following is the process typically followed: Create a fork of the repository that you want to contribute code to Clone your forked repository to your local machine In your local machine, add a remote to the “main” repository, we call this “upstream” by running git remote add upstream https://github.com/vinyldns/vinyldns.git. Note: you can also use ssh instead of https Create a local branch for your work git checkout -b your-user-name/user-branch-name. Add whatever your GitHub user name is before whatever you want your branch to be. Begin working on your local branch Be sure to add necessary unit, integration, and functional tests, see the Testing section of the Developer Guide. Make sure you run all builds before posting a Pull Request! Its faster to run everything locally rather than waiting for the build server to complete its job. See DEVELOPER_GUIDE.md for information on local development. When you are ready to contribute your code, run git push origin your-user-name/user-branch-name to push your changes to your own fork Go to the VinylDNS main repository (or whatever repo you are contributing to) and you will see your change waiting and a link to “Create a Pull Request”. Click the link to create a Pull Request. Be as detailed as possible in the description of your Pull Request. Describe what you changed, why you changed it, and give a detailed list of changes and impacted files. If your Pull Request is related to an existing issue, be sure to link the issue in the Pull Request itself, in addition to the Pull Request description. You will receive comments on your Pull Request. Use the Pull Request as a dialog on your changes. Pull Request Requirements Commit Messages Limit the first line to 72 characters or fewer. Use the present tense (“Add validation” not “Added validation”). Use the imperative mood (“Move database call” not “Moves database call”). Reference issues and other pull requests liberally after the first line. Use GitHub Auto Linking to link your Pull Request to other issues. Use markdown syntax as much as you want Testing When making changes to the VinylDNS codebase, be sure to add necessary unit, integration, and functional tests. For specifics on our tests, see the Testing section of the Developer Guide. Documentation Edits Documentation for the VinylDNS project lives in files such as this one in the root of the project directory, as well as in modules/docs/src/main/mdoc for the docs you see on vinyldns.io. Many changes, such as those that impact an API endpoint, config, portal usage, etc, will also need corresponding documentation edited to prevent it from going stale. The VinylDNS gh-pages branch README has information on how to run and edit the documentation page. Style Guides For Scala code we use Scalastyle. The configs are scalastyle-config.xml and scalastyle-test-config.xml for source code and test code respectively We have it set to fail builds if the styling rules are not followed. For example, one of our rules is that all lines must be <= 120 characters, and a build will fail if that is violated. For our python code that we use for functional testing, we generally try to follow PEP 8 License Header Checks VinylDNS is configured with sbt-header. All existing scala files have the appropriate header. To add or check for headers, follow these steps: API You can check for headers in the API in sbt with: > ;project api;headerCheck;test:headerCheck;it:headerCheck If you add a new file, you can add the appropriate header in sbt with: > ;project api;headerCreate;test:headerCreate;it:headerCreate Portal You can check for headers in the Portal in sbt with: > ;project portal;headerCheck;test:headerCheck;checkJsHeaders If you add a new file, you can add the appropriate header in sbt with: > ;project portal;headerCreate;test:headerCreate;createJsHeaders Contributor License Agreement Before Comcast merges your code into the project you must sign the Comcast Contributor License Agreement (CLA). If you havent previously signed a Comcast CLA, youll automatically be asked to when you open a pull request. Alternatively, we can send you a PDF that you can sign and scan back to us. Please create a new GitHub issue to request a PDF version of the CLA. Modifying your Pull Requests Often times, you will need to make revisions to your Pull Requests that you submit. This is part of the standard process of code review. There are different ways that you can make revisions, but the following process is pretty standard. Sync with upstream first. git checkout master && git fetch upstream && git rebase upstream master && git push origin master Checkout your branch on your local git checkout your-user-name/user-branch-name Sync your branch with latest git rebase master. Note: If you have merge conflicts, you will have to resolve them Revise your Pull Request, making changes recommended in the comments / code review Stage and commit these changes on top of your existing commits When all tests pass, git push origin your-user-name/user-branch-name to revise your commit. Note: If you rebased or altered the commit history, you will have to force push with a -f flag. GitHub automatically recognizes the update and will re-run verification on your Pull Request! Pull Request Approval A pull request must satisfy our pull request requirements Afterwards, if a Pull Request is approved, a maintainer of the project will merge it. If you are a maintainer, you can merge your Pull Request once you have the approval of at least 2 other maintainers. Note: The first time you make a Pull Request, add yourself to the authors list here as part of the Pull Request"
} ,
{
"title": "Create a Group",
"url": "/portal/create-a-group.html",
"content": "Create a group In the Groups area of the site select the New Group button. This will bring up a form. Enter a name for the group, email address and an optional description. Select the Create button to submit the group information. If all fields are valid youll see the group listed in the table on the screen when the form closes."
} ,
{
"title": "Create Batch Change",
"url": "/api/create-batchchange.html",
"content": "Create Batch Change Creates a batch change with SingleAddChanges and/or SingleDeleteRRSetChanges across different zones. A delete and add of the same record will be treated as an update on that record set. Regardless of the input order in the batch change, all deletes for the same recordset will be logically applied before the adds. Current supported record types for creating a batch change are: A, AAAA, CNAME, MX, PTR, TXT. A batch must contain at least one change and no more than 20 changes. Supported record types for records in shared zones may vary. Contact your VinylDNS administrators to find the allowed record types. This does not apply to zone administrators or users with specific ACL access rules. HTTP REQUEST POST /zones/batchrecordchanges?allowManualReview={true | false} Note that the batch change request inputs are a subset of the full batch change model. HTTP REQUEST PARAMS name type required? description comments string no Optional comments about the batch change. changes Array of ChangeInput yes Set of ChangeInputs in the batch change. A ChangeInput is an AddChangeInput or DeleteChangeInput. Type is inferred from specified changeType. ownerGroupId string sometimes Record ownership assignment. Required if any records in the batch change are in shared zones and are new or unowned. scheduledTime date-time no Optional datetime. Stored as UTC. Batch change will not be processed until after the scheduled time. Required format is an ISO 8601 date time string. allowManualReview boolean no Optional override to control whether manual review is enabled for the batch change request. Default value is true. Must be passed in as a query parameter, not in the request body. AddChangeInput name type required? description changeType ChangeInputType yes Type of change input. Must be set to Add for AddChangeInput. inputName string yes The fully qualified domain name of the record being added. For PTR, the input name is a valid IPv4 or IPv6 address. type RecordType yes Type of DNS record. Supported records for batch changes are currently: A, AAAA, CNAME, and PTR. ttl long no The time-to-live in seconds. The minimum and maximum values are 30 and 2147483647, respectively. If excluded, this will be set to the system default for new adds, or the existing TTL for updates record RecordData yes The data for the record. DeleteChangeInput name type required? description changeType ChangeInputType yes Type of change input. Must be DeleteRecordSet for DeleteChangeInput. inputName string yes The fully qualified domain name of the record being deleted. type RecordType yes Type of DNS record. Supported records for batch changes are currently: A, AAAA, CNAME, and PTR. record RecordData no The data for the record. If specified, only this DNS entry for the existing DNS recordset will be deleted; if unspecified, the entire DNS recordset will be deleted. EXAMPLE HTTP REQUEST { \"comments\": \"this is optional\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\", \"changes\": [ { \"inputName\": \"example.com.\", \"changeType\": \"Add\", \"type\": \"A\", \"ttl\": 3600, \"record\": { \"address\": \"1.1.1.1\" } }, { \"inputName\": \"192.0.2.195\", \"changeType\": \"Add\", \"type\": \"PTR\", \"ttl\": 3600, \"record\": { \"ptrdname\": \"ptrdata.data.\" } }, { \"inputName\": \"cname.example.com.\", \"changeType\": \"DeleteRecordSet\", \"type\": \"CNAME\" }, { \"inputName\": \"update.another.example.com.\", \"changeType\": \"DeleteRecordSet\", \"type\": \"AAAA\", \"record\": { \"address\": \"2:3:4:5:6:7:8:9\" } }, { \"inputName\": \"update.another.example.com.\", \"changeType\": \"Add\", \"type\": \"AAAA\", \"ttl\": 4000, \"record\": { \"address\": \"1:2:3:4:5:6:7:8\" } } ] } The first two items in the changes list are SingleAddChanges of an A record and a PTR record. Note that for the PTR record, the inputName is a valid IP address. The third item is a delete of a CNAME record. The last two items represent an update (delete & add) of an AAAA record with the fully qualified domain name “update.another.example.com.”. HTTP RESPONSE TYPES Code description 202 Accepted - The batch change is validated and is returned in the response body. Based on status, the batch will either be sent for immediate backend processing (PendingProcessing) or pending manual review (PendingReview). 400 Bad Request - Error in the batch change. See Batch Change Errors page. 403 Forbidden - The user does not have the access required to perform the action. 413 Request Entity Too Large - Cannot request more than changes in a single batch change request. 422 Unprocessable Entity - the batch does not contain any changes, thus cannot be processed. A batch change goes through numerous validations before it is processed. This results in corresponding BadRequest or error responses. View the full list of batch change errors here. HTTP RESPONSE ATTRIBUTES On success, the response from create batch change includes the fields the user input, as well as some additional information provided by the system. This response is the same as that of get batch change. EXAMPLE RESPONSE { \"userId\": \"vinyl\", \"userName\": \"vinyl201\", \"comments\": \"this is optional\", \"createdTimestamp\": \"2018-05-09T14:19:34Z\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\" \"changes\": [ { \"changeType\": \"Add\", \"inputName\": \"example.com.\", \"type\": \"A\", \"ttl\": 3600, \"record\": { \"address\": \"1.1.1.1\" }, \"status\": \"Pending\", \"recordName\": \"example.com.\", \"zoneName\": \"example.com.\", \"zoneId\": \"74e93bfc-7296-4b86-83d3-1ffcb0eb3d13\", \"validationErrors\": [], \"id\": \"7573ca11-3e30-45a8-9ba5-791f7d6ae7a7\" }, { \"changeType\": \"Add\", \"inputName\": \"192.0.2.195\", \"type\": \"PTR\", \"ttl\": 3600, \"record\": { \"ptrdname\": \"ptrdata.data.\" }, \"status\": \"Pending\", \"recordName\": \"195\", \"zoneName\": \"2.0.192.in-addr.arpa.\", \"zoneId\": \"7fd52634-5a0c-11e8-9c2d-fa7ae01bbebc\", \"validationErrors\": [], \"id\": \"bece5338-5a0c-11e8-9c2d-fa7ae01bbebc\" }, { \"changeType\": \"DeleteRecordSet\", \"inputName\": \"cname.example.com.\", \"type\": \"CNAME\", \"status\": \"Pending\", \"recordName\": \"cname\", \"zoneName\": \"example.com.\", \"zoneId\": \"74e93bfc-7296-4b86-83d3-1ffcb0eb3d13\", \"validationErrors\": [], \"id\": \"02048500-5a0d-11e8-a10f-fa7ae01bbebc\" }, { \"changeType\": \"DeleteRecordSet\", \"inputName\": \"update.example.com.\", \"type\": \"AAAA\", \"status\": \"Pending\", \"recordName\": \"update\", \"zoneName\": \"example.com.\", \"zoneId\": \"74e93bfc-7296-4b86-83d3-1ffcb0eb3d13\", \"validationErrors\": [], \"id\": \"1cee1c78-5a0d-11e8-9c2d-fa7ae01bbebc\" }, { \"changeType\": \"Add\", \"inputName\": \"update.another.example.com.\", \"type\": \"AAAA\", \"ttl\": 3600, \"record\": { \"address\": \"1:2:3:4:5:6:7:8\" }, \"status\": \"Pending\", \"recordName\": \"update\", \"zoneName\": \"another.example.com.\", \"zoneId\": \"7fd52634-5a0c-11e8-9c2d-fa7ae01bbebc\", \"validationErrors\": [], \"id\": \"43dd1226-5a0d-11e8-9c2d-fa7ae01bbebc\" } ], \"status\": \"PendingProcessing\", \"id\": \"02bd95f4-a32c-443b-82eb-54dbaa55b31a\" }"
} ,
{
"title": "Create Group",
"url": "/api/create-group.html",
"content": "Create Group Creates a Group in VinylDNS. HTTP REQUEST POST /groups HTTP REQUEST PARAMS name type required? description name string yes The name of the group. Should be one word, use hyphens if needed but no spaces email string yes The email distribution list for the group description string no A short description of the group if more info is needed other than the name members Array of User id objects yes Set of User ids in the group admins Array of User id objects yes Set of User ids that are admins of the group. All admin user ids should also be in the members array EXAMPLE HTTP REQUEST { \"name\": \"some-group\", \"email\": \"test@example.com\", \"description\": \"an example group\", \"members\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ], \"admins\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ] } HTTP RESPONSE TYPES Code description 200 OK - The group has been created and the group info is returned in the response body 400 Bad Request - The group was invalid 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 404 Not Found - A user id was not found 409 Conflict - A group with the same name already exists HTTP RESPONSE ATTRIBUTES name type description id string Unique UUID of the group name string The name of the group email string The email distribution list of the group description string The group description, the group will not have this attribute if it was not included in the create request created string The timestamp (UTC) the group was created status string Active or Deleted, in this case Active members Array of User ID objects IDs of members of the group including admins admins Array of User ID objects IDs of admins of the group EXAMPLE RESPONSE { \"id\": \"6f8afcda-7529-4cad-9f2d-76903f4b1aca\", \"name\": \"some-group\", \"email\": \"test@example.com\", \"description\": \"an example group\", \"created\": \"2017-03-02T15:29:21Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ], \"admins\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ] }"
} ,
{
"title": "Create RecordSet",
"url": "/api/create-recordset.html",
"content": "Create RecordSet Creates a RecordSet in a specified zone. HTTP REQUEST POST /zones/{zoneId}/recordsets HTTP REQUEST PARAMS name type required? description zoneId string yes id of the zone where the recordset belongs name string yes the name of the recordset being updated type string yes the type of recordset ttl integer yes the TTL in seconds records array of record data yes record data for recordset, see RecordSet Model ownerGroupId string no Record ownership assignment, applicable if the recordset is in a shared zone EXAMPLE HTTP REQUEST { \"name\": \"foo\", \"type\": \"A\", \"ttl\": 300, \"records\": [ { \"address\": \"10.10.10.10\" } ], \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\" } HTTP RESPONSE TYPES Code description 202 Accepted - The record set is valid and has been accepted for processing; the record set change resource is returned 400 Bad Request - The zone specified is not Active; typically because the zone has no connection information 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - the zone with the id specified was not found 409 Conflict - A record set with the same name and type already exists in the zone 422 Unprocessable Entity HTTP RESPONSE ATTRIBUTES name type description zone map Contains information about the zone when the change was created recordSet map Contains the recordset model userId string The user id that initiated the change changeType string Type of change requested (Create, Update, Delete); in this case Create created string The timestamp (UTC) the change was initiated id string The ID of the change. This is not the ID of the recordset status RecordSetChangeStatus The status of the change (Pending, Complete, or Failed) singleBatchChangeIds array of SingleBatchChange Id objects If the recordset change was part of a batch change, the IDs of the single changes that comprise the recordset change EXAMPLE RESPONSE { \"zone\": { \"name\": \"vinyl.\", \"email\": \"test@test.com\", \"status\": \"Active\", \"created\": \"2017-02-23T14:52:44Z\", \"id\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"shared\": false, \"acl\": { \"rules\": [ ] }, \"adminGroupId\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\" }, \"recordSet\": { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"foo\", \"ttl\": 300, \"status\": \"Pending\", \"created\": \"2017-02-23T14:58:54Z\", \"records\": [ { \"address\": \"10.10.10.10\" } ], \"id\": \"9a41b99c-8e67-445f-bcf3-f9c7cd1f2357\", \"account\": \"0215d410-9b7e-4636-89fd-b6b948a06347\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\", \"ownerGroupName\": \"Shared Group\" }, \"userId\": \"0215d410-9b7e-4636-89fd-b6b948a06347\", \"changeType\": \"Create\", \"status\": \"Pending\", \"created\": \"2017-02-23T14:58:54Z\", \"id\": \"fef81f0b-f439-462d-88df-c773d3686c9b\", \"singleBatchChangeIds\": [] }"
} ,
{
"title": "Create Zone",
"url": "/api/create-zone.html",
"content": "Create Zone Connects user to an existing zone. User must be a member of the group that has access to the zone. Connection info is optional, if no info is provided the default VinylDNS connections will be used. HTTP REQUEST POST /zones HTTP REQUEST PARAMS Zone fields - adminGroupId, name, and email are required. Refer to zone model. EXAMPLE HTTP REQUEST { \"adminGroupId\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"name\": \"dummy.\", \"email\": \"test@example.com\" } HTTP RESPONSE TYPES Code description 202 Accepted - The zone change is queued and is returned in the response body 400 Bad Request - Connection failed, or group did not have access to the zone 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - the user does not have the access required to perform the action 409 Conflict - Zone already connected to HTTP RESPONSE ATTRIBUTES name type description status string Status of zone change zone map Refer to zone model created string The timestamp (UTC) the change was initiated changeType string Type of change requested (Create, Update, Sync, Delete); in this case Create userId string The user id that initiated the change id string The ID of the change. This is not the ID of the zone EXAMPLE RESPONSE { \"status\": \"Pending\", \"zone\": { \"status\": \"Pending\", \"account\": \"test_group\", \"name\": \"488e6063-7832-40f6-87d3-87dae50c690a.\", \"created\": \"2016-12-28T18:00:32Z\", \"adminGroupId\": \"test-group-id\", \"email\": \"test@test.com\", \"shared\": false, \"acl\": { \"rules\": [ ] }, \"id\": \"8ba20b72-cfdb-49d3-9216-9100aeaee7fc\" }, \"created\": \"2016-12-28T18:00:32Z\", \"changeType\": \"Create\", \"userId\": \"vinyl\", \"id\": \"dd449c27-bed5-4cd5-95e6-4c54fb20d930\" }"
} ,
{
"title": "Credentials",
"url": "/portal/credentials.html",
"content": "Credentials In order to use tooling to access VinylDNS, all users must download their credentials from the VinylDNS portal. The credentials are located in the User Menu in the top right corner of the site after login. Regenerate Credentials If your credentials are compromised you can generate new ones. In the User Menu select Regenerate Credentials. Regenerating your credentials will invalidate your previous credentials. If you are using any VinylDNS tools beyond the portal you can then select Download Credentials to retrieve your new credentials and update the tools you use."
} ,
{
"title": "Delete Group",
"url": "/api/delete-group.html",
"content": "Delete Group Deletes a Group in VinylDNS. HTTP REQUEST DELETE /groups/{groupId} HTTP RESPONSE TYPES Code description 200 OK - The group has been delete and the group info is returned in the response body 400 Bad Request - The group could not be deleted 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - The group was not found HTTP RESPONSE ATTRIBUTES name type description id string Unique UUID of the group name map The name of the group email string The email distribution list of the group description string The group description, the group will not have this attribute if it was not set created string The timestamp (UTC) the group was created status string Active or Deleted, in this case Deleted members Array of User ID objects IDs of members of the group including admins admins Array of User ID objects IDs of admins of the group EXAMPLE RESPONSE { \"id\": \"6f8afcda-7529-4cad-9f2d-76903f4b1aca\", \"name\": \"some-group\", \"email\": \"test@example.com\", \"created\": \"2017-03-02T15:29:21Z\", \"status\": \"Deleted\", \"members\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" }, { \"id\": \"c8630ebc-0af2-4c9a-a0a0-d18c590ed03e\" } ], \"admins\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ] }"
} ,
{
"title": "Delete RecordSet",
"url": "/api/delete-recordset.html",
"content": "Delete RecordSet Delete a RecordSet in a specified zone. HTTP REQUEST DELETE /zones/{zoneId}/recordsets/{recordSetId} HTTP RESPONSE TYPES Code description 202 Accepted - the delete is valid and has been accepted for processing; the record set change resource is returned in the response body 400 Bad Request - the zone being updated is not active; typically because the connection information does not exist for the zone 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone or RecordSet not found 409 Conflict - There is an existing pending change against this zone HTTP RESPONSE ATTRIBUTES name type description zone map Contains information about the zone when the change was created recordSet map Contains the recordset model userId string The user ID that initiated the change changeType string Type of change requested (Create, Update, Delete); in this case Delete created string The timestamp (UTC) the change was initiated id string The ID of the change. This is not the ID of the recordset EXAMPLE RESPONSE { \"zone\": { \"name\": \"vinyl.\", \"email\": \"test@test.com\", \"status\": \"Active\", \"created\": \"2017-02-23T14:52:44Z\", \"updated\": \"2017-02-23T15:12:33Z\", \"id\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"shared\": false, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"latestSync\": \"2017-02-23T15:12:33Z\" }, \"recordSet\": { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"foo\", \"ttl\": 38400, \"status\": \"PendingDelete\", \"created\": \"2017-02-23T15:12:33Z\", \"updated\": \"2017-02-23T15:18:27Z\", \"records\": [ { \"address\": \"2.2.2.2\" } ], \"id\": \"da57c384-d6e8-4166-986d-2ca9d483f760\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\" }, \"userId\": \"0215d410-9b7e-4636-89fd-b6b948a06347\", \"changeType\": \"Delete\", \"status\": \"Pending\", \"created\": \"2017-02-23T15:18:27Z\", \"updates\": { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"foo\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:33Z\", \"records\": [ { \"address\": \"2.2.2.2\" } ], \"id\": \"da57c384-d6e8-4166-986d-2ca9d483f760\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\" }, \"id\": \"c46cf622-285f-4f1b-b5b2-993a5a51ea5b\" }"
} ,
{
"title": "Delete Zone",
"url": "/api/delete-zone.html",
"content": "Delete Zone Abandons an existing zone that has already been connected to. The zone will be disconnected from VinylDNS, but the RecordSets still exist in the backend DNS zone. To delete the RecordSets see Delete RecordSet Note: We do not recommend that you abandon zones, as your zone history will be lost after the Delete. This endpoint is provided in certain situations where a zone was incorrectly started. HTTP REQUEST DELETE /zones/{zoneId} HTTP RESPONSE TYPES Code description 202 Accepted - The change has been queued and is returned in the response body 400 Bad Request - Zone was not empty and contains records 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone not found 409 Conflict - Zone is unavailable HTTP RESPONSE ATTRIBUTES name type description zone map Zone being deleted userId string The user id that initiated the change changeType string Type of change requested (Create, Update, Sync, Delete); in this case Delete created string The timestamp (UTC) the change was initiated id string The ID of the change. This is not the ID of the zone status string The status of the zone change EXAMPLE RESPONSE { \"status\": \"Pending\", \"zone\": { \"status\": \"Deleted\", \"updated\": \"2016-12-28T18:45:53Z\", \"name\": \"443ad9ff-8f38-4540-b53f-e23a35fdfc28.\", \"adminGroupId\": \"test-group-id\", \"created\": \"2016-12-28T18:45:53Z\", \"account\": \"test_group\", \"email\": \"test@test.com\", \"shared\": false, \"acl\": { \"rules\": [] }, \"id\": \"4995e883-f314-4c5f-8ee8-75003ca08ab0\" }, \"created\": \"2016-12-28T18:45:53Z\", \"changeType\": \"Delete\", \"userId\": \"vinyl\", \"id\": \"89c463e3-1615-42f7-8299-a0ca7ccea439\" }"
} ,
{
"title": "DNS Changes",
"url": "/portal/dns-changes.html",
"content": "DNS Changes DNS Changes is an alternative to submitting individual RecordSet changes and provides the following: The ability to include records of multiple record types across multiple zones. Input names are entered as fully-qualified domain names (or IP addresses for PTR records), so users dont have to think in record/zone context. Note: DNS Change is portal-only terminology. The API equivalent is batch change. Access Access permissions will follow existing rules (admin group or ACL access). Note that an update (delete and add of the same record name or delete of single entry of multi-record DNS record set, zone and record type combination) requires Write or Delete access. Records in shared zones. All users are permitted to create new records or update unowned records in shared zones. Supported record types Current supported record types for DNS change are: A, AAAA, CNAME, PTR, TXT, and MX. Additionally, there are A+PTR and AAAA+PTR types that will be processed as separate A (or AAAA) and PTR changes in the VinylDNS backend. Deletes for A+PTR and AAAA+PTR require Input Name and Record Data. Supported record types for records in shared zones may vary. Contact your VinylDNS administrators to find the allowed record types. This does not apply to zone administrators or users with specific ACL access rules. Requirements DNS change requests must contain at least one change. The maximum number of single changes within a DNS change varies by instance of VinylDNS. Contact your VinylDNS administrators to find the DNS change limit for your instance. To update an existing record, you must delete the record first and add all expected records within the same request; a delete and add of the same record set within a DNS change request will be processed as an update. When creating a new record in a shared zone, or updating an existing unowned record, a record owner group is required. Once the owner group is assigned only users in that group, zone admins, and users with ACL permissions can modify the record. Create a DNS Change Go to the DNS Changes section of the site. Select the New DNS Change button. Add a description. Add record changes in one of two ways: Select the Add a Change button to add additional rows for data entry as needed. Select the Import CSV button to choose and upload a CSV file of the record changes. See DNS Change CSV Import for more information. Select the submit button. Confirm your submission. If your submission was successful youll redirect to the DNS Change summary page where you will see the status of the DNS Change request overall and of the individual records in the DNS Change. If there are errors in the DNS Change you will remain on the form with prompts to correct errors before you attempt to submit again. DNS Change CSV Import Download a sample CSV here The header row is required. The order of the columns is Change Type, Record Type, Input Name, TTL, Record Data. The TTL field is optional for each record, but the column is still required. If TTL is empty VinylDNS will use the existing TTL value for record updates or the default TTL value for new records. Review a DNS Change You can review your submitted DNS Change requests by selecting the linked DNS Change ID or View button for the DNS Change on the main page of the DNS Changes section in the portal."
} ,
{
"title": "FAQ",
"url": "/faq.html",
"content": "VinylDNS FAQ Frequently Asked Questions Can I create a zone in VinylDNS? How do I know my zone ID? How can I create a record with the same name as my zone? When I try to connect to my zone, I am seeing REFUSED When I try to connect to my zone, I am seeing NOTAUTH When I try to connect to my zone, I am seeing “dotted host” errors When I try to connect to my zone, I am seeing “invalid name server” errors How do I get API credentials? How are requests authenticated to the VinylDNS API? Why am I not able to view the Change History tab on a Group? 1. Can I create a zone in VinylDNS? To get started with VinylDNS, you must have an existing DNS zone. VinylDNS currently does not create zones, rather it connects to existing zones. 2. How do I know my zone ID? When viewing your zone in the portal, the zone ID is listed in the Manage Zone tab of your zone. This ID is also present in the URL (if on that page its the ID after /zones/). 3. How can I create a record with the same name as my zone? To create a record with the same name as your zone, you have to use the special @ character for the record name when you create your record set. You cannot create CNAME records with @ as those are not supported. While some DNS services like Route 53 support an ALIAS record type that does support a CNAME style @, ALIAS are not an official standard yet. All other record types should be fine using the @ symbol. 4. When I try to connect to my zone, I am seeing REFUSED When VinylDNS connects to a zone, it first validates that the zone is suitable for use in VinylDNS. To do so, it tests that the connections work, and that the zone data is valid. REFUSED indicates that VinylDNS could not do a zone transfer to load the DNS records for examination. A few reasons for this are: The Transfer Connection you entered is invalid. Please verify that the TSIG information you entered works. You can attempt to do a dig and request a zone transfer from the command line. You did not setup a Transfer Connection, but the VinylDNS default keys do not have transfer access to your zone. Steps must be taken outside of VinylDNS. 5. When I try to connect to my zone, I am seeing NOTAUTH NOTAUTH indicates that the primary connection that VinylDNS uses to validate the zone is not working. The reasons are: The Connection you entered is invalid. Please verify that the TSIG information you entered works. You did not setup a Connection, but the VinylDNS default keys do not have update access to your zone. Steps must be taken outside of VinylDNS. 6. When I try to connect to my zone, I am seeing “dotted host” errors VinylDNS validates zones upon connect. One validation is to make sure that there are no “dotted” host. A “dotted host” is a record label inside of a zone that has a “dot” in its name, but is not part of a subdomain of the zone. For example, “foo.bar.example.com” is invalid, and considered a “dotted host”, if it lives inside of the “example.com” DNS zone. For this to be a valid record, this label would need to be a record named “foo” inside of the “bar.example.com” zone. You will not be able to use VinylDNS for zones with dotted hosts until they are remediated. All remediation steps must be taken outside of VinylDNS. If possible, use dashes instead of dots. In the example, you can have “foo-bar.example.com” 7. When I try to connect to my zone, I am seeing “invalid Name Server” errors One of the validations VinylDNS performs is to make sure the name servers that are in use in the zone are in a list of approved name servers. If your zone is hosted on name servers that are not in this list, you will not be able to use VinylDNS to manage your zone. 8. How do I get API credentials? After logging in to the portal, click your username at the top right and select Download API Credentials. If you need new API credentials select Regenerate Credentials. This will invalidate your previous credentials. If you use any VinylDNS tools beyond the portal you will need to provide those tools with your new credentials. 9. How are requests authenticated to the VinylDNS API? Refer to API Authentication. 10. Why am I not able to view the Change History tab on a Group? To view a groups change history, you should be a member or admin of that group. Only individuals who are part of the group can view the change history."
} ,
{
"title": "Get Batch Change",
"url": "/api/get-batchchange.html",
"content": "Get Batch Change Retrieves a batch change given the batch change ID. Only the user who created a batch change and VinylDNS administrators will have access to get it. HTTP REQUEST GET /zones/batchrecordchanges/{id} HTTP REQUEST PARAMS name type required? description id string yes Unique identifier assigned to each created batch change. HTTP RESPONSE TYPES Code description 200 OK - The batch change is returned in response body. 403 Forbidden - The user does not have the access required to perform the action. 404 Not Found - Batch change not found. HTTP RESPONSE ATTRIBUTES name type description userId string The unique identifier of the user that created the batch change. userName string The username of the user that created the batch change. comments string Optional comments about the batch change. createdTimestamp date-time The timestamp (UTC) when the batch change was created. changes Array of SingleChange Array of single changes within a batch change. A SingleChange can either be a SingleAddChange or a SingleDeleteRRSetChange. status BatchChangeStatus Status of the batch change. id string The unique identifier for this batch change. scheduledTime date-time Optional requested date and time to process the batch change. approvalStatus BatchChangeApprovalStatus Approval status of the batch change. reviewerId string Optional identifier of reviewer if batch change required manual review reviewComment string Optional comment by reviewer if batch change required manual review reviewTimestamp date-time Optional timestamp (UTC) when the batch change was reviewed if manual review was required. cancelledTimestamp date-time Optional timestamp (UTC) if the batch change was cancelled by the creator EXAMPLE RESPONSE { \"userId\": \"vinyl\", \"userName\": \"vinyl201\", \"comments\": \"this is optional\", \"createdTimestamp\": \"2018-05-09T14:19:34Z\", \"changes\": [ { \"changeType\": \"Add\", \"inputName\": \"parent.com.\", \"type\": \"A\", \"ttl\": 200, \"record\": { \"address\": \"4.5.6.7\" }, \"status\": \"Pending\", \"recordName\": \"parent.com.\", \"zoneName\": \"parent.com.\", \"zoneId\": \"74e93bfc-7296-4b86-83d3-1ffcb0eb3d13\", \"recordChangeId\": \"a07299ce-5f81-11e8-9c2d-fa7ae01bbebc\", \"recordSetId\": \"a0729f00-5f81-11e8-9c2d-fa7ae01bbebc\", \"id\": \"7573ca11-3e30-45a8-9ba5-791f7d6ae7a7\" }, { \"changeType\": \"DeleteRecordSet\", \"inputName\": \"deleting.parent.com.\", \"type\": \"CNAME\", \"status\": \"Pending\", \"recordName\": \"deleting\", \"zoneName\": \"parent.com.\", \"zoneId\": \"74e93bfc-7296-4b86-83d3-1ffcb0eb3d13\", \"recordChangeId\": \"bed15986-5f82-11e8-9c2d-fa7ae01bbebc\", \"recordSetId\": \"c089e52c-5f82-11e8-9c2d-fa7ae01bbebc\", \"id\": \"7573ca11-3e30-45a8-9ba5-791f7d6ae7a7\" } ], \"status\": \"PendingProcessing\", \"id\": \"02bd95f4-a32c-443b-82eb-54dbaa55b31a\" }"
} ,
{
"title": "Get Group Change",
"url": "/api/get-group-change.html",
"content": "Get Group Change Retrieves a group change given the group change ID. HTTP REQUEST GET /groups/change/{groupChangeId} HTTP RESPONSE TYPES Code description 200 OK - The group change is returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - The group change was not found HTTP RESPONSE ATTRIBUTES name type description newGroup map The new group as a result of the change. Refer to Membership Model oldGroup map The old group before the change. Refer to Membership Model created string Millisecond timestamp that change was created userId string User Id of user who made the change id string Id of the group change userName string Username of user who made the change groupChangeMessage string The description of the changes made to the group changeType string The type change, either Create, Update, or Delete EXAMPLE RESPONSE { \"newGroup\": { \"id\": \"7f420e07-3043-46f3-97e2-8d1ac47d08db\", \"name\": \"test-group\", \"email\": \"test@test.com\", \"created\": \"2023-09-29T06:37:04Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"d4f47898-7a41-4b0d-ba18-de4788b9f102\" }, { \"id\": \"6c4bfd61-d1c6-426e-8123-6f7c28f89d2d\" } ], \"admins\": [ { \"id\": \"d4f47898-7a41-4b0d-ba18-de4788b9f102\" } ] }, \"changeType\": \"Update\", \"userId\": \"d4f47898-7a41-4b0d-ba18-de4788b9f102\", \"oldGroup\": { \"id\": \"7f420e07-3043-46f3-97e2-8d1ac47d08db\", \"name\": \"test-group\", \"email\": \"test@test.com\", \"created\": \"2023-09-29T06:37:04Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"d4f47898-7a41-4b0d-ba18-de4788b9f102\" } ], \"admins\": [ { \"id\": \"d4f47898-7a41-4b0d-ba18-de4788b9f102\" } ] }, \"id\": \"a3227632-a166-407e-8a74-c0624d967b58\", \"created\": \"2023-09-29T06:37:12.061Z\", \"userName\": \"testuser\", \"groupChangeMessage\": \"Group member/s with user name/s 'hermes' added.\" }"
} ,
{
"title": "Get Group",
"url": "/api/get-group.html",
"content": "Get Group Gets a group that you are a part of. HTTP REQUEST GET /groups/{groupId} HTTP RESPONSE TYPES Code description 200 OK - The group is returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 404 Not Found - The group was not found HTTP RESPONSE ATTRIBUTES name type description id string Unique UUID of the group name map The name of the group email string The email distribution list of the group description string The group description, the group may not have this field if it was not set created string The timestamp (UTC) the group was created status string Active or Deleted members Array of User Id objects Ids of members of the group including admins admins Array of User Id objects Ids of admins of the group EXAMPLE RESPONSE { \"id\": \"6f8afcda-7529-4cad-9f2d-76903f4b1aca\", \"name\": \"some-group\", \"email\": \"test@example.com\", \"created\": \"2017-03-02T15:29:21Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" }, { \"id\": \"c8630ebc-0af2-4c9a-a0a0-d18c590ed03e\" } ], \"admins\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ] }"
} ,
{
"title": "Get RecordSet Change History",
"url": "/api/get-recordset-change-history.html",
"content": "Get RecordSet Change History Gets the history of all the changes that has been made to a recordset HTTP REQUEST GET /recordsetchange/history?zoneId={zoneId}&fqdn={recordsetFqdn}&recordType={recordsetType}&startFrom={response.nextId}&maxItems={1 - 100} HTTP REQUEST PARAMS name type required? description zoneId string yes The id of the zone where the recordset is present fqdn string yes The fqdn of the recordset whose history will be returned recordType string yes The record type of the recordset startFrom int no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems int no The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 OK - The record set change history is returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - The history for provided recordset was not found HTTP RESPONSE ATTRIBUTES name type description zoneId string The id of the zone where the recordset is present recordSetChanges array of recordset changes Array of recordset changes sorted by created time in descending order startFrom int (optional) The startFrom parameter that was sent in on the HTTP request. Will not be present if the startFrom parameter was not sent nextId int (optional) The identifier to be passed in as the startFrom parameter to retrieve the next page of results. If there are no results left, this field will not be present maxItems int The maxItems parameter that was sent in on the HTTP request. This will be 100 if not sent EXAMPLE RESPONSE { \"zoneId\": \"56b03014-7f68-4a9b-b5b6-c0e6a212992d\", \"recordSetChanges\": [ { \"zone\": { \"name\": \"ok.\", \"email\": \"test@test.com\", \"status\": \"Active\", \"created\": \"2023-09-27T07:41:12Z\", \"id\": \"56b03014-7f68-4a9b-b5b6-c0e6a212992d\", \"account\": \"system\", \"shared\": false, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"7e56dfdf-df1b-4a39-a3e1-2977db13a1fd\", \"latestSync\": \"2023-09-27T07:41:13Z\", \"isTest\": false }, \"recordSet\": { \"type\": \"A\", \"zoneId\": \"56b03014-7f68-4a9b-b5b6-c0e6a212992d\", \"name\": \"ok.\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2023-09-27T07:41:28Z\", \"updated\": \"2023-09-27T07:41:28Z\", \"records\": [ { \"address\": \"5.5.5.6\" } ], \"id\": \"cda5f6e1-b103-41ad-af7d-013a4379c591\", \"account\": \"system\" }, \"userId\": \"83bd9eda-145d-4799-98fb-20d0bf1ed1e1\", \"changeType\": \"Update\", \"status\": \"Complete\", \"created\": \"2023-09-27T07:41:28Z\", \"updates\": { \"type\": \"A\", \"zoneId\": \"56b03014-7f68-4a9b-b5b6-c0e6a212992d\", \"name\": \"ok.\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2023-09-27T07:41:13Z\", \"records\": [ { \"address\": \"5.5.5.5\" } ], \"id\": \"cda5f6e1-b103-41ad-af7d-013a4379c591\", \"account\": \"system\" }, \"id\": \"55994cb7-9dcb-41ff-980c-44385d1d2cfa\", \"userName\": \"professor\" }, { \"zone\": { \"name\": \"ok.\", \"email\": \"test@test.com\", \"status\": \"Syncing\", \"created\": \"2023-09-27T07:41:12Z\", \"id\": \"56b03014-7f68-4a9b-b5b6-c0e6a212992d\", \"account\": \"system\", \"shared\": false, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"7e56dfdf-df1b-4a39-a3e1-2977db13a1fd\", \"isTest\": false }, \"recordSet\": { \"type\": \"A\", \"zoneId\": \"56b03014-7f68-4a9b-b5b6-c0e6a212992d\", \"name\": \"ok.\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2023-09-27T07:41:13Z\", \"records\": [ { \"address\": \"5.5.5.5\" } ], \"id\": \"cda5f6e1-b103-41ad-af7d-013a4379c591\", \"account\": \"system\" }, \"userId\": \"83bd9eda-145d-4799-98fb-20d0bf1ed1e1\", \"changeType\": \"Create\", \"status\": \"Complete\", \"created\": \"2023-09-27T07:41:13Z\", \"systemMessage\": \"Change applied via zone sync\", \"id\": \"3575868a-ccde-40ec-aaeb-b33cb8410eaf\", \"userName\": \"professor\" } ], \"maxItems\": 100 }"
} ,
{
"title": "Get RecordSet Change",
"url": "/api/get-recordset-change.html",
"content": "Get RecordSet Change RecordSet changes (Create, Update, Delete) are not immediately applied to the DNS backend; they are queued up for processing. Most changes are applied within a few seconds. When you submit a change for processing, the response is a Change model. You can use the information in that change model in order to poll for the status of the change until it completes (status = Complete) or fails (status = Failed). HTTP REQUEST GET /zones/{zoneId}/recordsets/{recordSetId}/changes/{recordChangeId} HTTP RESPONSE TYPES Code description 200 OK - The record set change is returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - The zone, record set, or change was not found HTTP RESPONSE ATTRIBUTES name type description zone map Contains information about the zone when the change was created recordSet map Contains the recordset model userId string The user ID that initiated the change changeType string Type of change requested (Create, Update, or Delete) created string The timestamp (UTC) the change was initiated id string The ID of the change. This is not the ID of the recordset status RecordSetChangeStatus The status of the change (Pending, Complete, or Failed) singleBatchChangeIds array of SingleBatchChange ID objects If the recordset change was part of a batch change, the IDs of the single changes that comprise the recordset change EXAMPLE RESPONSE { \"zone\": { \"name\": \"vinyl.\", \"email\": \"test@test.com\", \"status\": \"Active\", \"created\": \"2017-02-23T14:52:44Z\", \"id\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"shared\": false, \"acl\": { \"rules\": [ ] }, \"adminGroupId\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\" }, \"recordSet\": { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"foo\", \"ttl\": 300, \"status\": \"Pending\", \"created\": \"2017-02-23T14:58:54Z\", \"records\": [ { \"address\": \"10.10.10.10\" } ], \"id\": \"9a41b99c-8e67-445f-bcf3-f9c7cd1f2357\", \"account\": \"0215d410-9b7e-4636-89fd-b6b948a06347\" }, \"userId\": \"0215d410-9b7e-4636-89fd-b6b948a06347\", \"changeType\": \"Create\", \"status\": \"Pending\", \"created\": \"2017-02-23T14:58:54Z\", \"id\": \"fef81f0b-f439-462d-88df-c773d3686c9b\", \"singleBatchChangeIds\": [] }"
} ,
{
"title": "Get RecordSet Count",
"url": "/api/get-recordset-count.html",
"content": "Get RecordSet Count Gets the count of total recordsets in a specified zone. HTTP REQUEST GET /zones/{zoneId}/recordsetcount HTTP RESPONSE TYPES Code description 200 OK - The total record set count in a zone is returned 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - The zone with the id specified was not found HTTP RESPONSE ATTRIBUTES name type description count integer Total count of recordsets in a zone EXAMPLE RESPONSE { \"count\": 10 }"
} ,
{
"title": "Get RecordSet",
"url": "/api/get-recordset.html",
"content": "Get RecordSet Gets a RecordSet in a specified zone. HTTP REQUEST GET /zones/{zoneId}/recordsets/{recordSetId} HTTP RESPONSE TYPES Code description 200 OK - The record set is returned 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - The zone with the id specified was not found, or the record set with id was not found HTTP RESPONSE ATTRIBUTES The returned json object has all the fields from the RecordSet as well as an added accessLevel field name type description type string Type of record set zoneId string The zone the record is stored in name string The name of the record set ttl integer The TTL of the record set in seconds status string The status of the record set created string The timestamp (UTC) the change was initiated updated string The timestamp (UTC) the change was last updated records array of record data Array of record data objects id string The unique ID of the record set account string DEPRECATED the ID of the account that created the record set accessLevel string accessLevel that user has to record set based off acl rules and whether or not user is in Zone Admin Group ownerGroupId string Record ownership assignment, if found, applicable if the recordset is in a shared zone ownerGroupName string Name of assigned owner group, if found EXAMPLE RESPONSE { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"already-exists\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:41Z\", \"updated\": \"2017-02-23T15:12:41Z\", \"records\": [ { \"address\": \"6.6.6.1\" } ], \"id\": \"dd9c1120-0594-4e61-982e-8ddcbc8b2d21\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"accessLevel\": \"Delete\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\", \"ownerGroupName\": \"Shared Group\" }"
} ,
{
"title": "Get User",
"url": "/api/get-user.html",
"content": "Get User Gets a user corresponding to the given identifier (user ID or username). HTTP REQUEST GET /users/{userIdentifier} HTTP RESPONSE TYPES Code description 200 OK - The user is returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 404 Not Found - The user was not found HTTP RESPONSE ATTRIBUTES name type description id string Unique UUID of the user userName string The username of the user groupId Array of groupIds The Group IDs of the user EXAMPLE RESPONSE { \"id\": \"ok\", \"userName\": \"ok\", \"groupId\" : [ { \"id\": \"ok-group\" } ] }"
} ,
{
"title": "Get Valid Email Domains",
"url": "/api/get-valid-email-domains.html",
"content": "Get Valid Email Domains Gets a list of valid email domains which are allowed while entering groups and zones email. HTTP REQUEST GET groups/valid/domains HTTP RESPONSE TYPES Code description 200 OK - The valid email domains are returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 404 Not Found - The valid email domains are not found HTTP RESPONSE ATTRIBUTES type description     Array of string The list of all valid email domains EXAMPLE RESPONSE [ \"gmail.com\", \"test.com\" ]"
} ,
{
"title": "Get Zone by ID",
"url": "/api/get-zone-by-id.html",
"content": "Get Zone by ID Retrieves a zone with the matching zone ID. HTTP REQUEST GET /zones/{zoneId} HTTP RESPONSE TYPES Code description 200 OK - Successful lookup, the zone is returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone not found HTTP RESPONSE ATTRIBUTES name type description zone map Refer to zone model EXAMPLE RESPONSE { \"zone\": { \"status\": \"Active\", \"account\": \"6baa85ad-267f-44ff-b535-818b7d7a2467\", \"name\": \"system-test.\", \"created\": \"2016-12-28T18:12:09Z\", \"adminGroupId\": \"6baa85ad-267f-44ff-b535-818b7d7a2467\", \"email\": \"test@example.com\", \"connection\": { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"system-test.\", \"key\": \"OBF:1:B2cetOaRf1YAABAAek/w22XyKAleCRjA/hZO9fkNtNufPIRWTYHXviAk9GjrfcFOG9nNuB==\" }, \"transferConnection\": { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"system-test.\", \"key\": \"OBF:1:PNt2k1nYkC0AABAAePpNMrDp+4C4GDbicWWlAqB5c4mKoKhvfpiWY1PfuRCVzSAeXydztB==\" }, \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"0f2fcece-b4ee-4982-b671-e5946f7db81d\", \"latestSync\": \"2016-12-16T15:27:26Z\" } }"
} ,
{
"title": "Get Zone by Name",
"url": "/api/get-zone-by-name.html",
"content": "Get Zone by Name Retrieves a zone with the matching zone name. HTTP REQUEST GET /zones/name/{zoneName} HTTP RESPONSE TYPES Code description 200 OK - Successful lookup, the zone is returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone not found HTTP RESPONSE ATTRIBUTES name type description zone map Refer to zone model EXAMPLE RESPONSE { \"zone\": { \"status\": \"Active\", \"account\": \"6baa85ad-267f-44ff-b535-818b7d7a2467\", \"name\": \"system-test.\", \"created\": \"2016-12-28T18:12:09Z\", \"adminGroupId\": \"6baa85ad-267f-44ff-b535-818b7d7a2467\", \"email\": \"test@example.com\", \"connection\": { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"system-test.\", \"key\": \"OBF:1:B2cetOaRf1YAABAAek/w22XyKAleCRjA/hZO9fkNtNufPIRWTYHXviAk9GjrfcFOG9nNuB==\" }, \"transferConnection\": { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"system-test.\", \"key\": \"OBF:1:PNt2k1nYkC0AABAAePpNMrDp+4C4GDbicWWlAqB5c4mKoKhvfpiWY1PfuRCVzSAeXydztB==\" }, \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"0f2fcece-b4ee-4982-b671-e5946f7db81d\", \"latestSync\": \"2016-12-16T15:27:26Z\" } }"
} ,
{
"title": "Getting Help",
"url": "/getting-help.html",
"content": "Getting Help VinylDNS Discussions: https://github.com/vinyldns/vinyldns/discussions"
} ,
{
"title": "Groups",
"url": "/portal/groups.html",
"content": "Groups Groups are the primary way users are granted access to zones. Users can create groups for two purposes in VinylDNS: to be the zone admin group for a zone or to be assigned more limited access via ACL rules. Every zone in VinylDNS must have a zone admin group assigned. VinylDNS does not currently integrate with any services to generate pre-defined zone admin groups. Create a group Manage membership"
} ,
{
"title": "Portal Guide",
"url": "/portal/",
"content": "Portal Guide The VinylDNS portal is the primary user interface for interacting with VinylDNS. Users can retrieve their credentials and manage zones, records, and user groups. This guide covers the functionality of the portal. Navigating the Portal User Menu The User Menu is located in the top right corner of the portal and accessed by selecting your username. It contains a Logout link to sign out of the portal and the Download Credentials link. Credentials In order to use tooling to access VinylDNS, all users must download their credentials from the VinylDNS portal. Learn more Zones The Zones section of the portal is for managing DNS zones and records. This area also includes more granular management of user abilities. To access Zones in the portal select the Zones link in the left column navigation. Access to individual zones in this part of the portal is limited to zone administrators and users with explicit permissions. Learn More Groups The Groups section of the portal is for managing high level user access and abilities. To access Groups in the portal select the Groups link in the left column navigation. Learn More DNS Changes The DNS Changes section of the portal allows users to implement multiple record changes simultaneously and across different zones. To access DNS Changes in the portal select the DNS Changes link in the left column navigation. Learn More"
} ,
{
"title": "API documentation",
"url": "/api/",
"content": "API documentation Authentication Zone RecordSet Batch Change Membership"
} ,
{
"title": "Operator Guide",
"url": "/operator/",
"content": "Operator Guide This operator guide will help administrators install and operate VinylDNS API and Portal. Setup the pre-requisite systems - VinylDNS has several external dependencies that are required in order to operate. Setup the VinylDNS API server Setup the VinylDNS Portal server"
} ,
{
"title": "Home",
"url": "/",
"content": "Welcome VinylDNS is a vendor agnostic front-end for enabling self-service DNS and streamlining DNS operations. It is designed to integrate with your existing DNS infrastructure, and provides extensibility to fit your installation. VinylDNS manages millions of DNS records supporting thousands of engineers in production at Comcast. The platform provides fine-grained access controls, auditing of changes, a self-service user interface, secure RESTful API, and integration with infrastructure automation tools like Ansible and Terraform. VinylDNS helps secure DNS management via: AWS Sig4 signing of all messages to ensure that the message that was sent was not altered in transit Throttling of DNS updates to rate limit concurrent updates against your DNS systems Encrypting user secrets and TSIG keys at rest and in-transit Recording every change made to DNS records and zones Integration is simple with first-class language support including: Java JavaScript Python Go"
} ,
{
"title": "List Batch Changes",
"url": "/api/list-batchchanges.html",
"content": "List Batch Changes Retrieves the most recent 100 batch changes created by the user. This call will return a subset of the full information in each change, as detailed in the attributes section. The max number of batch changes that are returned from a single request has been set to 100. HTTP REQUEST GET zones/batchrecordchanges?startFrom={response.nextId}&maxItems={1-100}&ignoreAccess={true | false}&approvalStatus={batchChangeApprovalStatus}&userName={submitterUserName}&dateTimeRangeStart={dateTimeRangeStart}&dateTimeRangeEnd={dateTimeRangeEnd} HTTP REQUEST PARAMS name type required? description startFrom int no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results. maxItems int no The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided. ignoreAccess boolean no Flag determining whether to retrieve only batch changes made by calling user or to retrieve all changes. Only affects system administrators (ie. support and super users). Defaults to false if not provided. approvalStatus BatchChangeApprovalStatus no Filter batch changes based on approval status. Can be one of AutoApproved, PendingReview, ManuallyApproved, Rejected, or Cancelled. userName string no Filter batch changes based on submitter user name dateTimeRangeStart string no Start date time value to filter batch changes based on date time range dateTimeRangeEnd string no End date time value to filter batch changes based on date time range HTTP RESPONSE TYPES Code description 200 OK - the batch change is returned in response body. 403 Forbidden - the user does not have the access required to perform the action. If there are no batch changes created by the user, a successful empty response body is returned. HTTP RESPONSE ATTRIBUTES name type description batchChanges Array of BatchChangeSummary Summary information for the most recent 100 batch changes created by the user. startFrom int startFrom sent in request, will not be returned if not provided. nextId int startFrom parameter of next page request, will not be returned if record sets are exhausted. maxItems integer maxItems sent in request, default is 100. ignoreAccess boolean ignoreAccess sent in request, default is false. approvalStatus BatchChangeApprovalStatus approvalStatus sent in request, will not be returned if not provided. userName string userName sent in request, will not be returned if not provided. dateTimeRangeStart string dateTimeRangeStart sent in request, will not be returned if not provided. dateTimeRangeEnd string dateTimeRangeEnd sent in request, will not be returned if not provided. BatchChangeSummary name type description userId string The unique identifier of the user that created the batch change. userName string The username of the user that created the batch change. comments string Conditional: comments about the batch change, if provided. createdTimestamp date-time The timestamp (UTC) when the batch change was created. totalChanges int The total number of single changes within the batch change. status BatchChangeStatus Status of the batch change. id string The unique identifier for this batch change. ownerGroupName string Conditional: Record ownership assignment, if provided. approvalStatus BatchChangeApprovalStatus Whether the batch change is currently awaiting manual review. Can be one of AutoApproved, PendingReview, ManuallyApproved, Rejected, or Cancelled. EXAMPLE RESPONSE { \"batchChanges\": [ { \"userId\": \"vinyl\", \"userName\": \"vinyl201\", \"comments\": \"this is optional\", \"createdTimestamp\": \"2018-05-11T18:12:13Z\", \"totalChanges\": 5, \"status\": \"Complete\", \"id\": \"bd03175c-6fd7-419e-991c-3d5d1441d995\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\", \"ownerGroupName\": \"some owner group name\", \"approvalStatus\": \"AutoApproved\" }, { \"userId\": \"vinyl\", \"userName\": \"vinyl201\", \"comments\": \"this is optional\", \"createdTimestamp\": \"2018-05-11T18:12:12Z\", \"totalChanges\": 10, \"status\": \"Complete\", \"id\": \"743cbd16-5440-4cf7-bca9-20319df9b651\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\", \"ownerGroupName\": \"some owner group name\", \"approvalStatus\": \"ManuallyApproved\" }, { \"userId\": \"vinyl\", \"userName\": \"vinyl201\", \"comments\": \"this is optional\", \"createdTimestamp\": \"2018-05-11T18:12:12Z\", \"totalChanges\": 7, \"status\": \"Complete\", \"id\": \"2b827a33-7c4f-4623-8dd9-277c6fba0e54\", \"approvalStatus\": \"Rejected\", \"reviewerId\": \"270ba4b3-f5eb-4043-a283-1a6cec0993f3\", \"reviewerName\": \"some reviewer\", \"reviewTimestamp\": \"2018-05-13T13:12:10Z\" } ], \"maxItems\": 100, \"ignoreAccess\": false }"
} ,
{
"title": "List Abandoned Zones",
"url": "/api/list-deleted-zones.html",
"content": "List Abandoned Zones Retrieves the list of deleted zones a user has access to. The zone name is only sorted alphabetically. HTTP REQUEST GET /zones/deleted/changes?nameFilter={yoursearchhere}&startFrom={response.nextId}&maxItems={1 - 100}&ignoreAccess={true false} HTTP REQUEST PARAMS name type required? description nameFilter string no Characters that are part of the deleted zone name to search for. The wildcard character * is supported, for example www*. Omit the wildcard character when searching for an exact deleted zone name. startFrom any no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems int no The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided. ignoreAccess boolean no If false, returns only zones the requesting user owns or has ACL access to. If true, returns zones in the system, regardless of ownership. Defaults to false if not provided. HTTP RESPONSE TYPES Code description 200 OK - The deleted zones and search info are returned in response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action HTTP RESPONSE ATTRIBUTES name type description zonesDeletedInfo Array of Deleted Zones An array of the deleted zones found. The zones are sorted alphabetically by zone name. startFrom string (optional) The startFrom parameter that was sent in on the HTTP request. Will not be present if the startFrom parameter was not sent nextId any (optional) The identifier to be passed in as the startFrom parameter to retrieve the next page of results. If there are no results left, this field will not be present. maxItems int The maxItems parameter that was sent in the HTTP request. This will be 100 if not sent. ignoreAccess boolean The ignoreAccess parameter that was sent in the HTTP request. This will be false if not sent. EXAMPLE RESPONSE { \"zonesDeletedInfo\": [ { \"zoneChange\": { \"zone\": { \"name\": \"dummy.\", \"email\": \"test@test.com\", \"status\": \"Deleted\", \"created\": \"2023-09-26T09:32:08Z\", \"updated\": \"2023-09-26T09:32:24Z\", \"id\": \"01975877-ff13-4605-a940-533b87718726\", \"account\": \"system\", \"shared\": false, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"7d034091-d14f-40fa-a42f-5264a71fe6af\", \"latestSync\": \"2023-09-26T09:32:08Z\", \"isTest\": false }, \"userId\": \"4b2f14fc-d57a-4ea3-88ee-602d5cfb533c\", \"changeType\": \"Delete\", \"status\": \"Synced\", \"created\": \"2023-09-26T09:32:24Z\", \"id\": \"ff28aa95-0b35-469e-8fef-e2fb97b9e247\" }, \"adminGroupName\": \"duGroup\", \"userName\": \"professor\", \"accessLevel\": \"NoAccess\" }, { \"zoneChange\": { \"zone\": { \"name\": \"ok.\", \"email\": \"test@test.com\", \"status\": \"Deleted\", \"created\": \"2023-09-25T14:16:56Z\", \"updated\": \"2023-09-26T09:19:27Z\", \"id\": \"96b85fed-61d4-41bf-ac81-fdbfe3d1c037\", \"account\": \"system\", \"shared\": false, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"1f938110-cd0d-4670-8c64-5f53f1cce2f1\", \"latestSync\": \"2023-09-25T14:16:57Z\", \"isTest\": false }, \"userId\": \"8628a36b-9302-41d1-bd0a-7610cc964086\", \"changeType\": \"Delete\", \"status\": \"Synced\", \"created\": \"2023-09-26T09:19:27Z\", \"id\": \"8925f690-4586-465d-8309-c3d4ca6dd420\" }, \"adminGroupName\": \"name\", \"userName\": \"fry\", \"accessLevel\": \"Delete\" } ], \"maxItems\": 100, \"ignoreAccess\": true }"
} ,
{
"title": "List Group Activity",
"url": "/api/list-group-activity.html",
"content": "List Group Activity Retrieves a list of group activity. HTTP REQUEST GET /groups/{groupId}/activity?startFrom={response.nextId}&maxItems={1 - 100} HTTP REQUEST PARAMS name type required? description startFrom integer no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems integer no The number of items to return in the page. Valid values are 1 to 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 OK - The changes have been returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 404 Not Found - The group was not found HTTP RESPONSE ATTRIBUTES name type description changes Array of Group Changes refer to Group Change startFrom integer startFrom sent in request, will not be returned if not provided nextId integer nextId, used as startFrom parameter of next page request, will not be returned if activity is exhausted maxItems integer maxItems sent in request, default is 100 GROUP CHANGE ATTRIBUTES name type description newGroup map The new group as a result of the change. Refer to Membership Model oldGroup map The old group before the change. Refer to Membership Model created string Millisecond timestamp that change was created userId string User Id of user who made the change id string Id of the group change userName string Username of user who made the change groupChangeMessage string The description of the changes made to the group changeType string The type change, either Create, Update, or Delete EXAMPLE RESPONSE { \"changes\": [ { \"newGroup\": { \"id\": \"6edb08fe-8179-4e18-aa08-2acc1785c364\", \"name\": \"test-group\", \"email\": \"test@test.com\", \"created\": \"2024-02-22T07:32:51Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"6a8545e7-cbab-47c9-8aa2-c56e413c44b6\" }, { \"id\": \"6c83a035-cc1b-4d94-acd6-bb2da351edca\" }, { \"id\": \"864f7002-e48e-451c-9909-50567ecdc1a5\" } ], \"admins\": [ { \"id\": \"6a8545e7-cbab-47c9-8aa2-c56e413c44b6\" } ] }, \"changeType\": \"Update\", \"userId\": \"6a8545e7-cbab-47c9-8aa2-c56e413c44b6\", \"oldGroup\": { \"id\": \"6edb08fe-8179-4e18-aa08-2acc1785c364\", \"name\": \"test-group\", \"email\": \"test@test.com\", \"created\": \"2024-02-22T07:32:51Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"6a8545e7-cbab-47c9-8aa2-c56e413c44b6\" }, { \"id\": \"6c83a035-cc1b-4d94-acd6-bb2da351edca\" }, { \"id\": \"864f7002-e48e-451c-9909-50567ecdc1a5\" } ], \"admins\": [ { \"id\": \"6a8545e7-cbab-47c9-8aa2-c56e413c44b6\" }, { \"id\": \"6c83a035-cc1b-4d94-acd6-bb2da351edca\" } ] }, \"id\": \"1c1151e9-099f-4cb8-aa24-bf43d21e5fd5\", \"created\": \"2024-02-22T07:33:09.262Z\", \"userName\": \"professor\", \"groupChangeMessage\": \"Group admin/s with user name/s 'fry' removed.\" } ], \"startFrom\": 1, \"nextId\": 2, \"maxItems\": 1 }"
} ,
{
"title": "List Group Admins",
"url": "/api/list-group-admins.html",
"content": "List Group Admins Retrieves a groups admins. HTTP REQUEST GET /groups/{groupId}/admins HTTP RESPONSE TYPES Code description 200 OK - The admins have been returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 404 Not Found - The group was not found HTTP RESPONSE ATTRIBUTES name type description admins Array of Users Refer to membership model EXAMPLE RESPONSE { \"admins\": [ { \"userName\": \"jdoe201\", \"firstName\": \"john\", \"created\": \"2017-03-02T16:39:02Z\", \"lastName\": \"doe\", \"email\": \"john_doe@example.com\", \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" }, { \"userName\": \"jdoe202\", \"firstName\": \"jane\", \"created\": \"2017-03-02T16:50:02Z\", \"lastName\": \"doe\", \"email\": \"jane_doe@example.com\", \"id\": \"1764183c-5e75-4ae6-8833-503cd5f4dcb4\" } ] }"
} ,
{
"title": "List Group Members",
"url": "/api/list-group-members.html",
"content": "List Group Members Retrieves a list of group members. HTTP REQUEST GET /groups/{groupId}/members?startFrom={response.nextId}&maxItems={1 - 100} HTTP REQUEST PARAMS name type required? description startFrom string no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems integer no The number of items to return in the page. Valid values are 1 to 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 OK - The members have been returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 404 Not Found - The group was not found HTTP RESPONSE ATTRIBUTES name type description members Array of Users refer to membership model, these Users will also include an isAdmin attribute startFrom string startFrom sent in request, will not be returned if not provided nextId string nextId, used as startFrom parameter of next page request, will not be returned if members are exhausted maxItems integer maxItems sent in request, default is 100 EXAMPLE RESPONSE { \"members\": [ { \"id\": \"0b1acc37-7d97-4da7-8a28-f1770bb99643\", \"userName\": \"jdoe201\", \"firstName\": \"John\", \"lastName\": \"Doe\", \"email\": \"John_Doe@example.com\", \"created\": \"2017-03-02T18:42:31Z\", \"isAdmin\": true }, { \"id\": \"0cb85121-671a-4920-ab02-0c17a7b40874\", \"userName\": \"bwayne300\", \"firstName\": \"Bruce\", \"lastName\": \"Wayne\", \"email\": \"Bruce_Wayne@cable.example.com\", \"created\": \"2017-03-02T18:42:54Z\", \"isAdmin\": false } ], \"maxItems\": 100 }"
} ,
{
"title": "List Groups",
"url": "/api/list-groups.html",
"content": "List Groups Retrieves a list of groups that you are a part of. HTTP REQUEST GET /groups?startFrom={response.nextId}&maxItems={1 - 100}&groupNameFilter={filter}&ignoreAccess={true | false}&abridged={true | false} HTTP REQUEST PARAMS name type required? description groupNameFilter string no One or more characters contained in the name of the group set to search for. For example TP. This is a contains search only, no wildcards or regular expressions are supported startFrom string no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems integer no The number of items to return in the page. Valid values are 1 to 100. Defaults to 100 if not provided. ignoreAccess boolean no If false, returns only groups the requesting user is a member of. If true, returns groups in the system, regardless of membership. Defaults to false if not provided. Super and support admin see all groups regardless of this value. abridged boolean no If false, returns all the group details. If true, returns an abridged version of group details. Defaults to false if not provided. HTTP RESPONSE TYPES Code description 200 OK - The groups have been returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect HTTP RESPONSE ATTRIBUTES name type description groups Array of Groups refer to membership model groupNameFilter string name filter sent in request startFrom string startFrom sent in request, will not be returned if not provided nextId string nextId, used as startFrom parameter of next page request, will not be returned if groups are exhausted maxItems integer maxItems sent in request, default is 100 ignoreAccess boolean The ignoreAccess parameter that was sent in the HTTP request. This will be false if not sent. EXAMPLE RESPONSE { \"maxItems\": 100, \"groups\": [ { \"id\": \"93887728-2b26-4749-ba69-98871dda9cc0\", \"name\": \"some-other-group\", \"email\": \"test@example.com\", \"created\": \"2017-03-02T16:23:07Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ], \"admins\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ] }, { \"id\": \"aa1ea217-70a7-4350-b22b-c7e2f2158fb9\", \"name\": \"some-group\", \"email\": \"test@example.com\", \"created\": \"2017-03-02T16:22:57Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ], \"admins\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ] } ], \"ignoreAccess\": false }"
} ,
{
"title": "List RecordSet Change Failures",
"url": "/api/list-recordset-change-failures.html",
"content": "List Recordset Change Failures Retrieves a list of RecordSet changes that failed in a zone. HTTP REQUEST GET metrics/health/zones/{zoneId}/recordsetchangesfailure?startFrom={response.nextId}&maxItems={1 - 100} HTTP REQUEST PARAMS name type required? description startFrom int no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems int no The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 OK - the list of failed recordset changes are returned in response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone not found HTTP RESPONSE ATTRIBUTES name type description failedRecordSetChanges array of failed recordset changes array of recordset changes sorted by created time in descending order startFrom int (optional) The startFrom parameter that was sent in on the HTTP request. Will not be present if the startFrom parameter was not sent nextId int (optional) The identifier to be passed in as the startFrom parameter to retrieve the next page of results. If there are no results left, this field will not be present maxItems int The maxItems parameter that was sent in on the HTTP request. This will be 100 if not sent EXAMPLE RESPONSE { \"failedRecordSetChanges\": [ { \"zone\": { \"name\": \"ok.\", \"email\": \"test@test.com\", \"status\": \"Active\", \"created\": \"2020-11-17T18:50:46Z\", \"updated\": \"2023-09-28T13:51:30Z\", \"id\": \"fbf7a440-891c-441a-ad09-e1cbc861fda1\", \"account\": \"system\", \"shared\": true, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"7611734a-8409-4827-9e8b-960d115b9f9c\", \"scheduleRequestor\": \"testuser\", \"latestSync\": \"2023-09-28T13:51:30Z\", \"isTest\": true, \"backendId\": \"func-test-backend\" }, \"recordSet\": { \"type\": \"DS\", \"zoneId\": \"fbf7a440-891c-441a-ad09-e1cbc861fda1\", \"name\": \"ns-test-2\", \"ttl\": 7200, \"status\": \"Inactive\", \"created\": \"2023-09-28T16:44:47Z\", \"updated\": \"2023-09-28T16:44:47Z\", \"records\": [ { \"keytag\": 1, \"algorithm\": 3, \"digesttype\": 1, \"digest\": \"01\" } ], \"id\": \"a40de44e-1b13-4cfe-9485-79749bd360fa\", \"account\": \"system\", \"ownerGroupId\": \"7611734a-8409-4827-9e8b-960d115b9f9c\" }, \"userId\": \"6741d4df-81b7-40bd-9856-896c730c189b\", \"changeType\": \"Create\", \"status\": \"Failed\", \"created\": \"2023-09-28T16:44:47Z\", \"systemMessage\": \"Failed applying update to DNS for change 8094c9a9-d279-4847-81f4-de08f2454ff1:ns-test-2: Format Error: the server was unable to interpret the query: ;; ->>HEADER<<- opcode: UPDATE, status: FORMERR, id: 41792\\n;; flags: qr ; qd: 1 an: 0 au: 0 ad: 0 \\n;; TSIG invalid\\n;; ZONE:\\n;;\\tok., type = SOA, class = IN\\n\\n;; PREREQUISITES:\\n\\n;; UPDATE RECORDS:\\n\\n;; ADDITIONAL RECORDS:\\n\\n;; Message size: 20 bytes\", \"id\": \"8094c9a9-d279-4847-81f4-de08f2454ff1\", \"singleBatchChangeIds\": [] } ], \"nextId\": 0, \"startFrom\": 0, \"maxItems\": 100 }"
} ,
{
"title": "List RecordSet Changes",
"url": "/api/list-recordset-changes.html",
"content": "List RecordSet Changes RecordSet changes (Create, Update, Delete) are not immediately applied to the DNS backend; they are queued up for processing. Most changes are applied within a few seconds. When you submit a change for processing, the response is a Change model. You can use the information in that change model in order to poll for the status of the change until it completes (status = Complete) or fails (status = Failed). Retrieves a list of RecordSet changes in a zone. All RecordSet changes are stored, including those coming from zone syncs. RecordSet changes come in max page sizes of 100 changes, paging must be done independently using startFrom and nextId parameters. HTTP REQUEST GET /zones/{zoneId}/recordsetchanges?startFrom={response.nextId}&maxItems={1 - 100} HTTP REQUEST PARAMS name type required? description startFrom int no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems int no The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 OK - the recordset changes are returned in response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone not found HTTP RESPONSE ATTRIBUTES name type description zoneId string Id of zone used for request recordSetChanges array of recordset changes array of recordset changes sorted by created time in descending order startFrom int (optional) The startFrom parameter that was sent in on the HTTP request. Will not be present if the startFrom parameter was not sent nextId int (optional) The identifier to be passed in as the startFrom parameter to retrieve the next page of results. If there are no results left, this field will not be present maxItems int The maxItems parameter that was sent in on the HTTP request. This will be 100 if not sent status string The status of the change (Pending, Complete, Failed) EXAMPLE RESPONSE { \"recordSetChanges\": [ { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:58Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:58Z\", \"name\": \"test-create-cname-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"cname\": \"changed-cname.\" } ], \"ttl\": 200, \"type\": \"CNAME\", \"id\": \"f62235df-5372-443c-9ba4-bdd3fca452f4\" }, \"changeType\": \"Delete\", \"userId\": \"history-id\", \"updates\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:58Z\", \"name\": \"test-create-cname-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"cname\": \"changed-cname.\" } ], \"ttl\": 200, \"type\": \"CNAME\", \"id\": \"f62235df-5372-443c-9ba4-bdd3fca452f4\" }, \"id\": \"68fd6dbe-0da8-4280-bcf3-37f54528dc41\" }, { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:58Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:58Z\", \"name\": \"test-create-aaaa-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"2003:db8:0:0:0:0:0:4\" }, { \"address\": \"2002:db8:0:0:0:0:0:3\" } ], \"ttl\": 200, \"type\": \"AAAA\", \"id\": \"9559103d-4cb4-4d34-9d3f-eab3fe2e8aed\" }, \"changeType\": \"Delete\", \"userId\": \"history-id\", \"updates\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-aaaa-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"2003:db8:0:0:0:0:0:4\" }, { \"address\": \"2002:db8:0:0:0:0:0:3\" } ], \"ttl\": 200, \"type\": \"AAAA\", \"id\": \"9559103d-4cb4-4d34-9d3f-eab3fe2e8aed\" }, \"id\": \"dabf1e57-49e7-4d2d-8a00-814d88546b0c\" }, { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:58Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:58Z\", \"name\": \"test-create-a-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"9.9.9.9\" }, { \"address\": \"10.2.2.2\" } ], \"ttl\": 200, \"type\": \"A\", \"id\": \"f1fd620e-5ff3-4ee9-839f-bc747a9867d9\" }, \"changeType\": \"Delete\", \"userId\": \"history-id\", \"updates\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-a-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"9.9.9.9\" }, { \"address\": \"10.2.2.2\" } ], \"ttl\": 200, \"type\": \"A\", \"id\": \"f1fd620e-5ff3-4ee9-839f-bc747a9867d9\" }, \"id\": \"23ae1487-bc7f-481b-a544-10ceb7a87540\" }, { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:57Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:58Z\", \"name\": \"test-create-cname-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"cname\": \"changed-cname.\" } ], \"ttl\": 200, \"type\": \"CNAME\", \"id\": \"f62235df-5372-443c-9ba4-bdd3fca452f4\" }, \"changeType\": \"Update\", \"userId\": \"history-id\", \"updates\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-cname-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"cname\": \"cname.\" } ], \"ttl\": 100, \"type\": \"CNAME\", \"id\": \"f62235df-5372-443c-9ba4-bdd3fca452f4\" }, \"id\": \"5c722555-c7be-4620-a1fd-8ca53a5b8683\" }, { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:57Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-aaaa-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"2003:db8:0:0:0:0:0:4\" }, { \"address\": \"2002:db8:0:0:0:0:0:3\" } ], \"ttl\": 200, \"type\": \"AAAA\", \"id\": \"9559103d-4cb4-4d34-9d3f-eab3fe2e8aed\" }, \"changeType\": \"Update\", \"userId\": \"history-id\", \"updates\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-aaaa-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"2001:db8:0:0:0:0:0:3\" }, { \"address\": \"2002:db8:0:0:0:0:0:3\" } ], \"ttl\": 100, \"type\": \"AAAA\", \"id\": \"9559103d-4cb4-4d34-9d3f-eab3fe2e8aed\" }, \"id\": \"480fff34-61d3-4a1d-9696-f5007842b38a\" }, { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:57Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-a-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"9.9.9.9\" }, { \"address\": \"10.2.2.2\" } ], \"ttl\": 200, \"type\": \"A\", \"id\": \"f1fd620e-5ff3-4ee9-839f-bc747a9867d9\" }, \"changeType\": \"Update\", \"userId\": \"history-id\", \"updates\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-a-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"10.1.1.1\" }, { \"address\": \"10.2.2.2\" } ], \"ttl\": 100, \"type\": \"A\", \"id\": \"f1fd620e-5ff3-4ee9-839f-bc747a9867d9\" }, \"id\": \"999d8674-e59b-478e-95c0-9d4eb964f2be\" }, { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"connection\": { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"system-test-history.\", \"key\": \"OBF:1:YVgGogd/Y+oAABAAIp4s3z7FAn92uvfOci9v0jMjihQ+uV3bOCyNwpMPh78tL4q/A8dR7A==\" }, \"transferConnection\": { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"system-test-history.\", \"key\": \"OBF:1:Pq3UqxiceV4AABAAdu90et1pkNn2ZO3MuYstki5BkQVm3T50RQLarpVhIgaoOKLi2CdL6Q==\" }, \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:57Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-cname-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"cname\": \"cname.\" } ], \"ttl\": 100, \"type\": \"CNAME\", \"id\": \"f62235df-5372-443c-9ba4-bdd3fca452f4\" }, \"changeType\": \"Create\", \"userId\": \"history-id\", \"id\": \"b05f0837-84bd-47aa-8a95-7bde91046268\" }, { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:57Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-aaaa-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"2001:db8:0:0:0:0:0:3\" }, { \"address\": \"2002:db8:0:0:0:0:0:3\" } ], \"ttl\": 100, \"type\": \"AAAA\", \"id\": \"9559103d-4cb4-4d34-9d3f-eab3fe2e8aed\" }, \"changeType\": \"Create\", \"userId\": \"history-id\", \"id\": \"e7e6b7f9-5253-4947-9580-3f0b81a48717\" }, { \"status\": \"Complete\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:57Z\", \"recordSet\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"test-create-a-ok\", \"created\": \"2016-12-30T15:37:57Z\", \"account\": \"history-id\", \"zoneId\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\", \"records\": [ { \"address\": \"10.1.1.1\" }, { \"address\": \"10.2.2.2\" } ], \"ttl\": 100, \"type\": \"A\", \"id\": \"f1fd620e-5ff3-4ee9-839f-bc747a9867d9\" }, \"changeType\": \"Create\", \"userId\": \"history-id\", \"id\": \"6743d428-7748-4348-a6c9-ae59e9eeaf97\" } ], \"maxItems\": 100 }"
} ,
{
"title": "List / Search RecordSets",
"url": "/api/list-recordsets-by-zone.html",
"content": "List / Search RecordSets by Zone Retrieves a list of RecordSets from the zone. HTTP REQUEST GET /zones/{zoneId}/recordsets?startFrom={response.nextId}&maxItems={1 - 100}&recordNameFilter={filter} HTTP REQUEST PARAMS name type required? description recordNameFilter string no Characters that are part of the record name to search for. The wildcard character * is supported, for example www*. Omit the wildcard when searching for an exact record name. recordTypeFilter Array of RecordType no An array of record types to filter for listing record sets. Refer to recordset mode for supported types. Invalid record types will be ignored. If left empty or no valid record types are provided, then all record types will be returned. nameSort string no Name sort order for record sets returned by list record set response. Valid values are ASC (ascending; default) and DESC (descending). startFrom string no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems integer no The number of items to return in the page. Valid values are 1 to 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 OK - The record sets are returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone or RecordSet not found HTTP RESPONSE ATTRIBUTES name type description recordSets Array of RecordSets refer to recordset model, the RecordSet data will also include the accessLevel the requesting user has based off acl rules and membership in Zone Admin Group startFrom string startFrom sent in request, will not be returned if not provided nextId string nextId, used as startFrom parameter of next page request, will not be returned if record sets are exhausted maxItems integer maxItems sent in request, default is 100 recordNameFilter string name filter sent in request recordTypeFilter Array of RecordType record type filter sent in request nameSort string name sort order sent in request EXAMPLE RESPONSE { \"recordSets\": [ { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"already-exists\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:41Z\", \"updated\": \"2017-02-23T15:12:41Z\", \"records\": [ { \"address\": \"6.6.6.1\" } ], \"id\": \"dd9c1120-0594-4e61-982e-8ddcbc8b2d21\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"accessLevel\": \"Delete\" }, { \"type\": \"NS\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"vinyl\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:33Z\", \"records\": [ { \"nsdname\": \"172.17.42.2.\" } ], \"id\": \"daf5ea7b-c28c-422a-ba47-2c37ca567a77\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"accessLevel\": \"Delete\" }, { \"type\": \"SOA\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"vinyl\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:33Z\", \"records\": [ { \"mname\": \"172.17.42.2.\", \"rname\": \"admin.test.com.\", \"serial\": 1439234395, \"refresh\": 10800, \"retry\": 3600, \"expire\": 604800, \"minimum\": 38400 } ], \"id\": \"9da83158-05ab-4f14-8bd0-0a4d85cdeb30\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"accessLevel\": \"Delete\" }, { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"vinyl\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:33Z\", \"records\": [ { \"address\": \"5.5.5.5\" } ], \"id\": \"d73275ff-e71e-4024-aef1-1236741443b5\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"accessLevel\": \"Delete\" }, { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"jenkins\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:33Z\", \"records\": [ { \"address\": \"10.1.1.1\" } ], \"id\": \"0432f63b-3947-4262-9ade-a3311d07a099\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"accessLevel\": \"Delete\" }, { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"test\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:33Z\", \"records\": [ { \"address\": \"4.4.4.4\" }, { \"address\": \"3.3.3.3\" } ], \"id\": \"dc0e3ce9-ec01-47f1-9418-461dc1754f48\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"accessLevel\": \"Delete\" } ], \"maxItems\": 100, \"nameSort\": \"ASC\" }"
} ,
{
"title": "Global List / Search RecordSets",
"url": "/api/list-recordsets-global.html",
"content": "Global List / Search RecordSets Retrieves a list of RecordSets globally in the VinylDNS database based on search criteria. A minimum of two alpha-numeric characters is required. HTTP REQUEST GET /recordsets?startFrom={response.nextId}&maxItems={1 - 100}&recordNameFilter={recordNameFilter}&recordTypeFilter={recordTypeFilter}&recordOwnerGroupFilter={recordOwnerGroupFilter}&nameSort={nameSort} HTTP REQUEST PARAMS name type required? description recordNameFilter string yes Characters that are part of the record name to search for. The wildcard character * is supported, for example www*. Omit the wildcard when searching for an exact record name. At least two alphanumeric characters are required for searching. recordTypeFilter Array of RecordType no An array of record types to filter for listing record sets. Refer to recordset mode for supported types. Invalid record types will be ignored. If left empty or no valid record types are provided, then all record types will be returned. recordOwnerGroupFilter string no Owner group ID for record set. nameSort string no Name sort order for record sets returned by list record set response. Valid values are ASC (ascending; default) and DESC (descending). startFrom string no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems integer no The number of items to return in the page. Valid values are 1 to 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 OK - The record sets are returned in the response body 422 Unprocessable Entity - recordNameFilter was either omitted or provided but does not contain at least two alphanumeric characters HTTP RESPONSE ATTRIBUTES name type description recordSets Array of RecordSets refer to recordset model startFrom string startFrom sent in request, will not be returned if not provided nextId string nextId, used as startFrom parameter of next page request, will not be returned if record sets are exhausted maxItems integer maxItems sent in request, default is 100 recordNameFilter string name filter sent in request recordTypeFilter Array of RecordType record type filter sent in request recordOwnerGroupFilter string record owner group sent in request nameSort string name sort order sent in request EXAMPLE RESPONSE { \"recordSets\": [ { \"type\": \"A\", \"zoneId\": \"5f5304ba-c81f-456c-9d33-bb6179c8b1f1\", \"name\": \"foo\", \"ttl\": 7200, \"status\": \"Active\", \"created\": \"2019-04-26T17:15:35Z\", \"records\": [ { \"address\": \"1.1.1.1\" } ], \"id\": \"f802596f-4f0e-4e65-bb43-c7ca439d2608\", \"account\": \"system\", \"fqdn\": \"foo.example.com.\", \"zoneName\": \"example.com.\", \"zoneShared\": true } ], \"maxItems\": 100, \"recordNameFilter\": \"foo*\", \"recordTypeFilter\": [ \"A\" ], \"nameSort\": \"ASC\" }"
} ,
{
"title": "List Zone Change Failures",
"url": "/api/list-zone-change-failures.html",
"content": "List Zone Change Failures Retrieves a list of failed zone changes. HTTP REQUEST GET metrics/health/zonechangesfailure?startFrom={response.nextId}&maxItems={1 - 100} HTTP REQUEST PARAMS name type required? description startFrom int no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems int no The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 Accepted - The zone changes will be returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone not found HTTP RESPONSE ATTRIBUTES name type description failedZoneChanges array of zone changes Array of failed zone changes sorted by created time in descending order. Refer to Zone Change startFrom int (optional) The startFrom parameter that was sent in on the HTTP request. Will not be present if the startFrom parameter was not sent nextId int (optional) The identifier to be passed in as the startFrom parameter to retrieve the next page of results. If there are no results left, this field will not be present maxItems int The maxItems parameter that was sent in on the HTTP request. This will be 100 if not sent ZONE CHANGE ATTRIBUTES name type description zone map Refer to zone model status string The status of the change. Either Pending, Failed or Synced changeType string The type of change. Either Create, Update, Delete, Sync or AutomatedSync systemMessage string (optional) A message regarding the change. Will not be present if the string is empty created string Millisecond timestamp that change was created userId string User Id of user who made the change id string Id of the group change EXAMPLE RESPONSE { \"failedZoneChanges\": [ { \"zone\": { \"name\": \"shared.\", \"email\": \"email\", \"status\": \"Active\", \"created\": \"2022-05-20T16:47:28Z\", \"updated\": \"2022-12-08T20:14:19Z\", \"id\": \"e6efbae3-ae2d-466d-bfa4-207aa276a024\", \"account\": \"system\", \"shared\": true, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"shared-zone-group\", \"isTest\": true }, \"userId\": \"6741d4df-81b7-40bd-9856-896c730c189b\", \"changeType\": \"Sync\", \"status\": \"Failed\", \"created\": \"2022-12-08T20:14:19Z\", \"id\": \"9ce7dc8b-a5ed-488d-82d4-8c7e7cf33285\" }, { \"zone\": { \"name\": \"dummy.\", \"email\": \"test@test.com\", \"status\": \"Active\", \"created\": \"2020-11-17T18:50:46Z\", \"updated\": \"2022-10-17T10:13:46Z\", \"id\": \"d7e433df-ad84-4fbe-9f52-3b2f3665412a\", \"connection\": { \"name\": \"dummy.\", \"keyName\": \"vinyldns.\", \"key\": \"OBF:1:uFOhH4AH8xEAABAAlertajQQHrQZB91yWQz5lyBf4O88js2S6aWNMtAq5MS5Otysb4Z7iiO9DoGY9A6BrDQ52b8SOQyj0QpzgPe0CuI/pLW1s/rulmlvgubHkIl7dsYAaRH7SrmZfNBe4BSn02zuv/ATyWEy\", \"primaryServer\": \"96.115.238.13\", \"algorithm\": \"HMAC-MD5\" }, \"transferConnection\": { \"name\": \"dummy.\", \"keyName\": \"vinyldns.\", \"key\": \"OBF:1:EonJvAJrMwQAABAAO+MPQq6fyNQcjnXUuV6YtvjeCGt8SEicWC6Ke9dLT1UmL4vAtlVg0nARl9rvhb1mxNndSf4ogx+/BvZx2AEvkTgCFxbsPMxJ/s6E/s6uaxa4sf/8+CpnR/1R0oYmfOaMSq04tgD+A+ym\", \"primaryServer\": \"96.115.238.13\", \"algorithm\": \"HMAC-MD5\" }, \"account\": \"system\", \"shared\": false, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"9945e0c5-41dd-42e9-a053-3f4dacf006c3\", \"latestSync\": \"2020-11-17T18:50:46Z\", \"isTest\": true }, \"userId\": \"c1f17f3e-59cc-491d-a1f3-ee3f50f38a09\", \"changeType\": \"Sync\", \"status\": \"Failed\", \"created\": \"2022-10-17T10:13:46Z\", \"id\": \"1cd5876f-b896-4823-86a6-286f21fa6a16\" } ], \"nextId\": 0, \"startFrom\": 0, \"maxItems\": 100 }"
} ,
{
"title": "List Zone Changes",
"url": "/api/list-zone-changes.html",
"content": "List Zone Changes Retrieves a list of zone changes to a zone. All zone changes are stored, including those coming from zone syncs. Zone changes come in max page sizes of 100 changes, paging must be done independently using startFrom and nextId parameters. HTTP REQUEST GET /zones/{zoneId}/changes?startFrom={response.nextId}&maxItems={1 - 100} HTTP REQUEST PARAMS name type required? description startFrom string no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems int no The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided. HTTP RESPONSE TYPES Code description 200 Accepted - The zone changes will be returned in the response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone not found HTTP RESPONSE ATTRIBUTES name type description zoneId string Id of zone used for request zoneChanges array of zone changes Array of zone changes sorted by created time in descending order. Refer to Zone Change startFrom string (optional) The startFrom parameter that was sent in on the HTTP request. Will not be present if the startFrom parameter was not sent nextId string (optional) The identifier to be passed in as the startFrom parameter to retrieve the next page of results. If there are no results left, this field will not be present maxItems int The maxItems parameter that was sent in on the HTTP request. This will be 100 if not sent ZONE CHANGE ATTRIBUTES name type description zone map Refer to zone model status string The status of the change. Either Pending, Failed or Synced changeType string The type of change. Either Create, Update, Delete, Sync or AutomatedSync systemMessage string (optional) A message regarding the change. Will not be present if the string is empty created string Millisecond timestamp that change was created userId string User Id of user who made the change id string Id of the group change EXAMPLE RESPONSE { \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"zoneChanges\": [ { \"status\": \"Synced\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.10.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:57Z\", \"changeType\": \"Update\", \"userId\": \"history-id\", \"id\": \"6d4deccb-4632-475e-9ebc-3f6bace5fe68\" }, { \"status\": \"Synced\", \"zone\": { \"status\": \"Active\", \"updated\": \"2016-12-30T15:37:57Z\", \"name\": \"system-test-history.\", \"adminGroupId\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"created\": \"2016-12-30T15:37:56Z\", \"account\": \"67b4da23-6832-4600-8450-9fa0664caeeb\", \"email\": \"i.changed.this.9.times@history-test.com\", \"shared\": true, \"acl\": { \"rules\": [] }, \"id\": \"9f353bc7-cb8d-491c-b074-34afafc97c5f\" }, \"created\": \"2016-12-30T15:37:57Z\", \"changeType\": \"Update\", \"userId\": \"history-id\", \"id\": \"59c2db90-41aa-49ae-8c56-e13a2ada918d\" } ], \"startFrom\": \"2910234\", \"nextId\": \"1034932\", \"maxItems\": 2 }"
} ,
{
"title": "List / Search Zones",
"url": "/api/list-zones.html",
"content": "List / Search Zone Retrieves the list of zones a user has access to. The zone name is only sorted alphabetically. HTTP REQUEST GET /zones?nameFilter={yoursearchhere}&startFrom={response.nextId}&maxItems={1 - 100}&ignoreAccess={true false}&searchByAdminGroup={true false}&includeReverse={true false} HTTP REQUEST PARAMS name type required? description nameFilter string no Characters that are part of the zone name to search for. The wildcard character * is supported, for example www*. Omit the wildcard character when searching for an exact zone name. startFrom string no In order to advance through pages of results, the startFrom is set to the nextId that is returned on the previous response. It is up to the client to maintain previous pages if the client wishes to advance forward and backward. If not specified, will return the first page of results maxItems int no The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided. ignoreAccess boolean no If false, returns only zones the requesting user owns or has ACL access to. If true, returns zones in the system, regardless of ownership. Defaults to false if not provided. searchByAdminGroup boolean no Used along with nameFilter. If false, returns a list of zones based on nameFilter value. If true, uses nameFilter value and filters the zone based on a group. Returns all the zones that is owned by a group given in the nameFilter. Defaults to false if not provided. includeReverse boolean no If false, returns only the forward zones. If true, returns both forward and reverse zones. HTTP RESPONSE TYPES Code description 200 OK - The zones and search info are returned in response body 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action HTTP RESPONSE ATTRIBUTES name type description zones Array of Zones An array of the zones found. The zones are sorted alphabetically by zone name. startFrom string (optional) The startFrom parameter that was sent in on the HTTP request. Will not be present if the startFrom parameter was not sent nextId string (optional) The identifier to be passed in as the startFrom parameter to retrieve the next page of results. If there are no results left, this field will not be present. maxItems int The maxItems parameter that was sent in the HTTP request. This will be 100 if not sent. ignoreAccess boolean The ignoreAccess parameter that was sent in the HTTP request. This will be false if not sent. searchByAdminGroup boolean The searchByAdminGroup parameter that was sent in the HTTP request. This will be false if not sent. includeReverse boolean The includeReverse parameter that was sent in the HTTP request. This will be false if not sent. EXAMPLE RESPONSE { \"zones\": [ { \"status\": \"Active\", \"account\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"name\": \"list-zones-test-searched-1.\", \"created\": \"2016-12-16T15:21:47Z\", \"adminGroupId\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"email\": \"test@test.com\", \"shared\": false, \"acl\": { \"rules\": [] }, \"id\": \"31a3d8a9-bea0-458f-9c24-3d39d4b929d6\", \"latestSync\": \"2016-12-16T15:27:26Z\", \"accessLevel\": \"NoAccess\" }, { \"status\": \"Active\", \"account\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"name\": \"list-zones-test-searched-2.\", \"created\": \"2016-12-16T15:21:47Z\", \"adminGroupId\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"email\": \"test@test.com\", \"shared\": false, \"acl\": { \"rules\": [] }, \"id\": \"f1a376b2-2d8f-41f3-b8c8-9c9fba308f5d\", \"latestSync\": \"2016-12-16T15:27:26Z\", \"accessLevel\": \"Delete\" }, { \"status\": \"Active\", \"account\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"name\": \"list-zones-test-searched-3.\", \"created\": \"2016-12-16T15:21:47Z\", \"adminGroupId\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"email\": \"test@test.com\", \"shared\": false, \"acl\": { \"rules\": [] }, \"id\": \"568de57d-cb34-4f05-a9b5-35f9187490af\", \"latestSync\": \"2016-12-16T15:27:26Z\", \"accessLevel\": \"Read\" }, { \"status\": \"Active\", \"account\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"name\": \"list-zones-test-unfiltered-1.\", \"created\": \"2016-12-16T15:21:47Z\", \"adminGroupId\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"email\": \"test@test.com\", \"shared\": false, \"acl\": { \"rules\": [] }, \"id\": \"98dac90c-236e-4171-8729-c977ad38717e\", \"latestSync\": \"2016-12-16T15:27:26Z\", \"accessLevel\": \"NoAccess\" }, { \"status\": \"Active\", \"account\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"name\": \"list-zones-test-unfiltered-2.\", \"created\": \"2016-12-16T15:21:47Z\", \"adminGroupId\": \"a0b5ea74-cc05-4932-a294-9bf935d52744\", \"email\": \"test@test.com\", \"shared\": false, \"acl\": { \"rules\": [] }, \"id\": \"e4942020-b85a-421f-a8e2-124d8ba79422\", \"latestSync\": \"2016-12-16T15:27:26Z\", \"accessLevel\": \"Read\" } ], \"maxItems\": 100, \"ignoreAccess\": true }"
} ,
{
"title": "Manage Access",
"url": "/portal/manage-access.html",
"content": "Manage Access to Zones and Records Full Access Members of a zone admin group have full access to all records and permissions in the zone. Each zone is limited to one admin group. Typically, this should be a limited set of users. If you wish to add other users to a group you can do so in the Groups section of the portal. Limited Access If you dont want a user to have full access to a zone you can use ACL rules to give them more granular access. With ACL rules, the zone admins can grant individual users or groups read, write or delete access to all records in the zone, or a subset of record names and/or types. Go to the desired zone Select the Manage Zone tab Select the Create ACL rule button Fill in the form Submit the form Shared Zones The shared zone feature is designed to allow more granular record ownership and management in a flexible way. Super users can mark zones as shared which then allow any users to create new records or claim existing unowned records in zones. Zone administrators can assign records in a shared zone to specific groups by designating a group when creating the record set or when updating existing records in the portal. Users who are not zone administrators can create new records in shared zones, or claim and modify unowned records in shared zones, through the DNS Changes interface."
} ,
{
"title": "Manage Membership",
"url": "/portal/manage-membership.html",
"content": "Manage membership If you create a group in VinylDNS you are automatically made a member and group manager of the group. To manage the members of the group select the View button next to the desired group to view the Membership page. Add members: In the text box over the table enter the username of the person you want to add to the group. If you want to make them a group manager check the Is Group Manager? checkbox. Select the Add Group Member button. Delete members: Select the Delete button in the row of the user you wish to remove. Change managerial rights: Toggle the switch under the Group Manager column in the row of the user. The switch to the right and green means the user is a group manager. If the switch is to the left and red it means the user is not an group manager. Relinquish managerial rights: You can relinquish your managerial rights if there is at least one other group manager in the group. If that condition is met you can toggle the Group Manager switch for yourself. Remove yourself from a group: If you wish to remove yourself entirely from a group there must be at least one other manager of the group. If that condition is met you can select the Delete button that corresponds with your username and you will be removed from the group entirely."
} ,
{
"title": "Manage Records",
"url": "/portal/manage-records.html",
"content": "Manage Records There are currently two ways to manage records in the VinylDNS portal. This covers managing individual records through their associated zone. To manage multiple records at once, possibly across zones, and records in shared zones you can use the DNS Changes area of the portal. Access Only zone administrators and users with ACL rules can manage records this way. Supported record types A, AAAA, CNAME, DS, MX, NAPTR, NS, PTR, SRV, SSHFP, and TXT To manage records in a zone go to the Zones section of the portal and select the View button that corresponds with the zone you want to manage. The Manage Records tab will be the active tab by default. Once you are in the Manage Records tab of the zone, you can create new records sets or update or delete existing record sets. The Records pane, below the Recent Record Changes pane, lists record sets. Record sets are records that have the same name but different record data. Not all record types support record sets. When you make any change, it will be immediately queued for processing. Typically processing happens in a second or two. You may need to select the Refresh button if you dont see the change reflected in the portal. If for any reason the change failed, you can view the change in the Recent Record Changes pane at the top of the screen, or look at the Change History tab to see what went wrong. The Additional Info column will contain details of the change failure. Record sorting and filtering It is now possible to sort records in VinylDNS by record name ascending/descending order in addition to filtering the record types that will be displayed, providing more ease and control when navigating your DNS records. To change the sort order for record name, click on the Name header in the Records table to toggle between ascending and descending order. To filter record types, click on the Filter By Record Type link to reveal the record type options and adjust your selection. When searching for a record name using the search bar, exact matches are returned; however it is possible to use * to fuzzy match on desired patterns (e.g. foo* will match foo and foobar). Sync Zones If you make changes to the records in a zone outside of VinylDNS you must manually sync the zone so VinylDNS is aware of those records. Use the Sync Zone button in the Records pane."
} ,
{
"title": "Manual Review & Scheduling",
"url": "/portal/manual-review-scheduling.html",
"content": "DNS Changes: Manual Review & Scheduling Configuration Note: DNS Change manual review and scheduling are configured features in VinylDNS. Check with your VinylDNS administrators to determine if they are enabled in your instance.** Manual Review Scheduling Filter by Open Requests Cancelling DNS Changes Reviewing Pending DNS Changes (administrators only) Manual Review If a DNS Change is submitted with only non-fatal errors you will be notified to either correct those errors or submit your DNS Change for manual review. If you submit the DNS Change for manual review a VinylDNS administrator will determine if your request can be approved or if it needs to be rejected. After the review your DNS Change will include the review details, including the review status, reviewer name, review time and review comment, if provided. Scheduling VinylDNS processes DNS Changes immediately, unless they have a Request Date and Time. The day and time must be in the future. The portal accepts and returns the Request Date and Time as your local time. A VinylDNS administrator will review the DNS Change after the requested time and either approve or reject it for processing. Filter by Open Requests If you have many DNS Changes you may find it helpful to filter your list of requests by those that are currently open. In the top right corner of the DNS Changes table is a checkbox labeled “View Open Requests Only”. If the checkbox is selected the DNS Changes list will be limited to only Pending Review and Scheduled DNS Changes. Cancelling DNS Changes Users can cancel any DNS Change they create if it has a review status of “Pending Review”. Either select the “Cancel” button in the main DNS Changes list or the “Cancel” button in the DNS Change Detail page. A modal will appear for the user to confirm the cancellation. Reviewing Pending DNS Changes VinylDNS administrators can use the portal to review DNS Changes. In the DNS Changes view there are two tabs, “My Requests” and “All Requests”. “My Requests” are only your own DNS Changes. “All Requests” are requests by everyone in the VinylDNS instance. Both tabs can be filtered by open requests. On the detail page for a DNS change that is pending review, administrators will see a review section beneath the list of single changes. The administrator can provide a comment, then choose Approve or Reject and finally confirm their choice. If the DNS Change is approved and there are no new errors or its rejected then the review is completed and the DNS Change status and review information is updated. If the DNS Change still has errors after the approval attempt, the page will display the new errors and the administrator needs to address those or reject the DNS change."
} ,
{
"title": "Membership Model",
"url": "/api/membership-model.html",
"content": "Membership Model Table of Contents Group Attributes Group Example User Attributes User Example MEMBERSHIP BREAKDOWN Every zone can be connected to by only one group in VinylDNS. That initial group will be the admin group for that zone, which can be changed later on in a Zone Update. Every member of the admin group will be an admin of that zone, and can preform zone syncs, zone updates, zone deletes, and record set changes regardless of any Access Control Rules set on them. While users in the admin group will have complete zone access, further users can be given limited membership through Zone ACL Rules. GROUP ATTRIBUTES field type description name string This should be a single word name used for the groups. Use hyphens if needed, no spaces email string The email distribution list for the group description string A short description of the group, if more info is needed other than the name. The group will not have this attribute if it was not included in the create request id string Unique UUID of the group created date-time The timestamp (UTC) when the group was created status string Active or Deleted members Array of User id objects Set of User ids in the group admins Array of User id objects Set of User ids that are admins of the group. All admin user ids should also be in the members array Being in the admin set of a group has no impact on zone privileges when the group is the zones admin group. Being a group admin allows adding users to the group, deleting users from the group, toggling other users admin statuses (including your own), and deleting the group GROUP EXAMPLE { \"id\": \"dc4c7c79-5bbc-41bf-992e-8d6c4ec574c6\", \"name\": \"some-group\", \"email\": \"test@example.com\", \"created\": \"2017-01-30T20:05:24Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" }, { \"id\": \"a6d35b1a-57d7-4a65-bec2-d7ed30a7c430\" } ], \"admins\": [ { \"id\": \"a6d35b1a-57d7-4a65-bec2-d7ed30a7c430\" } ] } USER ATTRIBUTES field type description userName string This should be the AD username of the user firstName string First name of the user lastName string Last name of the user email string Email address of the user created date-time The timestamp (UTC) when the user was created id string Unique UUID of the user isTest boolean Defaults to false. Used for restricted access during VinylDNS testing, can be ignored by clients To get your access and secret keys, log into the VinylDNS portal and then with the top right drop-down select Download Credentials USER EXAMPLE { \"userName\": \"jdoe201\", \"firstName\": \"John\", \"lastName\": \"Doe\", \"email\": \"john_doe@example.com\", \"id\": \"1764183c-5e75-4ae6-8833-503cd5f4dcb3\", \"isTest\": false }"
} ,
{
"title": "Permissions Guide",
"url": "/permissions.html",
"content": "VinylDNS Permissions Guide Vinyldns is about making DNS self-service safe. There are a number of ways that you can govern access to your DNS infrastructure, from extremely restrictive, to extremely lax, and anywhere in between. This guide attempts to explain the various options available for governing access to your VinylDNS installation. A few notes on VinylDNS Groups Most of the access controls available in VinylDNS are managed by the way of Groups. You can see the groups to which you belong to in the Groups tab in in the portal. Groups are completely separate from LDAP, OIDC, or other Authorization mechanisms. They are tied deeply into the permissions capability in VinylDNS. Users can belong to many different groups, but typically they will belong to one “Primary” group. Groups are completely self-service, so users can create new groups, add / remove users from their groups, and even delete groups. We strongly recommend creating a VinylDNS Admin group for DNS administrators. Permission Precedence We work on the most restrictive access wins. In general: High Value Domain - Cant get past this step in VinylDNS Zone Ownership - If the user owns a zone, the user can make any changes in that zone Zone ACL - If the user was granted access to the zone via an ACL they can make the change Shared Zone - If the zone is shared, and the record does not yet exist or has not yet been claimed Record Owner - If the zone is shared, and the record is owned, the user has to be a member of the group that owns the record to make the change Global ACL - If all the above fail, if the user has access to the record by way of a Global ACL, the user can make the change Permission Management High Value Domains - config file Zone Ownership - web portal / Manage Zone Zone ACL - web portal / Manage Zone Shared Zone web portal / Manage Zone Record Owner - (implicitly via DNS Requests) Global ACL - config file Manual Review - config file Zone Ownership The original way to govern access is via Zone Ownership and Zone ACLs. When connecting to a zone in VinylDNS, you must designate a VinylDNS group that will effectively “own” the Zone. We refer to “Zone Owners” as any VinylDNS user that is a member of the VinylDNS Group on the Zone. This can be changed subsequent to connecting at any time via the Manage Zone tab. Zone Owners have full rights on a zone. They can manage the zone, abandon it, change connection information, and assign ACLs. A Zone ACL Rule is a record level control that allows VinylDNS users who are not Zone Owners privileges to perform certain actions in the zone. For example, you can grant access to A, AAAA, CNAME records in Zone foo.baz.com to user Josh ACL rules provide an extremely flexible way to grant access to DNS records. Each ACL Rule consists of the following: recordMask - this is a regular expression that is used to match on the record name (without the zone name). For example, a record mask www.* would match any record that started with www For reverse zones, this is a CIDR expression. This allows you to grant access based on individual or contiguous IP address space. For example, you could have a record mask of 100.100.100.100/16 recordTypes - types of DNS records that an ACL rule applies to. Often times, special records like NS records you do not want to grant access to. Add one or more record types to restrict the types of records you are granting access to. accessLevel - what kinds of permissions to give. Create allows a user to create new records, but not change or delete them. Write allows a user to create AND change records, but not delete them Delete allows a user full permissions to create, change, and delete any records that match the rule NoAccess explicitly negates other rules as an override. user - the user that the rule grants access to. You can specify this OR a Group group - the group the rule grants access to. description - an optional description for the rule for personal audit purposes Depending on your organization, you may choose to exclusively use Zone Ownership for managing self-service. This does come at a higher cost of administrative overhead than other options; however, it is the most restrictive and still very flexible. Users and groups can have multiple ACL entries associated with them. Permission conflicts are resolved via the following rules: The MOST permissive rule is chosen in the case of a tie. For example, if a user has an ACL entry with a Write permission, and another with a Read permission, the Write permission will take precedence. NoAccess takes precedence over other permission levels. For example, if a user has three ACL rules, Read, Write, and NoAccess, NoAccess will take precedence. User rules take precedence over group rules. For example, if a user has an ACL entry with a Read permission, and a group ACL entry with a Write permission, the Read permission will take precedence, even though Write is more permissive. Shared Zone Ownership Shared Zones were introduced in order to alleviate the administrative burden of Zone Ownership for large organizations. If you mark a zone as Shared (via the Manage Zone tab or API), you effectively grant anyone who can login to VinylDNS permissions to manage records in that DNS Zone. Read this section closely, as it can be a little confusing. Shared Zones still have a Zone Owner group that has full access. This will typically be the VinylDNS Admin group / DNS administrators. However, they open up access to everyone. This is very useful for universally “shared” DNS zones, in particular IP space. Often times, IP space is not allocated to groups, but blocks (i.e. Reverse Zones) are shared across the enterprise. It is common to use Shared Zones as a way to allow rather unfettered access to IP space. Shared Zones still have restrictions. It wouldnt be safe to allow anyone the ability to manage anyone elses DNS records. Therefore, we use a Record Ownership model that works in concert with Shared Zones to ensure that the user/group that created a DNS record, is the only group that can update or delete it. You can think of Record Ownership like a land grab. If I create it, I own it. All changes to Shared zones are made via the DNS Changes tab. Here is where users create one or more DNS record changes. When users submit changes here, they assign a “Record Owner Group” to the DNS change. As you have just learned, this Record Owner Group will be the group that owns any new records created as part of the batch change. In addition to shared zones, you can configure which record types you allow broad access to. Certain record types like NS maybe sensitive to be “world writable”. You can configure the allowable record types via config as shown below: shared-approved-types = [\"A\", \"AAAA\", \"CNAME\", \"PTR\", \"TXT\"] Global ACL Rules Global ACL Rules provide an override mechanism that applies for specific groups and FQDNs across ALL of VinylDNS. These were created as a means of overriding Record Ownership. The use case that fits here is when You want to use Shared Zones You have group(s) that must override the record ownership model. For example, one group may create or provision a DNS record, and another group may update or decommission that record. Global ACL rules are configured in VinylDNS (i.e. they are config file entries not available in the UI yet). The configuration entry is global-acl-rules. An example entry follows global-acl-rules = [ { group-ids: ['global-acl-group-id'], fqdn-regex-list: ['.*shared.'] } ] The group-ids are one or more VinylDNS group id (UUID) for the groups that you want to grant access to. The fqdn-regex-list is a list of regular expressions matched against the FQDN (i.e. record name and zone name). High Value Domains High value domains are currently configured in VinylDNS. Sometimes, certain domain names are just too valuable that you do not want them to be even touched by VinylDNS. See the operator guide for more information on configuring high value domains. High Value IP Addresses Similarly to forward FQDN records, you can also set certain IP addresses as “off limits, do not touch in VinylDNS”. Also done via the configuration file. Manual Review VinylDNS provides the ability for have DNS changes made via the DNS Change screen to be manually reviewed before being applied. This is another tool in the permissions toolkit to help you govern self-service. Note: if you enable manual review, then someone will need to login to VinylDNS and Approve or Reject the changes that are submitted. This can also be accomplished via scripting against the API if desired. In addition, Manual Review allows you to override certain error conditions. For example, if you create a DNS change for a Zone that does not yet exist in VinylDNS, it will fail before the user can submit. But if you have manual-batch-review-enabled = true, then those DNS changes can be sent to manual review, where a DNS administrator can create the DNS zone, add it to VinylDNS (marking it as shared or otherwise creating ACL access), and then re submit the change to complete processing. To turn on manual review, set the manual-batch-review-enabled = true in your application configuration file. In addition, you can specify certain zones that are ALWAYS manually reviewed. Even with Shared Zones turned on, you can require manual inspection to certain FQDNs. This is also done via configuration. The following snippet shows the configuration for zones that are ALWAYS manually reviewed: manual-review-domains = { domain-list = [\".*imporant.biz.com\"] ip-list = [\"1.2.3.4\"] zone-name-list = [ \"zone.requires.review.\", \"foo.com.\", \"baz.com.\", \"curl.bz.\" ] }"
} ,
{
"title": "Pre-requisites",
"url": "/operator/pre.html",
"content": "VinylDNS Pre-requisites VinylDNS has the following external requirements that need to be setup so that VinylDNS can operate. Those include: DNS - your DNS servers VinylDNS will interact with Database - the database houses all of VinylDNS information including history, records, zones, and users Message Queue - the message queue supports high-availability and throttling of commands to DNS backend servers LDAP - ldap supports both authentication as well as the source of truth for users that are managed inside the VinylDNS database DNS VinylDNS is not a DNS, rather it integrates with your existing DNS installations to enable DNS self-service and streamline DNS operations. VinylDNS communicates to your DNS via: DDNS - DDNS is used for all record updates AXFR - Zone Transfers are used to load DNS records into the VinylDNS database. VinylDNS communicates to your DNS using “connections”. A connection allows you to specify: The TSIG key name The TSIG key secret The server (and optionally port) to communicate to DNS with There are 2 connections, one for DDNS and another for zone transfers. This allows you to use a different DNS server / key for zone transfers. Connections (DDNS and Transfer) can be setup per zone - every zone can override the global default by specifying its own connections. global default - assuming you are managing a primary system, you can configure default zone connections. When no zone connection is specified on a zone, the global defaults will be used. Message Queues Most operations that take place in VinylDNS use a message queue. These operations require high-availability, fault-tolerance with retry, and throttling. The message queue supports these characteristics in VinylDNS. Some operations do not use the message queue, these include user and group changes as they do not carry the same fault-tolerance and throttling requirements. Message Queue Types AWS SQS Our VinylDNS instance uses AWS SQS to fulfill its message queue service needs. SQS has the following characteristics: High-Availability Retry - in the event that a message cannot be processed, or if a node fails midstream processing, it will be automatically made available for another node to process Back-pressure - SQS is a pull based system, meaning that if VinylDNS is currently busy, new messages will not be pulled for processing. As soon as a node becomes available, the message will be pulled. This is much preferable to a push based system, where bottlenecks in processing could cause an increase in heap pressure in the API nodes themselves. Price - SQS is very reasonably priced. Comcast operates multiple message queues for different environments (dev, staging, prod, etc). The price to use SQS is in the single digit dollars per month. VinylDNS can be tuned to run exclusively in the free tier. Review the Setup AWS SQS Guide for more information. MySQL VinylDNS has also implemented a message queue using MySQL, which incorporates the features that we currently utilize through AWS SQS such as changing visibility timeout and re-queuing operations. Review the Setup MySQL Guide for more information. LDAP VinylDNS uses LDAP in order to authenticate users in the Portal. LDAP is not used in the API, instead the API uses its own user and group database for authentication. When a user first logs into VinylDNS, their user information (first name, last name, user name, email) will be pulled from LDAP, and stored in the UserRepository. Credentials will also be generated for the user and stored encrypted in the UserRepository. Review the Setup LDAP Guide for more information"
} ,
{
"title": "RecordSet Model",
"url": "/api/recordset-model.html",
"content": "RecordSet Model Table of Contents RecordSet Attributes Record Data Information Record Data Example RecordSet ATTRIBUTES field type description zoneId string the id of the zone to which this recordset belongs name string The name of the RecordSet type string Type of DNS record, supported records are currently: A, AAAA, CNAME, DS, MX, NAPTR, NS, PTR, SOA, SRV, TXT, SSHFP, and SPF. Unsupported types will be given the type UNKNOWN ttl long the TTL in seconds for the recordset status string Active - RecordSet is added is created and ready for use, Inactive - RecordSet effects are not applied, Pending - RecordSet is queued for creation, PendingUpdate - RecordSet is queued for update, PendingDelete - RecordSet is queued for delete created date-time The timestamp (UTC) when the recordset was created updated date-time The timestamp (UTC) when the recordset was last updated records Array of RecordData Array of record data, a single RecordSet can have multiple DNS records as long as they are all the same type id string the id of the recordset. This is important as you will use it for other recordset operations account string DEPRECATED The account that created the RecordSet RecordSet EXAMPLE { \"type\": \"A\", \"zoneId\": \"8f8f649f-998e-4428-a029-b4ba5f5bd4ca\", \"name\": \"foo\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-22T21:34:35Z\", \"records\": [ { \"address\": \"1.1.1.1\" }, { \"address\": \"2.2.2.2\" }, { \"address\": \"3.3.3.3\" } ], \"id\": \"8306cce4-e16a-4579-9b19-4af46dc75853\", \"account\": \"b34f8d18-646f-4843-a80a-7c0d58a22bf5\" } RECORD DATA INFORMATION Current supported record types are: A, AAAA, CNAME, DS, MX, NAPTR, NS, PTR, SOA, SRV, TXT, SSHFP, and SPF. Each individual record encodes its data in a record data object, in which each record type has different required attributes SOA records and NS origin records (record with the same name as the zone) are currently read-only and cannot be created, updated or deleted. Non-origin NS records can be created or updated for approved name servers only. Any non-origin NS record can be deleted. record type attribute type A address string     AAAA address string     CNAME cname string     DS keytag integer DS algorithm integer DS digesttype integer DS digest string     MX preference integer MX exchange string     NAPTR order integer NAPTR preference integer NAPTR flags string NAPTR service string NAPTR regexp string NAPTR replacement string     NS nsdname string     PTR ptrdname string     SOA mname string SOA rname string SOA serial long SOA refresh long SOA retry long SOA expire long SOA minimum long     SPF text string     SRV priority integer SRV weight integer SRV port integer SRV target string     SSHFP algorithm integer SSHFP type integer SSHFP fingerprint string     TXT text string RECORD DATA EXAMPLE Each record is a map that must include all attributes for the data type, the records are stored in the records field of the RecordSet. The records must be an array of at least one record map. All records in the records array must be of the type stored in the typ field of the RecordSet Use the @ symbol to point to the zone origin CNAME records cannot point to the zone origin, thus the RecordSet name cannot be @ nor the zone origin Individual SSHFP record: { \"type\": \"SSHFP\", \"zoneId\": \"8f8f649f-998e-4428-a029-b4ba5f5bd4ca\", \"name\": \"foo\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-22T21:34:35Z\", \"records\": [ { \"algorithm\": 1, \"type\": 3, \"fingerprint\": \"560c7d19d5da9a3a5c7c19992d1fbde15d8dad31\" } ], \"id\": \"8306cce4-e16a-4579-9b19-4af46dc75853\", \"account\": \"b34f8d18-646f-4843-a80a-7c0d58a22bf5\" } Multiple SSHFP records: { \"type\": \"SSHFP\", \"zoneId\": \"8f8f649f-998e-4428-a029-b4ba5f5bd4ca\", \"name\": \"foo\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-22T21:34:35Z\", \"records\": [ { \"algorithm\": 1, \"type\": 2, \"fingerprint\": \"560c7d19d5da9a3a5c7c19992d1fbde15d8dad31\" }, { \"algorithm\": 3, \"type\": 1, \"fingerprint\": \"160c7d19d5da9a3a5c7c19992d1fbde15d8dad31\" }, { \"algorithm\": 4, \"type\": 1, \"fingerprint\": \"260c7d19d5da9a3a5c7c19992d1fbde15d8dad31\" } ], \"id\": \"8306cce4-e16a-4579-9b19-4af46dc75853\", \"account\": \"b34f8d18-646f-4843-a80a-7c0d58a22bf5\" }"
} ,
{
"title": "RecordSet Search",
"url": "/portal/recordset-search.html",
"content": "RecordSet Search RecordSet Search provides a view to lookup the state of DNS records within VinylDNS without requiring access to the specific zone. To use the search, a search term containing at least two alphanumeric characters must be entered. Record type and/or record owner group to further filter the search results. There is also a collapsible help section that provides further information regarding search querying tips."
} ,
{
"title": "Reject Batch Change",
"url": "/api/reject-batchchange.html",
"content": "Reject Batch Change Manually rejects a batch change in pending review status given the batch change ID, resulting in immediate failure. Only system administrators (i.e., support or super user) can manually review a batch change. Note: If manual review is disabled in the VinylDNS instance, users trying to access this endpoint will encounter a 404 Not Found response since it will not exist. HTTP REQUEST POST /zones/batchrecordchanges/{id}/reject HTTP REQUEST PARAMS name type required? description id string yes Unique identifier assigned to each created batch change. reviewComment string no Optional rejection explanation. EXAMPLE HTTP REQUEST { \"reviewComment\": \"Comments are optional.\" } HTTP RESPONSE TYPES Code description 200 OK Batch change is rejected and is returned in response body. 400 BadRequest Batch change is not in pending approval status. 403 Forbidden User is not a system administrator (ie. support or super user). 404 NotFound Batch change does not exist. HTTP RESPONSE ATTRIBUTES name type description userId string The unique identifier of the user that created the batch change. userName string The username of the user that created the batch change. comments string Conditional: comments about the batch change, if provided. createdTimestamp date-time The timestamp (UTC) when the batch change was created. changes Array of SingleChange Array of single changes within a batch change. A SingleChange can either be a SingleAddChange or a SingleDeleteRRSetChange. status BatchChangeStatus Status of the batch change. id string The unique identifier for this batch change. ownerGroupId string Conditional: Record ownership assignment, if provided. approvalStatus BatchChangeApprovalStatus Whether the batch change is currently awaiting manual review. Will be Rejected status when rejecting. reviewerId string Unique identifier for the reviewer of the batch change. reviewerUserName string User name for the reviewer of the batch change. reviewComment string Conditional: Comment from the reviewer of the batch change, if provided. reviewTimestamp date-time The timestamp (UTC) of when the batch change was manually reviewed. EXAMPLE RESPONSE { \"userId\": \"vinyl\", \"userName\": \"vinyl201\", \"comments\": \"this is optional\", \"createdTimestamp\": \"2019-07-25T20:22:53Z\", \"changes\": [ { \"changeType\": \"Add\", \"inputName\": \"reject.parent.com.\", \"type\": \"A\", \"ttl\": 7200, \"record\": { \"address\": \"1.2.3.4\" }, \"status\": \"Rejected\", \"recordName\": \"\", \"zoneName\": \"\", \"zoneId\": \"\", \"validationErrors\": [ { \"errorType\": \"ZoneDiscoveryError\", \"message\": \"Zone Discovery Failed: zone for \\\"reject.parent.com.\\\" does not exist in VinylDNS. If zone exists, then it must be connected to in VinylDNS.\" } ], \"id\": \"db811a02-5b0f-44ad-8ad9-8ecac7ba6bb4\" } ], \"status\": \"Failed\", \"id\": \"50e1b48b-80fa-41e0-96ef-72438abc31ec\", \"ownerGroupId\": \"159a41c5-e67e-4951-b539-05f5ac788139\", \"reviewerId\": \"90c11ffc-5a71-4794-97c6-74d19c81af7d \", \"reviewComment\": \"We can't make *this* change - are you out of your mind?!\", \"reviewTimestamp\": \"2019-07-25T20:33:41Z\", \"approvalStatus\": \"Rejected\" }"
} ,
{
"title": "Search Zones",
"url": "/portal/search-zones.html",
"content": "Search Zones The search box on the Zones page is designed to search on the zone name. It will search the “My Zones” and “All Zones” tabs simultaneously. For partial name matching use * in the search term. Without * the search will be run for exact zone names. The trailing . is accounted for whether its in the search term or not. Examples: Given a list of zone names: another.example.com., example.com., test.com., test.net., xyz.efg. Search test returns: No Zones Search test.com returns: test.com. Search test* returns: test.com., test.net. Search *example returns: example.com., another.example.com. Search *e* returns: another.example.com., example.com., test.com., test.net., xyz.efg."
} ,
{
"title": "Setup API Server",
"url": "/operator/setup-api.html",
"content": "Setup API Server The API Server is the main run-time for VinylDNS. To setup the API server, follow these steps: Pre-requisites Setup MySQL Setup AWS SQS Configure API Server Using the API Docker Image Using the API Docker Image The API server is provided via the VinylDNS API Image. The docker image allows you to mount your own config, as well as your own external dependency jars. The API server is stateless, allowing you to run multiple instances in multiple data centers for high-availability purposes. Note: If using VinylDNS Java Crypto and the pre-requisites defined here, no additional jars need to be loaded. Environment variables MYSQL_ADDRESS - the IP address of the mysql server; defaults to vinyldns-mysql assuming a docker compose setup MYSQL_PORT - the port of the mysql server; defaults to 3306 Volume Mounts The API exposes volumes that allow the user to customize the runtime. Those mounts include: /opt/vinyldns/lib_extra - place here additional jar files that need to be loaded into the classpath when the application starts up. This is used for “plugins” that are proprietary or not part of the standard build. All jar files here will be placed on the class path. /opt/vinyldns/conf - place an application.conf file here with your own custom settings. Once you have your config created, place here. Ports The API only exposes port 9000 for HTTP access to all endpoints"
} ,
{
"title": "Setup LDAP",
"url": "/operator/setup-ldap.html",
"content": "Setup LDAP VinylDNS uses LDAP for authenticating users in the portal as well as the source of user information loaded into VinylDNS. VinylDNS does support service accounts, which are useful for automation. Important Note: VinylDNS presently maintains its own user, group, and membership repository. The only way for a user to be created is to login to the portal. Implementers can choose to out-of-band manage the VinylDNS repositories. There are no steps necessary for setup than having a Directory that can communicate via LDAP, and a user (account) that can read data from the Directory. Once you have that information, proceed to the Portal Configuration. Considerations You should communicate to your Directory over LDAP using TLS. To do so, the SSL certs should be installed on the portal servers, or provided via a java trust store (key store). The portal provides an option to specific a java key store when it starts up. Configuring LDAP Before you can configure LDAP, make note of the host, username, and password that you will be using. Follow the Portal Configuration to complete the setup. Syncing users against LDAP VinylDNS has implemented an optional feature to perform a recurring LDAP lookup against all non-test users in the database and perform a user lock for users that no longer exist in the directory. Automated user locking of deprecated accounts both streamlines the user management process and enforces an extra layer of security around VinylDNS."
} ,
{
"title": "Setup MySQL",
"url": "/operator/setup-mysql.html",
"content": "Setup MySQL Our instance of VinylDNS currently stores data in MySQL. zone - holds zones zone_access - holds user or group identifiers that have access to zones batch_change - holds batch changes (multiple changes across zones in a single batch) single_change - holds individual changes within a batch_change user - holds user information, including access keys and secrets record-set - holds record data Setting up the database VinylDNS uses Flyway to manage SQL migrations. This means that any database changes, including creating the database, adding tables, etc. are all automatically applied when VinylDNS starts up. You do not need to do anything other than giving access to VinylDNS API from your MySQL server instance. You can view the database schema and migrations in the mysql module db/migration folder VinylDNS uses HikariCP for a high-speed connection pool. Configuring MySQL Before you can configure MySQL, make note of the host, username, and password that you will be using. Follow the API Database Configuration to complete the setup."
} ,
{
"title": "Setup the Portal Server",
"url": "/operator/setup-portal.html",
"content": "Setup the Portal Server The Portal Server is the web UI for VinylDNS. To setup the Portal server, follow these steps: Setup API Server Setup LDAP Configure Portal Server Using the Portal Docker Image Once you have you pre-requisites ready, review the Portal Configuration Guide for how to build out your configuration file. Using the Portal Docker Image The Portal server is provided as a VinylDNS Portal Image. The API server is stateless, allowing you to run multiple instances in multiple data centers for high-availability purposes. Volume mounts /opt/vinyldns/lib_extra - place here additional jar files that need to be loaded into the classpath when the application starts up. This is used for “plugins” that are proprietary or not part of the standard build. All jar files here will be placed on the class path. /opt/vinyldns/conf/application.conf - to override default configuration settings. Follow the Portal Configuration Guide Configuring a custom Java trustStore To add a custom Java trustStore for LDAP certs, add the trustStore to /opt/vinyldns/conf/trustStore.jks. Then add -Djavax.net.ssl.trustStore=/opt/vinyldns/conf/trustStore.jks to the JVM_OPTS environment variable for the container. Example: docker run -e JVM_OPTS=\"-Djavax.net.ssl.trustStore=/opt/vinyldns/conf/trustStore.jks\" ... Additional JVM parameters Additional JVM parameters can be added to the JVM_OPTS environment variable"
} ,
{
"title": "Setup AWS SQS",
"url": "/operator/setup-sqs.html",
"content": "Setup AWS SQS SQS is used to provide high-availability and failover in the event that a node crashes mid-stream while processing a message. The backend processing for VinylDNS is built to be idempotent so changes can be fully re-applied. The SQS queue also provides a mechanism to throttle updates, in the event that an out-of-control client submits thousands or millions of concurrent requests, they will all be throttled through SQS. You must setup an SQS queue before you can start working with VinylDNS. An AWS SQS Getting Started Guide provides the information you need to setup your queue. Setting up AWS SQS As opposed to MySQL where everything is created when the application starts up, the SQS queue needs to be setup by hand. This section goes through those settings that are required. The traffic with AWS SQS is rather low. Presently, Comcast operates multiple SQS queues across multiple environments (dev, staging, prod), and incur a cost of less than $10 USD per month. SQS allows up to 1MM requests per month in the free tier. It is possible to operate VinylDNS entirely in the “free” tier. You can “tune down” your usage by increasing your polling interval. The following SQS Queue Attributes are recommended (these are in AWS when you create an SQS Queue): Queue Type - Standard Delivery Delay - 0 seconds Default Visibility Timeout - 1 minute (how long it takes a record change to complete, usually a second) Message Retention Period - 4 days Maximum Message Size - 256KB Receive Message Wait Time - 0 seconds Maximum Receives - 100 (how many times a message will be retried before failing. Note: if any messages retry more than 100 times, there is likely a problem requiring immediate attention) Dead Letter Queue - use a dead letter queue for all queues Configuring SQS Before you can configure SQS, make note of the AWS account (access key and secret access key) as well as the SQS Queue Url that you will be using. Follow the SQS Configuration to complete the setup."
} ,
{
"title": "Sync Zone",
"url": "/api/sync-zone.html",
"content": "Sync Zone Used to sync VinylDNS zone info with existing zone info. When a sync is performed, a zone transfer is initiated with the backend DNS server. The backend data is compared to the existing data in VinylDNS. If there are any differences, the backend DNS Server is considered the source of truth and will overwrite the data in VinylDNS. All changes will be recorded in VinylDNS so they can be seen in the zone history. While the zone is syncing, the zone will be unavailable for updates (read-only). We have done some testing on how long syncs take. These will vary with usage: 1000 records ~ 1 second 10,000 records ~ 10 seconds 100,000 records ~ 6 minutes Please keep these numbers in mind when you perform syncs. HTTP REQUEST POST /zones/{zoneId}/sync HTTP RESPONSE TYPES Code description 200 OK - Successful lookup, the zone is returned in the response body 400 Bad Request - invalid sync state, a sync has been performed recently, or zone is inactive 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - the user does not have the access required to perform the action 404 Not Found - Zone not found 409 Conflict - Zone has a pending update HTTP RESPONSE ATTRIBUTES name type description status string Sync status zone map Refer to zone model created string The timestamp (UTC) the sync was initiated changeType string Type of change requested (Create, Update, Sync, Delete); in this case Sync userId string The user ID that initiated the change id string The ID of the change. This is not the id of the zone EXAMPLE RESPONSE { \"status\": \"Pending\", \"zone\": { \"status\": \"Syncing\", \"updated\": \"2016-12-28T19:22:02Z\", \"name\": \"sync-test.\", \"adminGroupId\": \"cf00d1e4-46f1-493a-a3be-0ae79dd306a5\", \"created\": \"2016-12-28T19:22:01Z\", \"account\": \"cf00d1e4-46f1-493a-a3be-0ae79dd306a5\", \"email\": \"test@test.com\", \"shared\": false, \"acl\": { \"rules\": [] }, \"id\": \"621a13df-a2e3-4394-84c0-3eb3a664dff4\" }, \"created\": \"2016-12-28T19:22:02Z\", \"changeType\": \"Sync\", \"userId\": \"ok\", \"id\": \"03f1ee91-9053-4346-8b53-e0f6042600f2\" }"
} ,
{
"title": "Tools",
"url": "/tools.html",
"content": "VinylDNS Tools There are a few existing tools for working with the VinylDNS API. vinyldns-cli - a VinylDNS API command line client go-vinyldns - Go client package for VinylDNS vinyldns-java - Java client for VinylDNS vinyldns-python - Python client library for VinylDNS vinyldns-js - JavaScript client for use in Node.js terraform-provider-vinyldns - a Terraform provider for VinylDNS Integrations external-dns - DNS provider-agnostic synchronization of Cloud Foundry and Kubernetes resources, including VinylDNS"
} ,
{
"title": "Update Group",
"url": "/api/update-group.html",
"content": "Update Group Updates a Group in VinylDNS. HTTP REQUEST PUT /groups/{groupId} HTTP REQUEST PARAMS name type required? description id string yes The ID of the group name string yes The name of the group. Should be one word, use hyphens if needed but no spaces email string yes The email distribution list for the group description string no A short description of the group, if more info is needed other than the name created date-time yes The timestamp (UTC) when the group was created status string yes Active or Deleted, should not be changed in an update, a delete request will handle deleting a group members Array of User ID objects yes Set of User IDs in the group admins Array of User ID objects yes Set of User IDs that are admins of the group. All admin user ids should also be in the members array EXAMPLE HTTP REQUEST { \"id\": \"6f8afcda-7529-4cad-9f2d-76903f4b1aca\", \"name\": \"some-group\", \"email\": \"test@example.com\", \"created\": \"Thu Mar 02 2017 10:29:21\", \"status\": \"Active\", \"members\": [ { \"id\": \"4764183c-5e75-4ae6-8833-503cd5f4dcb0\" }, { \"id\": \"k8630ebc-0af2-4c9a-a0a0-d18c590ed03e\" } ], \"admins\": [ { \"id\": \"4764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ] } HTTP RESPONSE TYPES Code description 200 OK - The group has been updated and the group info is returned in the response body 400 Bad Request - The group was invalid or a user id was not found 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - The group was not found 409 Conflict - The group already exists HTTP RESPONSE ATTRIBUTES name type description id string Unique UUID of the group name map The name of the group email string The email distribution list of the group description string The group description, the group will not have this attribute if it was not included in the update request and already did not exist created string The timestamp (UTC) the group was created status string Active or Deleted, in this case Active members Array of User Id objects Ids of members of the group including admins admins Array of User Id objects Ids of admins of the group EXAMPLE RESPONSE { \"id\": \"6f8afcda-7529-4cad-9f2d-76903f4b1aca\", \"name\": \"some-group\", \"email\": \"test@example.com\", \"created\": \"2017-03-02T15:29:21Z\", \"status\": \"Active\", \"members\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" }, { \"id\": \"c8630ebc-0af2-4c9a-a0a0-d18c590ed03e\" } ], \"admins\": [ { \"id\": \"2764183c-5e75-4ae6-8833-503cd5f4dcb0\" } ] }"
} ,
{
"title": "Update RecordSet",
"url": "/api/update-recordset.html",
"content": "Update RecordSet Updates a RecordSet. This performs a delete of the old record, and inserts the new record. HTTP REQUEST PUT /zones/{zoneId}/recordsets/{recordSetId} HTTP REQUEST PARAMS name type required? description zoneId string yes id of the zone where the recordset belongs, this value must match the zoneId of the existing recordSet id string yes the id of the recordset being updated name string yes the name of the recordset being updated type string yes the type of recordset ttl integer yes the TTL in seconds records array of record data yes record data for recordset, see RecordSet Model ownerGroupId string sometimes* Record ownership assignment, applicable if the recordset is in a shared zone *Note: If a recordset has an ownerGroupId you must include that value in the update request, otherwise the update will remove the ownerGroupId value EXAMPLE HTTP REQUEST { \"id\": \"dd9c1120-0594-4e61-982e-8ddcbc8b2d21\", \"name\": \"already-exists\", \"type\": \"A\", \"ttl\": 38400, \"records\": [ { \"address\": \"6.5.4.3\" } ], \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\" } HTTP RESPONSE TYPES Code description 202 Accepted - the update is valid and has been accepted for processing; the record set change resource is returned in the response body 400 Bad Request - the zone being updated is not active; typically because the connection information does not exist for the zone 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - The user does not have the access required to perform the action 404 Not Found - Zone or RecordSet not found 409 Conflict - There is an existing pending change against this record set 422 Unprocessable Entity HTTP RESPONSE ATTRIBUTES name type description zone map Contains information about the zone when the change was created recordSet map Contains the recordset model updates map New data to overwrite current record set userId string The user id that initiated the change changeType string Type of change requested (Create, Update, Delete); in this case Update created string The timestamp (UTC) the change was initiated id string The ID of the change. This is not the ID of the recordset status RecordSetChangeStatus The status of the change (Pending, Complete, or Failed) singleBatchChangeIds array of SingleBatchChange ID objects If the recordset change was part of a batch change, the IDs of the single changes that comprise the recordset change EXAMPLE RESPONSE { \"zone\": { \"name\": \"vinyl.\", \"email\": \"test@test.com\", \"status\": \"Active\", \"created\": \"2017-02-23T14:52:44Z\", \"updated\": \"2017-02-23T15:12:33Z\", \"id\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"shared\": false, \"acl\": { \"rules\": [ ] }, \"adminGroupId\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"latestSync\": \"2017-02-23T15:12:33Z\" }, \"recordSet\": { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"already-exists\", \"ttl\": 38400, \"status\": \"PendingUpdate\", \"created\": \"2017-02-23T15:12:41Z\", \"updated\": \"2017-02-23T15:12:41Z\", \"records\": [ { \"address\": \"6.6.6.1\" } ], \"id\": \"dd9c1120-0594-4e61-982e-8ddcbc8b2d21\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\" }, \"userId\": \"0215d410-9b7e-4636-89fd-b6b948a06347\", \"changeType\": \"Update\", \"status\": \"Pending\", \"created\": \"2017-02-23T15:12:41Z\", \"updates\": { \"type\": \"A\", \"zoneId\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"name\": \"already-exists\", \"ttl\": 38400, \"status\": \"Active\", \"created\": \"2017-02-23T15:12:33Z\", \"records\": [ { \"address\": \"6.6.6.6\" } ], \"id\": \"dd9c1120-0594-4e61-982e-8ddcbc8b2d21\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"ownerGroupId\": \"f42385e4-5675-38c0-b42f-64105e743bfe\" }, \"id\": \"df69bc45-2942-4fb7-813c-4dd21cfad7fa\", \"singleBatchChangeIds\": [] }"
} ,
{
"title": "Update Zone",
"url": "/api/update-zone.html",
"content": "Update Zone Updates an existing zone that has already been connected to. Used to update the ACL rules or zone level meta data like the zone connection or email. HTTP REQUEST PUT /zones/{zoneId} HTTP REQUEST PARAMS Zone fields - Refer to zone model. EXAMPLE HTTP REQUEST { \"name\": \"vinyl.\", \"email\": \"update@update.com\", \"status\": \"Active\", \"created\": \"2017-02-23T14:52:44Z\", \"updated\": \"2017-02-23T19:05:33Z\", \"id\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"shared\": false, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"latestSync\": \"2017-02-23T19:05:33Z\", \"adminGroupName\": \"test\", \"hiddenKey\": \"\", \"hiddenTransferKey\": \"\" } HTTP RESPONSE TYPES Code description 200 Accepted - The zone change is returned in the response body 400 Bad Request - connection failed 401 Unauthorized - The authentication information provided is invalid. Typically the request was not signed properly, or the access key and secret used to sign the request are incorrect 403 Forbidden - the user does not have the access required to perform the action 404 Not Found - Zone not found 409 Conflict - Zone has a pending update HTTP RESPONSE ATTRIBUTES name type description zone map Zone sent with update request. Refer to zone model userId string The user id that initiated the change changeType string Type of change requested (Create, Update, Sync, Delete); in this case Update created string The timestamp (UTC) the change was initiated id string The ID of the change. This is not the ID of the zone status string The status of the zone change EXAMPLE RESPONSE { \"zone\": { \"name\": \"vinyl.\", \"email\": \"update@update.com\", \"status\": \"Active\", \"created\": \"2017-02-23T14:52:44Z\", \"updated\": \"2017-02-23T19:23:26Z\", \"id\": \"2467dc05-68eb-4498-a9d5-78d24bb0893c\", \"account\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"shared\": false, \"acl\": { \"rules\": [] }, \"adminGroupId\": \"9b22b686-54bc-47fb-a8f8-cdc48e6d04ae\", \"latestSync\": \"2017-02-23T19:05:33Z\" }, \"userId\": \"0215d410-9b7e-4636-89fd-b6b948a06347\", \"changeType\": \"Update\", \"status\": \"Pending\", \"created\": \"2017-02-23T19:23:26Z\", \"id\": \"d1fcd28d-61fe-4c24-ac0b-4377d66d50db\" }"
} ,
{
"title": "Zone Model",
"url": "/api/zone-model.html",
"content": "Zone Model Table of Contents Zone Attributes Zone JSON Example Zone Connection Attributes Zone Connection JSON Example Zone ACL Rule Attributes Zone ACL Rule Examples PTR ACL Rule PTR ACL Rule Examples Shared Zones ZONE ATTRIBUTES field type description status string Active - the zone is connected and ready for use; Syncing - the zone is currently syncing with the DNS backend and is not available until syncing is complete. updated date-time The last time the zone was changed. Note: this does not include changes to record sets, only the zone entity itself name string The name of the zone adminGroupId string The id of the administrators group for the zone created date-time The time when the zone was first created account string DEPRECATED The account that created the zone email string The distribution email for the zone backendId string Optional. Recommended over connection and transferConnection. The configuration ID of the DNS backend server for the zone. If not provided, default keys will be used unless connection and transfer connection are provided. connection ZoneConnection Optional. The connection used to issue DDNS updates to the backend zone. If not provided, default keys will be used unless backendId is provided. See the Zone Connection Attributes for more information transferConnection ZoneConnection Optional. The connection that is used to sync the zone with the DNS backend. This can be different than the update connection. If not provided, default keys will be used unless backendId is provided. shared boolean An indicator that the zone is shared with anyone. At this time only VinylDNS administrators can set this to true. acl ZoneACL The access control rules governing the zone. See the Zone ACL Rule Attributes for more information id string The unique identifier for this zone latestSync date-time The last date and time the zone was synced isTest boolean Defaults to false. Used for restricted access during VinylDNS testing, can be ignored by clients accessLevel string Access level of the user requesting the zone. Current levels are Delete (full access), Read and NoAccess. ZONE EXAMPLE { \"status\": \"Active\", \"updated\": \"2016-12-16T15:27:28Z\", \"name\": \"ok.\", \"adminGroupId\": \"92b298e8-97db-4f1b-881b-fd08ca0dd311\", \"created\": \"2016-12-16T15:27:26Z\", \"account\": \"92b298e8-97db-4f1b-881b-fd08ca0dd311\", \"email\": \"test@test.com\", \"connection\": { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"ok.\", \"key\": \"OBF:1:W1FXgpOjjrQAABAARrZmyLjFSOuFYTAw81mhvNEmNAc4RnYzPjJQMEjVQWWLRohu7gRAVw==\" }, \"transferConnection\": { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"ok.\", \"key\": \"OBF:1:W1FXgpOjjrQAABAARrZmyLjFSOuFYTAw81mhvNEmNAc4RnYzPjJQMEjVQWWLRohu7gRAVw==\" }, \"shared\": false, \"acl\": { \"rules\": [ { \"accessLevel\": \"Write\", \"userId\": \"<uuid>\", \"description\": \"some_test_rule\", \"recordTypes\": [] }, { \"recordMask\": \".*\", \"accessLevel\": \"Write\", \"userId\": \"<uuid>\", \"description\": \"some_test_rule\", \"recordTypes\": [] }, { \"recordMask\": \"test.*\", \"accessLevel\": \"Read\", \"groupId\": \"<uuid>\", \"description\": \"some_test_rule\", \"recordTypes\": [] } ] }, \"id\": \"9cbdd3ac-9752-4d56-9ca0-6a1a14fc5562\", \"latestSync\": \"2016-12-16T15:27:26Z\", \"backendId\":\"func-test-backend\", \"accessLevel\": \"Delete\" } ZONE ACL RULE ATTRIBUTES ACL Rules are used to govern user and group access to record operations on a zone. ACL Rules can be associated with a specific user, or all users in a specified group. If neither a user or a group is attached to an ACL rule, then the rule applies to all users in the system. Use the Zone Update endpoint to update the acl attribute of the zone Important! If a user is mentioned on an ACL Rule directly, or is a member of a group that is mentioned on an ACL Rule, that user will be able to see the zone. Rules made without selecting a group or user will apply to all users in VinylDNS. field type description recordMask string (optional) A regular expression that is used to match against record names. If left empty, then all records will be matched for the rule. All records matching the match will be governed by this rule. recordTypes Array[String] An array of all record types that this rule applies to. If left empty, then all record types will be governed by this rule. accessLevel string NoAccess - cannot see the data for the record; Read - can read only the record; Write - the user can create and edit records, but cannot delete them; Delete - the user can read, create, update, and delete records userId string (optional) The unique identifier for the user the rule applies to. Note: this is not the name of the user, but their uuid in VinylDNS groupId string (optional) The unique identifier for the group the rule applies to. Note: you cannot set both the userId and groupId, only one description string (optional) A user entered description for the rule The priority of ACL Rules in descending precedence: Individual rules placed on a user Rules placed on groups that a user is in Rules placed on all users in VinylDNS Note: Being in the admin group of a zone will grant users full access regardless of ACL Rules For conflicting rules, the rule that is more specific will take precedence. For example, if the account jdoe201 was given Read access to all records in a zone through the rule: { \"userId\": \"<uuid>\", \"accessLevel\": \"Read\", } and then Write access to only A records through the rule: { \"userId\": \"<uuid>\", \"accessLevel\": \"Write\", \"recordTypes\": [\"A\"] } and then Delete access to only A records that matched the expression *dev* through the rule: { \"userId\": \"<uuid>\", \"accessLevel\": \"Delete\", \"recordTypes\": [\"A\"], \"recordMask\": \"*dev*\" } then the rule with the recordMask will take precedence and give Delete access to matched A RecordSets, the rule with recordTypes will take precedence and give Write access to all other A records, and the more broad rule will give Read access to all other record types in the zone ZONE ACL RULE EXAMPLES Grant read/write/delete access to www.* records of type A, AAAA, CNAME to one user Under this rule, the user specified will be able to view, create, edit, and delete records in the zone that match the expression www.* and are of type A, AAAA, or CNAME. { \"recordMask\": \"www.*\", \"accessLevel\": \"Delete\", \"userId\": \"<uuid>\", \"recordTypes\": [\"A\", \"AAAA\", \"CNAME\"] } Grant read only access to all VinylDNS users to A, AAAA, CNAME records { \"accessLevel\": \"Read\", \"recordTypes\": [\"A\", \"AAAA\", \"CNAME\"] } Grant read/write/delete access to records of type A, AAAA, CNAME to one group* { \"accessLevel\": \"Delete\", \"groupId\": \"<uuid>\", \"recordTypes\": [\"A\", \"AAAA\", \"CNAME\"] } PTR ACL RULES WITH CIDR MASKS ACL rules can be applied to specific record types and can include record masks to further narrow down which records they apply to. These record masks apply to record names, but because PTR record names are part their reverse zone ip, the use of regular expressions for record masks are not supported. Instead PTR record masks must be CIDR rules, which will denote a range of IP addresses that the rule will apply to. While more information and useful CIDR rule utility tools can be found online, CIDR rules describe how many bits of an ip address binary representation must be the same for a match. PTR ACL RULES WITH CIDR MASKS EXAMPLE The ACL Rule { \"recordTypes\": [\"PTR\"], \"accessLevel\": \"Read\" } Will give Read permissions to PTR Record Sets to all users in VinylDNS The IPv4 ACL Rule { \"recordTypes\": [\"PTR\"], \"accessLevel\": \"Read\", \"recordMask\": \"100.100.100.100/16\" } Will give Read permissions to PTR Record Sets 100.100.000.000 to 100.100.255.255, as 16 bits is half of an IPv4 address The IPv6 ACL Rule { \"recordTypes\": [\"PTR\"], \"accessLevel\": \"Read\", \"recordMask\": \"1000:1000:1000:1000:1000:1000:1000:1000/64\" } Will give Read permissions to PTR Record Sets 1000:1000:1000:1000:0000:0000:0000:0000 to 1000:1000:1000:1000:FFFF:FFFF:FFFF:FFFF, as 64 bits is half of an IPv6 address. ZONE CONNECTION ATTRIBUTES In order for VinylDNS to make updates in DNS, it needs key information for every zone. There are 3 ways to specify that key information; ask your VinylDNS admin which is appropriate for your zone based on the configuration of the service: Leave connection, transfer connection, and backend ID blank: In this case, the default VinylDNS keys will be used Specify a backend ID on the zone: if multiple backends are configured for your instance of VinylDNS, you can specify a backend ID on the zone and the keys associated with that backend will be used. Specify zone connection and transfer connection on the zone itself: see below for details Note that if both a backend ID and specific connection keys are included on a zone, the specific connection keys will be used. Zone Connection specifies the connection information to the backend DNS server. field type description primaryServer string The IP address or host that is connected to. This can take a port as well 127.0.0.1:5300. If no port is specified, 53 will be assumed. keyName string The name of the DNS key that has access to the DNS server and zone. Note: For the transfer connection, the key must be given allow-transfer access to the zone. For the primary connection, the key must be given allow-update access to the zone. name string A user identifier for the connection. key string The TSIG secret key used to sign requests when communicating with the primary server. Note: After creating the zone, the key value itself is hashed and obfuscated, so it will be unusable from a client perspective. ZONE CONNECTION EXAMPLE { \"primaryServer\": \"127.0.0.1:5301\", \"keyName\": \"vinyl.\", \"name\": \"ok.\", \"key\": \"OBF:1:W1FXgpOjjrQAABAARrZmyLjFSOuFYTAw81mhvNEmNAc4RnYzPjJQMEjVQWWLRohu7gRAVw==\" } SHARED ZONES Shared zones allow for a more open management of records in VinylDNS. Zone administrators can assign ownership of records to groups. Any user in VinylDNS can claim existing unowned records in shared zones, as well as create records in those zones. Once a record is owned, only users in the record owner group, the zone administrators and those with relevant ACL rules can modify or delete the record. The batch change API endpoint and DNS change area of the portal are where users can create new records in shared zones, modify records they own, or claim unowned records. If a zones shared state changes to false the record ownership access is no longer applicable."
} ,
{
"title": "Zones",
"url": "/portal/zones.html",
"content": "Zones The My Zones tab lists zones you have access to (through ownership or ACL rules). The list contains links to the individual zone pages where you can manage the zone, its records and ACL access. The All Zones tab is intended as a reference, it includes zones you have access to as well as all other private and shared zones in VinylDNS. If needed, you can use the contact information in the list to reach out to the owners of the zones you dont have access to. Note you may have access to specific records in shared zones, but you are not permitted to access those zones in this area. Those records are accessible via the DNS Changes area of the portal. Search Zones Connect to your zone Manage records Manage access Understand connections"
}
];
idx = lunr(function () {
this.ref("title");
this.field("content");
docs.forEach(function (doc) {
this.add(doc);
}, this);
});
docs.forEach(function (doc) {
docMap.set(doc.title, doc.url);
});
}
// The onkeypress handler for search functionality
function searchOnKeyDown(e) {
const keyCode = e.keyCode;
const parent = e.target.parentElement;
const isSearchBar = e.target.id === "search-bar";
const isSearchResult = parent ? parent.id.startsWith("result-") : false;
const isSearchBarOrResult = isSearchBar || isSearchResult;
if (keyCode === 40 && isSearchBarOrResult) {
// On 'down', try to navigate down the search results
e.preventDefault();
e.stopPropagation();
selectDown(e);
} else if (keyCode === 38 && isSearchBarOrResult) {
// On 'up', try to navigate up the search results
e.preventDefault();
e.stopPropagation();
selectUp(e);
} else if (keyCode === 27 && isSearchBarOrResult) {
// On 'ESC', close the search dropdown
e.preventDefault();
e.stopPropagation();
closeDropdownSearch(e);
}
}
// Search is only done on key-up so that the search terms are properly propagated
function searchOnKeyUp(e) {
// Filter out up, down, esc keys
const keyCode = e.keyCode;
const cannotBe = [40, 38, 27];
const isSearchBar = e.target.id === "search-bar";
const keyIsNotWrong = !cannotBe.includes(keyCode);
if (isSearchBar && keyIsNotWrong) {
// Try to run a search
runSearch(e);
}
}
// Move the cursor up the search list
function selectUp(e) {
if (e.target.parentElement.id.startsWith("result-")) {
const index = parseInt(e.target.parentElement.id.substring(7));
if (!isNaN(index) && (index > 0)) {
const nextIndexStr = "result-" + (index - 1);
const querySel = "li[id$='" + nextIndexStr + "'";
const nextResult = document.querySelector(querySel);
if (nextResult) {
nextResult.firstChild.focus();
}
}
}
}
// Move the cursor down the search list
function selectDown(e) {
if (e.target.id === "search-bar") {
const firstResult = document.querySelector("li[id$='result-0']");
if (firstResult) {
firstResult.firstChild.focus();
}
} else if (e.target.parentElement.id.startsWith("result-")) {
const index = parseInt(e.target.parentElement.id.substring(7));
if (!isNaN(index)) {
const nextIndexStr = "result-" + (index + 1);
const querySel = "li[id$='" + nextIndexStr + "'";
const nextResult = document.querySelector(querySel);
if (nextResult) {
nextResult.firstChild.focus();
}
}
}
}
// Search for whatever the user has typed so far
function runSearch(e) {
if (e.target.value === "") {
// On empty string, remove all search results
// Otherwise this may show all results as everything is a "match"
applySearchResults([]);
} else {
const tokens = e.target.value.split(" ");
const moddedTokens = tokens.map(function (token) {
// "*" + token + "*"
return token;
})
const searchTerm = moddedTokens.join(" ");
const searchResults = idx.search(searchTerm);
const mapResults = searchResults.map(function (result) {
const resultUrl = docMap.get(result.ref);
return { name: result.ref, url: resultUrl };
})
applySearchResults(mapResults);
}
}
// After a search, modify the search dropdown to contain the search results
function applySearchResults(results) {
const dropdown = document.querySelector("div[id$='search-dropdown'] > .dropdown-content.show");
if (dropdown) {
//Remove each child
while (dropdown.firstChild) {
dropdown.removeChild(dropdown.firstChild);
}
//Add each result as an element in the list
results.forEach(function (result, i) {
const elem = document.createElement("li");
elem.setAttribute("class", "dropdown-item");
elem.setAttribute("id", "result-" + i);
const elemLink = document.createElement("a");
elemLink.setAttribute("title", result.name);
elemLink.setAttribute("href", result.url);
elemLink.setAttribute("class", "dropdown-item-link");
const elemLinkText = document.createElement("span");
elemLinkText.setAttribute("class", "dropdown-item-link-text");
elemLinkText.innerHTML = result.name;
elemLink.appendChild(elemLinkText);
elem.appendChild(elemLink);
dropdown.appendChild(elem);
});
}
}
// Close the dropdown if the user clicks (only) outside of it
function closeDropdownSearch(e) {
// Check if where we're clicking is the search dropdown
if (e.target.id !== "search-bar") {
const dropdown = document.querySelector("div[id$='search-dropdown'] > .dropdown-content.show");
if (dropdown) {
dropdown.classList.remove("show");
document.documentElement.removeEventListener("click", closeDropdownSearch);
}
}
}