diff --git a/nexus/db-model/src/schema_versions.rs b/nexus/db-model/src/schema_versions.rs index 2438f37fba8..cb0b6ae206c 100644 --- a/nexus/db-model/src/schema_versions.rs +++ b/nexus/db-model/src/schema_versions.rs @@ -17,7 +17,7 @@ use std::collections::BTreeMap; /// /// This must be updated when you change the database schema. Refer to /// schema/crdb/README.adoc in the root of this repository for details. -pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(93, 0, 0); +pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(94, 0, 0); /// List of all past database schema versions, in *reverse* order /// @@ -29,6 +29,7 @@ static KNOWN_VERSIONS: Lazy> = Lazy::new(|| { // | leaving the first copy as an example for the next person. // v // KnownVersion::new(next_int, "unique-dirname-with-the-sql-files"), + KnownVersion::new(94, "internet-gateway"), KnownVersion::new(93, "dataset-kinds-zone-and-debug"), KnownVersion::new(92, "lldp-link-config-nullable"), KnownVersion::new(91, "add-management-gateway-producer-kind"), diff --git a/nexus/external-api/output/nexus_tags.txt b/nexus/external-api/output/nexus_tags.txt index fb7c1f90c3f..75bd9a016bf 100644 --- a/nexus/external-api/output/nexus_tags.txt +++ b/nexus/external-api/output/nexus_tags.txt @@ -230,11 +230,11 @@ API operations found with tag "vpcs" OPERATION ID METHOD URL PATH internet_gateway_create POST /v1/internet-gateways internet_gateway_delete DELETE /v1/internet-gateways/{gateway} -internet_gateway_ip_address_create POST /v1/vpc-internet-gateway-ip-addrs -internet_gateway_ip_address_delete DELETE /v1/vpc-internet-gateway-ip-addrs/{address} +internet_gateway_ip_address_create POST /v1/internet-gateway-ip-addrs +internet_gateway_ip_address_delete DELETE /v1/internet-gateway-ip-addrs/{address} internet_gateway_ip_address_list GET /v1/internet-gateway-ip-addrs -internet_gateway_ip_pool_create POST /v1/vpc-internet-gateway-ip-pools -internet_gateway_ip_pool_delete DELETE /v1/vpc-internet-gateway-ip-pools/{pool} +internet_gateway_ip_pool_create POST /v1/internet-gateway-ip-pools +internet_gateway_ip_pool_delete DELETE /v1/internet-gateway-ip-pools/{pool} internet_gateway_ip_pool_list GET /v1/internet-gateway-ip-pools internet_gateway_list GET /v1/internet-gateways internet_gateway_view GET /v1/internet-gateways/{gateway} diff --git a/nexus/external-api/src/lib.rs b/nexus/external-api/src/lib.rs index b53df15e989..bab876ae7cd 100644 --- a/nexus/external-api/src/lib.rs +++ b/nexus/external-api/src/lib.rs @@ -2259,7 +2259,7 @@ pub trait NexusExternalApi { /// Attach ip pool to internet gateway #[endpoint { method = POST, - path = "/v1/vpc-internet-gateway-ip-pools", + path = "/v1/internet-gateway-ip-pools", tags = ["vpcs"], }] async fn internet_gateway_ip_pool_create( @@ -2271,7 +2271,7 @@ pub trait NexusExternalApi { /// Detach ip pool from internet gateway #[endpoint { method = DELETE, - path = "/v1/vpc-internet-gateway-ip-pools/{pool}", + path = "/v1/internet-gateway-ip-pools/{pool}", tags = ["vpcs"], }] async fn internet_gateway_ip_pool_delete( @@ -2299,7 +2299,7 @@ pub trait NexusExternalApi { /// Attach ip pool to internet gateway #[endpoint { method = POST, - path = "/v1/vpc-internet-gateway-ip-addrs", + path = "/v1/internet-gateway-ip-addrs", tags = ["vpcs"], }] async fn internet_gateway_ip_address_create( @@ -2311,7 +2311,7 @@ pub trait NexusExternalApi { /// Detach ip pool from internet gateway #[endpoint { method = DELETE, - path = "/v1/vpc-internet-gateway-ip-addrs/{address}", + path = "/v1/internet-gateway-ip-addrs/{address}", tags = ["vpcs"], }] async fn internet_gateway_ip_address_delete( diff --git a/nexus/tests/integration_tests/endpoints.rs b/nexus/tests/integration_tests/endpoints.rs index 9703004c733..06d5dd16b71 100644 --- a/nexus/tests/integration_tests/endpoints.rs +++ b/nexus/tests/integration_tests/endpoints.rs @@ -253,6 +253,83 @@ pub static DEMO_ROUTER_ROUTE_CREATE: Lazy = destination: RouteDestination::Subnet("loopback".parse().unwrap()), }); +// Internet Gateway used for testing +pub static DEMO_INTERNET_GATEWAY_NAME: Lazy = + Lazy::new(|| "demo-internet-gateway".parse().unwrap()); +pub static DEMO_INTERNET_GATEWAYS_URL: Lazy = Lazy::new(|| { + format!( + "/v1/internet-gateways?project={}&vpc={}", + *DEMO_PROJECT_NAME, *DEMO_VPC_NAME + ) +}); +pub static DEMO_INTERNET_GATEWAY_URL: Lazy = Lazy::new(|| { + format!( + "/v1/internet-gateways/{}?project={}&vpc={}", + *DEMO_INTERNET_GATEWAY_NAME, *DEMO_PROJECT_NAME, *DEMO_VPC_NAME + ) +}); +pub static DEMO_INTERNET_GATEWAY_CREATE: Lazy = + Lazy::new(|| params::InternetGatewayCreate { + identity: IdentityMetadataCreateParams { + name: DEMO_INTERNET_GATEWAY_NAME.clone(), + description: String::from(""), + }, + }); +pub static DEMO_INTERNET_GATEWAY_IP_POOL_CREATE: Lazy< + params::InternetGatewayIpPoolCreate, +> = Lazy::new(|| params::InternetGatewayIpPoolCreate { + identity: IdentityMetadataCreateParams { + name: DEMO_INTERNET_GATEWAY_NAME.clone(), + description: String::from(""), + }, + ip_pool_id: uuid::Uuid::new_v4(), + gateway_id: uuid::Uuid::new_v4(), +}); +pub static DEMO_INTERNET_GATEWAY_IP_ADDRESS_CREATE: Lazy< + params::InternetGatewayIpAddressCreate, +> = Lazy::new(|| params::InternetGatewayIpAddressCreate { + identity: IdentityMetadataCreateParams { + name: DEMO_INTERNET_GATEWAY_NAME.clone(), + description: String::from(""), + }, + gateway_id: uuid::Uuid::new_v4(), + address: IpAddr::V4(Ipv4Addr::UNSPECIFIED), +}); +pub static DEMO_INTERNET_GATEWAY_IP_POOLS_URL: Lazy = Lazy::new(|| { + format!( + "/v1/internet-gateway-ip-pools?project={}&vpc={}&gateway={}", + *DEMO_PROJECT_NAME, *DEMO_VPC_NAME, *DEMO_INTERNET_GATEWAY_NAME, + ) +}); +pub static DEMO_INTERNET_GATEWAY_IP_ADDRS_URL: Lazy = Lazy::new(|| { + format!( + "/v1/internet-gateway-ip-addrs?project={}&vpc={}&gateway={}", + *DEMO_PROJECT_NAME, *DEMO_VPC_NAME, *DEMO_INTERNET_GATEWAY_NAME, + ) +}); +pub static DEMO_INTERNET_GATEWAY_IP_POOL_NAME: Lazy = + Lazy::new(|| "demo-igw-pool".parse().unwrap()); +pub static DEMO_INTERNET_GATEWAY_IP_ADDRESS_NAME: Lazy = + Lazy::new(|| "demo-igw-address".parse().unwrap()); +pub static DEMO_INTERNET_GATEWAY_IP_POOL_URL: Lazy = Lazy::new(|| { + format!( + "/v1/internet-gateway-ip-pools/{}?project={}&vpc={}&gateway={}", + *DEMO_INTERNET_GATEWAY_IP_POOL_NAME, + *DEMO_PROJECT_NAME, + *DEMO_VPC_NAME, + *DEMO_INTERNET_GATEWAY_NAME, + ) +}); +pub static DEMO_INTERNET_GATEWAY_IP_ADDR_URL: Lazy = Lazy::new(|| { + format!( + "/v1/internet-gateway-ip-addrs/{}?project={}&vpc={}&gateway={}", + *DEMO_INTERNET_GATEWAY_IP_ADDRESS_NAME, + *DEMO_PROJECT_NAME, + *DEMO_VPC_NAME, + *DEMO_INTERNET_GATEWAY_NAME, + ) +}); + // Disk used for testing pub static DEMO_DISK_NAME: Lazy = Lazy::new(|| "demo-disk".parse().unwrap()); @@ -1602,6 +1679,72 @@ pub static VERIFY_ENDPOINTS: Lazy> = Lazy::new(|| { ], }, + /* Internet Gateways */ + + VerifyEndpoint { + url: &DEMO_INTERNET_GATEWAYS_URL, + visibility: Visibility::Protected, + unprivileged_access: UnprivilegedAccess::None, + allowed_methods: vec![ + AllowedMethod::GetNonexistent, + AllowedMethod::Post( + serde_json::to_value(&*DEMO_INTERNET_GATEWAY_CREATE).unwrap() + ), + ], + }, + + VerifyEndpoint { + url: &DEMO_INTERNET_GATEWAY_URL, + visibility: Visibility::Protected, + unprivileged_access: UnprivilegedAccess::None, + allowed_methods: vec![ + AllowedMethod::GetNonexistent, + AllowedMethod::Delete, + ], + }, + + VerifyEndpoint { + url: &DEMO_INTERNET_GATEWAY_IP_POOLS_URL, + visibility: Visibility::Protected, + unprivileged_access: UnprivilegedAccess::None, + allowed_methods: vec![ + AllowedMethod::GetNonexistent, + AllowedMethod::Post( + serde_json::to_value(&*DEMO_INTERNET_GATEWAY_IP_POOL_CREATE).unwrap() + ), + ], + }, + + VerifyEndpoint { + url: &DEMO_INTERNET_GATEWAY_IP_POOL_URL, + visibility: Visibility::Protected, + unprivileged_access: UnprivilegedAccess::None, + allowed_methods: vec![ + AllowedMethod::Delete, + ], + }, + + VerifyEndpoint { + url: &DEMO_INTERNET_GATEWAY_IP_ADDRS_URL, + visibility: Visibility::Protected, + unprivileged_access: UnprivilegedAccess::None, + allowed_methods: vec![ + AllowedMethod::GetNonexistent, + AllowedMethod::Post( + serde_json::to_value(&*DEMO_INTERNET_GATEWAY_IP_ADDRESS_CREATE).unwrap() + ), + ], + }, + + VerifyEndpoint { + url: &DEMO_INTERNET_GATEWAY_IP_ADDR_URL, + visibility: Visibility::Protected, + unprivileged_access: UnprivilegedAccess::None, + allowed_methods: vec![ + AllowedMethod::Delete, + ], + }, + /* Disks */ VerifyEndpoint { diff --git a/openapi/nexus.json b/openapi/nexus.json index 2570d836503..f259b4f4ebc 100644 --- a/openapi/nexus.json +++ b/openapi/nexus.json @@ -2705,6 +2705,123 @@ "gateway" ] } + }, + "post": { + "tags": [ + "vpcs" + ], + "summary": "Attach ip pool to internet gateway", + "operationId": "internet_gateway_ip_address_create", + "parameters": [ + { + "in": "query", + "name": "gateway", + "description": "Name or ID of the internet gateway", + "required": true, + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "project", + "description": "Name or ID of the project, only required if `vpc` is provided as a `Name`", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "vpc", + "description": "Name or ID of the VPC, only required if `gateway` is provided as a `Name`", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternetGatewayIpAddressCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "successful creation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternetGatewayIpAddress" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/v1/internet-gateway-ip-addrs/{address}": { + "delete": { + "tags": [ + "vpcs" + ], + "summary": "Detach ip pool from internet gateway", + "operationId": "internet_gateway_ip_address_delete", + "parameters": [ + { + "in": "path", + "name": "address", + "description": "Name or ID of the IP address", + "required": true, + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "gateway", + "description": "Name or ID of the internet gateway", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "project", + "description": "Name or ID of the project, only required if `vpc` is provided as a `Name`", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "vpc", + "description": "Name or ID of the VPC, only required if `gateway` is provided as a `Name`", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } } }, "/v1/internet-gateway-ip-pools": { @@ -2790,6 +2907,123 @@ "gateway" ] } + }, + "post": { + "tags": [ + "vpcs" + ], + "summary": "Attach ip pool to internet gateway", + "operationId": "internet_gateway_ip_pool_create", + "parameters": [ + { + "in": "query", + "name": "gateway", + "description": "Name or ID of the internet gateway", + "required": true, + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "project", + "description": "Name or ID of the project, only required if `vpc` is provided as a `Name`", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "vpc", + "description": "Name or ID of the VPC, only required if `gateway` is provided as a `Name`", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternetGatewayIpPoolCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "successful creation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternetGatewayIpPool" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, + "/v1/internet-gateway-ip-pools/{pool}": { + "delete": { + "tags": [ + "vpcs" + ], + "summary": "Detach ip pool from internet gateway", + "operationId": "internet_gateway_ip_pool_delete", + "parameters": [ + { + "in": "path", + "name": "pool", + "description": "Name or ID of the IP pool", + "required": true, + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "gateway", + "description": "Name or ID of the internet gateway", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "project", + "description": "Name or ID of the project, only required if `vpc` is provided as a `Name`", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + }, + { + "in": "query", + "name": "vpc", + "description": "Name or ID of the VPC, only required if `gateway` is provided as a `Name`", + "schema": { + "$ref": "#/components/schemas/NameOrId" + } + } + ], + "responses": { + "204": { + "description": "successful deletion" + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } } }, "/v1/internet-gateways": { @@ -8790,244 +9024,6 @@ } } }, - "/v1/vpc-internet-gateway-ip-addrs": { - "post": { - "tags": [ - "vpcs" - ], - "summary": "Attach ip pool to internet gateway", - "operationId": "internet_gateway_ip_address_create", - "parameters": [ - { - "in": "query", - "name": "gateway", - "description": "Name or ID of the internet gateway", - "required": true, - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "project", - "description": "Name or ID of the project, only required if `vpc` is provided as a `Name`", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "vpc", - "description": "Name or ID of the VPC, only required if `gateway` is provided as a `Name`", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternetGatewayIpAddressCreate" - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "successful creation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternetGatewayIpAddress" - } - } - } - }, - "4XX": { - "$ref": "#/components/responses/Error" - }, - "5XX": { - "$ref": "#/components/responses/Error" - } - } - } - }, - "/v1/vpc-internet-gateway-ip-addrs/{address}": { - "delete": { - "tags": [ - "vpcs" - ], - "summary": "Detach ip pool from internet gateway", - "operationId": "internet_gateway_ip_address_delete", - "parameters": [ - { - "in": "path", - "name": "address", - "description": "Name or ID of the IP address", - "required": true, - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "gateway", - "description": "Name or ID of the internet gateway", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "project", - "description": "Name or ID of the project, only required if `vpc` is provided as a `Name`", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "vpc", - "description": "Name or ID of the VPC, only required if `gateway` is provided as a `Name`", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - } - ], - "responses": { - "204": { - "description": "successful deletion" - }, - "4XX": { - "$ref": "#/components/responses/Error" - }, - "5XX": { - "$ref": "#/components/responses/Error" - } - } - } - }, - "/v1/vpc-internet-gateway-ip-pools": { - "post": { - "tags": [ - "vpcs" - ], - "summary": "Attach ip pool to internet gateway", - "operationId": "internet_gateway_ip_pool_create", - "parameters": [ - { - "in": "query", - "name": "gateway", - "description": "Name or ID of the internet gateway", - "required": true, - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "project", - "description": "Name or ID of the project, only required if `vpc` is provided as a `Name`", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "vpc", - "description": "Name or ID of the VPC, only required if `gateway` is provided as a `Name`", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternetGatewayIpPoolCreate" - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "successful creation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InternetGatewayIpPool" - } - } - } - }, - "4XX": { - "$ref": "#/components/responses/Error" - }, - "5XX": { - "$ref": "#/components/responses/Error" - } - } - } - }, - "/v1/vpc-internet-gateway-ip-pools/{pool}": { - "delete": { - "tags": [ - "vpcs" - ], - "summary": "Detach ip pool from internet gateway", - "operationId": "internet_gateway_ip_pool_delete", - "parameters": [ - { - "in": "path", - "name": "pool", - "description": "Name or ID of the IP pool", - "required": true, - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "gateway", - "description": "Name or ID of the internet gateway", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "project", - "description": "Name or ID of the project, only required if `vpc` is provided as a `Name`", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - }, - { - "in": "query", - "name": "vpc", - "description": "Name or ID of the VPC, only required if `gateway` is provided as a `Name`", - "schema": { - "$ref": "#/components/schemas/NameOrId" - } - } - ], - "responses": { - "204": { - "description": "successful deletion" - }, - "4XX": { - "$ref": "#/components/responses/Error" - }, - "5XX": { - "$ref": "#/components/responses/Error" - } - } - } - }, "/v1/vpc-router-routes": { "get": { "tags": [ diff --git a/schema/crdb/dbinit.sql b/schema/crdb/dbinit.sql index c45469b9d1e..daf56240568 100644 --- a/schema/crdb/dbinit.sql +++ b/schema/crdb/dbinit.sql @@ -1721,34 +1721,43 @@ CREATE UNIQUE INDEX IF NOT EXISTS lookup_route_by_router ON omicron.public.route time_deleted IS NULL; CREATE TABLE IF NOT EXISTS omicron.public.internet_gateway ( - /* Identity metadata (resource) */ id UUID PRIMARY KEY, name STRING(63) NOT NULL, description STRING(512) NOT NULL, time_created TIMESTAMPTZ NOT NULL, time_modified TIMESTAMPTZ NOT NULL, - /* Indicates that the object has been deleted */ time_deleted TIMESTAMPTZ, vpc_id UUID NOT NULL, rcgen INT NOT NULL, - /* - * version information used to trigger VPC router RPW. - * this is sensitive to CRUD on named resources beyond - * routers e.g. instances, subnets, ... - */ resolved_version INT NOT NULL DEFAULT 0 ); +CREATE UNIQUE INDEX IF NOT EXISTS lookup_internet_gateway_by_vpc ON omicron.public.internet_gateway ( + vpc_id, + name +) WHERE + time_deleted IS NULL; + CREATE TABLE IF NOT EXISTS omicron.public.internet_gateway_ip_pool ( + id UUID PRIMARY KEY, + name STRING(63) NOT NULL, + description STRING(512) NOT NULL, + time_created TIMESTAMPTZ NOT NULL, + time_modified TIMESTAMPTZ NOT NULL, + time_deleted TIMESTAMPTZ, internet_gateway_id UUID, - ip_pool_id UUID, - PRIMARY KEY (internet_gateway_id, ip_pool_id) + ip_pool_id UUID ); CREATE TABLE IF NOT EXISTS omicron.public.internet_gateway_ip_address ( + id UUID PRIMARY KEY, + name STRING(63) NOT NULL, + description STRING(512) NOT NULL, + time_created TIMESTAMPTZ NOT NULL, + time_modified TIMESTAMPTZ NOT NULL, + time_deleted TIMESTAMPTZ, internet_gateway_id UUID, - address INET, - PRIMARY KEY (internet_gateway_id, addr) + address INET ); @@ -4257,7 +4266,7 @@ INSERT INTO omicron.public.db_metadata ( version, target_version ) VALUES - (TRUE, NOW(), NOW(), '93.0.0', NULL) + (TRUE, NOW(), NOW(), '94.0.0', NULL) ON CONFLICT DO NOTHING; COMMIT; diff --git a/schema/crdb/internet-gateway/up01.sql b/schema/crdb/internet-gateway/up01.sql new file mode 100644 index 00000000000..bf08bfccc3c --- /dev/null +++ b/schema/crdb/internet-gateway/up01.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS omicron.public.internet_gateway ( + id UUID PRIMARY KEY, + name STRING(63) NOT NULL, + description STRING(512) NOT NULL, + time_created TIMESTAMPTZ NOT NULL, + time_modified TIMESTAMPTZ NOT NULL, + time_deleted TIMESTAMPTZ, + vpc_id UUID NOT NULL, + rcgen INT NOT NULL, + resolved_version INT NOT NULL DEFAULT 0 +); diff --git a/schema/crdb/internet-gateway/up02.sql b/schema/crdb/internet-gateway/up02.sql new file mode 100644 index 00000000000..5deca8277ba --- /dev/null +++ b/schema/crdb/internet-gateway/up02.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS omicron.public.internet_gateway_ip_pool ( + id UUID PRIMARY KEY, + name STRING(63) NOT NULL, + description STRING(512) NOT NULL, + time_created TIMESTAMPTZ NOT NULL, + time_modified TIMESTAMPTZ NOT NULL, + time_deleted TIMESTAMPTZ, + internet_gateway_id UUID, + ip_pool_id UUID +); + diff --git a/schema/crdb/internet-gateway/up03.sql b/schema/crdb/internet-gateway/up03.sql new file mode 100644 index 00000000000..b95fb8f43cc --- /dev/null +++ b/schema/crdb/internet-gateway/up03.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS omicron.public.internet_gateway_ip_address ( + id UUID PRIMARY KEY, + name STRING(63) NOT NULL, + description STRING(512) NOT NULL, + time_created TIMESTAMPTZ NOT NULL, + time_modified TIMESTAMPTZ NOT NULL, + time_deleted TIMESTAMPTZ, + internet_gateway_id UUID, + address INET +); + diff --git a/schema/crdb/internet-gateway/up04.sql b/schema/crdb/internet-gateway/up04.sql new file mode 100644 index 00000000000..c3608be9a99 --- /dev/null +++ b/schema/crdb/internet-gateway/up04.sql @@ -0,0 +1,5 @@ +CREATE UNIQUE INDEX IF NOT EXISTS lookup_internet_gateway_by_vpc ON omicron.public.internet_gateway ( + vpc_id, + name +) WHERE + time_deleted IS NULL;