Skip to content

Latest commit

 

History

History
3916 lines (3521 loc) · 123 KB

File metadata and controls

3916 lines (3521 loc) · 123 KB

API Reference

Packages:

ntn.operators.dev/v1alpha1

Resource Types:

GroundStationLifecycle

↩ Parent

GroundStationLifecycle manages the lifecycle of a satellite ground station, including health monitoring, firmware OTA, and GitOps-based configuration.

Name Type Description Required
apiVersion string ntn.operators.dev/v1alpha1 true
kind string GroundStationLifecycle true
metadata object Refer to the Kubernetes API documentation for the fields of the `metadata` field. true
spec object GroundStationLifecycleSpec defines the desired state of a ground station.
true
status object GroundStationLifecycleStatus defines the observed state of a ground station.
false

GroundStationLifecycle.spec

↩ Parent

GroundStationLifecycleSpec defines the desired state of a ground station.

Name Type Description Required
deployment object deployment defines the station deployment and location.
true
hardware object hardware describes the ground station equipment.
true
firmware object firmware defines OTA update configuration.
false
monitoring object monitoring defines health check parameters.
false

GroundStationLifecycle.spec.deployment

↩ Parent

deployment defines the station deployment and location.

Name Type Description Required
location object location is the geographic position of the ground station.

