Skip to content
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

[nexus] instance create: make hostname param optional #6824

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

david-crespo
Copy link
Contributor

@david-crespo david-crespo commented Oct 10, 2024

When hostname is None in the create request body, use the instance name.

Related to #68. There's pretty extensive discussion on there, but it's over two years old — what are hostnames for, could we just get rid of the param entirely, etc. But the change I've made here is a superficial one that we could make right away without much downside that I can see. I was going to make this change on the CLI layer, but then I realized it could just be done here and the CLI would get it for free.


Note that in #4938 we started validating hostname:

/// An RFC-1035-compliant hostname.
#[derive(
Clone, Debug, Deserialize, Display, Eq, PartialEq, SerializeDisplay,
)]
#[display("{0}")]
#[serde(try_from = "String", into = "String")]
pub struct Hostname(String);
impl Hostname {
/// Return the hostname as a string slice.
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
// Regular expression for hostnames.
//
// Each name is a dot-separated sequence of labels. Each label is supposed to
// be an "LDH": letter, dash, or hyphen. Hostnames can consist of one label, or
// many, separated by a `.`. While _domain_ names are allowed to end in a `.`,
// making them fully-qualified, hostnames are not.
//
// Note that labels are allowed to contain a hyphen, but may not start or end
// with one. See RFC 952, "Lexical grammar" section.
//
// Note that we need to use a regex engine capable of lookbehind to support
// this, since we need to check that labels don't end with a `-`.
const HOSTNAME_REGEX: &str = r#"^([a-zA-Z0-9]+[a-zA-Z0-9\-]*(?<!-))(\.[a-zA-Z0-9]+[a-zA-Z0-9\-]*(?<!-))*$"#;
// Labels need to be encoded on the wire, and prefixed with a signel length
// octet. They also need to end with a length octet of 0 when encoded. So the
// longest name is a single label of 253 characters, which will be encoded as
// `\xfd<the label>\x00`.
const HOSTNAME_MAX_LEN: u32 = 253;
impl FromStr for Hostname {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
anyhow::ensure!(
s.len() <= HOSTNAME_MAX_LEN as usize,
"Max hostname length is {HOSTNAME_MAX_LEN}"
);
let re = regress::Regex::new(HOSTNAME_REGEX).unwrap();
if re.find(s).is_some() {
Ok(Hostname(s.to_string()))
} else {
anyhow::bail!("Hostnames must comply with RFC 1035")
}
}
}

but it doesn't follow the same rules as Name. It seems to be a little broader: allowing up to 253 characters, not disallowing UUIDs, allowing .. So this can work as long as we are confident that any valid name is also a valid hostname. It seems true, but I am planning on adding some tests to help ensure it.

@@ -3173,6 +3173,9 @@ mod test {
for name in valid_names {
eprintln!("check name \"{}\" (should be valid)", name);
assert_eq!(name, name.parse::<Name>().unwrap().as_str());
// make sure valid names are also valid hostnames so we can use names as
// fallback hostnames, e.g., in instance create
assert_eq!(name, name.parse::<Hostname>().unwrap().as_str());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There aren't that many examples in the list. It would be cool to do a proptest type thing here but I didn't see any tests like that in omicron.

Copy link
Contributor

@ahl ahl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good and I like the idea, but I don't know that I'm the best person to confirm the validity of this approach. Perhaps @davepacheco or @smklein can validate the concept?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants