{ config, lib, pkgs, ... }: let cfg = config.alisceon.ociSecondaryVnics; configureSecondaryVnics = pkgs.writeShellApplication { name = "configure-oci-secondary-vnics"; runtimeInputs = [ pkgs.coreutils pkgs.curl pkgs.gnugrep pkgs.iproute2 pkgs.jq pkgs.systemd ]; text = '' metadata_url="http://169.254.169.254/opc/v2/vnics" network_dir="/run/systemd/network" mkdir -p "$network_dir" vnics="$(curl --fail --silent --show-error --max-time 10 \ -H "Authorization: Bearer Oracle" \ "$metadata_url")" index=0 configured=0 while IFS= read -r vnic; do index=$((index + 1)) mac="$(jq -r '.macAddr // empty' <<< "$vnic" | tr '[:upper:]' '[:lower:]')" address="$(jq -r '.privateIp // empty' <<< "$vnic")" cidr="$(jq -r '.subnetCidrBlock // empty' <<< "$vnic")" gateway="$(jq -r '.virtualRouterIp // empty' <<< "$vnic")" if [ -z "$mac" ] || [ -z "$address" ] || [ -z "$cidr" ] || [ -z "$gateway" ]; then echo "Skipping incomplete OCI VNIC metadata entry: $vnic" continue fi iface="$( for candidate in /sys/class/net/*; do [ -e "$candidate/address" ] || continue candidate_mac="$(tr '[:upper:]' '[:lower:]' < "$candidate/address")" if [ "$candidate_mac" = "$mac" ]; then basename "$candidate" break fi done )" if [ -z "$iface" ]; then echo "Skipping OCI VNIC $mac: no matching Linux interface" continue fi if ip -4 address show dev "$iface" | grep -q "inet $address/"; then echo "OCI VNIC $iface already has $address configured" continue fi prefix="''${cidr#*/}" table=$((1000 + index)) priority=$((1000 + index)) unit_name="$(systemd-escape --template=20-oci-secondary-vnic@.network "$iface")" network_file="$network_dir/$unit_name" { printf '%s\n' \ "[Match]" \ "MACAddress=$mac" \ "" \ "[Link]" \ "MTUBytes=9000" \ "" \ "[Network]" \ "Address=$address/$prefix" \ "" \ "[Route]" \ "Destination=$cidr" \ "Scope=link" \ "Table=$table" \ "" \ "[Route]" \ "Gateway=$gateway" \ "GatewayOnLink=yes" \ "Table=$table" \ "" \ "[RoutingPolicyRule]" \ "From=$address/32" \ "Table=$table" \ "Priority=$priority" } > "$network_file" echo "Configuring OCI secondary VNIC $iface as $address/$prefix via $gateway in table $table" networkctl reload networkctl reconfigure "$iface" configured=1 done < <(jq -c '.[]' <<< "$vnics") if [ "$configured" = 0 ]; then echo "No unconfigured OCI secondary VNICs found" fi ''; }; in { options.alisceon.ociSecondaryVnics.enable = lib.mkEnableOption "runtime configuration of OCI secondary VNICs from instance metadata"; config = lib.mkIf cfg.enable { systemd.services.configure-oci-secondary-vnics = { description = "Configure OCI secondary VNICs from instance metadata"; after = [ "network-online.target" "systemd-networkd.service" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; script = lib.getExe configureSecondaryVnics; }; }; }