Code Monkey home page Code Monkey logo

record_store's People

Contributors

andrewlouis93 avatar burke avatar charlescng avatar cttttt avatar dwradcliffe avatar elvinefendi avatar es avatar etiennebarrie avatar gooallen avatar ingytron avatar jameshageman avatar jeremyashton-shopify avatar jules2689 avatar kwyckmans avatar lei-lo avatar mathu97 avatar meganniu avatar mredan avatar oefd avatar pascal-de-ladurantaye avatar pseudomuto avatar ryandv avatar sbfaulkner avatar shopify-admins avatar stonith avatar vpetkar avatar weppos avatar wvanbergen avatar xaf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

record_store's Issues

Deploy to Heroku Button

Shopify uses ShipIt to deploy Record Store changes, but most organizations don't have that setup internally. A smoother workflow might be to deploy to Heroku and enable automatic deploys on Github merges into master. This could probably all be accomplished with the "Deploy to Heroku" button.

We'd also need to add the ability to inject secrets through environment variables.

Add rubocop support for record_store

Allow to have code linting for the record_store by enabling rubocop.

This will require:
1/ Fix all the issues that might trigger rubocop in the project
2/ Submit a PR with the rubocop configuration for any future change to be merged in the project

SPF Record Refactor

SPF records are really just TXT records underneath with specific content. Our code should reflect that by having Record::SPF inherit from Record::TXT.

Deprecate SPF record support

SPF records (which were part of the original proposal for SPF) are no longer used

TXT records are the standard

As such, we should probably remove support for SPF - although it may be possible to upgrade to TXT records "automatically"

Ensure all {fqdn,type} records have the same TTL

From DynECT technical support:

The use of differing TTL values for records within a record set has been deprecated as of RFC-2181. This means that for a given hostname, all the records of a given record type will need to use the same TTL value.

A validation should be added to zones ensure this spec is adhered to.

Always request JSON from provider APIs, or handle HTML error response bodies

It appears that (at least) NS1 may transiently return HTML response bodies with a 503 status code. We can't parse these as JSON:

$ bin/record-store assert_empty_diff
pid: 32416
#<Thread:0x00005561b66ce9a0@/app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/zone.rb:55 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	23: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/zone.rb:59:in `block (2 levels) in modified'
	22: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/zone.rb:83:in `unchanged?'
	21: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/zone.rb:76:in `build_changesets'
	20: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/zone.rb:76:in `map'
	19: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/zone.rb:77:in `block in build_changesets'
	18: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/changeset.rb:40:in `build_from'
	17: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider.rb:61:in `build_zone'
	16: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider/ns1.rb:56:in `retrieve_current_records'
	15: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider/ns1.rb:72:in `records_for_zone'
	14: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider.rb:150:in `retry_on_connection_errors'
	13: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider.rb:150:in `loop'
	12: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider.rb:152:in `block in retry_on_connection_errors'
	11: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider/ns1.rb:73:in `block in records_for_zone'
	10: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider/ns1/client.rb:17:in `zone'
	 9: from /app/data/bundler/ruby/2.6.0/gems/ns1-0.2.0/lib/ns1/api/zones.rb:12:in `zone'
	 8: from /app/data/bundler/ruby/2.6.0/gems/statsd-instrument-2.8.0/lib/statsd/instrument.rb:286:in `block (2 levels) in statsd_count'
	 7: from /app/data/bundler/ruby/2.6.0/gems/ns1-0.2.0/lib/ns1/client.rb:24:in `perform_request'
	 6: from /app/data/bundler/ruby/2.6.0/gems/ns1-0.2.0/lib/ns1/transport/net_http.rb:20:in `request'
	 5: from /usr/lib/ruby-shopify/ruby-shopify-2.6.4/lib/ruby/2.6.0/net/http.rb:605:in `start'
	 4: from /usr/lib/ruby-shopify/ruby-shopify-2.6.4/lib/ruby/2.6.0/net/http.rb:920:in `start'
	 3: from /app/data/bundler/ruby/2.6.0/gems/ns1-0.2.0/lib/ns1/transport/net_http.rb:22:in `block in request'
	 2: from /app/data/bundler/ruby/2.6.0/gems/record_store-6.2.1/lib/record_store/provider/ns1/patch_api_header.rb:21:in `process_response'
	 1: from /app/data/bundler/ruby/2.6.0/gems/json-2.3.1/lib/json/common.rb:263:in `parse'
