-
-
Notifications
You must be signed in to change notification settings - Fork 342
engine: resources: Add Cloudflare DNS resource #824
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
base: master
Are you sure you want to change the base?
Conversation
|
Thanks for the patch. A brief design review with some broad questions:
Thanks! |
The user needs to set the This will, in practice, wipe all the records, given that the only record that it's managed by the resource has state
I don't understand this question, sorry. I've tested this with invalid params, and the Validate() checks are working. I don't know what you mean by "doesn't get used".
I saw it, but the rate limiting that CF imposes is pretty lax: 1200 requests over 5 minutes (when why I wrote ~4req/s in a comment of my code, which is just an average). I've also made the polling rate check to always be bigger than 60s. So I don't think this is something that 's worth doing, at least not unless someone is managing some hundreds of records.
I tested this by running .mcl code like the one I pasted in the OP, and verifying that the changes were being applied correctly on CF's dashboard. It's of course possible to write tests, but we always need to provide an API key for auth, so that sort of precludes any automated testing that could be shared afaik.
My pleasure. |
For example, let's say you only wanted to remove all unmanaged records.
Well, I have over a 100 DNS records in my personal cloudflare account, and it's just small personal stuff mostly. But 100 shouldn't be seen as outrageous. I think it's elegant to have this nice fallback to regular DNS, that is if we have an algorithm to do that. |
Have you heard of "mock"-ing? |
But this is the already the behavior of the purge function. Purge only removes unmanaged resources.
I was digging a bit more into this, and I realized something: if we're thinking in the case of managing hundreds of records, our limit might not be the 1200req/5min that CF has, but rather the 200req/s per IP (cf. this). Given that each request spends 2 API tokens at the moment per resource managed, managing over 100 records might already trip some limits. Now, this might not be a problem at first, given that the GET requests will get a 429 and retry. This behavior can be configured at the library level when we're registering a new client (WithRequestTimeou and WithMaxRetries). While I was reading about it, I also found about WithMiddleware , and this might be used in conjunction with the stdlib rate package to implement a simple rate limiting system. I think that with these three options (setting those two options, and implementing the middleware) would allow us to be able to manage thousands of records, and always be inside the limits that CF imposes.
Can't say I have! |
2ca2bbf to
fff86a5
Compare
|
I pushed some small changes, namely I added the log functionality you suggested. I also had a look at how to mock tests, and I think I understand now: basically we're feeding the test some fake data (as if it would come from Cloudflare). But as far as I can tell, this would require some light refactoring of the current implementation, as I'd need to implement an interface which I could then use for mocked tests. Does this make sense? Also, how do you want to go about the rate-limiting part? |
fff86a5 to
91669b2
Compare
|
After what we talked about over Matrix, I've made the requested changes - this now checks against DNS records using the net package first, instead of directly going to the Cloudflare API to check the current state. Still, there's a kink here that I'm not sure how to deal with: there's three fields that we can't query with the DNS request - TTL, Proxied, and Comment, as these are internal to Cloudflare. They will always require that we fetch the info from the Cloudflare API, and if any of these fields are set, there's no savings in terms of API calls. Still, we need to check them otherwise we might introduce drift between the desired state and what's on Cloudflare, and that's why I opted for the current implementation of always checking. Let me know what you think. |
|
Sweet!
Alright, now we're talking. In matrix I mentioned:
Feels like the prophecy came true =D Was it fun to write the resolver code? Is there a chance that different casing or similar looking data would say "mismatch" even though the data is meant to be the same? (Cloudflare API might preserve case, for example, does resolver code and intermediate DNS servers do the same? -- I don't actually know the answer offhand, I don't remember enough DNS spec, but an easy question to ask.) So what should we do about the missing values? Here's one possible approach: CheckApply (the first time it runs) checks via API to CF. After it succeeds once with "values match, aka cloudflareCheckApply() -> true" then subsequent checks fall back to regular DNS. Remember, mgmt's default job is not meant to be a "guardian against a sysadmin messing with values", but in this case, we can add a flag (pick a better name?) What do you think? Some review comments:
vs So if one person wanted to guarantee never any purges, all you have to do is: And you'd never be able to cause a purge.
LMK if that all makes sense! Thank you for your work. |
This adds a resource to manage DNS on Cloudflare. Making use of the official Golang API, we add functionality to create, update, edit, delete records. A function to purge unmanaged records is also available. Since the REST API does not provide us with an event stream, we make use of polling to check for changes on Cloudflare.
91669b2 to
1e63b4e
Compare
|
Alright, I pushed an improved version of the code. Changes of notes:
Once I understood how to write one of the lookup functions, everything fell into place, as all the other ones were pretty similar. I wouldn't say "fun" is the right word, but it was a good exercise for sure!
Yes, and I already accounted for all the corner cases I could find.
It wouldn't fail. It shouldn't fail. I don't follow the question.
This is not what happens. I just tried it in my most recent commit - as long as there's a single |
|
Looking good, I think just the purge discussion needs to be handled how I discussed unless I missed a reason why it's better the original way? |
Sorry, could you point me to where there's a spec of how you want the purge function to work? |
purge param, not function, but: |
|
I answered this at the end of this comment. So it's not clear to me where you think it needs to change/improve. |
3221a93 to
4ad2b9a
Compare
This adds a resource to manage DNS on Cloudflare. Making use of the official Golang API, we add functionality to create, update, edit, delete records. A function to purge unmanaged records is also available. Since the REST API does not provide us with an event stream, we make use of polling to check for changes on Cloudflare.
I've tested each functionality with an mcl of this type, changing the values to test the different functionalities:
And everything seems to work. I've also tested changing two resources at once, and everything worked as well. Tests are also passing locally, so I'm submitting this for review.