diff --git a/.oxlintrc.json b/.oxlintrc.json index 17ac403c4..f0e3cc7db 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -2,8 +2,10 @@ "$schema": "./node_modules/oxlint/configuration_schema.json", "plugins": [ "import", - // defaults "react", + "jsx-a11y", + "promise", + // defaults (see https://oxc.rs/docs/guide/usage/linter/plugins.html#supported-plugins) "unicorn", "typescript", "oxc" diff --git a/OMICRON_VERSION b/OMICRON_VERSION index f18fa05d6..a9d8c15af 100644 --- a/OMICRON_VERSION +++ b/OMICRON_VERSION @@ -1 +1 @@ -99ffcbe2b1f4bddc4be85e45d9d1a0d920e2201b +ae1c739ca12f3d3fc94e78fb024bcaf2e2cbca56 diff --git a/app/api/__generated__/Api.ts b/app/api/__generated__/Api.ts index ba3609b9b..43299cfce 100644 --- a/app/api/__generated__/Api.ts +++ b/app/api/__generated__/Api.ts @@ -55,7 +55,7 @@ export type Address = { export type AddressConfig = { /** The set of addresses assigned to the port configuration. */ addresses: Address[] - /** Link to assign the address to */ + /** Link to assign the addresses to. On ports that are not broken out, this is always phy0. On a 2x breakout the options are phy0 and phy1, on 4x phy0-phy3, etc. */ linkName: Name } @@ -613,6 +613,63 @@ export type AntiAffinityGroupResultsPage = { */ export type AntiAffinityGroupUpdate = { description?: string | null; name?: Name | null } +/** + * An identifier for an artifact. + */ +export type ArtifactId = { + /** The kind of artifact this is. */ + kind: string + /** The artifact's name. */ + name: string + /** The artifact's version. */ + version: string +} + +export type AuditLogEntryActor = + | { kind: 'user_builtin'; userBuiltinId: string } + | { kind: 'silo_user'; siloId: string; siloUserId: string } + | { kind: 'unauthenticated' } + +/** + * Audit log entry + */ +export type AuditLogEntry = { + /** Indicates whether request was made with an API token or session cookie. Optional because it will not be defined on unauthenticated requests like login attempts. */ + accessMethod?: string | null + actor: AuditLogEntryActor + /** Error information if the action failed */ + errorCode?: string | null + errorMessage?: string | null + /** HTTP status code */ + httpStatusCode: number + /** Unique identifier for the audit log entry */ + id: string + /** API endpoint ID, e.g., `project_create` */ + operationId: string + /** Request ID for tracing requests through the system */ + requestId: string + /** Full URL of the request */ + requestUri: string + /** IP address that made the request */ + sourceIp: string + /** Time operation completed */ + timeCompleted: Date + /** When the request was received */ + timeStarted: Date + /** User agent string from the request */ + userAgent?: string | null +} + +/** + * A single page of results + */ +export type AuditLogEntryResultsPage = { + /** list of items on this page of results */ + items: AuditLogEntry[] + /** token used to fetch the next page of results (if any) */ + nextPage?: string | null +} + /** * Authorization scope for a timeseries. * @@ -837,7 +894,7 @@ export type BgpPeer = { /** How long to hold a peer in idle before attempting a new session (seconds). */ idleHoldTime: number /** The name of interface to peer on. This is relative to the port configuration this BGP peer configuration is a part of. For example this value could be phy0 to refer to a primary physical interface. Or it could be vlan47 to refer to a VLAN interface. */ - interfaceName: string + interfaceName: Name /** How often to send keepalive requests (seconds). */ keepalive: number /** Apply a local preference to routes received from this peer. */ @@ -855,7 +912,7 @@ export type BgpPeer = { } export type BgpPeerConfig = { - /** Link that the peer is reachable on */ + /** Link that the peer is reachable on. On ports that are not broken out, this is always phy0. On a 2x breakout the options are phy0 and phy1, on 4x phy0-phy3, etc. */ linkName: Name peers: BgpPeer[] } @@ -1192,6 +1249,26 @@ export type CertificateResultsPage = { nextPage?: string | null } +/** + * View of a console session + */ +export type ConsoleSession = { + /** A unique, immutable, system-controlled identifier for the session */ + id: string + timeCreated: Date + timeLastUsed: Date +} + +/** + * A single page of results + */ +export type ConsoleSessionResultsPage = { + /** list of items on this page of results */ + items: ConsoleSession[] + /** token used to fetch the next page of results (if any) */ + nextPage?: string | null +} + /** * A cumulative or counter data type. */ @@ -1646,6 +1723,7 @@ export type DeviceAccessToken = { /** A unique, immutable, system-controlled identifier for the token. Note that this ID is not the bearer token itself, which starts with "oxide-token-" */ id: string timeCreated: Date + /** Expiration timestamp. A null value means the token does not automatically expire. */ timeExpires?: Date | null } @@ -1816,7 +1894,7 @@ export type EphemeralIpCreate = { } export type ExternalIp = - | { ip: string; kind: 'ephemeral' } + | { ip: string; ipPoolId: string; kind: 'ephemeral' } /** A Floating IP is a well-known IP address which can be attached and detached from instances. */ | { /** human-readable free-form text about a resource */ @@ -2040,6 +2118,13 @@ export type GroupResultsPage = { */ export type Hostname = string +/** + * A range of ICMP(v6) types or codes + * + * An inclusive-inclusive range of ICMP(v6) types or codes. The second value may be omitted to represent a single parameter. + */ +export type IcmpParamRange = string + export type IdentityProviderType = 'saml' /** @@ -2259,7 +2344,7 @@ Currently, the global default auto-restart policy is "best-effort", so instances This disk can either be attached if it already exists or created along with the instance. -Specifying a boot disk is optional but recommended to ensure predictable boot behavior. The boot disk can be set during instance creation or later if the instance is stopped. +Specifying a boot disk is optional but recommended to ensure predictable boot behavior. The boot disk can be set during instance creation or later if the instance is stopped. The boot disk counts against the disk attachment limit. An instance that does not have a boot disk set will use the boot options specified in its UEFI settings, which are controlled by both the instance's UEFI firmware and the guest operating system. Boot options can change as disks are attached and detached, which may result in an instance that only boots to the EFI shell until a boot disk is set. */ bootDisk?: InstanceDiskAttachment | null @@ -2268,7 +2353,7 @@ An instance that does not have a boot disk set will use the boot options specifi Disk attachments of type "create" will be created, while those of type "attach" must already exist. -The order of this list does not guarantee a boot order for the instance. Use the boot_disk attribute to specify a boot disk. */ +The order of this list does not guarantee a boot order for the instance. Use the boot_disk attribute to specify a boot disk. When boot_disk is specified it will count against the disk attachment limit. */ disks?: InstanceDiskAttachment[] /** The external IP addresses provided to this instance. @@ -2726,11 +2811,11 @@ export type TxEqConfig = { * Switch link configuration. */ export type LinkConfigCreate = { - /** Whether or not to set autonegotiation */ + /** Whether or not to set autonegotiation. */ autoneg: boolean /** The requested forward-error correction method. If this is not specified, the standard FEC for the underlying media will be applied if it can be determined. */ fec?: LinkFec | null - /** Link name */ + /** Link name. On ports that are not broken out, this is always phy0. On a 2x breakout the options are phy0 and phy1, on 4x phy0-phy3, etc. */ linkName: Name /** The link-layer discovery protocol (LLDP) configuration for the link. */ lldp: LldpLinkConfigCreate @@ -2738,7 +2823,7 @@ export type LinkConfigCreate = { mtu: number /** The speed of the link. */ speed: LinkSpeed - /** Optional tx_eq settings */ + /** Optional tx_eq settings. */ txEq?: TxEqConfig | null } @@ -3173,28 +3258,6 @@ export type RackResultsPage = { nextPage?: string | null } -/** - * A name for a built-in role - * - * Role names consist of two string components separated by dot ("."). - */ -export type RoleName = string - -/** - * View of a Role - */ -export type Role = { description: string; name: RoleName } - -/** - * A single page of results - */ -export type RoleResultsPage = { - /** list of items on this page of results */ - items: Role[] - /** token used to fetch the next page of results (if any) */ - nextPage?: string | null -} - /** * A route to a destination network through a gateway address. */ @@ -3203,7 +3266,7 @@ export type Route = { dst: IpNet /** The route gateway. */ gw: string - /** Local preference for route. Higher preference indictes precedence within and across protocols. */ + /** Route RIB priority. Higher priority indicates precedence within and across protocols. */ ribPriority?: number | null /** VLAN id the gateway is reachable over. */ vid?: number | null @@ -3213,7 +3276,7 @@ export type Route = { * Route configuration data associated with a switch port configuration. */ export type RouteConfig = { - /** Link the route should be active on */ + /** Link name. On ports that are not broken out, this is always phy0. On a 2x breakout the options are phy0 and phy1, on 4x phy0-phy3, etc. */ linkName: Name /** The set of routes assigned to a switch port. */ routes: Route[] @@ -3389,6 +3452,14 @@ export type SamlIdentityProviderCreate = { technicalContactEmail: string } +/** + * Configuration of inbound ICMP allowed by API services. + */ +export type ServiceIcmpConfig = { + /** When enabled, Nexus is able to receive ICMP Destination Unreachable type 3 (port unreachable) and type 4 (fragmentation needed), Redirect, and Time Exceeded messages. These enable Nexus to perform Path MTU discovery and better cope with fragmentation issues. Otherwise all inbound ICMP traffic will be dropped. */ + enabled: boolean +} + /** * Parameters for PUT requests to `/v1/system/update/target-release`. */ @@ -3644,7 +3715,7 @@ An expunged sled is always non-provisionable. */ | { kind: 'expunged' } /** - * The current state of the sled, as determined by Nexus. + * The current state of the sled. */ export type SledState = /** The sled is currently active, and has resources allocated on it. */ @@ -3666,7 +3737,7 @@ export type Sled = { policy: SledPolicy /** The rack to which this Sled is currently attached */ rackId: string - /** The current state Nexus believes the sled to be in. */ + /** The current state of the sled. */ state: SledState /** timestamp when this resource was created */ timeCreated: Date @@ -3823,6 +3894,11 @@ export type SshKeyResultsPage = { nextPage?: string | null } +export type SupportBundleCreate = { + /** User comment for the support bundle */ + userComment?: string | null +} + export type TypedUuidForSupportBundleKind = string export type SupportBundleState = @@ -3852,6 +3928,7 @@ export type SupportBundleInfo = { reasonForFailure?: string | null state: SupportBundleState timeCreated: Date + userComment?: string | null } /** @@ -3864,6 +3941,11 @@ export type SupportBundleInfoResultsPage = { nextPage?: string | null } +export type SupportBundleUpdate = { + /** User comment for the support bundle */ + userComment?: string | null +} + /** * An operator's view of a Switch. */ @@ -3899,7 +3981,7 @@ export type SwitchInterfaceConfig = { /** A unique identifier for this switch interface. */ id: string /** The name of this switch interface. */ - interfaceName: string + interfaceName: Name /** The switch interface kind. */ kind: SwitchInterfaceKind2 /** The port settings object this switch interface configuration belongs to. */ @@ -3929,7 +4011,7 @@ export type SwitchInterfaceKind = export type SwitchInterfaceConfigCreate = { /** What kind of switch interface this configuration represents. */ kind: SwitchInterfaceKind - /** Link the interface will be assigned to */ + /** Link name. On ports that are not broken out, this is always phy0. On a 2x breakout the options are phy0 and phy1, on 4x phy0-phy3, etc. */ linkName: Name /** Whether or not IPv6 is enabled. */ v6Enabled: boolean @@ -3944,7 +4026,7 @@ export type SwitchPort = { /** The id of the switch port. */ id: string /** The name of this switch port. */ - portName: string + portName: Name /** The primary settings group of this switch port. Will be `None` until this switch port is configured. */ portSettingsId?: string | null /** The rack this switch port belongs to. */ @@ -3966,7 +4048,7 @@ export type SwitchPortAddressView = { /** The name of the address lot this address is drawn from. */ addressLotName: Name /** The interface name this address belongs to. */ - interfaceName: string + interfaceName: Name /** The port settings object this address configuration belongs to. */ portSettingsId: string /** An optional VLAN ID */ @@ -4050,7 +4132,7 @@ export type SwitchPortLinkConfig = { /** The requested forward-error correction method. If this is not specified, the standard FEC for the underlying media will be applied if it can be determined. */ fec?: LinkFec | null /** The name of this link. */ - linkName: string + linkName: Name /** The link-layer discovery protocol service configuration for this link. */ lldpLinkConfig?: LldpLinkConfig | null /** The maximum transmission unit for this link. */ @@ -4082,10 +4164,10 @@ export type SwitchPortRouteConfig = { /** The route's gateway address. */ gw: string /** The interface name this route configuration is assigned to. */ - interfaceName: string + interfaceName: Name /** The port settings object this route configuration belongs to. */ portSettingsId: string - /** RIB Priority indicating priority within and across protocols. */ + /** Route RIB priority. Higher priority indicates precedence within and across protocols. */ ribPriority?: number | null /** The VLAN identifier for the route. Use this if the gateway is reachable over an 802.1Q tagged L2 segment. */ vlanId?: number | null @@ -4147,19 +4229,19 @@ export type SwitchPortSettings = { * Parameters for creating switch port settings. Switch port settings are the central data structure for setting up external networking. Switch port settings include link, interface, route, address and dynamic network protocol configuration. */ export type SwitchPortSettingsCreate = { - /** Addresses indexed by interface name. */ + /** Address configurations. */ addresses: AddressConfig[] - /** BGP peers indexed by interface name. */ + /** BGP peer configurations. */ bgpPeers?: BgpPeerConfig[] description: string groups?: NameOrId[] - /** Interfaces indexed by link name. */ + /** Interface configurations. */ interfaces?: SwitchInterfaceConfigCreate[] - /** Links indexed by phy name. On ports that are not broken out, this is always phy0. On a 2x breakout the options are phy0 and phy1, on 4x phy0-phy3, etc. */ + /** Link configurations. */ links: LinkConfigCreate[] name: Name portConfig: SwitchPortConfigCreate - /** Routes indexed by interface name. */ + /** Route configurations. */ routes?: RouteConfig[] } @@ -4285,6 +4367,82 @@ export type TimeseriesSchemaResultsPage = { nextPage?: string | null } +/** + * Metadata about an individual TUF artifact. + * + * Found within a `TufRepoDescription`. + */ +export type TufArtifactMeta = { + /** The hash of the artifact. */ + hash: string + /** The artifact ID. */ + id: ArtifactId + /** The size of the artifact in bytes. */ + size: number +} + +/** + * Metadata about a TUF repository. + * + * Found within a `TufRepoDescription`. + */ +export type TufRepoMeta = { + /** The file name of the repository. + +This is purely used for debugging and may not always be correct (e.g. with wicket, we read the file contents from stdin so we don't know the correct file name). */ + fileName: string + /** The hash of the repository. + +This is a slight abuse of `ArtifactHash`, since that's the hash of individual artifacts within the repository. However, we use it here for convenience. */ + hash: string + /** The system version in artifacts.json. */ + systemVersion: string + /** The version of the targets role. */ + targetsRoleVersion: number + /** The time until which the repo is valid. */ + validUntil: Date +} + +/** + * A description of an uploaded TUF repository. + */ +export type TufRepoDescription = { + /** Information about the artifacts present in the repository. */ + artifacts: TufArtifactMeta[] + /** Information about the repository. */ + repo: TufRepoMeta +} + +/** + * Data about a successful TUF repo get from Nexus. + */ +export type TufRepoGetResponse = { + /** The description of the repository. */ + description: TufRepoDescription +} + +/** + * Status of a TUF repo import. + * + * Part of `TufRepoInsertResponse`. + */ +export type TufRepoInsertStatus = + /** The repository already existed in the database. */ + | 'already_exists' + + /** The repository did not exist, and was inserted into the database. */ + | 'inserted' + +/** + * Data about a successful TUF repo import into Nexus. + */ +export type TufRepoInsertResponse = { + /** The repository as present in the database. */ + recorded: TufRepoDescription + /** Whether this repository already existed or is new. */ + status: TufRepoInsertStatus +} + /** * A sled that has not been added to an initialized rack yet */ @@ -4305,6 +4463,28 @@ export type UninitializedSledResultsPage = { nextPage?: string | null } +/** + * Trusted root role used by the update system to verify update repositories. + */ +export type UpdatesTrustRoot = { + /** The UUID of this trusted root role. */ + id: string + /** The trusted root role itself, a JSON document as described by The Update Framework. */ + rootRole: Record + /** Time the trusted root role was added. */ + timeCreated: Date +} + +/** + * A single page of results + */ +export type UpdatesTrustRootResultsPage = { + /** list of items on this page of results */ + items: UpdatesTrustRoot[] + /** token used to fetch the next page of results (if any) */ + nextPage?: string | null +} + /** * View of a User */ @@ -4432,6 +4612,8 @@ All IPv6 subnets created from this VPC must be taken from this range, which shou name: Name } +export type VpcFirewallIcmpFilter = { code?: IcmpParamRange | null; icmpType: number } + export type VpcFirewallRuleAction = 'allow' | 'deny' export type VpcFirewallRuleDirection = 'inbound' | 'outbound' @@ -4454,7 +4636,10 @@ export type VpcFirewallRuleHostFilter = /** * The protocols that may be specified in a firewall rule's filter */ -export type VpcFirewallRuleProtocol = 'TCP' | 'UDP' | 'ICMP' +export type VpcFirewallRuleProtocol = + | { type: 'tcp' } + | { type: 'udp' } + | { type: 'icmp'; value: VpcFirewallIcmpFilter | null } /** * Filters reduce the scope of a firewall rule. Without filters, the rule applies to all packets to the targets (or from the targets, if it's an outbound rule). With multiple filters, the rule applies only to packets matching ALL filters. The maximum number of each type of filter is 256. @@ -4741,22 +4926,15 @@ export type NameOrIdSortMode = /** sort in increasing order of "id" */ | 'id_ascending' -/** - * Supported set of sort modes for scanning by id only. - * - * Currently, we only support scanning in ascending order. - */ -export type IdSortMode = 'id_ascending' - /** * Supported set of sort modes for scanning by timestamp and ID */ export type TimeAndIdSortMode = /** sort in increasing order of timestamp and ID, i.e., earliest first */ - | 'ascending' + | 'time_and_id_ascending' /** sort in increasing order of timestamp and ID, i.e., most recent first */ - | 'descending' + | 'time_and_id_descending' export type DiskMetricName = | 'activated' @@ -4771,6 +4949,13 @@ export type DiskMetricName = */ export type PaginationOrder = 'ascending' | 'descending' +/** + * Supported set of sort modes for scanning by id only. + * + * Currently, we only support scanning in ascending order. + */ +export type IdSortMode = 'id_ascending' + export type SystemMetricName = | 'virtual_disk_space_provisioned' | 'cpus_provisioned' @@ -4813,13 +4998,17 @@ export interface ProbeDeleteQueryParams { export interface SupportBundleListQueryParams { limit?: number | null pageToken?: string | null - sortBy?: IdSortMode + sortBy?: TimeAndIdSortMode } export interface SupportBundleViewPathParams { bundleId: string } +export interface SupportBundleUpdatePathParams { + bundleId: string +} + export interface SupportBundleDeletePathParams { bundleId: string } @@ -5643,6 +5832,14 @@ export interface SnapshotDeleteQueryParams { project?: NameOrId } +export interface AuditLogListQueryParams { + endTime?: Date | null + limit?: number | null + pageToken?: string | null + sortBy?: TimeAndIdSortMode + startTime?: Date +} + export interface PhysicalDiskListQueryParams { limit?: number | null pageToken?: string | null @@ -5976,15 +6173,6 @@ export interface NetworkingSwitchPortSettingsViewPathParams { port: NameOrId } -export interface RoleListQueryParams { - limit?: number | null - pageToken?: string | null -} - -export interface RoleViewPathParams { - roleName: string -} - export interface SystemQuotasListQueryParams { limit?: number | null pageToken?: string | null @@ -6036,6 +6224,28 @@ export interface SystemTimeseriesSchemaListQueryParams { pageToken?: string | null } +export interface SystemUpdatePutRepositoryQueryParams { + fileName: string +} + +export interface SystemUpdateGetRepositoryPathParams { + systemVersion: string +} + +export interface SystemUpdateTrustRootListQueryParams { + limit?: number | null + pageToken?: string | null + sortBy?: IdSortMode +} + +export interface SystemUpdateTrustRootViewPathParams { + trustRootId: string +} + +export interface SystemUpdateTrustRootDeletePathParams { + trustRootId: string +} + export interface SiloUserListQueryParams { limit?: number | null pageToken?: string | null @@ -6082,6 +6292,34 @@ export interface UserListQueryParams { sortBy?: IdSortMode } +export interface UserViewPathParams { + userId: string +} + +export interface UserTokenListPathParams { + userId: string +} + +export interface UserTokenListQueryParams { + limit?: number | null + pageToken?: string | null + sortBy?: IdSortMode +} + +export interface UserLogoutPathParams { + userId: string +} + +export interface UserSessionListPathParams { + userId: string +} + +export interface UserSessionListQueryParams { + limit?: number | null + pageToken?: string | null + sortBy?: IdSortMode +} + export interface VpcFirewallRulesViewQueryParams { project?: NameOrId vpc: NameOrId @@ -6388,10 +6626,14 @@ export class Api extends HttpClient { /** * Create a new support bundle */ - supportBundleCreate: (_: EmptyObj, params: FetchParams = {}) => { + supportBundleCreate: ( + { body }: { body: SupportBundleCreate }, + params: FetchParams = {} + ) => { return this.request({ path: `/experimental/v1/system/support-bundles`, method: 'POST', + body, ...params, }) }, @@ -6408,6 +6650,20 @@ export class Api extends HttpClient { ...params, }) }, + /** + * Update a support bundle + */ + supportBundleUpdate: ( + { path, body }: { path: SupportBundleUpdatePathParams; body: SupportBundleUpdate }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/experimental/v1/system/support-bundles/${path.bundleId}`, + method: 'PUT', + body, + ...params, + }) + }, /** * Delete an existing support bundle */ @@ -8421,6 +8677,20 @@ export class Api extends HttpClient { ...params, }) }, + /** + * View audit log + */ + auditLogList: ( + { query = {} }: { query?: AuditLogListQueryParams }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/system/audit-log`, + method: 'GET', + query, + ...params, + }) + }, /** * List physical disks */ @@ -9351,6 +9621,30 @@ export class Api extends HttpClient { ...params, }) }, + /** + * Return whether API services can receive limited ICMP traffic + */ + networkingInboundIcmpView: (_: EmptyObj, params: FetchParams = {}) => { + return this.request({ + path: `/v1/system/networking/inbound-icmp`, + method: 'GET', + ...params, + }) + }, + /** + * Set whether API services can receive limited ICMP traffic + */ + networkingInboundIcmpUpdate: ( + { body }: { body: ServiceIcmpConfig }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/system/networking/inbound-icmp`, + method: 'PUT', + body, + ...params, + }) + }, /** * List loopback addresses */ @@ -9468,30 +9762,6 @@ export class Api extends HttpClient { ...params, }) }, - /** - * List built-in roles - */ - roleList: ( - { query = {} }: { query?: RoleListQueryParams }, - params: FetchParams = {} - ) => { - return this.request({ - path: `/v1/system/roles`, - method: 'GET', - query, - ...params, - }) - }, - /** - * Fetch built-in role - */ - roleView: ({ path }: { path: RoleViewPathParams }, params: FetchParams = {}) => { - return this.request({ - path: `/v1/system/roles/${path.roleName}`, - method: 'GET', - ...params, - }) - }, /** * Lists resource quotas for all silos */ @@ -9650,6 +9920,33 @@ export class Api extends HttpClient { ...params, }) }, + /** + * Upload system release repository + */ + systemUpdatePutRepository: ( + { query }: { query: SystemUpdatePutRepositoryQueryParams }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/system/update/repository`, + method: 'PUT', + query, + ...params, + }) + }, + /** + * Fetch system release repository description by version + */ + systemUpdateGetRepository: ( + { path }: { path: SystemUpdateGetRepositoryPathParams }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/system/update/repository/${path.systemVersion}`, + method: 'GET', + ...params, + }) + }, /** * Get the current target release of the rack's system software */ @@ -9674,6 +9971,56 @@ export class Api extends HttpClient { ...params, }) }, + /** + * List root roles in the updates trust store + */ + systemUpdateTrustRootList: ( + { query = {} }: { query?: SystemUpdateTrustRootListQueryParams }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/system/update/trust-roots`, + method: 'GET', + query, + ...params, + }) + }, + /** + * Add trusted root role to updates trust store + */ + systemUpdateTrustRootCreate: (_: EmptyObj, params: FetchParams = {}) => { + return this.request({ + path: `/v1/system/update/trust-roots`, + method: 'POST', + ...params, + }) + }, + /** + * Fetch trusted root role + */ + systemUpdateTrustRootView: ( + { path }: { path: SystemUpdateTrustRootViewPathParams }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/system/update/trust-roots/${path.trustRootId}`, + method: 'GET', + ...params, + }) + }, + /** + * Delete trusted root role + */ + systemUpdateTrustRootDelete: ( + { path }: { path: SystemUpdateTrustRootDeletePathParams }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/system/update/trust-roots/${path.trustRootId}`, + method: 'DELETE', + ...params, + }) + }, /** * List built-in (system) users in silo */ @@ -9785,6 +10132,60 @@ export class Api extends HttpClient { ...params, }) }, + /** + * Fetch user + */ + userView: ({ path }: { path: UserViewPathParams }, params: FetchParams = {}) => { + return this.request({ + path: `/v1/users/${path.userId}`, + method: 'GET', + ...params, + }) + }, + /** + * List user's access tokens + */ + userTokenList: ( + { + path, + query = {}, + }: { path: UserTokenListPathParams; query?: UserTokenListQueryParams }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/users/${path.userId}/access-tokens`, + method: 'GET', + query, + ...params, + }) + }, + /** + * Log user out + */ + userLogout: ({ path }: { path: UserLogoutPathParams }, params: FetchParams = {}) => { + return this.request({ + path: `/v1/users/${path.userId}/logout`, + method: 'POST', + ...params, + }) + }, + /** + * List user's console sessions + */ + userSessionList: ( + { + path, + query = {}, + }: { path: UserSessionListPathParams; query?: UserSessionListQueryParams }, + params: FetchParams = {} + ) => { + return this.request({ + path: `/v1/users/${path.userId}/sessions`, + method: 'GET', + query, + ...params, + }) + }, /** * Fetch resource utilization for user's current silo */ diff --git a/app/api/__generated__/OMICRON_VERSION b/app/api/__generated__/OMICRON_VERSION index 907cbd5f8..469489c1c 100644 --- a/app/api/__generated__/OMICRON_VERSION +++ b/app/api/__generated__/OMICRON_VERSION @@ -1,2 +1,2 @@ # generated file. do not update manually. see docs/update-pinned-api.md -99ffcbe2b1f4bddc4be85e45d9d1a0d920e2201b +ae1c739ca12f3d3fc94e78fb024bcaf2e2cbca56 diff --git a/app/api/__generated__/msw-handlers.ts b/app/api/__generated__/msw-handlers.ts index 096491ef6..53b00ef04 100644 --- a/app/api/__generated__/msw-handlers.ts +++ b/app/api/__generated__/msw-handlers.ts @@ -96,6 +96,7 @@ export interface MSWHandlers { }) => Promisable> /** `POST /experimental/v1/system/support-bundles` */ supportBundleCreate: (params: { + body: Json req: Request cookies: Record }) => Promisable> @@ -105,6 +106,13 @@ export interface MSWHandlers { req: Request cookies: Record }) => Promisable> + /** `PUT /experimental/v1/system/support-bundles/:bundleId` */ + supportBundleUpdate: (params: { + path: Api.SupportBundleUpdatePathParams + body: Json + req: Request + cookies: Record + }) => Promisable> /** `DELETE /experimental/v1/system/support-bundles/:bundleId` */ supportBundleDelete: (params: { path: Api.SupportBundleDeletePathParams @@ -936,6 +944,12 @@ export interface MSWHandlers { req: Request cookies: Record }) => Promisable + /** `GET /v1/system/audit-log` */ + auditLogList: (params: { + query: Api.AuditLogListQueryParams + req: Request + cookies: Record + }) => Promisable> /** `GET /v1/system/hardware/disks` */ physicalDiskList: (params: { query: Api.PhysicalDiskListQueryParams @@ -1341,6 +1355,17 @@ export interface MSWHandlers { req: Request cookies: Record }) => Promisable> + /** `GET /v1/system/networking/inbound-icmp` */ + networkingInboundIcmpView: (params: { + req: Request + cookies: Record + }) => Promisable> + /** `PUT /v1/system/networking/inbound-icmp` */ + networkingInboundIcmpUpdate: (params: { + body: Json + req: Request + cookies: Record + }) => Promisable /** `GET /v1/system/networking/loopback-address` */ networkingLoopbackAddressList: (params: { query: Api.NetworkingLoopbackAddressListQueryParams @@ -1394,18 +1419,6 @@ export interface MSWHandlers { req: Request cookies: Record }) => Promisable> - /** `GET /v1/system/roles` */ - roleList: (params: { - query: Api.RoleListQueryParams - req: Request - cookies: Record - }) => Promisable> - /** `GET /v1/system/roles/:roleName` */ - roleView: (params: { - path: Api.RoleViewPathParams - req: Request - cookies: Record - }) => Promisable> /** `GET /v1/system/silo-quotas` */ systemQuotasList: (params: { query: Api.SystemQuotasListQueryParams @@ -1481,6 +1494,18 @@ export interface MSWHandlers { req: Request cookies: Record }) => Promisable> + /** `PUT /v1/system/update/repository` */ + systemUpdatePutRepository: (params: { + query: Api.SystemUpdatePutRepositoryQueryParams + req: Request + cookies: Record + }) => Promisable> + /** `GET /v1/system/update/repository/:systemVersion` */ + systemUpdateGetRepository: (params: { + path: Api.SystemUpdateGetRepositoryPathParams + req: Request + cookies: Record + }) => Promisable> /** `GET /v1/system/update/target-release` */ targetReleaseView: (params: { req: Request @@ -1492,6 +1517,29 @@ export interface MSWHandlers { req: Request cookies: Record }) => Promisable> + /** `GET /v1/system/update/trust-roots` */ + systemUpdateTrustRootList: (params: { + query: Api.SystemUpdateTrustRootListQueryParams + req: Request + cookies: Record + }) => Promisable> + /** `POST /v1/system/update/trust-roots` */ + systemUpdateTrustRootCreate: (params: { + req: Request + cookies: Record + }) => Promisable> + /** `GET /v1/system/update/trust-roots/:trustRootId` */ + systemUpdateTrustRootView: (params: { + path: Api.SystemUpdateTrustRootViewPathParams + req: Request + cookies: Record + }) => Promisable> + /** `DELETE /v1/system/update/trust-roots/:trustRootId` */ + systemUpdateTrustRootDelete: (params: { + path: Api.SystemUpdateTrustRootDeletePathParams + req: Request + cookies: Record + }) => Promisable /** `GET /v1/system/users` */ siloUserList: (params: { query: Api.SiloUserListQueryParams @@ -1542,6 +1590,32 @@ export interface MSWHandlers { req: Request cookies: Record }) => Promisable> + /** `GET /v1/users/:userId` */ + userView: (params: { + path: Api.UserViewPathParams + req: Request + cookies: Record + }) => Promisable> + /** `GET /v1/users/:userId/access-tokens` */ + userTokenList: (params: { + path: Api.UserTokenListPathParams + query: Api.UserTokenListQueryParams + req: Request + cookies: Record + }) => Promisable> + /** `POST /v1/users/:userId/logout` */ + userLogout: (params: { + path: Api.UserLogoutPathParams + req: Request + cookies: Record + }) => Promisable + /** `GET /v1/users/:userId/sessions` */ + userSessionList: (params: { + path: Api.UserSessionListPathParams + query: Api.UserSessionListQueryParams + req: Request + cookies: Record + }) => Promisable> /** `GET /v1/utilization` */ utilizationView: (params: { req: Request @@ -1872,12 +1946,20 @@ export function makeHandlers(handlers: MSWHandlers): HttpHandler[] { ), http.post( '/experimental/v1/system/support-bundles', - handler(handlers['supportBundleCreate'], null, null) + handler(handlers['supportBundleCreate'], null, schema.SupportBundleCreate) ), http.get( '/experimental/v1/system/support-bundles/:bundleId', handler(handlers['supportBundleView'], schema.SupportBundleViewParams, null) ), + http.put( + '/experimental/v1/system/support-bundles/:bundleId', + handler( + handlers['supportBundleUpdate'], + schema.SupportBundleUpdateParams, + schema.SupportBundleUpdate + ) + ), http.delete( '/experimental/v1/system/support-bundles/:bundleId', handler(handlers['supportBundleDelete'], schema.SupportBundleDeleteParams, null) @@ -2552,6 +2634,10 @@ export function makeHandlers(handlers: MSWHandlers): HttpHandler[] { '/v1/snapshots/:snapshot', handler(handlers['snapshotDelete'], schema.SnapshotDeleteParams, null) ), + http.get( + '/v1/system/audit-log', + handler(handlers['auditLogList'], schema.AuditLogListParams, null) + ), http.get( '/v1/system/hardware/disks', handler(handlers['physicalDiskList'], schema.PhysicalDiskListParams, null) @@ -2908,6 +2994,14 @@ export function makeHandlers(handlers: MSWHandlers): HttpHandler[] { '/v1/system/networking/bgp-status', handler(handlers['networkingBgpStatus'], null, null) ), + http.get( + '/v1/system/networking/inbound-icmp', + handler(handlers['networkingInboundIcmpView'], null, null) + ), + http.put( + '/v1/system/networking/inbound-icmp', + handler(handlers['networkingInboundIcmpUpdate'], null, schema.ServiceIcmpConfig) + ), http.get( '/v1/system/networking/loopback-address', handler( @@ -2969,14 +3063,6 @@ export function makeHandlers(handlers: MSWHandlers): HttpHandler[] { '/v1/system/policy', handler(handlers['systemPolicyUpdate'], null, schema.FleetRolePolicy) ), - http.get( - '/v1/system/roles', - handler(handlers['roleList'], schema.RoleListParams, null) - ), - http.get( - '/v1/system/roles/:roleName', - handler(handlers['roleView'], schema.RoleViewParams, null) - ), http.get( '/v1/system/silo-quotas', handler(handlers['systemQuotasList'], schema.SystemQuotasListParams, null) @@ -3034,6 +3120,22 @@ export function makeHandlers(handlers: MSWHandlers): HttpHandler[] { null ) ), + http.put( + '/v1/system/update/repository', + handler( + handlers['systemUpdatePutRepository'], + schema.SystemUpdatePutRepositoryParams, + null + ) + ), + http.get( + '/v1/system/update/repository/:systemVersion', + handler( + handlers['systemUpdateGetRepository'], + schema.SystemUpdateGetRepositoryParams, + null + ) + ), http.get( '/v1/system/update/target-release', handler(handlers['targetReleaseView'], null, null) @@ -3042,6 +3144,34 @@ export function makeHandlers(handlers: MSWHandlers): HttpHandler[] { '/v1/system/update/target-release', handler(handlers['targetReleaseUpdate'], null, schema.SetTargetReleaseParams) ), + http.get( + '/v1/system/update/trust-roots', + handler( + handlers['systemUpdateTrustRootList'], + schema.SystemUpdateTrustRootListParams, + null + ) + ), + http.post( + '/v1/system/update/trust-roots', + handler(handlers['systemUpdateTrustRootCreate'], null, null) + ), + http.get( + '/v1/system/update/trust-roots/:trustRootId', + handler( + handlers['systemUpdateTrustRootView'], + schema.SystemUpdateTrustRootViewParams, + null + ) + ), + http.delete( + '/v1/system/update/trust-roots/:trustRootId', + handler( + handlers['systemUpdateTrustRootDelete'], + schema.SystemUpdateTrustRootDeleteParams, + null + ) + ), http.get( '/v1/system/users', handler(handlers['siloUserList'], schema.SiloUserListParams, null) @@ -3075,6 +3205,22 @@ export function makeHandlers(handlers: MSWHandlers): HttpHandler[] { ) ), http.get('/v1/users', handler(handlers['userList'], schema.UserListParams, null)), + http.get( + '/v1/users/:userId', + handler(handlers['userView'], schema.UserViewParams, null) + ), + http.get( + '/v1/users/:userId/access-tokens', + handler(handlers['userTokenList'], schema.UserTokenListParams, null) + ), + http.post( + '/v1/users/:userId/logout', + handler(handlers['userLogout'], schema.UserLogoutParams, null) + ), + http.get( + '/v1/users/:userId/sessions', + handler(handlers['userSessionList'], schema.UserSessionListParams, null) + ), http.get('/v1/utilization', handler(handlers['utilizationView'], null, null)), http.get( '/v1/vpc-firewall-rules', diff --git a/app/api/__generated__/validate.ts b/app/api/__generated__/validate.ts index 3c54af9f8..4b833599e 100644 --- a/app/api/__generated__/validate.ts +++ b/app/api/__generated__/validate.ts @@ -602,6 +602,57 @@ export const AntiAffinityGroupUpdate = z.preprocess( }) ) +/** + * An identifier for an artifact. + */ +export const ArtifactId = z.preprocess( + processResponseBody, + z.object({ kind: z.string(), name: z.string(), version: z.string() }) +) + +export const AuditLogEntryActor = z.preprocess( + processResponseBody, + z.union([ + z.object({ kind: z.enum(['user_builtin']), userBuiltinId: z.string().uuid() }), + z.object({ + kind: z.enum(['silo_user']), + siloId: z.string().uuid(), + siloUserId: z.string().uuid(), + }), + z.object({ kind: z.enum(['unauthenticated']) }), + ]) +) + +/** + * Audit log entry + */ +export const AuditLogEntry = z.preprocess( + processResponseBody, + z.object({ + accessMethod: z.string().nullable().optional(), + actor: AuditLogEntryActor, + errorCode: z.string().nullable().optional(), + errorMessage: z.string().nullable().optional(), + httpStatusCode: z.number().min(0).max(65535), + id: z.string().uuid(), + operationId: z.string(), + requestId: z.string(), + requestUri: z.string(), + sourceIp: z.string().ip(), + timeCompleted: z.coerce.date(), + timeStarted: z.coerce.date(), + userAgent: z.string().nullable().optional(), + }) +) + +/** + * A single page of results + */ +export const AuditLogEntryResultsPage = z.preprocess( + processResponseBody, + z.object({ items: AuditLogEntry.array(), nextPage: z.string().nullable().optional() }) +) + /** * Authorization scope for a timeseries. * @@ -805,7 +856,7 @@ export const BgpPeer = z.preprocess( enforceFirstAs: SafeBoolean, holdTime: z.number().min(0).max(4294967295), idleHoldTime: z.number().min(0).max(4294967295), - interfaceName: z.string(), + interfaceName: Name, keepalive: z.number().min(0).max(4294967295), localPref: z.number().min(0).max(4294967295).nullable().optional(), md5AuthKey: z.string().nullable().optional(), @@ -1161,6 +1212,26 @@ export const CertificateResultsPage = z.preprocess( z.object({ items: Certificate.array(), nextPage: z.string().nullable().optional() }) ) +/** + * View of a console session + */ +export const ConsoleSession = z.preprocess( + processResponseBody, + z.object({ + id: z.string().uuid(), + timeCreated: z.coerce.date(), + timeLastUsed: z.coerce.date(), + }) +) + +/** + * A single page of results + */ +export const ConsoleSessionResultsPage = z.preprocess( + processResponseBody, + z.object({ items: ConsoleSession.array(), nextPage: z.string().nullable().optional() }) +) + /** * A cumulative or counter data type. */ @@ -1711,7 +1782,11 @@ export const Error = z.preprocess( export const ExternalIp = z.preprocess( processResponseBody, z.union([ - z.object({ ip: z.string().ip(), kind: z.enum(['ephemeral']) }), + z.object({ + ip: z.string().ip(), + ipPoolId: z.string().uuid(), + kind: z.enum(['ephemeral']), + }), z.object({ description: z.string(), id: z.string().uuid(), @@ -1944,6 +2019,20 @@ export const Hostname = z.preprocess( .regex(/^([a-zA-Z0-9]+[a-zA-Z0-9\-]*(? {/* The [&+*]:pt-10 style is to ensure the page container isn't pushed out of screen as it uses 100vh for layout */} -