/app/data/bundler/ruby/2.6.0/gems/json-2.3.1/lib/json/common.rb:263:in `parse': 784: unexpected token at '<!DOCTYPE html> (JSON::ParserError)
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en-US"> <![endif]-->
<!--[if IE 7]>    <html class="no-js ie7 oldie" lang="en-US"> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8 oldie" lang="en-US"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en-US"> <!--<![endif]-->
<head>
<title>Temporarily unavailable | api.nsone.net | Cloudflare</title></title>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

We should probably set the Accept request header, or just be able to handle these sorts of responses from the NS1 API.

We should also check to see whether or not the DNSimple provider suffers from the same issue.

Add support for google cloud DNS

We're now putting critical DNS record in google cloud. The story for managing DNS there is not great.

They allow you to export/import a yml file to make changes. When you export a file, then modify it and re-import, it'll throw a bunch of errors telling you that the records you are importing already exist. They do allow you to modify records in a transaction, so you can apply a changeset all in one go. But you're still doing this through a bunch of manual commands, so it's still fairly error prone, especially if you're making multiple changes.

I imagine we'll only be putting more things in there in the future, so it'd be great if we could use the same record_store workflow for those DNS records as we do now for DYNect and DNSimple. It'd be much better if we could update a yml file and have those changes reviewed before merging and forgetting, instead of updating a bunch of records by hand on your own machine.

@es
cc @stonith

Remove add/remove/update Methods from Provider Classes

While working on adding support for Google Cloud DNS, I realized Provider#add, Provider#remove, and Provider#update should never be called outside of a provider as all changes are done through changesets. This means there's no need for add/remove/update to be public methods.

Steps to complete this PR:
TODO

Validate domain format in config.yml

It can be difficult to debug why adding a new domain is failing CI. To help with the process, more specific errors should be raised for invalid domain formats in config.yml.

record_store does not handle edits with multiple entries with the Dynect provider

Looks to have the same underlying problem as #27.

Given the scenario where we have two existing TXT entries for the same FQDN:

www.example.com TXT foo
www.example.com TXT bar

We want to update the bar entry to hello.

The existing code does not change the correct entry to hello with the Dynect entries. In fact it wants to delete the foo entry and update the bar entry to hello.

I suspect this is also a problem for other record types where there can be multiple entries which as A and AAAA.

The problem does not exist with DNSimple which is supported by Fog::DNS (without the need for another plugin).

rake failures

On a pristine, newly cloned copy of the repo, I get a mix of warnings and errors when trying to run the tests.

โžœ  record_store git:(master) rake
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/activesupport-4.2.9/lib/active_support/core_ext/enumerable.rb:20: warning: method redefined; discarding old sum
/Users/weppos/Code/record_store/lib/record_store/record/a.rb:27: warning: assigned but unused variable - e
/Users/weppos/Code/record_store/lib/record_store/record/aaaa.rb:27: warning: assigned but unused variable - e
/Users/weppos/Code/record_store/lib/record_store/provider.rb:11: warning: assigned but unused variable - e
/Users/weppos/Code/record_store/lib/record_store/provider/dynect.rb:51: warning: assigned but unused variable - e
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/cache.rb:207: warning: assigned but unused variable - name
/Users/weppos/Code/record_store/test/test_helper.rb:29: warning: File.exists? is a deprecated name, use File.exist? instead
/Users/weppos/Code/record_store/test/zone_test.rb:358: warning: ambiguous first argument; put parentheses or a space even after `/' operator
/Users/weppos/Code/record_store/test/zone_test.rb:259: warning: method redefined; discarding old test_zone_unchanged_describes_if_zone_matches_multiple_provider
/Users/weppos/Code/record_store/test/zone_test.rb:249: warning: previous definition of test_zone_unchanged_describes_if_zone_matches_multiple_provider was here
Run options: --seed 49428

# Running:

