-
Notifications
You must be signed in to change notification settings - Fork 10
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
refactor using library crates #15
Conversation
Provides a working devshell and package binary.
Thanks to #7 which could not be directly applied due to conflict.
DNS resolution from google produced a different IP every time, which isn't what we want.
Potentially finished but cannot test due to an upstream issue with one of the endpoints: cloudflare/cloudflare-rs#198
Both the public ip crate, and the cloudflare api crate have small issues that prevent them from working properly, yet both have open PRs upstream to fix these issues, so simply patch the crates for now to get this working.
Allows for specifying the API in an intuitive way, and also automatically gives us a user help message.
Also add myself as a crate author
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.
-
Feels like a lot of (lines, complexity, etc) of Nix to add. I'm not opposed, but triggers a feeling of, "oh god, should all Rust projects need this much Nix to be a part of the ecosystem". Not a problem or blocker, just a thought I had.
-
If this fixes paging, can you note that in the README.
|
||
inputs.std.url = "github:divnix/std/v0.24.0-1"; | ||
inputs.std.inputs.nixpkgs.follows = "nixpkgs"; | ||
|
||
inputs.fenix.url = "github:nix-community/fenix"; | ||
inputs.crane.url = "github:ipetkov/crane"; | ||
inputs.crane.inputs.nixpkgs.follows = "nixpkgs"; | ||
inputs.crane.inputs.flake-compat.follows = ""; | ||
inputs.crane.inputs.rust-overlay.follows = ""; | ||
|
||
inputs.std.inputs.devshell.url = "github:numtide/devshell"; | ||
|
||
inputs.nixpkgs.follows = "fenix/nixpkgs"; |
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.
Mostly for my knowledge, can you fill me in on why these are all necessary?
Why fenix + crane? (I usually have used fenix to get a nightly toolchain, is that somehow needed here)?
What does std
provide?
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.
Sorry I didn't even think much about the Nix, I just used the Rust template that I made for Standard, that I am used to, but I can remove the Nix honestly. That was mostly for my own use, but it does setup a nice devshell with rust-analyzer ready to go for those who use terminal based editors.
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.
doesn't bother me, especially if you're maintaining it :)
I'm happy to give you maintainership, whether that means:
Or I can merge this in a bit and keep limping along 🙃. Let me know what you prefer, I don't have a strong preference, maybe a smidge of a note of origination if we do move the repo, but it's not really something I'm going to lose sleep over. |
I'm okay with any of the options, although I'd probably prefer to transfer to my user if that's okay with you, as I have more work I'd like to do. Of course I'll mention the proper attributions in the README |
Some questions:
Maybe I'm over-thinking it, but it feels like there's a chance that users could potentially end up in a situation where there's a stale/mismatched record -- imagine I have a laptop, I've previously setup A and AAAA records, and then run cfdyndns from a network where I only have ipv4 connectivity. It's hard to know what to do without requiring the user to be more explicit about A/AAAA records:
I guess it just depends on how comprehensive you want it to be. And I say all of this without really even remembering if the existing code adds missing records, and knowing that it doesn't have any support for AAAA. |
Yes, but so did the existing code. I didn't change substantially the code semantics at all, although some rethinking is likely in order at this point, and iterating over the
Only the IP that has been resolved on the localhost will be updated. So if I resolved ipv4 and there is an existing
|
Ah, well, note to my older, less wise self 😉. I feel like I just signed you up for more work, but I like the answers. 👍 Also, forgot to say but happy to transfer the repo, and it doesn't have to wait for the merge. Let me know. |
Also adds logic to remove stale DNS records.
for sanity & efficiencies sake
If you wouldn't mind redirecting at this point to my fork via github that would be great. I implemented the suggestions from our last conversation. So any non-existing records will now be created when a public ip is resolved, and stale records which no longer resolve locally will be deleted. These features are included in the v0.1.1 tag. |
this is top of my list to review tomorrow. |
Just saw this. I was going to transfer the repo to you. Not sure what will happen if I do that if you already have a repo named I'll look over this and then, merge and see what happens if I try to transfer. |
let mut handles = Vec::with_capacity(cli.records.len()); | ||
|
||
for (record, zone, dns_v4, dns_v6) in records { | ||
if let Some(zone) = zone { |
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.
This is mostly a nit, but:
- check the opposite condition
- warn if there's a record specified on CLI that doesn't have a matching Zone in CF
Right now, if the user passes a --record
that doesn't exist, this silently skips it. As a user, I'd like to be warned, or errored.
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.
(prevents some right-ward drift too)
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.
IMO, I'd probably elide the known domain suffix check too, in this case, and let CF be the arbiter of that. I don't know if CF allows "invalid" suffixes, maybe some folks use CF public DNS for internal names?
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.
Right now, if the user passes a
--record
that doesn't exist, this silently skips it. As a user, I'd like to be warned, or errored.
actually it should create a new record now, assuming at least the zone exists.
As for style in general, I have more recfactoring planned as well as time allows.
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.
It does create the record, but if I pass --record thisdoesntmatter.thiszonedoesntexist.com
then it silently exits with 0, even though there was no Zone found with a matching name. (aka, the second parameter of the tuple is None, and so this falls through)
(no matching Zone means it can't create the record, of course, but the user might want to know they've messed up)
params: ListZonesParams::default(), | ||
}; | ||
let zones = client.request(¶ms); | ||
// HACK: make a second call since dns::Zone does not implement Clone upstream |
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.
If I'm not mistaken, I think you can avoid this by cloning the zone_id and only capturing that in the async closure. A quick test shows this builds and seems to still work:
diff --git a/src/fns.rs b/src/fns.rs
index 81ff477..35e6469 100644
--- a/src/fns.rs
+++ b/src/fns.rs
@@ -72,19 +72,18 @@ pub async fn get_records(
let params = ListZones {
params: ListZonesParams::default(),
};
- let zones = client.request(¶ms);
- // HACK: make a second call since dns::Zone does not implement Clone upstream
- let zones2 = client.request(¶ms).await?.result;
+ let zones = client.request(¶ms).await?.result;
- let mut handles = Vec::with_capacity(zones2.len());
- let mut records = Vec::with_capacity(zones2.len() * 10);
+ let mut handles = Vec::with_capacity(zones.len());
+ let mut records = Vec::with_capacity(zones.len() * 10);
- for zone in zones.await?.result {
+ for zone in &zones {
let client = client.clone();
+ let zone_id = zone.id.to_string();
handles.push(tokio::spawn(async move {
client
.request(&ListDnsRecords {
- zone_identifier: &zone.id,
+ zone_identifier: zone_id.to_string().as_ref(),
params: ListDnsRecordsParams::default(),
})
.await
@@ -117,10 +116,10 @@ pub async fn get_records(
.map(|r| {
(
r.to_owned(),
- zones2
- .iter()
- .find(|z| r.contains(&z.name))
- .map(|z| z.id.to_owned()),
+ zones.iter().find(|z| r.contains(&z.name)).map(|z| {
+ log::info!("{}", z.id.to_owned());
+ z.id.to_owned()
+ }),
records
.iter()
.find(|rec| {
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.
I tried a bunch of ways to try and avoid the second call. I may submit a PR upstream to the cloudflare crate to just implement clone on some of the data types eventually. At least as I have it the first and second call happen asynchronously so as to avoid the overhead as much as possible.
I used this as a chance to check my own Rust knowledge. I'm happy to merge as-is. Do you want to rename your fork so the transfer is ... easier to assume what will happen? |
I renamed to |
Resolves #11
Fixes #12
This is a pretty hefty refactor which uses upstream crates to query cloudflare's API and to acquire the users public IP. In addition a basic clap API has been defined to make the required options discoverable directly from the command line. In addition, this adds ipv6 handling and will set both v4 and v6 addresses if found.
Not sure if you want to merge this, or if, as you mentioned elsewhere, you just want to hand over maintainership. Either way is fine by me. Just opening this to have that discussion.