-
-
Notifications
You must be signed in to change notification settings - Fork 15
fix!: Make fields on S3 structs mandatory, add S3 helpers #863
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
Conversation
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.
Partial review (as I see changes are still coming in)
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.
Partial review again :)
Co-authored-by: Nick <10092581+NickLarsenNZ@users.noreply.github.com>
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 didn't look at the S3 stuff super closely (I can if you want @sbernauer). The TLS code looks fine (as it is copy+pasted from the previous location).
All other comments are minor notes / suggestions.
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.
LGTM, only minor changes.
Co-authored-by: Techassi <git@techassi.dev>
Co-authored-by: Techassi <git@techassi.dev>
Co-authored-by: Techassi <git@techassi.dev>
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.
LGTM overall, just three small comments.
Co-authored-by: Techassi <git@techassi.dev>
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { | ||
String::json_schema(gen) | ||
} |
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 effectively dropping the validation regex from the composite type.
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're right. So far we don't have any regex on HostName, but instead let IpAddr::parse do it's thing and try to parse it as domain name in case it#s not an IP.
We should be able to come up with an regex that accepts a DomainName, IPv4 or IPv6 address. But do you think it's worth the effort?
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.
That's fair.
pub enum HostName { | ||
IpAddress(IpAddr), | ||
DomainName(DomainName), | ||
} |
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.
Do we actually care about distinguishing these cases?
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 personally modeled it as String, but @Techassi suggested using an enum instead, which sounded fine to me. No preference from me.
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.
The RFC calls for these two distinct variants of a hostname.
Why should we remove all the value we get from using proper types by just using a plain string? We could simplify the DomainName
variant to use String
, but I would definitely keep the enum.
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.
Ultimately the question here is the purpose of the type. Detailed types makes sense for inspecting and manipulating the hostname. The original intent for Hostname
was the much smaller scope of "make sure this opaque looks close enough to a hostname that it won't fuck up the syntax of the config file it's string-templated into".
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.
looks close enough
If we want to achieve this, sure. But then why reference RFC 1123 and only vaguely conform to it. If we want to conform to various RFCs, we should do so as closely as possible.
Another region where we try to conform to an RFC (1035), we also completely miss the mark when validating domain labels. So I'm just trying to avoid the same thing happening here (even tho the domain name is not 100% valid).
InvalidHostnameSnafu { | ||
hostname: value.to_owned(), | ||
} | ||
.fail() |
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 dropping the context for why validation failed.
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.
At this code point we have access to an IpAdd::parse error and and regex validation error.
if let Ok(ip) = value.parse::<IpAddr>() {
return Ok(HostName::IpAddress(ip));
}
if let Ok(domain_name) = value.parse() {
return Ok(HostName::DomainName(domain_name));
};
InvalidHostnameSnafu {
hostname: value.to_owned(),
}
.fail()
Should we capture both errors and put them both in? E.g. "needs to be an ip, which it does'nt because of {error1}, and also is no domain name because of [error2}"?
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.
That's one way, but it loses the error chain. Another alternative would be to guess based on a cursory inspection.. something like:
if value.starts_with(char::is_ascii_digit) || value.contains(':') {
Ok(HostName::IpAddress(value.parse().context(InvalidIpAddressSnafu { hostname: value })?))
} else {
Ok(HostName::DomainName(value.parse().context(InvalidDomainNameSnafu { hostname: value })?))
}
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.
We could also do something like:
match value.parse::<IpAddr>() {
Ok(ip_addr) => return Ok(Hostname::IpAddr(ip_addr)),
Err(ip_err) => match value.parse::<DomainName>() {
Ok(dn) => return Ok(Hostname::DomainName(dn)),
Err(dn_err) => // return both errors
}
}
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.
Yes that's effectively what @sbernauer suggested. There problem is that there's no way for an Error
to have multiple source()
s, so we'd have to pick one primary and render the other one as unawkwardly as we can.
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.
there's no way for an Error to have multiple source()s, so we'd have to pick one primary and render the other one as unawkwardly as we can.
That is indeed very true (and unfortunate). The cursed inspection is also kinda meh tho. I don't know if it helps (I assume not), RFC 1123 states that the host name should first tried to be parsed as an IP address. So at least we do the correct thing RFC-wise.
Description
Reviving #679 (replacing it)
Example usage is in https://github.com/stackabletech/trino-operator/tree/chore/new-s3-structs
Definition of Done Checklist