......../Users/weppos/Code/record_store/lib/record_store/provider.rb:99: warning: File.exists? is a deprecated name, use File.exist? instead
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/models/dns/record.rb:69: warning: shadowing outer local variable - record
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/models/dns/zone.rb:33: warning: assigned but unused variable - data
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/models/dns/records.rb:15: warning: assigned but unused variable - type
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/attributes/default.rb:43: warning: method redefined; discarding old domain=
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/attributes/default.rb:43: warning: previous definition of domain= was here
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/attributes/default.rb:52: warning: method redefined; discarding old domain
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/attributes/default.rb:52: warning: previous definition of domain was here
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/requests/dns/get_record.rb:40: warning: shadowing outer local variable - record
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/requests/dns/get_record.rb:61: warning: shadowing outer local variable - record
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/requests/dns/get_record.rb:63: warning: shadowing outer local variable - record
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/requests/dns/get_record.rb:67: warning: shadowing outer local variable - record
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/requests/dns/get_zone.rb:33: warning: shadowing outer local variable - zone
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-dynect-0.2.0/lib/fog/dynect/requests/dns/get_zone.rb:33: warning: shadowing outer local variable - data
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
....../Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/Code/record_store/test/zone_test.rb:168: warning: File.exists? is a deprecated name, use File.exist? instead
...../Users/weppos/Code/record_store/lib/record_store/provider.rb:99: warning: File.exists? is a deprecated name, use File.exist? instead
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/requests/dns/get_domain.rb:27: warning: shadowing outer local variable - domain
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/requests/dns/update_record.rb:36: warning: shadowing outer local variable - record
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
E......../Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/Code/record_store/test/zone_test.rb:210: warning: File.exists? is a deprecated name, use File.exist? instead
..../Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
./Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
./Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
Applying 0 additions, 0 removals, & 1 updates...
Updating record with ID 12345678 to [TXTRecord] test-record.dns-test.shopify.io. 3600 IN TXT "update"...
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized

Published dns-test.shopify.io changes to DynECT
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
.........../Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
Applying 1 additions, 0 removals, & 0 updates...
Creating [ARecord] test-record.dns-test.shopify.io. 86400 IN A 10.10.10.42...
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized

Published dns-test.shopify.io changes to DynECT
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
........../Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
............Applying 1 additions, 0 removals, & 0 updates...
Creating [ARecord] test-record.dns-scratch.me. 86400 IN A 10.10.10.42...
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
E../Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
E./Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
EApplying 1 additions, 0 removals, & 0 updates...
Creating [ALIASRecord] dns-scratch.me. 86400 IN ALIAS dns-scratch.herokuapp.com....
/Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:103: warning: instance variable @path_prefix not initialized
E..............

Finished in 0.611692s, 143.8633 runs/s, 407.0676 assertions/s.

  1) Error:
ZoneTest#test_download_creates_zone_with_alias_support_based_on_provider:
VCR::Errors::UnusedHTTPInteractionError: There are unused HTTP interactions left in the cassette:
  - [get https://api.dnsimple.com/v1/domains/dns-scratch.me/records ""] => [200 "[{\"record\":{\"id\":5207716,\"domain_id\":222002,\"parent_id\":null,\"name\":\"test-record"]
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette/http_interaction_list.rb:68:in `assert_no_unused_interactions!'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette.rb:68:in `eject'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:156:in `eject_cassette'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:96:in `block in current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `loop'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:122:in `current_matchers'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:118:in `match_request_on_body?'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:110:in `request_description'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:84:in `construct_message'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:72:in `initialize'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `new'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `on_unhandled_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:24:in `handle'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:68:in `before_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:20:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/mock.rb:48:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/instrumentor.rb:26:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/connection.rb:249:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:81:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-xml-0.1.3/lib/fog/xml/connection.rb:9:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/dns.rb:102:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/requests/dns/list_records.rb:16:in `list_records'
    /Users/weppos/Code/record_store/lib/record_store/provider/dnsimple.rb:41:in `retrieve_current_records'
    /Users/weppos/Code/record_store/lib/record_store/zone.rb:25:in `download'
    /Users/weppos/Code/record_store/test/zone_test.rb:196:in `block (2 levels) in test_download_creates_zone_with_alias_support_based_on_provider'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:189:in `use_cassette'
    /Users/weppos/Code/record_store/test/zone_test.rb:195:in `block in test_download_creates_zone_with_alias_support_based_on_provider'
    /Users/weppos/Code/record_store/test/zone_test.rb:407:in `block in with_zones_tmpdir'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/2.4.0/tmpdir.rb:89:in `mktmpdir'
    /Users/weppos/Code/record_store/test/zone_test.rb:405:in `with_zones_tmpdir'
    /Users/weppos/Code/record_store/test/zone_test.rb:193:in `test_download_creates_zone_with_alias_support_based_on_provider'

  2) Error:
