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

Omdb networking #4147

Merged
merged 6 commits into from
Oct 3, 2023
Merged

Omdb networking #4147

merged 6 commits into from
Oct 3, 2023

Conversation

rcgoodfellow
Copy link
Contributor

@rcgoodfellow rcgoodfellow commented Sep 27, 2023

Adds an omdb command to list external network IP addresses along with their parent.

./omdb db network list-eips
note: database URL not specified.  Will search DNS.
note: (override with --db-url or OMDB_DB_URL)
note: using DNS server for subnet fd00:1122:3344::/48
note: (if this is not right, use --dns-server to specify an alternate DNS server)
note: using database URL postgresql://root@[fd00:1122:3344:109::3]:32221,[fd00:1122:3344:105::3]:32221,[fd00:1122:3344:10b::3]:32221,[fd00:1122:3344:107::3]:32221,[fd00:1122:3344:108::3]:32221/omicron?sslmode=disable
note: database schema version matches expected (4.0.0)
 ip               ports        kind       owner
 172.20.26.1/32   0/65535      Floating   Service ExternalDns
 172.20.26.2/32   0/65535      Floating   Service ExternalDns
 172.20.26.3/32   0/65535      Floating   Service Nexus
 172.20.26.4/32   0/65535      Floating   Service Nexus
 172.20.26.5/32   0/65535      Floating   Service Nexus
 172.20.26.6/32   0/16383      SNat       Service Ntp
 172.20.26.7/32   16384/32767  SNat       Service Ntp
 172.20.26.11/32  49152/65535  SNat       Instance try/sysbench-mysql-3
 172.20.26.11/32  32768/49151  SNat       Instance try/sysbench-mysql-2
 172.20.26.11/32  16384/32767  SNat       Instance try/test-upgrade-2
 172.20.26.13/32  0/65535      Ephemeral  Instance try/test-upgrade-2
 172.20.26.14/32  0/65535      Ephemeral  Instance try/sysbench-mysql-2
 172.20.26.15/32  0/65535      Ephemeral  Instance try/sysbench-mysql-3
 172.20.26.16/32  0/16383      SNat       Instance try/sysbench-mysql-4
 172.20.26.16/32  32768/49151  SNat       Instance try/sysbench-mysql-6
 172.20.26.16/32  49152/65535  SNat       Instance try/sysbench-mysql-7

Also comes with a verbose mode to print raw datastore structures.

BRM44220005 # ./omdb db network --verbose list-eips
note: database URL not specified.  Will search DNS.
note: (override with --db-url or OMDB_DB_URL)
note: using DNS server for subnet fd00:1122:3344::/48
note: (if this is not right, use --dns-server to specify an alternate DNS server)
note: using database URL postgresql://root@[fd00:1122:3344:109::3]:32221,[fd00:1122:3344:105::3]:32221,[fd00:1122:3344:10b::3]:32221,[fd00:1122:3344:107::3]:32221,[fd00:1122:3344:108::3]:32221/omicron?sslmode=disable
note: database schema version matches expected (4.0.0)
ExternalIp {
    id: 01043656-d049-449a-9b33-1bad7f4affdd,
    name: None,
    description: None,
    time_created: 2023-08-30T20:27:57.649708Z,
    time_modified: 2023-08-30T20:27:57.649708Z,
    time_deleted: None,
    ip_pool_id: cadb8535-e32f-4be2-9259-e45dec9fa3c7,
    ip_pool_range_id: 73aede53-8fe2-40c5-a6fb-23675269e979,
    is_service: false,
    parent_id: Some(
        33e6d4a4-6cc7-440f-8a9f-152d94136191,
    ),
    kind: SNat,
    ip: V4(
        Ipv4Network {
            addr: 172.20.26.41,
            prefix: 32,
        },
    ),
    first_port: SqlU16(
        16384,
    ),
    last_port: SqlU16(
        32767,
    ),
}
ExternalIp {
    id: 015fd6de-a47a-4804-bc96-2b5880c42ac3,
    name: None,
    description: None,
    time_created: 2023-08-30T19:48:56.391829Z,
    time_modified: 2023-08-30T19:48:56.391829Z,
    time_deleted: None,
...

@rcgoodfellow rcgoodfellow marked this pull request as ready for review September 27, 2023 01:02
@@ -84,6 +84,24 @@ stderr:
note: using database URL postgresql://root@[::1]:REDACTED_PORT/omicron?sslmode=disable
note: database schema version matches expected (4.0.0)
=============================================
EXECUTING COMMAND: omdb ["db", "network"]
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems like this output would go in the "usage" test (if you want to cover it). The point of the "successes" test is to sanity-check that the command produces reasonable-looking output against a real system. You might add omdb db network list-eips to this test instead? Or if it's too annoying to get that to work (you might have to add more redactions for the output to be stable across runs), skip it altogether?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved this test to usage.

Comment on lines 292 to 284

/// Fetch all external IP addresses of any kind for the provided instance
pub async fn lookup_external_ips(
&self,
opctx: &OpContext,
) -> LookupResult<Vec<ExternalIp>> {
use db::schema::external_ip::dsl;
dsl::external_ip
.filter(dsl::time_deleted.is_null())
.select(ExternalIp::as_select())
.get_results_async(self.pool_authorized(opctx).await?)
.await
.map_err(|e| public_error_from_diesel_pool(e, ErrorHandler::Server))
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's pretty dangerous to add a non-authz-gated datastore operation like this. If this is a generally useful function, I'd just do the authz check. If we don't think we'd need this kind of functionality in Nexus, or if authz is a problem, I think it's fine to just put this code straight into omdb (without an authz check).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. I just moved this into the omdb code.

.await
.context("loading requested instance")?
.pop()
.context("requested instance not found")?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not critical but I'd consider continuing rather than bailing out for this case (so that if there's an errant "owner" in the database, we can still use the tool to see as much as we can).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. Done

.await
.context("loading requested project")?
.pop()
.context("requested project not found")?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same -- I'd considering continuing instead of bailing out here (but definitely not a blocker).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


#[derive(Tabled)]
enum Owner {
Instance { project: String, name: String },
Copy link
Collaborator

Choose a reason for hiding this comment

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

I always wonder if the tool should report ids (which are immutable and unique across silos) or names like this that potentially save someone a separate lookup (or both, but that uses up valuable space too). It's all tradeoffs -- just mentioning it to see what you think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I explicitly chose names here - as my use case for this is mapping external IPs to something immediately tangible. I added an option for verbose output that provides the raw data structures from the DB that shows references based on UUID.

@davepacheco
Copy link
Collaborator

Thanks for doing this! This will be very useful.

Copy link
Collaborator

@davepacheco davepacheco left a comment

Choose a reason for hiding this comment

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

Just spotted one stray commented-out block but otherwise looks good!

Comment on lines 1137 to 1142
/*
let ips = datastore
.lookup_external_ips(&opctx)
.await
.context("listing external ips")?;
*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: probably want to remove this
I can't tell if this was here before because I can't access the incremental review. (Maybe a force push?)

@rcgoodfellow rcgoodfellow merged commit d300fb8 into main Oct 3, 2023
22 checks passed
@rcgoodfellow rcgoodfellow deleted the omdb-networking branch October 3, 2023 19:45
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