-
Notifications
You must be signed in to change notification settings - Fork 372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLOUDFLAREAPI: Adds CF_WORKER_ROUTE. #1243
Conversation
Added initial tests, similar to Guidance required for the integration tests (I didn't find where the expected result should be). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few more comments.
- Please rebase
- Please add a test to integrationTest/integration_test.go
About the integration tests... I am somewhat lost. 😢 How do we test this? How could I check if the test is passing or not (won't I need some API credentials to run it locally?). I'm surely missing something here 😅 |
Here is how to add a simple integration test: #1250 To run the integration tests you'll need a test domain:
Even without that PR, I've found a small bug. It looks like the code assumes that there will be a worker route list.
|
FYI: The automated tests (https://github.com/StackExchange/dnscontrol/pull/1243/checks) are skipping CloudFlare because it can't find any credentials. Github Actions uses the credentials from the fdcastel/dnscontrol repo and there are none. Once it is merged to StackExchange/dnscontrol it will have access to the credentials in StackExchange/dnscontrol and the tests will run. (this is to protect someone from writing a PR that steals the creds.) |
I'm still missing something. Even after pulling your sample code and settings my env vars like: $env:CLOUDFLAREAPI_DOMAIN='my-cf-domain.com'
$env:CLOUDFLAREAPI_KEY='my-api-key'
$env:CLOUDFLAREAPI_USER='my-api-user' A call to go test -v -verbose -provider CLOUDFLAREAPI gives me
Running on Windows 10 / Powershell |
Just to be clear: I already read https://stackexchange.github.io/dnscontrol/byo-secrets and it seems clear to me. But I'm trying to run the tests locally on my machine before I put them into the CI. Is this possible or I misunderstood something? (i.e., the tests would only run inside Github CI engine?) |
Got it! go test -v ./integrationTest -verbose -provider CLOUDFLAREAPI Tests are running now 🙌 . Working on it. |
3eb0e13
to
56085e6
Compare
There is some way -- in the current test infrastructure -- to run additional code before some Rationale: I have the following test: testgroup("CF_WORKER_ROUTE",
only("CLOUDFLAREAPI"),
tc("simple", cfWorkerRoute("cnn.**current-domain-no-trailing**/*", "cnn-worker")),
tc("changeScript", cfWorkerRoute("cnn.**current-domain-no-trailing**/*", "msnbc-worker")), But before it, I need to call an additional Cloudflare api to create Without this, the API calls under test will fail with a [{"code":10019,"message":"workers.api.error.invalid_route_script_missing"}] |
✔️ Rebase done. |
There isn't a uniform way to do setup code. However.... Around line 55 of integration_test.go we do some "just for CloudFlare" actions. Maybe that could call a function that creates the workers if they don't already exist? Please create them with names that won't overlap real workers... maybe dnsctrl_integrationtest_foo and dnsctrl_integrationtest_bar ? Tom |
Minor update: Yet working on it. I should update this PR in a few days. Thanks, @tlimoncelli ! |
Sorry for the delay. It has been a long week around here. It's almost done. However, I'm having a hard time making Cloudflare-specific API calls from One solution would be to add a Could we use |
Pushed what I got so far. Looking for advice. I added I also added two new env vars AccountName is not used, actually. However, there is a test in |
Hi there! Sorry for the delay. It's been a crazy week! A few things:
The code either needs to automagically detect if Workers is disabled and be silent or there needs to be a feature-flag to enable Workers. Otherwise this will be a breaking change... people that don't use workers can't break and can't be asked to modify permissions on the API key just because of a new feature. I don't know how to detect if workers is enabled, but I'm making a PR that adds the feature flag in case you go that route: https://github.com/fdcastel/dnscontrol/pull/1/files
The right place for At least I think that will work. I'm not entirely sure as I can't test it myself until I fix my own permission problem. I'm in the US/Eastern timezone if you would like to screenshare and work on this in real time. Tom |
Thanks, Tom, for the insights and the pragmatism 😉 - I will return to this in a few hours. About your points:
|
7a6f2cf
to
e272171
Compare
Rebase to latest release. |
Added feature flag for CF Workers per @tlimoncelli suggestion. Porting tests back to |
All done! Integration tests are creating test workers now. Two considerations:
|
I ran all tests twice (first without test workers and then with them) in a test domain and everything looks good to me. Save for further coding improvements (see last comment) I would consider the work now done. Also, if agreed, I would like to rewrite the commit history to put the commits in a better shape before merge. |
Looks very good so far! I do want to find a way to make legacy domains "just work". Here's the one I use for tests:
|
Sorry, Tom. I should have stressed this : To make the tests work you must now set That Maybe I should add a test and emit a P.S: |
Hi there! I'm sorry but I'm having trouble getting this to run on a legacy domain. It is very important that we make this change in an upwards compatible manner. Currently we get errors like:
How about we add a feature-flag? For example, with "CLOUDFLARE_WORKERS=1" the new code runs. If it isn't set, the new code silently disables itself. Tom |
Sorry, Tom. I don't understand. Did you see my last message? According to your error message:
It seems that the To make the things clearer, this is how I ran the tests: go build
$env:CLOUDFLAREAPI_DOMAIN='my-test-domain.com'
$env:CLOUDFLAREAPI_KEY='my-api-key'
$env:CLOUDFLAREAPI_USER='my@email.com'
$env:CLOUDFLAREAPI_ACCOUNTID='my-account-id'
$env:CLOUDFLAREAPI_ACCOUNTNAME='MyAccountName'
go test -v ./integrationTest -verbose -provider CLOUDFLAREAPI The Please tell me how this has worked for you. I don't see the need for an additional feature flag given that we already added one ( |
@tlimoncelli this PR seems to work fine for me. I don't use cloudflare workers normally and everything runs as expected (I don't set accountId and @fdcastel Here are the changes I made to work with latest master and get Also, this doesn't cleanup the workers after-the-fact which may not be great, but I don't think it's really hurting anything. diff --git a/integrationTest/integration_test.go b/integrationTest/integration_test.go
index a8250c51..28e749e4 100644
--- a/integrationTest/integration_test.go
+++ b/integrationTest/integration_test.go
@@ -70,8 +70,12 @@ func getProvider(t *testing.T) (providers.DNSServiceProvider, string, map[int]bo
}
}
- // Cloudflare only. Will do nothing if provider != *cloudflareProvider.
- cloudflare.PrepareCloudflareTestWorkers(t, provider)
+ if name == "CLOUDFLAREAPI" {
+ // Cloudflare only. Will do nothing if provider != *cloudflareProvider.
+ if err := cloudflare.PrepareCloudflareTestWorkers(provider); err != nil {
+ t.Fatal(err)
+ }
+ }
return provider, cfg["domain"], fails, cfg
}
diff --git a/providers/cloudflare/cloudflareProvider.go b/providers/cloudflare/cloudflareProvider.go
index 9ceb4418..e1e4851e 100644
--- a/providers/cloudflare/cloudflareProvider.go
+++ b/providers/cloudflare/cloudflareProvider.go
@@ -6,7 +6,6 @@ import (
"log"
"net"
"strings"
- "testing"
"github.com/cloudflare/cloudflare-go"
"github.com/miekg/dns/dnsutil"
@@ -506,8 +505,6 @@ func newCloudflare(m map[string]string, metadata json.RawMessage) (providers.DNS
api.cfClient.AccountID = m["accountid"]
}
- api.cfClient.AccountID = api.AccountID
-
if len(metadata) > 0 {
parsedMeta := &struct {
IPConversions string `json:"ip_conversions"`
@@ -674,17 +671,18 @@ func (c *cloudflareProvider) EnsureDomainExists(domain string) error {
}
// PrepareCloudflareWorkers creates Cloudflare Workers required for CF_WORKER_ROUTE tests.
-func PrepareCloudflareTestWorkers(t *testing.T, prv providers.DNSServiceProvider) {
+func PrepareCloudflareTestWorkers(prv providers.DNSServiceProvider) error {
cf, ok := prv.(*cloudflareProvider)
if ok {
err := cf.createTestWorker("dnscontrol_integrationtest_cnn")
if err != nil {
- t.Fatal(err)
+ return err
}
err = cf.createTestWorker("dnscontrol_integrationtest_msnbc")
if err != nil {
- t.Fatal(err)
+ return err
}
}
+ return nil
} |
@tlimoncelli to be clear, I ran the integration tests as follows. I've sanitized the domain I use as it's not really a testing domain :-P $ cd integrationTest
$ export CLOUDFLAREAPI_ACCOUNTID=[ACCOUNT_ID]
$ export CLOUDFLAREAPI_DOMAIN=[DOMAIN]
$ export CLOUDFLAREAPI_TOKEN=[TOKEN]
$ go test -v -verbose -provider CLOUDFLAREAPI --start 41
=== RUN TestDNSProviders
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/Clean_Slate:Empty
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:simple
integration_test.go:208: CREATE WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN} cnn.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_cnn ttl=1
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:changeScript
integration_test.go:208: MODIFY WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN}: (cnn.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_cnn ttl=1) -> (cnn.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_msnbc ttl=1)
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:changePattern
integration_test.go:208: MODIFY WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN}: (cnn.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_msnbc ttl=1) -> (cable.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_msnbc ttl=1)
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:Empty
integration_test.go:208: DELETE WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN} cable.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_msnbc ttl=1
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:createMultiple
integration_test.go:208: CREATE WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN} cnn.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_cnn ttl=1
integration_test.go:208: CREATE WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN} msnbc.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_msnbc ttl=1
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:addOne
integration_test.go:208: CREATE WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN} api.${CLOUDFLAREAPI_DOMAIN}/cnn/*,dnscontrol_integrationtest_cnn ttl=1
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:changeOne
integration_test.go:208: MODIFY WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN}: (msnbc.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_msnbc ttl=1) -> (msn.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_msnbc ttl=1)
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:deleteOne
integration_test.go:208: DELETE WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN} cnn.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_cnn ttl=1
=== RUN TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/Post_cleanup:Empty
integration_test.go:208: DELETE WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN} api.${CLOUDFLAREAPI_DOMAIN}/cnn/*,dnscontrol_integrationtest_cnn ttl=1
integration_test.go:208: DELETE WORKER_ROUTE ${CLOUDFLAREAPI_DOMAIN} msn.${CLOUDFLAREAPI_DOMAIN}/*,dnscontrol_integrationtest_msnbc ttl=1
--- PASS: TestDNSProviders (31.58s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN} (24.06s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/Clean_Slate:Empty (1.49s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:simple (2.36s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:changeScript (2.69s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:changePattern (2.78s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:Empty (1.06s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:createMultiple (3.17s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:addOne (2.31s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:changeOne (3.45s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/41:CF_WORKER_ROUTE:deleteOne (2.65s)
--- PASS: TestDNSProviders/${CLOUDFLAREAPI_DOMAIN}/Post_cleanup:Empty (1.99s)
=== RUN TestDualProviders
integration_test.go:313: Clearing everything
integration_test.go:319: Adding nameservers from another provider
WARNING: cloudflare does not support modifying NS records on base domain. ns1.example.com. will not be added.
WARNING: cloudflare does not support modifying NS records on base domain. ns2.example.com. will not be added.
integration_test.go:322: Running again to ensure stability
WARNING: cloudflare does not support modifying NS records on base domain. ns1.example.com. will not be added.
WARNING: cloudflare does not support modifying NS records on base domain. ns2.example.com. will not be added.
--- PASS: TestDualProviders (9.31s)
PASS
ok github.com/StackExchange/dnscontrol/v3/integrationTest 41.469s
$ |
I'm getting a build error:
|
@tlimoncelli Yeah, need the patch I included above to make it work with latest master. |
Sorry for the delay. Working on it now! |
- CLOUDFLAREAPI: Initial support for CF_WORKER_ROUTE. - Put CF_WORKER_ROUTE behind a per-domain feature-flag. - Adds Integration Test. - Create Cloudflare workers for tests. - Updates documentation.
5a25b14
to
f750a6a
Compare
Rebase done with latest master. @tresni patch applied. All tests passing. 🎉 |
Fully agreed. I don't like this either. We just took the pragmatic approach, here.
Yep. Not ideal. But, also agreed, not a big problem. Thanks for the patch for the latest master. 👍 |
@tlimoncelli please let me know if you have any problem with the integration tests. |
.github/workflows/build.yml
Outdated
@@ -94,6 +94,8 @@ jobs: | |||
CLOUDFLAREAPI_KEY: ${{ secrets.CLOUDFLAREAPI_KEY }} | |||
CLOUDFLAREAPI_TOKEN: ${{ secrets.CLOUDFLAREAPI_TOKEN }} | |||
CLOUDFLAREAPI_USER: ${{ secrets.CLOUDFLAREAPI_USER }} | |||
CLOUDFLAREAPI_ACCOUNTID: ${{ secrets.CLOUDFLAREAPI_ACCOUNTID }} | |||
CLOUDFLAREAPI_ACCOUNTNAME: ${{ secrets.CLOUDFLAREAPI_ACCOUNTNAME }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this, it's not needed anymore :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch! 😅
Here's what I get:
However if I run "dnscontrol preview" on Stackoverflow's dnsconfig.js or my personal dnsconfig.js it works just fine. So, that tells me that it is only the integration tests that are still poking at workers when they shouldn't. |
@tlimoncelli that sounds like the API key doesn't have the right privileges to access workers. If you update the permissions to the following for your testing API key, it should go off with out a hitch. I think this should be the expected behavior if we want integration tests to be able to test the worker routes. Another possibility would be to try and bail in the test group if CLOUDFLAREAPI_ACCOUNTID isn't set, but there's no existing support for that in the integration test framework. This leads to a default behavior of "if you want to test the Cloudflare integration, you need to test all of it." (You could replace Cloudflare with any other provider.) That seems to be how page rules are treated today (they just don't require an account id ;-) ). |
@tlimoncelli Could you ask the person responsible for the Cloudflare account used in DNSControl tests to fix the permissions above? |
Sadly I can't change that domain because I need it to test legacy configurations. That said, I'm providing fdcastel#2 which adds a flag to the integration tests for legacy domains and updates the docs. If you merge those changes into your PR, we should be done. I appreciate your patience. It's very busy at Stack right now as I'm in the middle of some big system upgrades. That said, I'm super excited to see this functionality come to DNSControl and I appreciate all your effort to get this working. Thanks! |
Great! Working on it... |
* alltrue() should be implemented like other filters. * Update documentation.
997c37f
to
f4ad8b6
Compare
All done! Clean merge. Thanks @tlimoncelli !! 🙌 |
Thanks to everyone involved in getting this done! |
Initial implementation of CF_WORKER_ROUTE.
Adds Cloudflare Worker routes support via new
CF_WORKER_ROUTE
function.No tests, as I have yet to understand the tests infrastructure. But the code is working as I did some manual tests with a personal CF account (Create, Modify and Delete routes are working as expected).
Thanks to @tlimoncelli for guidance and incentive.