DNSimpleTest#test_apply_changeset_sets_state_to_match_changeset:
VCR::Errors::UnusedHTTPInteractionError: There are unused HTTP interactions left in the cassette:
  - [post https://api.dnsimple.com/v1/domains/dns-scratch.me/records "{\"record\":{\"name\":\"test-record\",\"record_type\":\"A\",\"content\":\"10.10.10.42\",\"ttl\":"] => [201 "{\"record\":{\"id\":5207716,\"domain_id\":222002,\"parent_id\":null,\"name\":\"test-record\""]
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette/http_interaction_list.rb:68:in `assert_no_unused_interactions!'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette.rb:68:in `eject'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:156:in `eject_cassette'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:96:in `block in current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `loop'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:122:in `current_matchers'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:118:in `match_request_on_body?'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:110:in `request_description'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:84:in `construct_message'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:72:in `initialize'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `new'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `on_unhandled_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:24:in `handle'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:68:in `before_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:20:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/mock.rb:48:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/instrumentor.rb:26:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/connection.rb:249:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:81:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-xml-0.1.3/lib/fog/xml/connection.rb:9:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/dns.rb:102:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/requests/dns/create_record.rb:31:in `create_record'
    /Users/weppos/Code/record_store/lib/record_store/provider/dnsimple.rb:12:in `add'
    /Users/weppos/Code/record_store/lib/record_store/provider.rb:80:in `block in apply_changeset'
    /Users/weppos/Code/record_store/lib/record_store/provider.rb:73:in `each'
    /Users/weppos/Code/record_store/lib/record_store/provider.rb:73:in `apply_changeset'
    /Users/weppos/Code/record_store/test/providers/dnsimple_test.rb:207:in `block in test_apply_changeset_sets_state_to_match_changeset'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:189:in `use_cassette'
    /Users/weppos/Code/record_store/test/providers/dnsimple_test.rb:206:in `test_apply_changeset_sets_state_to_match_changeset'

  3) Error:
DNSimpleTest#test_retrieve_current_records_returns_array_of_records:
VCR::Errors::UnusedHTTPInteractionError: There are unused HTTP interactions left in the cassette:
  - [get https://api.dnsimple.com/v1/domains/dns-scratch.me/records ""] => [200 "[{\"record\":{\"id\":5207716,\"domain_id\":222002,\"parent_id\":null,\"name\":\"test-record"]
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette/http_interaction_list.rb:68:in `assert_no_unused_interactions!'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette.rb:68:in `eject'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:156:in `eject_cassette'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:96:in `block in current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `loop'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:122:in `current_matchers'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:118:in `match_request_on_body?'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:110:in `request_description'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:84:in `construct_message'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:72:in `initialize'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `new'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `on_unhandled_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:24:in `handle'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:68:in `before_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:20:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/mock.rb:48:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/instrumentor.rb:26:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/connection.rb:249:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:81:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-xml-0.1.3/lib/fog/xml/connection.rb:9:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/dns.rb:102:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/requests/dns/list_records.rb:16:in `list_records'
    /Users/weppos/Code/record_store/lib/record_store/provider/dnsimple.rb:41:in `retrieve_current_records'
    /Users/weppos/Code/record_store/test/providers/dnsimple_test.rb:280:in `block in test_retrieve_current_records_returns_array_of_records'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:189:in `use_cassette'
    /Users/weppos/Code/record_store/test/providers/dnsimple_test.rb:279:in `test_retrieve_current_records_returns_array_of_records'

  4) Error:
DNSimpleTest#test_zones_returns_list_of_zones_managed_by_provider:
VCR::Errors::UnusedHTTPInteractionError: There are unused HTTP interactions left in the cassette:
  - [get https://api.dnsimple.com/v1/domains ""] => [200 "[{\"domain\":{\"id\":222002,\"user_id\":null,\"registrant_id\":null,\"name\":\"dns-scratch."]
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette/http_interaction_list.rb:68:in `assert_no_unused_interactions!'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette.rb:68:in `eject'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:156:in `eject_cassette'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:96:in `block in current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `loop'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:122:in `current_matchers'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:118:in `match_request_on_body?'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:110:in `request_description'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:84:in `construct_message'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:72:in `initialize'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `new'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `on_unhandled_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:24:in `handle'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:68:in `before_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:20:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/mock.rb:48:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/instrumentor.rb:26:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/connection.rb:249:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:81:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-xml-0.1.3/lib/fog/xml/connection.rb:9:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/dns.rb:102:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/requests/dns/list_domains.rb:16:in `list_domains'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/models/dns/zones.rb:12:in `all'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/collection.rb:112:in `lazy_load'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/collection.rb:16:in `map'
    /Users/weppos/Code/record_store/lib/record_store/provider/dnsimple.rb:55:in `zones'
    /Users/weppos/Code/record_store/test/providers/dnsimple_test.rb:287:in `block in test_zones_returns_list_of_zones_managed_by_provider'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:189:in `use_cassette'
    /Users/weppos/Code/record_store/test/providers/dnsimple_test.rb:286:in `test_zones_returns_list_of_zones_managed_by_provider'

  5) Error:
DNSimpleTest#test_apply_changeset_with_alias_cleans_up_txt_record:
VCR::Errors::UnusedHTTPInteractionError: There are unused HTTP interactions left in the cassette:
  - [post https://api.dnsimple.com/v1/domains/dns-scratch.me/records "{\"record\":{\"name\":\"\",\"record_type\":\"ALIAS\",\"content\":\"dns-scratch.herokuapp.com\""] => [201 "{\"record\":{\"id\":5209959,\"domain_id\":222002,\"parent_id\":null,\"name\":\"\",\"content\":"]
  - [get https://api.dnsimple.com/v1/domains/dns-scratch.me/records ""] => [200 "[{\"record\":{\"id\":5207716,\"domain_id\":222002,\"parent_id\":null,\"name\":\"test-record"]
  - [delete https://api.dnsimple.com/v1/domains/dns-scratch.me/records/5209960 ""] => [200 "{}"]
  - [get https://api.dnsimple.com/v1/domains/dns-scratch.me/records ""] => [200 "[{\"record\":{\"id\":5207716,\"domain_id\":222002,\"parent_id\":null,\"name\":\"test-record"]
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette/http_interaction_list.rb:68:in `assert_no_unused_interactions!'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/cassette.rb:68:in `eject'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:156:in `eject_cassette'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:96:in `block in current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `loop'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:95:in `current_cassettes'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:122:in `current_matchers'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:118:in `match_request_on_body?'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:110:in `request_description'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:84:in `construct_message'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/errors.rb:72:in `initialize'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `new'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:97:in `on_unhandled_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/request_handler.rb:24:in `handle'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:68:in `before_request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/middleware/excon.rb:20:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/mock.rb:48:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/instrumentor.rb:26:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/middlewares/base.rb:16:in `request_call'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/excon-0.57.0/lib/excon/connection.rb:249:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-core-1.44.3/lib/fog/core/connection.rb:81:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-xml-0.1.3/lib/fog/xml/connection.rb:9:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/dns.rb:102:in `request'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/fog-1.33.0/lib/fog/dnsimple/requests/dns/create_record.rb:31:in `create_record'
    /Users/weppos/Code/record_store/lib/record_store/provider/dnsimple.rb:12:in `add'
    /Users/weppos/Code/record_store/lib/record_store/provider.rb:80:in `block in apply_changeset'
    /Users/weppos/Code/record_store/lib/record_store/provider.rb:73:in `each'
    /Users/weppos/Code/record_store/lib/record_store/provider.rb:73:in `apply_changeset'
    /Users/weppos/Code/record_store/test/providers/dnsimple_test.rb:220:in `block in test_apply_changeset_with_alias_cleans_up_txt_record'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
    /Users/weppos/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/vcr-3.0.3/lib/vcr.rb:189:in `use_cassette'
    /Users/weppos/Code/record_store/test/providers/dnsimple_test.rb:219:in `test_apply_changeset_with_alias_cleans_up_txt_record'

88 runs, 249 assertions, 0 failures, 5 errors, 0 skips
rake aborted!
Command failed with status (1)
/Users/weppos/.rbenv/versions/2.4.2/bin/bundle:23:in `load'
/Users/weppos/.rbenv/versions/2.4.2/bin/bundle:23:in `<main>'
Tasks: TOP => default => test
(See full trace by running task with --trace)

Is this expected? It looks like most of the tests passed fine, but there are 5 failures related to the cassettes.

Am I doing something wrong?


On a separate note, I was reading the README and it's not clear which file you refer to here:

In order to test changes on providers, you're going to need to update dev/secrets.json with credentials. Note: make sure the credentials are for test zone(s) as the changes specified in the directory will be applied.

TXT record quoting treated inconsistently across providers

quoting of TXT records is not being applied consistently across all providers

  1. (unquoted) text without whitespace appears to be applied correctly across all providers
  2. quoted text appears to be applied correctly across all providers
  3. (unquoted) text with whitespace is not applied correctly on GoogleCloudDNS BUG
  4. diff incorrectly detects a difference for unquoted text on GoogleCloudDNS BUG
  5. diff incorrectly detects a difference for quoted text on DynECT BUG

given the following TXT record definitions in yml...

  - type: TXT
    fqdn: txt.shopify.test.
    ttl: 30
    txtdata: text

  - type: TXT
    fqdn: txt.shopify.test.
    ttl: 30
    txtdata: "text with whitespace"

  - type: TXT
    fqdn: txt.shopify.test.
    ttl: 30
    txtdata: '"quoted text with whitespace"'

after applying in all three providers (DNSimple, DynECT, and GoogleCloudDNS), dig shows the following records...

$ dig +short TXT txt.shopify.test @ns1.dnsimple.com
"quoted text with whitespace"
"text"
"text with whitespace"

$ dig +short TXT txt.shopify.test @ns1.p19.dynect.net
"quoted text with whitespace"
"text"
"text with whitespace"

$ dig +short TXT txt.shopify.test @ns-cloud-a4.googledomains.com
"text"
"text" "with" "whitespace"
"quoted text with whitespace"

and record-store diff shows...

$ bin/record-store diff
Diffing 2 zones
.
Zone: shopify.test
--------------------
Provider: DynECT
Update:
 - [TXTRecord] txt.shopify.test. 30 IN TXT ""quoted text with whitespace""
--------------------
Provider: GoogleCloudDNS
Update:
 - [TXTRecord] txt.shopify.test. 30 IN TXT "text with whitespace"
 - [TXTRecord] txt.shopify.test. 30 IN TXT "text"
====================

[OCI] Divergence after pushing records

What's the problem?

The OCI provider isn't quite ready for prime time. For example, assert_empty_diff fails after pushing all types of a records to an OCI zone.

$ bin/record-store apply
pid: 66310
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
Applying 5 additions, 0 removals, and 0 updates...
Creating [AAAARecord] test_aaaa_type_record.test-oci.recordstore.com. 600 IN AAAA 2001:0db8:85a3:0000:0000:8a2e:0370:7334...
Creating [SPFRecord] test_spf_type_record.test-oci.recordstore.com. 600 IN SPF "thisistextforspfupdating"...
Creating [SRVRecord] test_srv_type_record.test-oci.recordstore.com. 3600 IN SRV 1 2 3 spf.test-oci.recordstore.com....
Creating [TXTRecord] test_txt_type_record.test-oci.recordstore.com. 1200 IN TXT "thisistextfortxt"...
Creating [TXTRecord] test_txt_type_record.test-oci.recordstore.com. 1200 IN TXT "thisistextfortxt2"...
Published test-oci.recordstore.com changes to OracleCloudDNS
$ bin/record-store assert_empty_diff
pid: 66338
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
SPF record type is deprecated (See RFC 7208 Section 14.1)
The following zones have diverged: test-oci.recordstore.com.
bin/record-store assert_empty_diff terminated with exit status 1

Clues

  • This may be have something to do with NS records injected by Oracle Cloud DNS.
  • Performing a diff could be handy after initially pushing records, in order to detect what the actual divergence is.

diff with record_store 5.0.x returns unexpected diffs for DNSimple

Related to: #47

For example:

bin/record-store diff
...
Zone: jadedpixel.com
--------------------
Provider: DNSimple
Add:
 - [TXTRecord] jadedpixel.com. 600 IN TXT "spycloud-domain-verification=39c758f7-86e8-4d72-a7c0-39fb9d3032e4"
====================
...

The record exists from the DNSimple UI:
image

EDIT: Due to fog/fog-dnsimple#4, diff is broken for DNSimple with 5.0.x releases.

Running the diff with record_store 4.0.7 returns no diffs.

/cc @weppos @es

Potential issue in TXT record updates

@Shopify/traffic

I'm pretty sure I hit a bug in TXT record updates when deploying https://github.com/Shopify/record-store/pull/961. The deploy failed: https://shipit.shopify.io/shopify/record-store/production/deploys/408593

Updating record with ID 6556402 to [TXTRecord] shopify.com. 3600 IN TXT "google-site-verification=a4GkGdS7vBnkI284VSCo4bfYDNg-8OcEyjz8PR8ZhDM"...
/app/data/bundler/ruby/2.3.0/gems/excon-0.54.0/lib/excon/middlewares/expects.rb:7:in `response_call': Expected(200) <=> Actual(400 Bad Request) (Excon::Error::BadRequest)
excon.error.response
  :body          => "{\"message\":\"Validation failed\",\"errors\":{\"base\":[\"Matching record already exists for this domain\"]}}"
  :cookies       => [
  ]
  :headers       => {
    "Access-Control-Allow-Headers"      => "Authorization,Accepts,Content-Type,X-DNSimple-Token,X-DNSimple-Domain-Token,X-CSRF-Token,x-requested-with"
    "Access-Control-Allow-Methods"      => "GET,POST,PUT,DELETE,OPTIONS"
    "Access-Control-Allow-Origin"       => "*"
    "Cache-Control"                     => "no-cache"
    "Connection"                        => "keep-alive"
    "Content-Type"                      => "application/json; charset=utf-8"
    "Date"                              => "Mon, 21 Nov 2016 12:15:33 GMT"
    "Server"                            => "nginx"
    "X-Content-Type-Options"            => "nosniff"
    "X-Download-Options"                => "noopen"
    "X-Frame-Options"                   => "DENY"
    "X-Permitted-Cross-Domain-Policies" => "none"
    "X-Request-Id"                      => "df60e897-3038-4a64-936d-159e9bab05f7"
    "X-Runtime"                         => "0.048308"
    "X-XSS-Protection"                  => "1; mode=block"
  }
  :host          => "api.dnsimple.com"
  :local_address => "172.20.72.27"
  :local_port    => 51821
  :path          => "/v1/domains/shopify.com/records/6556402"
  :port          => 443
  :reason_phrase => "Bad Request"
  :remote_ip     => "208.93.64.253"
  :status        => 400
  :status_line   => "HTTP/1.1 400 Bad Request\r\n"
	from /app/data/bundler/ruby/2.3.0/gems/excon-0.54.0/lib/excon/middlewares/response_parser.rb:9:in `response_call'
	from /app/data/bundler/ruby/2.3.0/gems/excon-0.54.0/lib/excon/connection.rb:388:in `response'
	from /app/data/bundler/ruby/2.3.0/gems/excon-0.54.0/lib/excon/connection.rb:252:in `request'
	from /app/data/bundler/ruby/2.3.0/gems/fog-core-1.43.0/lib/fog/core/connection.rb:81:in `request'
	from /app/data/bundler/ruby/2.3.0/gems/fog-xml-0.1.2/lib/fog/xml/connection.rb:9:in `request'
	from /app/data/bundler/ruby/2.3.0/gems/fog-1.33.0/lib/fog/dnsimple/dns.rb:102:in `request'
	from /app/data/bundler/ruby/2.3.0/gems/fog-1.33.0/lib/fog/dnsimple/requests/dns/update_record.rb:25:in `update_record'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/provider/dnsimple.rb:36:in `update'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/provider.rb:81:in `block in apply_changeset'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/provider.rb:71:in `each'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/provider.rb:71:in `apply_changeset'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/changeset.rb:61:in `apply'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/cli.rb:107:in `each'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/cli.rb:107:in `block in apply'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/cli.rb:103:in `each'
	from /app/data/bundler/ruby/2.3.0/gems/record_store-4.0.0/lib/record_store/cli.rb:103:in `apply'
	from /app/data/bundler/ruby/2.3.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
	from /app/data/bundler/ruby/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
	from /app/data/bundler/ruby/2.3.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
	from /app/data/bundler/ruby/2.3.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
	from bin/record-store:6:in `<main>'
bin/record-store apply exited with status 1

In the shopify.com zone I was adjusting the TTLs of some TXT records. The error Matching record already exists for this domain leads me to believe that Record Store was trying to create a new record instead of update the TTL. Note that this issue was only seen with the DNSimple update.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.