Validations:
  • double(self.lat) >= -90.0 && double(self.lat) <= 90.0: lat must be between -90 and 90
  • double(self.lon) >= -180.0 && double(self.lon) <= 180.0: lon must be between -180 and 180
  • true
    gitopsRepo string gitopsRepo is the Git repository URL for GitOps-managed configuration.
    false
    k8sDistro enum k8sDistro is the Kubernetes distribution running on the edge box.

    Enum: k3s, microk8s, rke2
    Default: k3s
    false

    GroundStationLifecycle.spec.deployment.location

    ↩ Parent

    location is the geographic position of the ground station.

    Name Type Description Required
    lat string lat is the latitude in decimal degrees (string, e.g., "25.0330").
    true
    lon string lon is the longitude in decimal degrees (string, e.g., "121.5654").
    true
    alt string alt is the altitude in meters above sea level (string, e.g., "15").
    false

    GroundStationLifecycle.spec.hardware

    ↩ Parent

    hardware describes the ground station equipment.

    Name Type Description Required
    model string model is the hardware model identifier.
    true
    vendor string vendor is the hardware manufacturer (e.g., "ennoconn").
    true
    antennaType string antennaType is the antenna type (e.g., "flat-panel", "parabolic").
    false
    bands []string bands lists the supported frequency bands (e.g., ["Ka", "Ku", "S"]).
    false

    GroundStationLifecycle.spec.firmware

    ↩ Parent

    firmware defines OTA update configuration.

    Name Type Description Required
    autoUpdate boolean autoUpdate enables automatic firmware updates.

    Default: false
    false
    channel string channel is the firmware update channel (e.g., "stable", "beta").

    Default: stable
    false
    maintenanceWindow string maintenanceWindow is the time window for updates. Format: "HH:MM-HH:MM UTC" (e.g., "02:00-04:00 UTC").
    false

    GroundStationLifecycle.spec.monitoring

    ↩ Parent

    monitoring defines health check parameters.

    Name Type Description Required
    endpoint string endpoint is the monitoring endpoint of the ground station agent.
    false
    healthCheckInterval string healthCheckInterval is how often to check ground station health.

    Default: 30s
    false

    GroundStationLifecycle.status

    ↩ Parent

    GroundStationLifecycleStatus defines the observed state of a ground station.

    Name Type Description Required
    conditions []object conditions represent the current state of the ground station.
    false
    firmwareUpdateStarted string firmwareUpdateStarted is when the current firmware update began. Used for timeout detection.

    Format: date-time
    false
    firmwareVersion string firmwareVersion is the currently running firmware version.
    false
    k8sVersion string k8sVersion is the Kubernetes version running on the edge node.
    false
    lastHealthCheck string lastHealthCheck is the timestamp of the last successful health check.

    Format: date-time
    false
    phase enum phase is the current lifecycle phase.

    Enum: Provisioning, Running, Degraded, Offline, Updating
    false

    GroundStationLifecycle.status.conditions[index]

    ↩ Parent

    Condition contains details for one aspect of the current state of this API Resource.

    Name Type Description Required
    lastTransitionTime string lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.

    Format: date-time
    true
    message string message is a human readable message indicating details about the transition. This may be an empty string.
    true
    reason string reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
    true
    status enum status of the condition, one of True, False, Unknown.

    Enum: True, False, Unknown
    true
    type string type of condition in CamelCase or in foo.example.com/CamelCase.
    true
    observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

    Format: int64
    Minimum: 0
    false

    NTNCellConfig

    ↩ Parent

    NTNCellConfig manages NTN-specific radio parameters for a gNB cell, delegating configuration to the specified NTN backend provider.

    Name Type Description Required
    apiVersion string ntn.operators.dev/v1alpha1 true
    kind string NTNCellConfig true
    metadata object Refer to the Kubernetes API documentation for the fields of the `metadata` field. true
    spec object NTNCellConfigSpec defines the desired NTN cell configuration.

    Validations:
  • !has(self.provider.remoteControl) || has(self.cellID): cellID is required when provider.remoteControl is set (runtime push targets a cell by plmn+nci)
  • true
    status object NTNCellConfigStatus defines the observed state of NTNCellConfig.
    false

    NTNCellConfig.spec

    ↩ Parent

    NTNCellConfigSpec defines the desired NTN cell configuration.

    Name Type Description Required
    ntn object ntn contains NTN-specific radio parameters per 3GPP TS 38.213 / OCUDU geo_ntn.yml.

    Validations:
  • has(self.ephemerisECEF) || has(self.ephemerisOrbital): exactly one of ephemerisECEF or ephemerisOrbital must be set
  • !(has(self.ephemerisECEF) && has(self.ephemerisOrbital)): ephemerisECEF and ephemerisOrbital are mutually exclusive
  • !has(self.ephemerisECEF) || self.ephemerisECEF.posX != 0 || self.ephemerisECEF.posY != 0 || self.ephemerisECEF.posZ != 0: ephemerisECEF position must not be all zeros
  • true
    provider object provider specifies which NTN backend to configure.
    true
    cellID object cellID identifies the OCUDU cell (plmn + nci) that runtime remote commands target. Required when provider.remoteControl is set; the value must match the cell the gNB booted with. Unset ⇒ ConfigMap bootstrap path only.
    false
    cellOverrides object cellOverrides allows fine-tuning PUCCH, PDSCH, PRACH, and RRC parameters.
    false
    ephemerisNoradID integer ephemerisNoradID selects which satellite's propagated state vector, from the referenced SatelliteEphemeris (ephemerisRef), to push at runtime (#176). When unset, the single tracked satellite's state is used; if the referenced ephemeris exposes more than one satellite the push fails closed (EphemerisPushed=False, reason EphemerisSelectionAmbiguous) until this field selects one — the controller never guesses which satellite to serve.
    false
    ephemerisRef string ephemerisRef is the name of a SatelliteEphemeris CR in the same namespace. When set, the controller re-reconciles this NTNCellConfig whenever the referenced SatelliteEphemeris is updated and invokes runtime ephemeris push on the provider reconcile path. The static ephemeris in spec.ntn (ephemerisECEF or ephemerisOrbital) remains required as the source payload.
    false

    NTNCellConfig.spec.ntn

    ↩ Parent

    ntn contains NTN-specific radio parameters per 3GPP TS 38.213 / OCUDU geo_ntn.yml.

    Name Type Description Required
    cellSpecificKoffset integer cellSpecificKoffset is the cell-specific K_offset for NTN scheduling timing (3GPP TS 38.213 / TS 38.300 §16.14.2). Its unit is milliseconds: OCUDU stores cell_specific_koffset as std::chrono::milliseconds and converts it to operating-SCS slots internally, so the value passes through this operator unchanged with no unit conversion. (3GPP expresses K_offset as a slot count assuming the 15 kHz reference SCS, where 1 slot = 1 ms; that identity is only how the IE is defined, not a conversion the user applies here.) The 3GPP IE cellSpecificKoffset-r17 is INTEGER(0..1023), but OCUDU rejects 0 (its CLI and config validation enforce 1-1023), so Minimum is 1 to mirror the backend rather than the spec.

    Default: 150
    Minimum: 1
    Maximum: 1023
    false
    distanceThreshold integer distanceThreshold sets the distance threshold for cell selection in metres.

    Minimum: 0
    false
    ephemerisECEF object ephemerisECEF defines the satellite position and velocity in ECEF coordinates. Mutually exclusive with ephemerisOrbital.
    false
    ephemerisOrbital object ephemerisOrbital defines the satellite orbit using Keplerian elements. Mutually exclusive with ephemerisECEF. Preferred for LEO satellites where source data is in OMM/TLE form (CelesTrak, SpaceTrack).
    false
    epochTime object epochTime defines the SFN/subframe reference for NTN timing alignment.
    false
    feederLinkInfo object feederLinkInfo provides feeder link parameters for Doppler compensation.
    false
    movingRefLocation object movingRefLocation defines the Earth-moving reference location for LEO NTN cells. 3GPP Release 18 SIB19 field. Used by UEs for timing/Doppler estimation.
    false
    neighborCells []object neighborCells lists neighbor NTN cells for measurement/handover. OCUDU YAML renders as "ncells:" for compatibility.
    false
    ntnGatewayLocation object ntnGatewayLocation specifies the NTN gateway (ground station) coordinates.
    false
    ntnUlSyncValidityDur integer ntnUlSyncValidityDur sets the UL synchronization validity duration in seconds (SIB19 ntn-Config-r17 ntn-UlSyncValidityDuration). A UE runs timer T430 = this duration from the SIB19 epochTime (TS 38.331 §5.2.2.4.21) and, on T430 expiry (§5.2.2.6), deems UL sync lost and re-acquires SIB19; the resulting cessation of uplink transmission is the lower-layer MAC/PHY behaviour (TS 38.321 / TS 38.213 — T430 itself is a 38.331 timer). Unset is NOT "no validity": the operator applies 5 s (the runtime push sends it, and OCUDU's own config default is 5 s), so the advisory evaluates an unset field against 5 s too. Two deployment-sizing rules follow (see docs/ntn-ul-sync-timing.md): (1) the SIB19 broadcast period (cellOverrides.sibSchedule.siPeriod) must be shorter than this value so the UE can re-read SIB19 in time — the operator raises a SIB19CadenceSane=False Warning when it is not (gated on the gNB re-anchoring its SIB19 epoch; see provider.sib19EpochMode); (2) the ephemeris re-push cadence vs this value is a NON-issue on OCUDU (the primary provider re-anchors the broadcast SIB19 epochTime to the SI-window end on each regeneration, so validity self-renews) — it would only matter for a provider that pins the broadcast epochTime to the pushed timestamp, where it is a deployment-sizing responsibility (not auto-enforced).

    Enum: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 120, 180, 240, 900
    false
    payloadType enum payloadType specifies the satellite payload architecture.

    Enum: transparent, regenerative
    Default: transparent
    false
    polarization object polarization specifies the antenna polarization for downlink and uplink. Per 3GPP TS 38.331 SIB19, ntn-PolarizationDL-r17 and ntn-PolarizationUL-r17 are independent IEs. OCUDU collapses them under a single `polarization:` map with `dl:` / `ul:` sub-keys, matching this CRD layout.

    Validations:
  • has(self.dl) || has(self.ul): at least one of dl or ul must be set
  • false
    referenceLocation object referenceLocation defines the NTN cell reference location.
    false
    satSwitchWithResync object satSwitchWithResync provides satellite switch handover hints to UEs during satellite-to-satellite transitions. 3GPP Release 18 SIB19 field.
    false
    tService integer tService sets the expected NTN service duration in seconds.

    Minimum: 1
    false
    taCommon integer taCommon sets the common Timing Advance value (0-66485757).

    Default: 0
    Minimum: 0
    Maximum: 6.6485756e+07
    false
    taInfo object taInfo provides extended Timing Advance parameters per 3GPP TS 38.213. When set, taInfo.taCommon takes precedence over the top-level taCommon field.
    false
    taReport boolean taReport enables UE TA reporting.
    false

    NTNCellConfig.spec.ntn.ephemerisECEF

    ↩ Parent

    ephemerisECEF defines the satellite position and velocity in ECEF coordinates. Mutually exclusive with ephemerisOrbital.

    Name Type Description Required
    posX integer posX is the X position in 1.3 m/LSB codepoints (3GPP positionX-r17, -33554432 to 33554431). The operator emits posX × 1.3 as metres to OCUDU.

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    posY integer posY is the Y position in 1.3 m/LSB codepoints (-33554432 to 33554431).

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    posZ integer posZ is the Z position in 1.3 m/LSB codepoints (-33554432 to 33554431).

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    velX integer velX is the X velocity in 0.06 m/s/LSB codepoints (3GPP velocityVX-r17, -131072 to 131071; 0 for GEO). The operator emits velX × 0.06 as m/s.

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false
    velY integer velY is the Y velocity in 0.06 m/s/LSB codepoints (-131072 to 131071; 0 for GEO).

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false
    velZ integer velZ is the Z velocity in 0.06 m/s/LSB codepoints (-131072 to 131071; 0 for GEO).

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false

    NTNCellConfig.spec.ntn.ephemerisOrbital

    ↩ Parent

    ephemerisOrbital defines the satellite orbit using Keplerian elements. Mutually exclusive with ephemerisECEF. Preferred for LEO satellites where source data is in OMM/TLE form (CelesTrak, SpaceTrack).

    Name Type Description Required
    argOfPeriapsis integer argOfPeriapsis is the argument of periapsis in 1e-4 degrees (0-3600000).

    Minimum: 0
    Maximum: 3.6e+06
    true
    eccentricity integer eccentricity is the orbital eccentricity scaled by 1e6 (0-15005). The operator emits eccentricity × 1e-6; OCUDU accepts e ≤ 0.01500510825.

    Minimum: 0
    Maximum: 15005
    true
    inclination integer inclination is the orbital inclination in 1e-4 degrees; the operator emits inclination × π/1.8e6 as radians. OCUDU's orbital ephemeris accepts only [0°, 90°] (0 to +π/2 rad), so inclinations above 90° (e.g. sun-synchronous ~98°, retrograde) are NOT representable via the orbital path — use ephemerisECEF (SGP4 state vector) for those. Max is 900000 (90°).

    Minimum: 0
    Maximum: 900000
    true
    meanAnomaly integer meanAnomaly is the mean anomaly in 1e-4 degrees (0-3600000).

    Minimum: 0
    Maximum: 3.6e+06
    true
    rightAscension integer rightAscension is the right ascension of the ascending node in 1e-4 degrees (0-3600000).

    Minimum: 0
    Maximum: 3.6e+06
    true
    semiMajorAxis integer semiMajorAxis is the semi-major axis in metres, emitted as-is to OCUDU (which accepts 6500000-42998632 m).

    Minimum: 6.5e+06
    Maximum: 4.2998632e+07
    true

    NTNCellConfig.spec.ntn.epochTime

    ↩ Parent

    epochTime defines the SFN/subframe reference for NTN timing alignment.

    Name Type Description Required
    sfn integer sfn is the System Frame Number (0-1023).

    Minimum: 0
    Maximum: 1023
    true
    subframeNumber integer subframeNumber is the subframe within the SFN (0-9).

    Minimum: 0
    Maximum: 9
    true

    NTNCellConfig.spec.ntn.feederLinkInfo

    ↩ Parent

    feederLinkInfo provides feeder link parameters for Doppler compensation.

    Name Type Description Required
    dlFreqHz integer dlFreqHz is the downlink frequency in Hz. Required when feederLinkInfo is set.

    Format: int64
    Minimum: 1
    true
    enableDopplerCompensation boolean enableDopplerCompensation enables feeder link Doppler compensation.
    true
    ulFreqHz integer ulFreqHz is the uplink frequency in Hz. Required when feederLinkInfo is set.

    Format: int64
    Minimum: 1
    true

    NTNCellConfig.spec.ntn.movingRefLocation

    ↩ Parent

    movingRefLocation defines the Earth-moving reference location for LEO NTN cells. 3GPP Release 18 SIB19 field. Used by UEs for timing/Doppler estimation.

    Name Type Description Required
    latitude integer latitude in 1e-4 degrees (-900000 to 900000 = -90° to 90°).

    Minimum: -900000
    Maximum: 900000
    true
    longitude integer longitude in 1e-4 degrees (-1800000 to 1800000 = -180° to 180°).

    Minimum: -1.8e+06
    Maximum: 1.8e+06
    true

    NTNCellConfig.spec.ntn.neighborCells[index]

    ↩ Parent

    NTNNeighborCell describes a neighbor NTN cell.

    Name Type Description Required
    physicalCellID integer physicalCellID of the neighbor (0-1007).

    Minimum: 0
    Maximum: 1007
    true
    frequency integer frequency is the neighbor cell's ARFCN (NR-ARFCN, always >= 1).

    Minimum: 1
    false

    NTNCellConfig.spec.ntn.ntnGatewayLocation

    ↩ Parent

    ntnGatewayLocation specifies the NTN gateway (ground station) coordinates.

    Name Type Description Required
    altitude integer altitude in metres above sea level. Required when ntnGatewayLocation is set.
    true
    latitude integer latitude in 1e-4 degrees (-900000 to 900000).

    Minimum: -900000
    Maximum: 900000
    true
    longitude integer longitude in 1e-4 degrees (-1800000 to 1800000).

    Minimum: -1.8e+06
    Maximum: 1.8e+06
    true

    NTNCellConfig.spec.ntn.polarization

    ↩ Parent

    polarization specifies the antenna polarization for downlink and uplink. Per 3GPP TS 38.331 SIB19, ntn-PolarizationDL-r17 and ntn-PolarizationUL-r17 are independent IEs. OCUDU collapses them under a single polarization: map with dl: / ul: sub-keys, matching this CRD layout.

    Name Type Description Required
    dl enum dl is the downlink polarization broadcast in SIB19 ntn-PolarizationDL-r17.

    Enum: rhcp, lhcp, linear
    false
    ul enum ul is the uplink polarization broadcast in SIB19 ntn-PolarizationUL-r17.

    Enum: rhcp, lhcp, linear
    false

    NTNCellConfig.spec.ntn.referenceLocation

    ↩ Parent

    referenceLocation defines the NTN cell reference location.

    Name Type Description Required
    latitude integer latitude in 1e-4 degrees (-900000 to 900000).

    Minimum: -900000
    Maximum: 900000
    true
    longitude integer longitude in 1e-4 degrees (-1800000 to 1800000).

    Minimum: -1.8e+06
    Maximum: 1.8e+06
    true

    NTNCellConfig.spec.ntn.satSwitchWithResync

    ↩ Parent

    satSwitchWithResync provides satellite switch handover hints to UEs during satellite-to-satellite transitions. 3GPP Release 18 SIB19 field.

    Name Type Description Required
    ntnConfig object ntnConfig is the target satellite's NTN configuration after the switch. Required: OCUDU rejects a sat_switch_with_resync that has no ntn_cfg.

    Validations:
  • has(self.ephemerisECEF) || has(self.ephemerisOrbital): exactly one of ephemerisECEF or ephemerisOrbital must be set
  • !(has(self.ephemerisECEF) && has(self.ephemerisOrbital)): ephemerisECEF and ephemerisOrbital are mutually exclusive
  • !has(self.ephemerisECEF) || self.ephemerisECEF.posX != 0 || self.ephemerisECEF.posY != 0 || self.ephemerisECEF.posZ != 0: ephemerisECEF position must not be all zeros
  • true
    epochUnixMs integer epochUnixMs is the reference epoch for the target assistance info, in Unix milliseconds. 0 omits the field. Unlike the serving-cell epoch, OCUDU does not require the sat-switch epoch to be in the future.

    Format: int64
    false
    gatewayLocation object gatewayLocation is the target satellite's NTN gateway (feeder) location, emitted as OCUDU's ntn_gateway_location geodetic coordinates.
    false
    ssbTimeOffsetSubframes integer ssbTimeOffsetSubframes is the SSB time offset in subframes (0-159), mapping to OCUDU's ssb_time_offset_sf.

    Minimum: 0
    Maximum: 159
    false
    tServiceStartUnixMs integer tServiceStartUnixMs is when the target satellite starts serving, in Unix milliseconds. 0 omits the field.

    Format: int64
    false

    NTNCellConfig.spec.ntn.satSwitchWithResync.ntnConfig

    ↩ Parent

    ntnConfig is the target satellite's NTN configuration after the switch. Required: OCUDU rejects a sat_switch_with_resync that has no ntn_cfg.

    Name Type Description Required
    cellSpecificKoffset integer cellSpecificKoffset is the target cell-specific K_offset in milliseconds, same semantics as NTNParams.cellSpecificKoffset: 1-1023, with Minimum 1 because OCUDU rejects 0. Omit the field to leave it unset.

    Minimum: 1
    Maximum: 1023
    false
    ephemerisECEF object ephemerisECEF is the target satellite's ECEF state vector. Mutually exclusive with ephemerisOrbital.
    false
    ephemerisOrbital object ephemerisOrbital is the target satellite's Keplerian elements. Mutually exclusive with ephemerisECEF.
    false
    kMac integer kMac is the MAC-CE scheduling offset k_mac (3GPP kmac-r17, INTEGER 1..512). It tunes the k-offset applied to MAC CE contention-based resolution so UE MAC feedback stays time-aligned with the satellite round-trip; distinct from cellSpecificKoffset (PUSCH/PDSCH offset).

    This is the ONLY OCUDU surface that accepts k_mac (issue #52): the runtime ntn_config_update command's sat_switch_with_resync.ntn_cfg. k_mac is NOT in OCUDU's bootstrap YAML on any cell (serving, neighbor, or satswitch), so the serving-cell static config remains 7/8 on the ntn_config field set by design.

    The 1..512 bound here is LOAD-BEARING: OCUDU's runtime update path does not range-check k_mac (verified against a live gNB — it accepts out-of-range values that would then violate the ASN.1 kmac-r17 constraint), so this CRD validation is the only guard keeping a 3GPP-invalid k_mac off the wire.

    Minimum: 1
    Maximum: 512

    false
    ntnUlSyncValidityDur integer ntnUlSyncValidityDur is the target UL-sync validity duration in seconds. OCUDU keys this ntn_ul_sync_validity_dur inside ntn_cfg — deliberately distinct from the serving-cell ntn_ul_sync_validity_duration key.

    Enum: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 120, 180, 240, 900
    false
    taInfo object taInfo provides the target satellite's timing-advance parameters. The runtime ntn_cfg accepts only ta_common / ta_common_drift / ta_common_drift_variant — NOT ta_common_offset (that key is YAML-only), so taInfo.taCommonOffset is ignored when pushed here.
    false
    taReport boolean taReport enables UE TA reporting for the target satellite.
    false

    NTNCellConfig.spec.ntn.satSwitchWithResync.ntnConfig.ephemerisECEF

    ↩ Parent

    ephemerisECEF is the target satellite's ECEF state vector. Mutually exclusive with ephemerisOrbital.

    Name Type Description Required
    posX integer posX is the X position in 1.3 m/LSB codepoints (3GPP positionX-r17, -33554432 to 33554431). The operator emits posX × 1.3 as metres to OCUDU.

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    posY integer posY is the Y position in 1.3 m/LSB codepoints (-33554432 to 33554431).

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    posZ integer posZ is the Z position in 1.3 m/LSB codepoints (-33554432 to 33554431).

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    velX integer velX is the X velocity in 0.06 m/s/LSB codepoints (3GPP velocityVX-r17, -131072 to 131071; 0 for GEO). The operator emits velX × 0.06 as m/s.

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false
    velY integer velY is the Y velocity in 0.06 m/s/LSB codepoints (-131072 to 131071; 0 for GEO).

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false
    velZ integer velZ is the Z velocity in 0.06 m/s/LSB codepoints (-131072 to 131071; 0 for GEO).

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false

    NTNCellConfig.spec.ntn.satSwitchWithResync.ntnConfig.ephemerisOrbital

    ↩ Parent

    ephemerisOrbital is the target satellite's Keplerian elements. Mutually exclusive with ephemerisECEF.

    Name Type Description Required
    argOfPeriapsis integer argOfPeriapsis is the argument of periapsis in 1e-4 degrees (0-3600000).

    Minimum: 0
    Maximum: 3.6e+06
    true
    eccentricity integer eccentricity is the orbital eccentricity scaled by 1e6 (0-15005). The operator emits eccentricity × 1e-6; OCUDU accepts e ≤ 0.01500510825.

    Minimum: 0
    Maximum: 15005
    true
    inclination integer inclination is the orbital inclination in 1e-4 degrees; the operator emits inclination × π/1.8e6 as radians. OCUDU's orbital ephemeris accepts only [0°, 90°] (0 to +π/2 rad), so inclinations above 90° (e.g. sun-synchronous ~98°, retrograde) are NOT representable via the orbital path — use ephemerisECEF (SGP4 state vector) for those. Max is 900000 (90°).

    Minimum: 0
    Maximum: 900000
    true
    meanAnomaly integer meanAnomaly is the mean anomaly in 1e-4 degrees (0-3600000).

    Minimum: 0
    Maximum: 3.6e+06
    true
    rightAscension integer rightAscension is the right ascension of the ascending node in 1e-4 degrees (0-3600000).

    Minimum: 0
    Maximum: 3.6e+06
    true
    semiMajorAxis integer semiMajorAxis is the semi-major axis in metres, emitted as-is to OCUDU (which accepts 6500000-42998632 m).

    Minimum: 6.5e+06
    Maximum: 4.2998632e+07
    true

    NTNCellConfig.spec.ntn.satSwitchWithResync.ntnConfig.taInfo

    ↩ Parent

    taInfo provides the target satellite's timing-advance parameters. The runtime ntn_cfg accepts only ta_common / ta_common_drift / ta_common_drift_variant — NOT ta_common_offset (that key is YAML-only), so taInfo.taCommonOffset is ignored when pushed here.

    Name Type Description Required
    taCommon integer taCommon is the common Timing Advance value (0-66485757). Required when taInfo is set — explicitly provide 0 for GEO satellites.

    Minimum: 0
    Maximum: 6.6485756e+07
    true
    taCommonDrift integer taCommonDrift is the TA drift rate in 3GPP codepoints (ta-CommonDrift-r17, -257303 to 257303). The operator emits taCommonDrift × 2e-4 as µs/s (OCUDU accepts ±51.4606 µs/s).

    Minimum: -257303
    Maximum: 257303
    false
    taCommonDriftVariant integer taCommonDriftVariant is the TA drift-rate variant in codepoints (ta-CommonDriftVariant-r17, 0 to 28949). Emitted × 2e-5 as µs/s² (OCUDU accepts 0-0.57898 µs/s²).

    Minimum: 0
    Maximum: 28949
    false
    taCommonOffset integer taCommonOffset is an additional common-TA offset in codepoints (same 0.004072 µs granularity as taCommon; 0 to 2455796 maps to OCUDU's 0-10000 µs).

    Minimum: 0
    Maximum: 2.455795e+06
    false

    NTNCellConfig.spec.ntn.satSwitchWithResync.gatewayLocation

    ↩ Parent

    gatewayLocation is the target satellite's NTN gateway (feeder) location, emitted as OCUDU's ntn_gateway_location geodetic coordinates.

    Name Type Description Required
    altitude integer altitude in metres above sea level. Required when ntnGatewayLocation is set.
    true
    latitude integer latitude in 1e-4 degrees (-900000 to 900000).

    Minimum: -900000
    Maximum: 900000
    true
    longitude integer longitude in 1e-4 degrees (-1800000 to 1800000).

    Minimum: -1.8e+06
    Maximum: 1.8e+06
    true

    NTNCellConfig.spec.ntn.taInfo

    ↩ Parent

    taInfo provides extended Timing Advance parameters per 3GPP TS 38.213. When set, taInfo.taCommon takes precedence over the top-level taCommon field.

    Name Type Description Required
    taCommon integer taCommon is the common Timing Advance value (0-66485757). Required when taInfo is set — explicitly provide 0 for GEO satellites.

    Minimum: 0
    Maximum: 6.6485756e+07
    true
    taCommonDrift integer taCommonDrift is the TA drift rate in 3GPP codepoints (ta-CommonDrift-r17, -257303 to 257303). The operator emits taCommonDrift × 2e-4 as µs/s (OCUDU accepts ±51.4606 µs/s).

    Minimum: -257303
    Maximum: 257303
    false
    taCommonDriftVariant integer taCommonDriftVariant is the TA drift-rate variant in codepoints (ta-CommonDriftVariant-r17, 0 to 28949). Emitted × 2e-5 as µs/s² (OCUDU accepts 0-0.57898 µs/s²).

    Minimum: 0
    Maximum: 28949
    false
    taCommonOffset integer taCommonOffset is an additional common-TA offset in codepoints (same 0.004072 µs granularity as taCommon; 0 to 2455796 maps to OCUDU's 0-10000 µs).

    Minimum: 0
    Maximum: 2.455795e+06
    false

    NTNCellConfig.spec.provider

    ↩ Parent

    provider specifies which NTN backend to configure.

    Name Type Description Required
    type enum type is the provider type. Currently only "ocudu" is supported.

    Enum: ocudu
    true
    endpoint string endpoint is the provider-specific endpoint (e.g., O1 NETCONF address).
    false
    namespace string namespace where the provider resources (e.g., OCUDU gNB) are deployed.
    false
    remoteControl object remoteControl configures the gNB remote_control WebSocket for live NTN config push. When set together with spec.cellID, the operator pushes runtime ntn_config_update commands; otherwise it uses the ConfigMap path only.
    false
    sib19EpochMode enum sib19EpochMode declares how this gNB build derives the BROADCAST SIB19 epochTime — which the operator cannot observe at runtime, but which decides whether the SIB19-cadence advisory (SIB19CadenceSane) is meaningful. "reanchored": each periodic SIB19 regeneration refreshes the broadcast epoch, so a UE re-acquiring SIB19 within the validity window advances its T430 deadline — the advisory applies. "pinned": the gNB re-broadcasts a fixed epoch, so re-acquisition does not extend validity and the cadence check would mislead — the operator then expresses NO opinion (no SIB19CadenceSane condition). Unset falls back to the provider-type default: OCUDU is VERIFIED to re-anchor at the revision recorded in docs/ntn-ul-sync-timing.md, so unset+ocudu ⇒ reanchored. Set this explicitly (e.g. "pinned") if you run a gNB build whose SIB19 epoch behaviour differs from that verified revision — a doc note alone cannot stop a changed build from being trusted, so this is the enforceable override.

    Enum: reanchored, pinned
    false

    NTNCellConfig.spec.provider.remoteControl

    ↩ Parent

    remoteControl configures the gNB remote_control WebSocket for live NTN config push. When set together with spec.cellID, the operator pushes runtime ntn_config_update commands; otherwise it uses the ConfigMap path only.

    Name Type Description Required
    endpoint string endpoint is host:port of the gNB remote_control server — a hostname/IPv4 ("127.0.0.1:8001") or a bracketed IPv6 literal ("[::1]:8001") for dual-stack clusters. The provider prepends ws://, so include NEITHER a scheme nor a path — a value like "ws://host:8001" would dial "ws://ws://host:8001" and fail. Validation is layered: the pattern enforces the bare host:port shape with a DNS-1123 hostname or bracketed IPv6, and CEL rules enforce the port range (1-65535), that a bracketed host is a valid IP, that an all-numeric host is a valid IPv4 (so "999.999.999.999:1" is rejected, not treated as a hostname), and that a DNS host obeys the RFC 1035 length limits (whole name <= 253, each label 1-63) — a permanent admission error beats a silent tight-requeue on a mistyped value. The pattern alone cannot bound the label/host length (a regex quantifier would, but the DNS-1123 label form makes that unreadable), so CEL carries it.

    Shape validation does NOT restrict WHICH host the operator will dial; the endpoint is CR-author-controlled, so confining it is an admin egress control (SSRF), not a CRD rule. Set the operator flag --remote-control-allowed-endpoint-hosts to permit only sanctioned gNB hosts for the runtime push (empty = any, backward compatible), and pair it with the operator egress NetworkPolicy (config/network-policy/allow-egress-traffic.yaml). See #299.

    Validations:

  • int(self.substring(self.lastIndexOf(':') + 1)) >= 1 && int(self.substring(self.lastIndexOf(':') + 1)) <= 65535: endpoint port must be between 1 and 65535
  • !self.startsWith('[') || isIP(self.substring(1, self.lastIndexOf(']'))): a bracketed endpoint host must be a valid IP address
  • !self.substring(0, self.lastIndexOf(':')).matches('^[0-9.]+$') || isIP(self.substring(0, self.lastIndexOf(':'))): an all-numeric endpoint host must be a valid IPv4 address
  • self.startsWith('[') || (self.substring(0, self.lastIndexOf(':')).size() <= 253 && self.substring(0, self.lastIndexOf(':')).split('.').all(l, l.size() >= 1 && l.size() <= 63)): endpoint host must be a DNS name of at most 253 characters with each dot-separated label 1-63 characters
  • true
    tls object tls, when set, secures the runtime push: the provider dials wss:// (TLS) instead of plaintext ws:// and authenticates with the material in the referenced Secret. Omit it to keep the plaintext ws:// behavior (N-12).
    false

    NTNCellConfig.spec.provider.remoteControl.tls

    ↩ Parent

    tls, when set, secures the runtime push: the provider dials wss:// (TLS) instead of plaintext ws:// and authenticates with the material in the referenced Secret. Omit it to keep the plaintext ws:// behavior (N-12).

    Name Type Description Required
    mode enum mode selects the transport-security posture: "tls" — dial wss://, verify the server certificate, and (if the Secret carries a token) send it as an Authorization: Bearer header. "mtls" — additionally present a client certificate (mutual TLS); the Secret MUST then carry tls.crt + tls.key.

    Enum: tls, mtls
    true
    secretName string secretName is the Secret (in this NTNCellConfig's namespace) holding the TLS trust and auth material. Recognized keys: "ca.crt" (PEM CA to verify the gNB/proxy server certificate — omit to use the system roots), "token" (the shared secret sent as Authorization: Bearer — optional), and, for mode=mtls, "tls.crt" + "tls.key" (the client certificate/key). A bare shared secret is replayable, so it is only ever sent over the wss:// (TLS) connection.

    "ca.crt" is REQUIRED whenever "token" is set: endpoint is caller-controlled, so a token validated only by the public roots could be delivered to any host whose owner can obtain a publicly-trusted certificate. Pin the gNB's own CA. mode=mtls without ca.crt is still permitted — it proves a key rather than sending one.

    SECURITY: the Secret's owner must opt it in for remote-control use with the label "ntn.operators.dev/remote-control-credential: true", and a Kubernetes API credential (a service-account or bootstrap-token Secret) is refused. This is a mitigation, not a full authorization boundary: the opt-in is namespace-scoped, so ANY NTNCellConfig in the namespace may use a labelled Secret. Do not grant NTNCellConfig write to principals who should not be able to use every labelled remote-control credential in that namespace.

    true
    serverName string serverName overrides the TLS ServerName (SNI) verified against the server certificate's SubjectAltNames. Defaults to the endpoint host. Set it when the gNB/proxy certificate's SAN does not match the dialed host (e.g. an IP endpoint fronted by a DNS-named certificate).
    false

    NTNCellConfig.spec.cellID

    ↩ Parent

    cellID identifies the OCUDU cell (plmn + nci) that runtime remote commands target. Required when provider.remoteControl is set; the value must match the cell the gNB booted with. Unset ⇒ ConfigMap bootstrap path only.

    Name Type Description Required
    nci integer nci is the 36-bit NR Cell Identity (0 to 2^36-1).

    Format: int64
    Minimum: 0
    Maximum: 6.8719476735e+10
    true
    plmn string plmn is the cell's PLMN, 5 or 6 digits (e.g. "00101").
    true

    NTNCellConfig.spec.cellOverrides

    ↩ Parent

    cellOverrides allows fine-tuning PUCCH, PDSCH, PRACH, and RRC parameters.

    Name Type Description Required
    pdschMaxHarqRetxs integer pdschMaxHarqRetxs sets the max HARQ retransmissions (0 = disabled for NTN).

    Default: 0
    false
    prachMaxMsg3HarqRetx integer prachMaxMsg3HarqRetx sets the max msg3 HARQ retransmissions.

    Default: 0
    false
    rrcGuardTimeMs integer rrcGuardTimeMs sets the RRC procedure guard time in ms.

    Default: 12800
    false
    sibSchedule object sibSchedule tunes SIB19 broadcast scheduling. Any unset sub-field falls back to the defaults (siWindowLength=5, siPeriod=16, siWindowPosition=2). Tune when PDCCH capacity is tight or when SIB19 broadcast cadence needs to track short ntn-UlSyncValidityDur.
    false

    NTNCellConfig.spec.cellOverrides.sibSchedule

    ↩ Parent

    sibSchedule tunes SIB19 broadcast scheduling. Any unset sub-field falls back to the defaults (siWindowLength=5, siPeriod=16, siWindowPosition=2). Tune when PDCCH capacity is tight or when SIB19 broadcast cadence needs to track short ntn-UlSyncValidityDur.

    Name Type Description Required
    siPeriod integer siPeriod is the SIB19 broadcast period in radio frames (1 frame = 10 ms; unset defaults to 16). Shorter periods keep UEs' NTN assistance fresh but cost air time. It should be shorter than ntn.ntnUlSyncValidityDur so a UE can re-acquire SIB19 within the UL-sync validity window — an engineering consequence of the TS 38.331 §5.2.2.4.21 re-acquisition requirement, not a normative 38.331 constraint; the operator raises a SIB19CadenceSane=False Warning when fewer than two SIB19 broadcasts fit inside that window (see docs/ntn-ul-sync-timing.md).

    Enum: 8, 16, 32, 64, 128, 256, 512
    false
    siWindowLength integer siWindowLength is the SI window length in slots. OCUDU accepts the standard set; picking a larger value increases PDCCH pressure.

    Enum: 5, 10, 20, 40, 80, 160, 320, 640, 1280
    false
    siWindowPosition integer siWindowPosition is SIB19's slot offset within the SI period (schedulingInfoList2-r17). It must be strictly greater than the number of preceding schedulingInfoList entries; the emitter always schedules one SIB2 (ID < 15) before SIB19, so the minimum is 2. Pointer so an explicit value is distinguished from unset (which defaults to 2).

    Minimum: 2
    Maximum: 79
    false

    NTNCellConfig.status

    ↩ Parent

    NTNCellConfigStatus defines the observed state of NTNCellConfig.

    Name Type Description Required
    appliedKoffset integer appliedKoffset is the last successfully applied k-offset value.
    false
    conditions []object conditions represent the current state of the resource.
    false
    configMapRef string configMapRef is the name of the ConfigMap containing the generated config.
    false
    lastPushedSatSwitchDigest string lastPushedSatSwitchDigest is the content digest of the sat_switch_with_resync last delivered to the gNB by the runtime push. The switch is re-attached to a runtime update only when this changes, so a (possibly non-idempotent) MAC/RRC-resync command is not re-sent on every ephemeris heartbeat (issue #207). Empty when no switch has been sent.
    false

    NTNCellConfig.status.conditions[index]

    ↩ Parent

    Condition contains details for one aspect of the current state of this API Resource.

    Name Type Description Required
    lastTransitionTime string lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.

    Format: date-time
    true
    message string message is a human readable message indicating details about the transition. This may be an empty string.
    true
    reason string reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
    true
    status enum status of the condition, one of True, False, Unknown.

    Enum: True, False, Unknown
    true
    type string type of condition in CamelCase or in foo.example.com/CamelCase.
    true
    observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

    Format: int64
    Minimum: 0
    false

    NTNSlice

    ↩ Parent

    NTNSlice manages terrestrial-satellite network slice failover, QoS mapping, and session continuity for NTN enterprise services.

    Name Type Description Required
    apiVersion string ntn.operators.dev/v1alpha1 true
    kind string NTNSlice true
    metadata object Refer to the Kubernetes API documentation for the fields of the `metadata` field. true
    spec object NTNSliceSpec defines the desired state of an NTN network slice with terrestrial-satellite failover policy.

    Validations:
  • self.terrestrialPath.priority == 'primary': terrestrialPath.priority must be 'primary'
  • self.satellitePath.priority == 'failover': satellitePath.priority must be 'failover'
  • true
    status object
    false

    NTNSlice.spec

    ↩ Parent

    NTNSliceSpec defines the desired state of an NTN network slice with terrestrial-satellite failover policy.

    Name Type Description Required
    failoverPolicy object failoverPolicy defines when and how to switch between paths.

    Validations:
  • self.triggers.all(t, t.matches('^ *(rsrp|latency|packetLoss|terrestrialRSRP|terrestrialLatency|terrestrialPacketLoss) *(<=|>=|<|>) *[-+]?([0-9]{1,10}([.][0-9]{1,10})?|[.][0-9]{1,10})([eE][-+]?[0-9]{1,2})? *$')): each failoverPolicy.trigger must be 'metric op value' where metric is one of rsrp/latency/packetLoss/terrestrialRSRP/terrestrialLatency/terrestrialPacketLoss, op is one of < <= > >=, and value is a finite decimal (up to 10 integer and 10 fraction digits with an optional 2-digit exponent, e.g. 'rsrp < -120'); overflowing forms like '1e9999' are rejected here and, defensively, at runtime
  • true
    satellitePath object satellitePath defines the failover satellite connectivity.
    true
    tenant string tenant is the organization or entity that owns this slice.
    true
    terrestrialPath object terrestrialPath defines the primary terrestrial connectivity.
    true
    billing object billing defines CDR generation parameters.
    false
    metricsSource object metricsSource selects where the failover engine reads path quality metrics (RSRP, latency, packet loss) from. When omitted, the controller falls back to annotation-driven simulation for backward compatibility with existing development deployments.

    Validations:
  • self.type != 'prometheus' || has(self.prometheus): prometheus block is required when type is 'prometheus'
  • false
    qosMapping object qosMapping defines QoS parameter mapping between paths.
    false
    security object security defines handover security requirements.
    false

    NTNSlice.spec.failoverPolicy

    ↩ Parent

    failoverPolicy defines when and how to switch between paths.

    Name Type Description Required
    triggers []string triggers defines conditions that initiate failover (OR logic). Format: "metric operator value" (e.g., "rsrp < -120"). Validated at admission by the XValidation rule on this type and at runtime by the failover engine (pkg/slice.ParseTrigger). Order is intentionally not significant; set merge semantics are desired.
    true
    confirmationSamples integer confirmationSamples is the number of CONSECUTIVE reconcile samples on which the terrestrial triggers must fire before a failover to satellite is taken (production load balancers such as AWS ALB / GCP count consecutive, not windowed, probe results). It absorbs a single-sample blip so one noisy reading does not trip a switch. 1 (the default when unset) preserves the prior immediate-failover behavior; a value of N delays failover by up to (N-1) reconcile intervals. The confirmation counter is kept in memory and resets on any healthy reliable sample; losing it on a controller restart or leader-election handoff only re-requires confirmation (a DELAY), never causes a spurious switch.

    Format: int32
    Minimum: 1
    Maximum: 10
    false
    hysteresisMargin string hysteresisMargin is a dead-band applied to trigger thresholds during switchback evaluation, preventing flapping when metrics oscillate near the threshold. The value uses the same unit as the trigger (dB for RSRP, ms for latency, percent for packetLoss). Example: with trigger "rsrp < -120" and hysteresisMargin "10", failover fires at RSRP < -120, but switchback requires RSRP >= -110.
    false
    minTerrestrialDwell string minTerrestrialDwell is the minimum time the terrestrial path must be held after a switchback before another failover to satellite may be taken. It bounds sub-minute ping-pong after a hand-back. It is a soft, bounded delay — a genuinely failing terrestrial still fails over once the dwell elapses, so it never indefinitely blocks a real failover. 0 (the default) disables it; 30s–120s is a sane range relative to a LEO pass. A negative value would silently disable the dwell (elapsed < negative is never true), so admission bounds it to [0s, 24h].

    Validations:
  • duration(self) >= duration('0s') && duration(self) <= duration('24h'): minTerrestrialDwell must be a non-negative duration no greater than 24h
  • Format: duration
    false
    sessionContinuity boolean sessionContinuity is accepted for forward compatibility but is NOT enforced by this build: no runtime session preservation is performed during a path switch, so active sessions may drop on failover regardless of this value. It is retained so the intent stays expressible and a future release can honor it (#69); do not rely on it for session survival today. The default stays true only to preserve the field's prior admission behavior — it turns no preservation on.

    Default: true
    false
    switchbackDelay string switchbackDelay is how long to wait after terrestrial recovers before switching back (prevents flapping). A negative value is meaningless here, so admission bounds it to [0s, 24h] (24h is a fat-finger ceiling, far above any LEO-pass-relative value).

    Validations:
  • duration(self) >= duration('0s') && duration(self) <= duration('24h'): switchbackDelay must be a non-negative duration no greater than 24h
  • Format: duration
    Default: 60s
    false

    NTNSlice.spec.satellitePath

    ↩ Parent

    satellitePath defines the failover satellite connectivity.

    Name Type Description Required
    ephemerisRef string ephemerisRef is the name of the SatelliteEphemeris resource used to determine satellite pass availability. The referenced ephemeris is treated as a CONSTELLATION POOL: the satellite path is available whenever ANY tracked member is overhead and deliverable — the slice is deliberately not pinned to one NORAD, because LEO members hand over. Which member a given cell broadcasts is NTNCellConfig.ephemerisNoradID's concern, not this path's. See ADR-0008.
    true
    priority enum priority is the path priority.

    Enum: primary, failover
    true
    provider string provider is the network operator name (e.g., "chunghwa-telecom").
    true
    apn string apn is the Access Point Name.
    false

    NTNSlice.spec.terrestrialPath

    ↩ Parent

    terrestrialPath defines the primary terrestrial connectivity.

    Name Type Description Required
    priority enum priority is the path priority.

    Enum: primary, failover
    true
    provider string provider is the network operator name (e.g., "chunghwa-telecom").
    true
    apn string apn is the Access Point Name.
    false

    NTNSlice.spec.billing

    ↩ Parent

    billing defines CDR generation parameters.

    Name Type Description Required
    satelliteRate enum satelliteRate is the charging model for satellite path.

    Enum: per-volume, per-time, per-minute, flat
    false
    terrestrialRate enum terrestrialRate is the charging model for terrestrial path.

    Enum: per-volume, per-time, flat
    false

    NTNSlice.spec.metricsSource

    ↩ Parent

    metricsSource selects where the failover engine reads path quality metrics (RSRP, latency, packet loss) from. When omitted, the controller falls back to annotation-driven simulation for backward compatibility with existing development deployments.

    Name Type Description Required
    prometheus object prometheus configures the Prometheus HTTP API backend. Required when type is 'prometheus'.

    Validations:
  • size(self.queries.rsrpDbm) > 0 || size(self.queries.latencyMs) > 0 || size(self.queries.packetLossPercent) > 0: at least one query must be non-empty
  • false
    type enum type is the backend kind.

    Enum: annotations, prometheus
    Default: annotations
    false

    NTNSlice.spec.metricsSource.prometheus

    ↩ Parent

    prometheus configures the Prometheus HTTP API backend. Required when type is 'prometheus'.

    Name Type Description Required
    endpoint string endpoint is the base URL of the Prometheus HTTP API.
    true
    queries object queries holds the PromQL expressions for each observable metric.
    true
    queryTimeout string queryTimeout limits the wall-clock time spent on each individual PromQL fetch; the controller issues up to three fetches per reconcile (one per metric), so the upper bound for a Read is roughly 3x this value. Defaults to 2s when unset.

    Format: duration
    false

    NTNSlice.spec.metricsSource.prometheus.queries

    ↩ Parent

    queries holds the PromQL expressions for each observable metric.

    Name Type Description Required
    latencyMs string latencyMs is a PromQL expression returning a scalar in milliseconds.
    false
    packetLossPercent string packetLossPercent is a PromQL expression returning a scalar in percent (0-100).
    false
    rsrpDbm string rsrpDbm is a PromQL expression returning a scalar in dBm.
    false

    NTNSlice.spec.qosMapping

    ↩ Parent

    qosMapping defines QoS parameter mapping between paths.

    Name Type Description Required
    maxLatencyBudget string maxLatencyBudget is the maximum acceptable latency including satellite propagation delay.

    Format: duration
    Default: 150ms
    false
    satelliteQCI enum satelliteQCI is the QoS class for the satellite path.

    Enum: conversational, streaming, interactive, background, best-effort
    Default: best-effort
    false
    terrestrial5QI integer terrestrial5QI is the 5G QoS Identifier for the terrestrial path.

    Minimum: 1
    Maximum: 255
    false

    NTNSlice.spec.security

    ↩ Parent

    security defines handover security requirements.

    Name Type Description Required
    authOnHandover enum authOnHandover defines authentication behavior during path switch.

    Enum: re-authenticate, continue
    Default: re-authenticate
    false
    encryptionLevel enum encryptionLevel specifies the encryption standard.

    Enum: AES-128, AES-256, SNOW3G, ZUC
    Default: AES-256
    false

    NTNSlice.status

    ↩ Parent

    Name Type Description Required
    activePathType enum activePathType is the currently active network path.

    Enum: terrestrial, satellite, unavailable
    false
    appliedEncryption string appliedEncryption is the encryption level in effect for the current path.
    false
    appliedQoS string appliedQoS summarizes the QoS mapping in effect for the current path.
    false
    billingMode string billingMode is the billing model active for the current path.
    false
    conditions []object conditions represent the current state of the slice.
    false
    contactCandidate object contactCandidate is the constellation member behind the current FailoverReady evaluation: which satellite, seen from which ground station, over which window, and on element data of what age. FailoverReady alone says a contact opportunity exists but not which one, so an operator cannot tell a healthy handover between members from the same member re-evaluated, and cannot audit the decision after the fact.

    It is a CONTACT OPPORTUNITY, not delivered service: nothing here says the slice's serving cell is configured for this member. Cleared when no candidate can be proven, so a stale entry can never outlive the condition it explains (ADR-0008).

    false
    failoverCount integer failoverCount is the total number of failover events since creation.
    false
    lastFailover string lastFailover is the timestamp of the last failover event.

    Format: date-time
    false
    lastSwitchbackTime string lastSwitchbackTime is when the slice last switched back to terrestrial from an available satellite (a quality-driven hand-back). It is persisted so the anti-flap minimum-terrestrial-dwell survives a controller restart or leader-election handoff: the in-memory flap clock resets on handoff, and without this a re-degradation within the dwell window could switch to satellite earlier than the dwell intended. The other flap clocks stay in-memory (losing them only delays a switch, never advances one).

    Format: date-time
    false
    sessionCount integer sessionCount is the number of active sessions on this slice.
    false

    NTNSlice.status.conditions[index]

    ↩ Parent

    Condition contains details for one aspect of the current state of this API Resource.

    Name Type Description Required
    lastTransitionTime string lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.

    Format: date-time
    true
    message string message is a human readable message indicating details about the transition. This may be an empty string.
    true
    reason string reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
    true
    status enum status of the condition, one of True, False, Unknown.

    Enum: True, False, Unknown
    true
    type string type of condition in CamelCase or in foo.example.com/CamelCase.
    true
    observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

    Format: int64
    Minimum: 0
    false

    NTNSlice.status.contactCandidate

    ↩ Parent

    contactCandidate is the constellation member behind the current FailoverReady evaluation: which satellite, seen from which ground station, over which window, and on element data of what age. FailoverReady alone says a contact opportunity exists but not which one, so an operator cannot tell a healthy handover between members from the same member re-evaluated, and cannot audit the decision after the fact.

    It is a CONTACT OPPORTUNITY, not delivered service: nothing here says the slice's serving cell is configured for this member. Cleared when no candidate can be proven, so a stale entry can never outlive the condition it explains (ADR-0008).

    Name Type Description Required
    noradID integer noradID is the canonical satellite identity. satellite is a display label only.
    true
    aos string aos and los bound the pass window this candidate is currently inside.

    Format: date-time
    false
    groundStation string groundStation is the GroundStationLifecycle this window was predicted for. A pass is only meaningful relative to an observer, so a candidate without one is not auditable.
    false
    los string

    Format: date-time
    false
    propagatedEpochUnixMs integer propagatedEpochUnixMs is the future epoch the state was propagated TO.

    Format: int64
    false
    satellite string satellite is the externally sourced display name, bounded and rune-safe. Not unique: correlate on noradID.
    false
    selectionReason string selectionReason names the rule that chose this candidate over its siblings, so the choice is reproducible from the status alone.
    false
    sourceEpochUnixMs integer sourceEpochUnixMs is the epoch of the element set the window was propagated FROM — the age that decides deliverability, not the propagation target below. Absent when no propagatedStates entry matches noradID.

    Format: int64
    false
    validUntil string validUntil is when this candidate stops being usable: the EARLIER of the pass ending and its element set aging past the delivery freshness bound. Reporting only LOS would promise a window the runtime push would refuse to use before it closes.

    Format: date-time
    false

    SatelliteEphemeris

    ↩ Parent

    SatelliteEphemeris manages GP data fetching (OMM JSON from CelesTrak/SpaceTrack), orbital propagation (SGP4 via akhenakh/sgp4), and pass prediction for a set of satellites against ground stations.

    Orbit-regime support: v1.0 is LEO-only. The propagator is the near-earth SGP4 model; element sets whose orbital period is >= 225 minutes (deep space — roughly MEO and above, e.g. O3b or GEO) are rejected rather than propagated into a wrong position, and surface as the UnsupportedOrbitRegime status condition. Multi-orbit (MEO/GEO) support is a v1.1 roadmap item.

    Name Type Description Required
    apiVersion string ntn.operators.dev/v1alpha1 true
    kind string SatelliteEphemeris true
    metadata object Refer to the Kubernetes API documentation for the fields of the `metadata` field. true
    spec object SatelliteEphemerisSpec defines the desired state of SatelliteEphemeris.
    true
    status object SatelliteEphemerisStatus defines the observed state of SatelliteEphemeris.
    false

    SatelliteEphemeris.spec

    ↩ Parent

    SatelliteEphemerisSpec defines the desired state of SatelliteEphemeris.

    Name Type Description Required
    source object source defines where to fetch GP (General Perturbations) data.

    Validations:
  • self.type != 'SpaceTrack' || has(self.credentials): SpaceTrack source type requires credentials (spec.source.credentials)
  • true
    passPrediction object passPrediction configures automatic pass window computation.
    false
    satellites object satellites filters which satellites to track from the source.
    false

    SatelliteEphemeris.spec.source

    ↩ Parent

    source defines where to fetch GP (General Perturbations) data.

    Name Type Description Required
    refreshInterval string refreshInterval is how often to re-fetch GP data. CelesTrak updates every 2 hours; setting this below 2h wastes bandwidth.

    Format: duration
    Default: 4h
    true
    type enum type is the source type. Supported: "CelesTrak", "SpaceTrack".

    Enum: CelesTrak, SpaceTrack
    true
    url string url is the endpoint to fetch GP data from. Use https for any public source: a cleartext http:// URL that resolves to a public IP is refused at runtime (InsecureURL condition) because an on-path attacker could inject forged OMM data that is propagated into SIB19. http:// is permitted only for a private/in-cluster mirror (NetworkPolicy-protected). For CelesTrak: https://celestrak.org/NORAD/elements/gp.php?GROUP=oneweb&FORMAT=JSON For SpaceTrack: https://www.space-track.org/basicspacedata/query/class/gp/...
    true
    credentials object credentials is a reference to a Secret containing auth credentials (required for SpaceTrack, optional for CelesTrak).
    false

    SatelliteEphemeris.spec.source.credentials

    ↩ Parent

    credentials is a reference to a Secret containing auth credentials (required for SpaceTrack, optional for CelesTrak).

    Name Type Description Required
    name string name of the Secret.
    true
    key string key within the Secret data.

    Default: password
    false

    SatelliteEphemeris.spec.passPrediction

    ↩ Parent

    passPrediction configures automatic pass window computation.

    Name Type Description Required
    groundStations []string groundStations is a list of GroundStationLifecycle resource names to compute pass windows against.
    true
    horizon string horizon is how far into the future to predict passes.

    Default: 24h
    false
    minElevation string minElevation is the minimum elevation angle in degrees (string, e.g., "10"), in the range [0, 90]: 0 is the geometric horizon and 90 the zenith. A negative or >90 mask is physically meaningless (it would make every / no pass "usable"), so the pattern rejects negatives and the CEL rule rejects values above 90. The pattern keeps the pre-existing grammar otherwise (a trailing "." such as "10." stays valid — only the leading "-" was removed) to avoid an unrelated API-grammar break. The bound is on the parsed float64 value (the pipeline is float64), so a literal within ~half a ULP above 90 rounds to 90 and is accepted; the controller uses the float64 value.

    Validations:
  • double(self) <= 90.0: minElevation must be between 0 and 90 degrees
  • Default: 10
    false

    SatelliteEphemeris.spec.satellites

    ↩ Parent

    satellites filters which satellites to track from the source.

    Name Type Description Required
    constellation string constellation is DEPRECATED and performs no filtering at all — the controller has never consumed it (neither server- nor client-side). Select a constellation in the source URL instead (CelesTrak's GROUP= query parameter, e.g. GROUP=oneweb, returns only that constellation's element sets) and/or list explicit noradIDs. It stays accepted in v1alpha1; removal is deferred to a future versioned API migration — a v1alpha2 that drops it must ship conversion so v1alpha1<->v1alpha2 round-trips losslessly, plus stored-object migration and storedVersions cleanup; a version rename alone is not enough to safely drop the data.

    Deprecated: select the constellation via source.url (GROUP=) or spec.satellites.noradIDs.

    false
    noradIDs []integer noradIDs is an explicit list of NORAD catalog IDs to track.
    false

    SatelliteEphemeris.status

    ↩ Parent

    SatelliteEphemerisStatus defines the observed state of SatelliteEphemeris.

    Name Type Description Required
    conditions []object conditions represent the current state of the resource.
    false
    lastPassPredictionInputHash string lastPassPredictionInputHash is a digest of the inputs that determine the pass windows: the pass-prediction spec (ground stations, minElevation, horizon), the tracked NORAD selector, the source identity, and each resolved ground station's identity/generation. The sweep re-runs IMMEDIATELY when this changes — not only on the passPredictionInterval time cadence — so a ground-station edit/add/delete, a selector change, or an elevation/horizon change re-predicts at once instead of leaving stale windows for up to an interval (ADR 0006 / #234). Cleared whenever the pass windows are invalidated (see invalidatePassPredictionStatus).
    false
    lastPassPredictionTime string lastPassPredictionTime is when the pass-window sweep last ran. The sweep runs on its own lower cadence (passPredictionInterval), decoupled from the propagation heartbeat, so its O(horizon x satellites x ground stations) cost stays out of the runtime-push epoch cadence (ADR 0006 / #234). Persisted rather than in-memory so the "sweep is due" decision survives a leader failover. Absent means the sweep has not run since this field appeared (or ever).

    Format: date-time
    false
    lastUpdated string lastUpdated is when the GP data was last successfully fetched.

    Format: date-time
    false
    nextPassWindows []object nextPassWindows contains upcoming contact opportunities.
    false
    propagatedStates []object propagatedStates holds SGP4-propagated ECEF state vectors (per satellite) at the last refresh epoch, consumed by NTNCellConfig runtime ephemeris push (#176). Capped (maxItems) to match the controller's maxPropagatedStates and stay well under the etcd object-size limit.
    false
    propagatedStatesInputHash string propagatedStatesInputHash is a digest of the spec fields that determine WHICH orbital data is fetched and WHICH satellites are propagated (source type/url and the NORAD selector) — NOT the whole spec. It is stamped whenever the current propagatedStates are (re)computed, from a fresh fetch or a valid cache entry for the same upstream fetch identity (the OMM cache is keyed on source type+url, NOT on .metadata.generation). The NTNCellConfig runtime-push consumer recomputes the hash from the live spec and refuses to push when it differs — i.e. the persisted states were computed under different propagation inputs (a source/selector edit whose re-propagate has not yet succeeded), WITHOUT falsely invalidating on a pass-prediction-only edit (#204-G1). Empty means the states predate this field (never re-propagated since upgrade) or no successful reconcile yet.
    false
    satelliteCount integer satelliteCount is the number of satellites currently tracked.
    false
    truncatedSatelliteCount integer truncatedSatelliteCount is how many selected satellites were NOT propagated because the maxPropagatedStates cap (128) had already been reached — the count actually dropped by the cap, not merely (selected - 128), so satellites that fail SGP4 propagation do not inflate it. ABSENT or 0 means nothing was dropped (the field is omitempty). Narrow spec.satellites.noradIDs or the source URL's GROUP= to eliminate it. Mirrored by the StatesTruncated condition; a Warning StatesTruncated event fires once per transition into the truncated state.
    false

    SatelliteEphemeris.status.conditions[index]

    ↩ Parent

    Condition contains details for one aspect of the current state of this API Resource.

    Name Type Description Required
    lastTransitionTime string lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.

    Format: date-time
    true
    message string message is a human readable message indicating details about the transition. This may be an empty string.
    true
    reason string reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
    true
    status enum status of the condition, one of True, False, Unknown.

    Enum: True, False, Unknown
    true
    type string type of condition in CamelCase or in foo.example.com/CamelCase.
    true
    observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

    Format: int64
    Minimum: 0
    false

    SatelliteEphemeris.status.nextPassWindows[index]

    ↩ Parent

    PassWindow represents a predicted contact opportunity between a satellite and ground station.

    Name Type Description Required
    aos string aos is the Acquisition of Signal time (satellite rises above minElevation).

    Format: date-time
    true
    groundStation string groundStation is the name of the GroundStationLifecycle resource.
    true
    los string los is the Loss of Signal time (satellite drops below minElevation).

    Format: date-time
    true
    maxElevation string maxElevation is the peak elevation angle during the pass in degrees (string, e.g., "72.5").
    true
    satellite string satellite is the satellite's display name (externally sourced OMM ObjectName), bounded and rune-safe. The canonical identity is noradID; treat this as a label only.
    true
    noradID integer noradID is the satellite's NORAD catalog number — the canonical key that maps this window to its propagatedStates entry, so a consumer (NTNSlice) can gate pass availability on the backing element set's delivery freshness (same contract as the runtime push). 0 only for windows written before this field existed (freshness then treated as unverifiable).
    false

    SatelliteEphemeris.status.propagatedStates[index]

    ↩ Parent

    PropagatedState is a satellite state vector propagated (SGP4) to a specific epoch, in the 3GPP ECEF codepoint form the runtime ephemeris push consumes.

    Name Type Description Required
    ecef object ecef is the propagated position/velocity in 3GPP codepoints. The provider converts these to physical SI when pushing to OCUDU.
    true
    epochUnixMs integer epochUnixMs is the propagation epoch in Unix milliseconds (in the future, as OCUDU's ntn_config_update requires).

    Format: int64
    true
    noradID integer noradID is the satellite's NORAD catalog number, used by NTNCellConfig (spec.ephemerisNoradID) to select which state to push.
    true
    satellite string satellite is the satellite name or object ID (bounded; the controller truncates the externally-sourced name to this length).
    true
    sourceEpochUnixMs integer sourceEpochUnixMs is the epoch of the SOURCE orbital element set (the OMM EPOCH) this state was propagated FROM, in Unix milliseconds. Unlike epochUnixMs (the future propagation target), this is the element-set age used by the runtime-push consumer to refuse pushing THIS satellite's drifting elements — a per-satellite freshness bound, so a stale sibling in the same SatelliteEphemeris does not block this one. The producer no longer emits a state whose source epoch it could not parse (those satellites are skipped and surfaced via the SourceEpochRejected condition), so a 0 here is the zero value of an omitted field; the consumer treats a 0 epoch as the 1970 instant subject to the normal staleness bound, not as "unknown" or fresh.

    Format: int64
    false

    SatelliteEphemeris.status.propagatedStates[index].ecef

    ↩ Parent

    ecef is the propagated position/velocity in 3GPP codepoints. The provider converts these to physical SI when pushing to OCUDU.

    Name Type Description Required
    posX integer posX is the X position in 1.3 m/LSB codepoints (3GPP positionX-r17, -33554432 to 33554431). The operator emits posX × 1.3 as metres to OCUDU.

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    posY integer posY is the Y position in 1.3 m/LSB codepoints (-33554432 to 33554431).

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    posZ integer posZ is the Z position in 1.3 m/LSB codepoints (-33554432 to 33554431).

    Minimum: -3.3554432e+07
    Maximum: 3.355443e+07
    true
    velX integer velX is the X velocity in 0.06 m/s/LSB codepoints (3GPP velocityVX-r17, -131072 to 131071; 0 for GEO). The operator emits velX × 0.06 as m/s.

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false
    velY integer velY is the Y velocity in 0.06 m/s/LSB codepoints (-131072 to 131071; 0 for GEO).

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false
    velZ integer velZ is the Z velocity in 0.06 m/s/LSB codepoints (-131072 to 131071; 0 for GEO).

    Default: 0
    Minimum: -131072
    Maximum: 131071
    false