Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/admin-cli/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,7 @@ impl ApiClient {
.create_vpc(VpcCreationRequest {
vni: None,
routing_profile_type: None,
routing_profile_overrides: None,
tenant_organization_id: "devenv_test_org".to_string(),
tenant_keyset_id: None,
network_virtualization_type: Some(
Expand Down Expand Up @@ -1296,6 +1297,7 @@ impl ApiClient {
.create_vpc(VpcCreationRequest {
vni: None,
routing_profile_type: None,
routing_profile_overrides: None,
tenant_organization_id: "devenv_test_org".to_string(),
tenant_keyset_id: None,
network_virtualization_type: Some(VpcVirtualizationType::Flat.into()),
Expand Down
1 change: 1 addition & 0 deletions crates/admin-cli/src/vpc/create/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl From<Args> for forge::VpcCreationRequest {
default_nvlink_logical_partition_id: None,
vni: None,
routing_profile_type: None,
routing_profile_overrides: None,
}
}
}
70 changes: 70 additions & 0 deletions crates/admin-cli/src/vpc/show/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ fn vpc_config(vpc: &forgerpc::Vpc) -> forgerpc::VpcConfig {
default_nvlink_logical_partition_id: vpc.default_nvlink_logical_partition_id,
vni: vpc.vni,
routing_profile_type: vpc.routing_profile_type.clone(),
routing_profile_overrides: None,
}
}
}
Expand Down Expand Up @@ -184,6 +185,19 @@ pub fn convert_vpc_to_nice_format(vpc: &forgerpc::Vpc) -> CarbideCliResult<Strin
let width = 25;
let mut lines = String::new();
let config = vpc_config(vpc);
let routing_profile_overrides = config
.routing_profile_overrides
.as_ref()
.map(serde_json::to_string_pretty)
.transpose()?
.unwrap_or_else(|| "None".to_string());
let effective_routing_profile = vpc
.status
.as_ref()
.and_then(|status| status.effective_routing_profile.as_ref())
.map(serde_json::to_string_pretty)
.transpose()?
.unwrap_or_else(|| "None".to_string());

let vpc_name = vpc
.metadata
Expand Down Expand Up @@ -227,6 +241,18 @@ pub fn convert_vpc_to_nice_format(vpc: &forgerpc::Vpc) -> CarbideCliResult<Strin
.as_str_name()
.into(),
),
(
"ROUTING PROFILE TYPE",
config.routing_profile_type.unwrap_or_default().into(),
),
(
"ROUTING PROFILE OVERRIDES",
routing_profile_overrides.into(),
),
(
"EFFECTIVE ROUTING PROFILE",
effective_routing_profile.into(),
),
];

for (key, value) in data {
Expand All @@ -235,3 +261,47 @@ pub fn convert_vpc_to_nice_format(vpc: &forgerpc::Vpc) -> CarbideCliResult<Strin

Ok(lines)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn vpc_details_include_routing_profiles() {
let vpc = forgerpc::Vpc {
config: Some(forgerpc::VpcConfig {
tenant_organization_id: "tenant".to_string(),
routing_profile_type: Some("INTERNAL".to_string()),
routing_profile_overrides: Some(forgerpc::VpcRoutingProfileOverrides {
leak_default_route_from_underlay: Some(false),
..Default::default()
}),
..Default::default()
}),
status: Some(forgerpc::VpcStatus {
effective_routing_profile: Some(forgerpc::VpcEffectiveRoutingProfile {
internal: true,
access_tier: 2,
..Default::default()
}),
..Default::default()
}),
..Default::default()
};

let display = convert_vpc_to_nice_format(&vpc).expect("VPC display");
assert!(display.contains("ROUTING PROFILE TYPE"));
assert!(display.contains("INTERNAL"));
let (_, routing_profiles) = display
.split_once("ROUTING PROFILE OVERRIDES")
.expect("routing-profile overrides");
let (overrides, effective) = routing_profiles
.split_once("EFFECTIVE ROUTING PROFILE")
.expect("effective routing profile");
assert!(overrides.contains("\"leak_default_route_from_underlay\": false"));
assert!(!overrides.contains("\"internal\""));
assert!(!overrides.contains("\"access_tier\""));
assert!(effective.contains("\"internal\": true"));
assert!(effective.contains("\"access_tier\": 2"));
}
}
34 changes: 24 additions & 10 deletions crates/api-core/src/cfg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ applicable.
| `compute_allocation_enforcement` | `ComputeAllocationEnforcement` | `WarnOnly` | `machines` | Controls enforcement of compute allocations on new instance requests. |
| `supernic_firmware_profiles` | nested `HashMap` | `{}` | `machines` | SuperNIC firmware profiles keyed by `part_number` then `PSID`. |
| `component_manager` | `Option<ComponentManagerConfig>` | — | `hardware` | Component manager for NvLink switches and power shelves. |
| `vpcs` | `Option<HashMap<String, VpcDefinition>>` | — | `networking` | VPCs to create at startup. Use the `CreateVpc` gRPC to create them later instead. |
| `vpcs` | `Option<HashMap<String, VpcDefinition>>` | — | `networking` | VPCs to create at startup (see [VpcDefinition](#vpcdefinition)). Use the `CreateVpc` gRPC to create them later instead. |
| `allow_bmc_basic_auth_fallback` | `bool` | `false` | `security` | When `true`, `GetBmcCredentials` may return `UsernamePassword` credentials for BMCs whose Redfish ServiceRoot does not expose `SessionService`. When `false`, such BMCs surface a `NoSessionService` error and no basic-auth fallback is performed. |
| `rack_validation_config` | `RackValidationConfig` | *(default)* | `hardware` | Rack-level validation: multi-node partition tests after firmware upgrade and maintenance to verify rack health (see [RackValidationConfig](#rackvalidationconfig)). |
| `oem_manager_profiles` | `BiosProfileVendor` | `{}` | `machines` | Vendor-specific iDRAC/BMC manager attributes applied during machine setup, before BMC lockdown. Keyed by vendor → model → profile → attribute name; targets the manager OEM attributes endpoint (e.g. Dell `DellAttributes`), as opposed to `bios_profiles` which targets BIOS settings. Model names are normalized to lowercase with underscores (e.g. `"PowerEdge R760"` → `"poweredge_r760"`). |
Expand Down Expand Up @@ -516,15 +516,29 @@ client-certificate authentication is not used.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `route_target_imports` | `Vec<RouteTargetConfig>` | `[]` | Route targets imported into DPU VRFs for VPC routes. |
| `route_targets_on_exports` | `Vec<RouteTargetConfig>` | `[]` | Route targets added to routes exported by the DPU. |
| `internal` | `bool` | `false` | Whether the profile uses internal VNI allocation. |
| `leak_default_route_from_underlay` | `bool` | `false` | Leak the default route from the underlay/default VRF into tenant VRFs. |
| `leak_tenant_host_routes_to_underlay` | `bool` | `false` | Leak tenant host routes into the underlay/default VRF. |
| `tenant_leak_communities_accepted` | `bool` | `false` | Honor route-leak communities sent by the tenant host OS. |
| `accepted_leaks_from_underlay` | `Vec<PrefixFilterPolicyEntry>` | `[]` | Specific underlay/default VRF prefixes allowed to leak into tenant VRFs. Routing only; does not affect ACLs. |
| `allowed_anycast_prefixes` | `Vec<PrefixFilterPolicyEntry>` | `[]` | IPv4 or IPv6 prefixes that tenant hosts are allowed to announce to the DPU as anycast routes. |
| `access_tier` | `u32` | `0` | Routing profile access tier. Lower values grant broader access. |
| `route_target_imports` | `Option<Vec<RouteTargetConfig>>` | — (effective `[]`) | Route targets imported into DPU VRFs for VPC routes. |
| `route_targets_on_exports` | `Option<Vec<RouteTargetConfig>>` | — (effective `[]`) | Route targets added to routes exported by the DPU. |
| `internal` | `Option<bool>` | — (effective `false`) | Whether the profile uses internal VNI allocation. This property cannot be overridden on a VPC. |
| `leak_default_route_from_underlay` | `Option<bool>` | — (effective `false`) | Leak the default route from the underlay/default VRF into tenant VRFs. |
| `leak_tenant_host_routes_to_underlay` | `Option<bool>` | — (effective `false`) | Leak tenant host routes into the underlay/default VRF. |
| `tenant_leak_communities_accepted` | `Option<bool>` | — (effective `false`) | Honor route-leak communities sent by the tenant host OS. |
| `accepted_leaks_from_underlay` | `Option<Vec<PrefixFilterPolicyEntry>>` | — (effective `[]`) | Specific underlay/default VRF prefixes allowed to leak into tenant VRFs. Routing only; does not affect ACLs. |
| `allowed_anycast_prefixes` | `Option<Vec<PrefixFilterPolicyEntry>>` | — (effective `[]`) | IPv4 or IPv6 prefixes that tenant hosts are allowed to announce to the DPU as anycast routes. |
| `access_tier` | `Option<u32>` | — (effective `0`) | Routing profile access tier. Lower values grant broader access. This property cannot be overridden on a VPC. |

Unset properties retain presence information so a VPC's inline
`routing_profile_overrides` can inherit them. After the named profile and VPC
override are combined, properties still unset use the effective defaults above.

### `VpcDefinition`

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `organization_id` | `Option<String>` | — | Tenant organization that owns the seeded VPC. |
| `network_virtualization_type` | `VpcVirtualizationType` | **required** | Data plane used by the VPC. |
| `routing_profile_type` | `Option<String>` | — | Named FNN routing profile recorded on the seeded VPC. |
| `routing_profile_overrides` | `Option<VpcRoutingProfileOverrides>` | — | Unsupported for seeded VPCs. Any configured value causes startup to fail; inline overrides are accepted only by VPC creation requests. |
| `vni` | `Option<i32>` | — | Desired VNI; when absent, one is allocated. |

### `PrefixFilterPolicyEntry`

Expand Down
Loading
Loading