e2e

package module
v0.0.0-...-06836ee Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 86 Imported by: 0

README

AgentBaker E2E Testing

This directory contains files related to the AgentBaker E2E testing framework.

Overview

AgentBaker E2E tests verify that node bootstrapping artifacts generated by the AgentBaker API are correct and capable of integrating Azure VMs into Azure Kubernetes Service (AKS) clusters.

The E2E scenario template is defined in RunScenario. From a high-level, for each scenario,

  1. a new VMSS containing a single VM will be created.
  2. CSE and custom data are generated, which will then be applied to the new VM so it can bootstrap and register with the AKS cluster apiserver.
  3. Liveness and health checks and then run to make sure the new VM's kubelet is posting NodeReady, and that workload pods can successfully be scheduled and run on the new node.

To write an E2E scenario,

  • choose a testing cluster. There are several defined in cache.go, e.g,
    • ClusterKubenet
    • ClusterAzureNetwork
    • ClusterAzureOverlayNetwork
    • ClusterAzureOverlayNetworkDualStack
    • ClusterCiliumNetwork
    • ClusterLatestKubernetesVersion
    • ClusterAzureBootstrapProfileCache (private ACR)
    • ClusterAzureNetworkIsolated (no internet access)
  • use NodeBootstrappingConfiugration (nbc) to setup your scenario. it is used to invoke the primary node-bootstrapping API GetLatestNodeBootstrapping. to modify agentpool properties, usually you need to set bothnbc.containerService.properties.AgentPoolProfiles[0].xxx as well as nbc.agentPoolProfile. It is because when RP invokes AgentBaker, it will set the properties in this way and in e2e we follow the pattern.
  • use VMConfigMutator to set VMSS properties such as SKU when needed. Check vmss for other configs. it is necessary to set nbc.agentPoolProfile.VMSize to match the VMSS SKU if you choose to change.
  • use Validator to include your own verification of the VM's live state, such as file existsnce, sysctl settings, etc.

Infrastructure Architecture

All E2E clusters share a single VNet and Azure Bastion in the abe2e-{location} resource group. This avoids creating a per-cluster Bastion (~10 min each) and ensures all clusters are reachable from a single SSH entry point.

graph TB
    subgraph RG["abe2e-{location} Resource Group"]
        subgraph VNET["abe2e-shared-vnet (10.0.0.0/8)"]
            BASTION_SUBNET["AzureBastionSubnet<br/>10.0.0.0/26"]
            FW_SUBNET["AzureFirewallSubnet<br/>10.0.1.0/24"]
            PE_SUBNET["abe2e-pe-subnet<br/>10.0.2.0/24<br/>(shared private endpoints)"]
            KUBENET_SUBNET["aks-subnet-abe2e-kubenet-v5<br/>10.x.x.0/20"]
            AZNET_SUBNET["aks-subnet-abe2e-azure-network-v4<br/>10.x.x.0/20"]
            MORE_SUBNETS["... more cluster subnets"]
        end
        BASTION["abe2e-shared-bastion<br/>(Standard SKU, Tunneling)"]
        FIREWALL["abe2e-fw<br/>(Azure Firewall)"]
        IDENTITY["abe2e-cluster-identity<br/>(User-Assigned MSI)"]
        PE_ACR["PE-for-abe2eprivate{location}<br/>PE-for-abe2eprivatenonanon{location}<br/>(shared ACR private endpoints)"]
        DNS_ZONE["privatelink.azurecr.io<br/>(Private DNS Zone)"]
        ACR_ANON["abe2eprivate{location}<br/>(Private ACR)"]
        ACR_NONANON["abe2eprivatenonanon{location}<br/>(Non-anonymous Private ACR)"]
    end

    subgraph MC_KUBENET["MC_abe2e-kubenet-v5 Resource Group"]
        VMSS_K["VMSS (system pool)"]
        VMSS_K_TEST["VMSS (test VMs)"]
        RT_K["Route Table<br/>(pod routes + firewall)"]
    end

    subgraph MC_NI["MC_abe2e-azure-networkisolated-v2 Resource Group"]
        VMSS_NI["VMSS (system pool)"]
        NSG_NI["NSG<br/>(blocks internet)"]
    end

    BASTION --> BASTION_SUBNET
    FIREWALL --> FW_SUBNET
    PE_ACR --> PE_SUBNET
    DNS_ZONE -.->|VNet link| VNET
    VMSS_K --> KUBENET_SUBNET
    RT_K -.->|associated| KUBENET_SUBNET
    VMSS_NI --> AZNET_SUBNET
    NSG_NI -.->|associated| AZNET_SUBNET

    DEV["Developer / CI"]
    DEV -->|SSH via tunnel| BASTION
    BASTION -->|"connects to any VM<br/>in shared VNet"| VMSS_K_TEST
Shared Infrastructure Setup

The shared infrastructure is created automatically on first test run via cached idempotent functions — no separate setup script is needed.

Resource Name Details
VNet abe2e-shared-vnet 10.0.0.0/8 — supports ~4096 /20 cluster subnets
Bastion abe2e-shared-bastion Standard SKU with tunneling enabled for native SSH
Bastion Subnet AzureBastionSubnet 10.0.0.0/26 (required by Azure Bastion)
Firewall Subnet AzureFirewallSubnet 10.0.1.0/24
PE Subnet abe2e-pe-subnet 10.0.2.0/24 — hosts shared private endpoints for ACRs
Identity abe2e-cluster-identity User-assigned MSI with Network Contributor on the VNet
Private DNS Zone privatelink.azurecr.io Shared zone in abe2e-{location} RG, linked to the VNet

Each AKS cluster gets its own /20 subnet (4091 usable IPs) in the shared VNet. The subnet is named aks-subnet-{clusterName}. CIDRs are auto-allocated from a hash of the cluster name to avoid collisions.

Cluster Types

All clusters use BYOV (Bring Your Own VNet) with the shared VNet. They differ in networking plugin, isolation level, and whether private ACR is needed.

Cluster Network Plugin Special Features Private ACR
abe2e-kubenet-v5 Kubenet Basic pod routing via route table
abe2e-azure-network-v4 Azure CNI Pods get IPs from subnet (MaxPods=30)
abe2e-azure-overlay-network-v4 Azure CNI Overlay Pods in virtual overlay, not subnet
abe2e-azure-overlay-dualstack-v4 Azure CNI Overlay IPv4+IPv6 dual-stack
abe2e-cilium-network-v4 Azure CNI + Cilium eBPF dataplane, replaces kube-proxy
abe2e-latest-kubernetes-version-v2 Kubenet Auto-discovers latest GA K8s version
abe2e-azure-bootstrapprofile-cache-v2 Azure CNI Bootstrap artifact caching from private ACR
abe2e-azure-networkisolated-v2 Azure CNI NSG blocks all internet except allowlist

Network-isolated cluster adds an NSG to its subnet that blocks all outbound traffic except management.azure.com, the cluster FQDN, and packages.aks.azure.com. Private endpoints for the ACRs are in the shared PE subnet, with DNS records in the shared privatelink.azurecr.io zone.

How It Works
  1. CachedEnsureSharedInfra — runs once per location per test run. Creates/verifies the shared VNet, Bastion, Firewall, PE subnet, and user-assigned identity.
  2. configureSharedVNet — tags the cluster model for BYOV. After the cluster name is hashed, CachedEnsureClusterSubnet creates the cluster's dedicated /20 subnet.
  3. prepareCluster — creates/gets the AKS cluster, then runs a DAG of parallel tasks:
    • Bastion lookup (shared)
    • Firewall route table (non-isolated clusters)
    • NSG association (network-isolated cluster)
    • Private DNS zone + VNet link (if ACR needed, runs once before ACR tasks)
    • Private ACR + PE creation (bootstrapprofile-cache and network-isolated)
    • VMSS garbage collection
    • Debug daemonsets
  4. SSH to test VMs goes through the shared Bastion, which can reach any VM in the VNet.
Test Flow
sequenceDiagram
    participant CI as Developer / CI
    participant Infra as Shared Infra (cached)
    participant ARM as Azure Resource Manager
    participant AB as AgentBaker API
    participant Bastion as Shared Bastion
    participant VM as Test VM
    participant K8s as Kube API Server

    CI->>Infra: Ensure shared VNet + Bastion
    Infra-->>CI: Ready (cached after first run)

    CI->>Infra: Ensure cluster subnet
    Infra-->>CI: Subnet ID

    CI->>ARM: Create/Get AKS cluster (BYOV subnet)
    ARM-->>CI: Cluster details

    CI->>AB: Generate CSE + CustomData
    AB-->>CI: VM configuration

    CI->>ARM: Create VMSS in cluster subnet
    ARM-->>CI: VM instance

    CI->>Bastion: SSH tunnel to VM private IP
    Bastion->>VM: Forward SSH connection

    CI->>VM: Run health checks + validators
    VM-->>CI: Results

    CI->>K8s: Verify node ready
    K8s-->>CI: Node ready ✓

    Bastion-->>CI: Close tunnel

Running Locally

Note: if you have changed code or artifacts used to generate custom data or custom script extension payloads, you should set DISABLE_SCRIPTLESS=true in .env. Otherwise scriptless provisioning only uses scripts that are built into VHD.

To run the E2E test suite locally, use e2e-local.sh. This script sets up the go test command.

Check config.go for the default configuration parameters. You can override these parameters by setting ENV variables.

Create a .env file in the e2e directory to set environment variables and avoid manual setup each time you run tests. Refer to .env.sample for an example.

Running Specific Tests

Use TAGS_TO_RUN= to specify scenarios based on tags. By default, all scenarios run. Multiple tags should be comma-separated and are case-insensitive. Check logs for test tags.

Example:

TAGS_TO_RUN="os=ubuntu,arch=amd64,wasm=false,gpu=false,imagename=2404gen2containerd" ./e2e-local.sh

To exclude scenarios, use TAGS_TO_SKIP=. Scenarios with any specified tags will be skipped (this logic is different to TAGS_TO_RUN).

To run a specific test, use the test name:

TAGS_TO_RUN="name=Test_azurelinuxv2" ./e2e-local.sh
# or
go test -run Test_azurelinuxv2 -v -timeout 90m

To run multiple specific scenarios by name, provide multiple Name= filters. When all filters are Name= filters, OR semantics are used automatically (matching any of the listed names):

TAGS_TO_RUN="name=Test_azurelinuxv2,name=Test_ubuntu2204" ./e2e-local.sh
Debugging

Set KEEP_VMSS=true to retain bootstrapped VMs for debugging. Setting this will also have the VM's private SSH key included in each scenario's log bundle. When using this flag, please ensure to run only test you need to debug, as the VMs will not be deleted after the test run.

Running Tests Manually

Run tests with custom arguments after setting required environment variables:

go test -parallel 100 -timeout 90m -v -count 1

Important go test flags:

  • -v: Verbose output
  • -parallel 100: Run 100 tests in parallel, default is limited to the number of cores
  • -timeout 90m: Set timeout, default is 10 minutes which is often exceeded
  • -count 1: Disable test caching
Cleanup

Azure resources are deleted periodically by an external garbage collector. Locally stopped tests attempt a graceful shutdown to clean up resources. Old VMs are deleted on startup unless created with KEEP_VMSS=true.

IDE Configuration

Global Settings

Set GOFLAGS="-timeout=90m -parallel=100" in your shell configuration file.

GoLand

In Run > Edit Configurations..., set -timeout=90m -parallel=100 in the Go tool arguments field.

VSCode

Add to settings.json:

{
  "go.testFlags": [
    "-parallel=100",
    "-v"
  ],
  "go.testTimeout": "90m"
}

Package Structure

The top-level package of the Golang E2E implementation is named e2e and is entirely separate from all AgentBaker packages.

The definitions and entry points for each test scenario, ran by go test, are located in scenario_test.go.

E2E VHDs.

Node images are pushed to Shared Image Gallery (SIG). Each image is tagged with branch name and build id. By default E2E tests use latest version of images from SIG with branch=refs/heads/main tag.

Using VHD Images from Custom ADO Builds

Set SIG_VERSION_TAG_NAME and SIG_VERSION_TAG_VALUE to specify custom VHD builds:

SIG_VERSION_TAG_NAME=buildId SIG_VERSION_TAG_VALUE=123456789 TAGS_TO_RUN="os=ubuntu2204" ./e2e-local.sh
Registering New VHD SKUs

When adding tests for a new VHD image, ensure to add a delete-lock to prevent the garbage collector from deleting the image version.

Scenarios

E2E scenarios can be configured with VMSS configuration mutators that change/set properties on the VMSS model used to deploy the new VM to be bootstrapped. This is primarily useful when testing out different VM SKUs, especially for GPU-enabled scenarios which affect which code paths AgentBaker will use to generate CSE and custom data

Further, in order to support E2E scenarios which test different underlying AKS cluster configurations, such as the cluster's network plugin, each E2E scenario uses one of the predefined clusters. Same cluster can be reused in different test runs. If cluster doesn't exist a new one will be created automatically.

Lastly, E2E scenarios also consist of a list of live VM validators. Each live VM validator consists of a description, a bash command which will actually be run on the newly bootstrapped VM, and an "asserter" function that will perform assertions on the contents of both the stdout and stderr streams that result from the execution of the command. The validators can be used to assert on numerous types of properties of the live VM, such as the live file system and kernel state.

Log Collection

Each E2E scenario will generate its own logs after execution. Currently, these logs consist of:

  • cluster-provision.log - CSE execution log, retrieved from /var/log/azure/aks/cluster-provision.log (collected in success and CSE failure cases)
  • kubelet.log - the kubelet systemd unit's logs retrived by running journalctl -u kubelet on the VM after bootstrapping has finished (collected in success and CSE failure cases)
  • vmssId.txt - a single line text file containing the unique resource ID of the VMSS created by the respective scenario, mainly collected for the purposes of posthoc resource deletion (collected in all cases where the VMSS is able to be created)

These logs will be uploaded in a bundle of the format:

└── scenario-logs
    └── <scenario>
        ├── cluster-provision.log
        ├── kubelet.log
        ├── vmssId.txt

Coverage report

After a PR is created in AgentBaker's repo on GitHub, a pipeline calculating code coverage changes will automatically run.

We are utilizing coveralls to display the coverage report. The coverage report will be available in the PR's description. You can also view previous runs for the AgentBaker repo here.

We calculate code coverage for both unit tests and E2E tests.

E2E coverage report

To generate E2E coverage reports, we use code coverage changes introduced in Go 1.20.

Coverage report is generated by running AgentBaker's API server locally as a binary created with the -cover flag. E2E tests are then ran against that binary.

The following packages are used during calculation of coverage for E2E tests:

- github.com/Azure/agentbaker/apiserver
- github.com/Azure/agentbaker/cmd
- github.com/Azure/agentbaker/cmd/starter
- github.com/Azure/agentbaker/pkg/agent
- github.com/Azure/agentbaker/pkg/agent/datamodel
- github.com/Azure/agentbaker/pkg/templates
Generating E2E coverage report locally

You can generate an E2E coverage report while running the E2E tests locally. To do so, follow the steps below:

  1. Build the AgentBaker server binary with -cover flag:
  cd cmd
  go build -cover -o baker -covermode count
  GOCOVERDIR=covdatafiles ./baker start &
  1. Create directory for coverage report files
  mkdir -p covdatafiles
  1. Run the binary
  GOCOVERDIR=covdatafiles ./baker start &
  1. Run the E2E tests locally
  /bin/bash e2e/e2e-local.sh
  1. Stop the binary - once the tests finish executing, you have to stop the binary with exit code 0 to generate the report. See the docs here.
  kill $(pgrep baker)
  1. Display the coverage report within the terminal
  go tool covdata percent -i=./cmd/somedata

Documentation

Index

Constants

View Source
const (
	SharedVNetName        = "abe2e-shared-vnet"
	SharedVNetCIDR        = "10.0.0.0/8"
	SharedVNetIPv6CIDR    = "fd00::/48"
	SharedBastionName     = "abe2e-shared-bastion"
	SharedBastionPIPName  = "abe2e-shared-bastion-pip"
	SharedClusterIdentity = "abe2e-cluster-identity"
	BastionSubnetCIDR     = "10.0.0.0/26"
	FirewallSubnetCIDR    = "10.0.1.0/24"
	PESubnetName          = "abe2e-pe-subnet"
	PESubnetCIDR          = "10.0.2.0/24"
)
View Source
const (
	SharedFirewallName    = "abe2e-fw"
	SharedFirewallPIPName = "abe2e-fw-pip"
)

Variables

View Source
var CachedCompileAndUploadAKSNodeController = cachedFunc(compileAndUploadAKSNodeController)
View Source
var CachedCreateGallery = cachedFunc(createGallery)
View Source
var CachedCreateGalleryImage = cachedFunc(createGalleryImage)
View Source
var CachedCreateVMManagedIdentity = cachedFunc(config.Azure.CreateVMManagedIdentity)
View Source
var CachedEnsureClusterSubnet = cachedFunc(ensureClusterSubnet)
View Source
var CachedEnsureResourceGroup = cachedFunc(ensureResourceGroup)
View Source
var CachedEnsureSharedInfra = cachedFunc(ensureSharedInfra)
View Source
var CachedGetLatestVMExtensionImageVersion = cachedFunc(
	func(ctx context.Context, req GetLatestExtensionVersionRequest) (string, error) {
		return config.Azure.GetLatestVMExtensionImageVersion(ctx, req.Location, req.ExtType, req.Publisher)
	},
)

CachedGetLatestVMExtensionImageVersion caches the result of querying the Azure API for the latest VM extension image version.

View Source
var CachedIsVMSizeGen2Only = cachedFunc(func(ctx context.Context, req VMSizeSKURequest) (bool, error) {
	return config.Azure.IsVMSizeGen2Only(ctx, req.Location, req.VMSize)
})

CachedIsVMSizeGen2Only caches the result of querying the Azure Resource SKUs API to determine if a VM size only supports the Gen2 hypervisor.

View Source
var CachedPrepareVHD = cachedFunc(prepareVHD)
View Source
var CachedVMSizeSupportsNVMe = cachedFunc(func(ctx context.Context, req VMSizeSKURequest) (bool, error) {
	return config.Azure.VMSizeSupportsNVMe(ctx, req.Location, req.VMSize)
})

CachedVMSizeSupportsNVMe caches the result of querying the Azure Resource SKUs API to determine if a VM size supports the NVMe disk controller type.

View Source
var ClusterAzureBootstrapProfileCache = cachedFunc(clusterAzureBootstrapProfileCache)
View Source
var ClusterAzureNetwork = cachedFunc(clusterAzureNetwork)
View Source
var ClusterAzureNetworkIsolated = cachedFunc(clusterAzureNetworkIsolated)
View Source
var ClusterAzureOverlayNetwork = cachedFunc(clusterAzureOverlayNetwork)
View Source
var ClusterAzureOverlayNetworkDualStack = cachedFunc(clusterAzureOverlayNetworkDualStack)
View Source
var ClusterCiliumNetwork = cachedFunc(clusterCiliumNetwork)
View Source
var ClusterKubenet = cachedFunc(clusterKubenet)
View Source
var ClusterLatestKubernetesVersion = cachedFunc(clusterLatestKubernetesVersion)
View Source
var ClusterLatestKubernetesVersionAzureBootstrapProfileCache = cachedFunc(clusterLatestKubernetesVersionAzureBootstrapProfileCache)
View Source
var ClusterLatestKubernetesVersionAzureNetwork = cachedFunc(clusterLatestKubernetesVersionAzureNetwork)
View Source
var ClusterLatestKubernetesVersionAzureOverlayNetworkDualStack = cachedFunc(clusterLatestKubernetesVersionAzureOverlayNetworkDualStack)
View Source
var ClusterLatestKubernetesVersionKubenet = cachedFunc(clusterLatestKubernetesVersionKubenet)

Functions

func CreateImage

func CreateImage(ctx context.Context, s *Scenario) (*config.Image, error)

func CreateSIGImageVersionFromDisk

func CreateSIGImageVersionFromDisk(ctx context.Context, s *Scenario, version string, diskResourceID string) (*config.Image, error)

CreateSIGImageVersionFromDisk creates a new SIG image version directly from a VM disk

func CustomDataWithNBCCmdHack

func CustomDataWithNBCCmdHack(customData, binaryURL string) (string, error)

CustomDataWithNBCCmdHack is similar to baker.boothooktemplate, but it uses a hack to run new aks-node-controller binary. Original aks-node-controller isn't run because it fails systemd check validating aks-node-controller-config.json exists (check aks-node-controller.service for details). with a coreos.units block to define and start the service instead.

func DialSSHOverBastion

func DialSSHOverBastion(
	ctx context.Context,
	bastion *Bastion,
	vmPrivateIP string,
	sshPrivateKey []byte,
) (*ssh.Client, error)

func GetFieldFromJsonObjectOnNode

func GetFieldFromJsonObjectOnNode(ctx context.Context, s *Scenario, fileName string, jsonPath string) (string, error)

func RebootVMAndWaitForSSH

func RebootVMAndWaitForSSH(ctx context.Context, s *Scenario) error

func RestartNodeProblemDetector

func RestartNodeProblemDetector(ctx context.Context, s *Scenario) error

func RunCommand

RunCommand executes a script on the VMSS VM with the configured instance ID via the Azure VMSS RunCommand v2 API (VirtualMachineRunCommand resource). This is the API already used by production aks-rp PIS code; using it here keeps test and production on the same surface and avoids the v1 RunCommand extension's failure modes (e.g. the Microsoft.CPlat.Core/RunCommandWindows "Keyset does not exist" error fixed by ADO PR https://msazure.visualstudio.com/CloudNativeCompute/_git/aks-rp/pullrequest/15721814).

Unlike SSH-based exec, this works even when WinRM/SSH are unavailable (e.g. mid-sysprep). It is generally slower than SSH because each call creates a VirtualMachineRunCommand resource on the VM and waits for it to provision.

func RunScenario

func RunScenario(t *testing.T, s *Scenario)

func ServiceCanRestartValidator

func ServiceCanRestartValidator(ctx context.Context, s *Scenario, serviceName string, restartTimeoutInSeconds int) error

func ValidateACLFIPSEnabled

func ValidateACLFIPSEnabled(ctx context.Context, s *Scenario) error

ValidateACLFIPSEnabled asserts ACL-specific FIPS markers are present on the node: the /etc/system-fips marker file written by vhdbuilder/scripts/linux/acl/tool_installs_acl.sh. Kernel FIPS mode (/proc/sys/crypto/fips_enabled == 1) is universal and is asserted by ValidateFIPSProvider; callers should compose the two validators when both are needed.

func ValidateAKSLocalDNSHostsSetupService

func ValidateAKSLocalDNSHostsSetupService(ctx context.Context, s *Scenario) error

ValidateAKSLocalDNSHostsSetupService checks that aks-localdns-hosts-setup.service ran successfully and the aks-localdns-hosts-setup.timer is active to ensure periodic refresh of /etc/localdns/hosts.

func ValidateAKSLogCollector

func ValidateAKSLogCollector(ctx context.Context, s *Scenario) error

func ValidateANCLauncherOutput

func ValidateANCLauncherOutput(ctx context.Context, s *Scenario, expectedContent string) error

ValidateANCLauncherOutput checks that the aks-node-controller-launcher.sh output contains expectedContent, regardless of how the VHD launches it:

  • ACL/Flatcar VHDs still launch the launcher via the aks-node-controller.service systemd unit (ignition doesn't support cloud-boothooks), so its stdout/stderr only lands in the journal.
  • All other VHDs launch the launcher as a direct fork from the cloud-boothook (not a systemd unit, for faster dispatch - see baker.go boothookTemplate), with stdout/stderr redirected to /var/log/azure/aks-node-controller.output.

func ValidateAcceleratedNetworkingTrafficFlowing

func ValidateAcceleratedNetworkingTrafficFlowing(ctx context.Context, s *Scenario) error

ValidateAcceleratedNetworkingTrafficFlowing checks that network traffic is actually flowing through the accelerated networking VF rather than the slower synthetic (NetVSC) path. It sends HTTP requests from a pod to the node's default gateway and verifies that the VF TX packet counters increase by at least that amount.

func ValidateAcceleratedNetworkingVFBonded

func ValidateAcceleratedNetworkingVFBonded(ctx context.Context, s *Scenario) error

ValidateAcceleratedNetworkingVFBonded checks that the accelerated networking VF interface exists and is properly bonded to the primary eth0 interface.

func ValidateAcceleratedNetworkingVFHardware

func ValidateAcceleratedNetworkingVFHardware(ctx context.Context, s *Scenario) error

ValidateAcceleratedNetworkingVFHardware verifies the accelerated networking VF is backed by a PCI function and bound to a kernel network driver.

func ValidateAppArmorBasic

func ValidateAppArmorBasic(ctx context.Context, s *Scenario) error

ValidateAppArmorBasic validates that AppArmor is running without requiring aa-status

func ValidateArtifactStreamingImagePull

func ValidateArtifactStreamingImagePull(ctx context.Context, s *Scenario) error

ValidateArtifactStreamingImagePull verifies that artifact streaming actually streams an image on pod launch, rather than merely bootstrapping the overlaybd/acr-mirror services.

Unlike the existing artifact-streaming scenarios (which only assert that overlaybd-snapshotter, overlaybd-tcmu and acr-mirror are running and that /etc/overlaybd exists), this validator:

  1. ensures an overlaybd-converted (artifact-streaming) image exists in the e2e private ACR,
  2. launches a pod from that image and waits for it to run (proving the image was pullable), and
  3. asserts on the node that overlaybd opened a TCMU-backed block device for it — the definitive signal that the image was *streamed* on demand rather than downloaded and unpacked into overlayfs (the fallback path taken for plain OCI images like busybox).

Uses the cluster's ANONYMOUS-pull private ACR (Cluster: ClusterAzureBootstrapProfileCache, which attaches one). Anonymous pull is required because on the standalone e2e VMSS node the acr-mirror service has no managed identity to obtain an AAD token, so it cannot authenticate to a non-anonymous ACR to serve the overlaybd streaming manifest — the pull then silently falls back to overlayfs. Against an anonymous-pull ACR, acr-mirror's anonymous path succeeds and streaming works. (Observed acr-mirror error on a non-anon ACR: "Error with azure sdk, request token error" -> "falling back to anonymous auth" -> 503.)

func ValidateAzureNetworkFiles

func ValidateAzureNetworkFiles(ctx context.Context, s *Scenario) error

ValidateAzureNetworkFiles checks that udev rules files exist.

func ValidateCiliumIsNotRunningWindows

func ValidateCiliumIsNotRunningWindows(ctx context.Context, s *Scenario) error

func ValidateCiliumIsRunningWindows

func ValidateCiliumIsRunningWindows(ctx context.Context, s *Scenario) error

func ValidateCollectWindowsLogsScript

func ValidateCollectWindowsLogsScript(ctx context.Context, s *Scenario) error

ValidateCollectWindowsLogsScript runs c:\k\debug\collect-windows-logs.ps1 on the node and verifies that a zip archive was produced by the script.

func ValidateCommonLinux

func ValidateCommonLinux(ctx context.Context, s *Scenario) error

func ValidateCommonWindows

func ValidateCommonWindows(ctx context.Context, s *Scenario) error

func ValidateContainerRuntimePlugins

func ValidateContainerRuntimePlugins(ctx context.Context, s *Scenario) error

func ValidateContainerd2Properties

func ValidateContainerd2Properties(ctx context.Context, s *Scenario, versions []string) error

func ValidateContainerdWindowsPriorityClass

func ValidateContainerdWindowsPriorityClass(ctx context.Context, s *Scenario) error

ValidateContainerdWindowsPriorityClass verifies that the containerd service is registered with nssm's AppPriority set to ABOVE_NORMAL_PRIORITY_CLASS, and that the running containerd process actually has that OS process priority class applied.

func ValidateCustomLinuxOSConfigPersistsAfterReboot

func ValidateCustomLinuxOSConfigPersistsAfterReboot(ctx context.Context, s *Scenario, customSysctls map[string]string, customContainerdUlimits map[string]string, swapFileSizeMB int32, thpEnabled, thpDefrag string) error

func ValidateDRAWorkloadSchedulable

func ValidateDRAWorkloadSchedulable(ctx context.Context, s *Scenario) (err error)

func ValidateDirectoryContent

func ValidateDirectoryContent(ctx context.Context, s *Scenario, path string, files []string) error

func ValidateDiskQueueService

func ValidateDiskQueueService(ctx context.Context, s *Scenario) error

func ValidateDllIsNotLoadedWindows

func ValidateDllIsNotLoadedWindows(ctx context.Context, s *Scenario, dllName string) error

func ValidateDllLoadedWindows

func ValidateDllLoadedWindows(ctx context.Context, s *Scenario, dllName string) error

func ValidateDotnetNotInstalledWindows

func ValidateDotnetNotInstalledWindows(ctx context.Context, s *Scenario) error

func ValidateDraDriverNvidiaGpuServiceRunning

func ValidateDraDriverNvidiaGpuServiceRunning(ctx context.Context, s *Scenario) error

func ValidateEmptyDirectory

func ValidateEmptyDirectory(ctx context.Context, s *Scenario, dirName string) error

func ValidateEnableNvidiaResource

func ValidateEnableNvidiaResource(ctx context.Context, s *Scenario) error

func ValidateFIPSProvider

func ValidateFIPSProvider(ctx context.Context, s *Scenario) error

ValidateFIPSProvider verifies that FIPS is properly configured on the node:

  1. Kernel FIPS mode is enabled (/proc/sys/crypto/fips_enabled == 1).
  2. OpenSSL (3.x) has an active FIPS or SymCrypt provider loaded. The check is skipped on hosts shipping OpenSSL 1.1.x (e.g. Ubuntu 20.04 FIPS), which use the legacy FIPS module rather than the providers interface.
  3. /opt/cni/bin/portmap runs without panicking (regression guard for ICM 51000001009688 where the OpenSSL FIPS provider was not loaded on AzureLinux V3 FIPS nodes).

func ValidateFileDoesNotExist

func ValidateFileDoesNotExist(ctx context.Context, s *Scenario, fileName string) error

func ValidateFileExcludesContent

func ValidateFileExcludesContent(ctx context.Context, s *Scenario, fileName string, contents string) error

ValidateFileExcludesContent fails the test if the specified file contains the specified contents. The contents doesn't need to be surrounded by non-word characters. E.g.: searching "bcd" in "abcdef" is a match, thus the validation fails.

func ValidateFileExcludesExactContent

func ValidateFileExcludesExactContent(ctx context.Context, s *Scenario, fileName string, contents string) error

ValidateFileExcludesExactContent fails the test if the specified file contains the specified contents. The contents needs to be surrounded by non-word characters. E.g.: searching "bcd" in "abcdef" is not a match, thus the validation passes.

func ValidateFileExists

func ValidateFileExists(ctx context.Context, s *Scenario, fileName string) error

func ValidateFileHasContent

func ValidateFileHasContent(ctx context.Context, s *Scenario, fileName string, contents string) error

ValidateFileHasContent passes the test if the specified file contains the specified contents. The contents doesn't need to be surrounded by non-word characters. E.g.: searching "bcd" in "abcdef" is a match, thus the validation passes.

func ValidateFileIsRegularFile

func ValidateFileIsRegularFile(ctx context.Context, s *Scenario, fileName string) error

func ValidateGPUWorkloadSchedulable

func ValidateGPUWorkloadSchedulable(ctx context.Context, s *Scenario, gpuCount int, resourceName string) error

func ValidateIMDSRestrictionRule

func ValidateIMDSRestrictionRule(ctx context.Context, s *Scenario, table string) error

func ValidateIPTablesCompatibleWithCiliumEBPF

func ValidateIPTablesCompatibleWithCiliumEBPF(ctx context.Context, s *Scenario) error

ValidateIPTablesCompatibleWithCiliumEBPF validates that all iptables rules in each table match the provided patterns which are accounted for when eBPF host routing is enabled.

func ValidateInspektorGadget

func ValidateInspektorGadget(ctx context.Context, s *Scenario) error

func ValidateInstalledPackageVersion

func ValidateInstalledPackageVersion(ctx context.Context, s *Scenario, component, version string) error

func ValidateJournalctlOutput

func ValidateJournalctlOutput(ctx context.Context, s *Scenario, serviceName string, expectedContent string) error

ValidateJournalctlOutput checks if specific content exists in the systemd service logs

func ValidateJsonFileDoesNotHaveField

func ValidateJsonFileDoesNotHaveField(ctx context.Context, s *Scenario, fileName string, jsonPath string, valueNotToBe string) error

func ValidateJsonFileHasField

func ValidateJsonFileHasField(ctx context.Context, s *Scenario, fileName string, jsonPath string, expectedValue string) error

func ValidateKataContainerdConfig

func ValidateKataContainerdConfig(ctx context.Context, s *Scenario) error

ValidateKataContainerdConfig asserts that AgentBaker rendered a containerd configuration containing the Kata runtime handlers on a Kata-enabled VHD.

This is the core regression check for the IsKata blocks of the containerd config templates in pkg/agent/baker.go. Note that AgentPoolProfile.IsContainerdV2Distro() returns false for every Kata distro (pkg/agent/datamodel/types.go), so Kata nodes are always rendered from containerdV1ConfigTemplate / containerdV1NoGPUConfigTemplate regardless of the underlying OS. The assertions below therefore target the containerd 1.x plugin paths that those templates emit. If Kata is ever promoted to the V2 templates, this validator should fail loudly rather than silently pass, which is why the plugin paths are asserted explicitly.

func ValidateKataContainerdConfigDump

func ValidateKataContainerdConfigDump(ctx context.Context, s *Scenario) error

ValidateKataContainerdConfigDump asserts that containerd itself accepted the rendered configuration and actually loaded the Kata runtime handlers.

Checking the file alone is not enough. Kata VHDs ship their own containerd build - CSE skips installing one (see the "azurelinuxkata" entries in parts/common/components.json) - so the containerd major version on the node is decided by the image, not by AgentBaker, while the template AgentBaker renders is decided by the distro (IsContainerdV2Distro short-circuits to the v1 template for every Kata distro). The two can therefore disagree: AzureLinux V3 Kata currently boots containerd 2.x while being handed a containerd 1.x style config.

That combination happens to work today because containerd 2.x migrates the legacy "io.containerd.grpc.v1.cri" runtime handlers onto the current "io.containerd.cri.v1.runtime" paths, but nothing guarantees it keeps doing so. This validator pins the property we actually care about: after containerd has parsed the config, the Kata handlers are present in the effective configuration and containerd raised no warnings while getting there.

func ValidateKataErofsContainerdConfig

func ValidateKataErofsContainerdConfig(ctx context.Context, s *Scenario) error

ValidateKataErofsContainerdConfig checks that the EROFS snapshotter is configured and that containerd loaded all of its EROFS plugins successfully.

func ValidateKataHostReadiness

func ValidateKataHostReadiness(ctx context.Context, s *Scenario) error

ValidateKataHostReadiness asserts the host-side prerequisites that the Kata VHD is expected to ship and that the containerd config references. Without these, the containerd config would be syntactically valid but the kata shim would fail at pod sandbox creation time.

func ValidateKataPodIsIsolated

func ValidateKataPodIsIsolated(ctx context.Context, s *Scenario, handler string) error

ValidateKataPodIsIsolated creates a RuntimeClass bound to the given Kata runtime handler, schedules a pod against it on the node under test, and asserts the pod is genuinely running inside a Kata VM.

This is the end-to-end proof that the containerd config AgentBaker generated is not merely syntactically present but actually usable: if the runtime handler were missing or misconfigured, the kubelet would reject the pod with "RuntimeHandler not supported" and the pod would never reach Running.

Isolation itself is asserted by comparing kernel releases. A Kata pod boots its own guest kernel, so it must report a different `uname -r` than the host; a matching value would mean the pod silently fell back to the shared-kernel runc runtime.

The RuntimeClass is pinned to this scenario's node via Scheduling.NodeSelector so it cannot interfere with other scenarios running in parallel against the same cluster, and is named after the handler so that several handlers can be validated on one node.

func ValidateKernelLogs

func ValidateKernelLogs(ctx context.Context, s *Scenario) error

ValidateKernelLogs checks kernel logs for critical errors across multiple categories: - Kernel panics/crashes (panic, oops, call trace, BUG, etc.) - CPU lockups/stalls (soft/hard lockup, RCU stall, hung task, watchdog) - Memory issues (OOM killer, page allocation failure, memory corruption) - I/O and filesystem errors (I/O error, filesystem errors, nvme/ata/scsi errors)

func ValidateKubeletActiveFlagsEvent

func ValidateKubeletActiveFlagsEvent(ctx context.Context, s *Scenario) error

ValidateKubeletActiveFlagsEvent checks that the emit-kubelet-active-flags oneshot service ran successfully and produced a guest agent event file containing kubelet config telemetry. Guarded: skips gracefully on VHDs that don't have the service baked in yet.

func ValidateKubeletArgs

func ValidateKubeletArgs(ctx context.Context, s *Scenario) error

func ValidateKubeletHasFlags

func ValidateKubeletHasFlags(ctx context.Context, s *Scenario, filePath string) error

ValidateKubeletHasFlags checks kubelet is started with the right flags and configs.

func ValidateKubeletHasNotStopped

func ValidateKubeletHasNotStopped(ctx context.Context, s *Scenario) error

func ValidateKubeletNodeIP

func ValidateKubeletNodeIP(ctx context.Context, s *Scenario) error

func ValidateKubeletServingCertificateRotation

func ValidateKubeletServingCertificateRotation(ctx context.Context, s *Scenario) error

func ValidateLeakedSecrets

func ValidateLeakedSecrets(ctx context.Context, s *Scenario) error

func ValidateLocalDNSExporterMetrics

func ValidateLocalDNSExporterMetrics(ctx context.Context, s *Scenario) error

ValidateLocalDNSExporterMetrics checks if the localdns metrics exporter is working and exports the expected VnetDNS and KubeDNS forward IP metrics.

The validation script is too large (~18KB) to send as a single command over bastion SSH tunnels which have an 8KB WebSocket buffer limit. To work around this, we encode the script in base64, upload it in small chunks via multiple SSH commands, then decode and execute it on the VM.

func ValidateLocalDNSHostsFile

func ValidateLocalDNSHostsFile(ctx context.Context, s *Scenario, fqdns []string) error

ValidateLocalDNSHostsFile checks that /etc/localdns/hosts contains at least one IPv4 entry for each critical FQDN. This validation approach avoids flakiness with CDN/frontdoor-backed FQDNs (like mcr.microsoft.com) whose A records can rotate between queries. We verify presence, not exact IP matching. The hosts file is populated asynchronously by the aks-localdns-hosts-setup timer/service, so we poll with a timeout.

func ValidateLocalDNSHostsPluginBypass

func ValidateLocalDNSHostsPluginBypass(ctx context.Context, s *Scenario) error

ValidateLocalDNSHostsPluginBypass verifies that localdns serves FQDNs from /etc/localdns/hosts via the CoreDNS hosts plugin. It checks:

  1. The node has the kubernetes.azure.com/localdns-hosts-plugin=enabled annotation
  2. The Corefile has the hosts plugin configured in both VnetDNS and KubeDNS listeners
  3. The IPs returned by dig match the entries in /etc/localdns/hosts for the same FQDN

We intentionally do NOT assert on DNS flags (AA, RA) because CoreDNS can set these regardless of which plugin served the response.

func ValidateLocalDNSHostsPluginColdStart

func ValidateLocalDNSHostsPluginColdStart(ctx context.Context, s *Scenario) error

ValidateLocalDNSHostsPluginColdStart verifies that localdns works correctly when started with an empty hosts file — the exact scenario that occurs when localdns starts before aks-localdns-hosts-setup finishes resolving FQDNs.

Test flow:

  1. Truncate hosts file, stop/start localdns — CoreDNS starts fresh with empty hosts file and empty cache
  2. Verify critical and non-critical FQDNs resolve via fallthrough (upstream DNS)
  3. Populate hosts file with a canary entry (simulates aks-localdns-hosts-setup completing)
  4. Wait for CoreDNS reload (5s), verify canary resolves (hosts plugin picks up new file)
  5. Restore original hosts file and stop/start localdns to leave node in clean state

func ValidateLocalDNSHostsPluginIPv6

func ValidateLocalDNSHostsPluginIPv6(ctx context.Context, s *Scenario) error

ValidateLocalDNSHostsPluginIPv6 checks that IPv6 entries in /etc/localdns/hosts are properly served by CoreDNS's hosts plugin. If the hosts file has no IPv6 entries (some FQDNs don't have AAAA records), the test is skipped gracefully.

Test flow:

  1. Find the first FQDN with an IPv6 entry in the hosts file
  2. Query localdns for AAAA records for that FQDN
  3. Verify the returned IPv6 addresses match the hosts file entries

func ValidateLocalDNSResolution

func ValidateLocalDNSResolution(ctx context.Context, s *Scenario, server string) error

ValidateLocalDNSResolution checks if the DNS resolution for an external domain is successful from localdns clusterlistenerIP. It uses the 'dig' command to check the DNS resolution and expects a successful response.

func ValidateLocalDNSService

func ValidateLocalDNSService(ctx context.Context, s *Scenario, state string) error

ValidateLocalDNSService checks if the localdns service is in the expected state (enabled or disabled).

func ValidateMANA

func ValidateMANA(ctx context.Context, s *Scenario) error

ValidateMANA runs all MANA (Microsoft Azure Network Adapter) checks. It verifies that the MANA PCI device is present, the kernel driver is loaded, the VF interface is bonded to eth0, PCI-backed and driver-bound, and traffic is flowing through the VF.

func ValidateMANADriverLoaded

func ValidateMANADriverLoaded(ctx context.Context, s *Scenario) error

ValidateMANADriverLoaded checks that the MANA Ethernet driver (mana) is loaded in the running kernel. For built-in drivers they appear in modules.builtin; for loadable modules they must be present in lsmod.

func ValidateMANAPCIDevice

func ValidateMANAPCIDevice(ctx context.Context, s *Scenario) error

ValidateMANAPCIDevice checks that the MANA PCI device is exposed to the VM. MANA hardware is identified by PCI device ID 0x00ba (Microsoft Corporation).

func ValidateMANATrafficFlowing

func ValidateMANATrafficFlowing(ctx context.Context, s *Scenario) error

ValidateMANATrafficFlowing checks that network traffic is actually flowing through the MANA Virtual Function rather than the slower synthetic (NetVSC) path.

func ValidateMANAVFBonded

func ValidateMANAVFBonded(ctx context.Context, s *Scenario) error

ValidateMANAVFBonded checks that the MANA Virtual Function (VF) interface exists and is properly bonded to the primary eth0 interface. When Accelerated Networking is enabled with MANA, a VF interface should appear as a subordinate (SLAVE) of eth0. The VF name varies by VM generation: - V5: enP* (e.g., enP30832p0s0) - V6+: ens1 or enp0s0

func ValidateMIGInstancesCreated

func ValidateMIGInstancesCreated(ctx context.Context, s *Scenario, migProfile string, instanceCountExpected int) error

func ValidateMIGModeEnabled

func ValidateMIGModeEnabled(ctx context.Context, s *Scenario, gpuCountExpected int) error

func ValidateMultipleKubeProxyVersionsExist

func ValidateMultipleKubeProxyVersionsExist(ctx context.Context, s *Scenario) error

func ValidateNPDFilesystemCorruption

func ValidateNPDFilesystemCorruption(ctx context.Context, s *Scenario) (err error)

func ValidateNPDGPUCountAfterFailure

func ValidateNPDGPUCountAfterFailure(ctx context.Context, s *Scenario) error

func ValidateNPDGPUCountCondition

func ValidateNPDGPUCountCondition(ctx context.Context, s *Scenario) error

func ValidateNPDGPUCountPlugin

func ValidateNPDGPUCountPlugin(ctx context.Context, s *Scenario) error

func ValidateNPDHealthyNvidiaGridLicenseStatus

func ValidateNPDHealthyNvidiaGridLicenseStatus(ctx context.Context, s *Scenario) error

func ValidateNPDIBLinkFlappingAfterFailure

func ValidateNPDIBLinkFlappingAfterFailure(ctx context.Context, s *Scenario) error

func ValidateNPDIBLinkFlappingCondition

func ValidateNPDIBLinkFlappingCondition(ctx context.Context, s *Scenario) error

func ValidateNPDUnhealthyNvidiaDCGMServices

func ValidateNPDUnhealthyNvidiaDCGMServices(ctx context.Context, s *Scenario) error

func ValidateNPDUnhealthyNvidiaDCGMServicesAfterFailure

func ValidateNPDUnhealthyNvidiaDCGMServicesAfterFailure(ctx context.Context, s *Scenario) error

func ValidateNPDUnhealthyNvidiaDCGMServicesCondition

func ValidateNPDUnhealthyNvidiaDCGMServicesCondition(ctx context.Context, s *Scenario) error

func ValidateNPDUnhealthyNvidiaDevicePlugin

func ValidateNPDUnhealthyNvidiaDevicePlugin(ctx context.Context, s *Scenario) error

func ValidateNPDUnhealthyNvidiaDevicePluginAfterFailure

func ValidateNPDUnhealthyNvidiaDevicePluginAfterFailure(ctx context.Context, s *Scenario) error

func ValidateNPDUnhealthyNvidiaDevicePluginCondition

func ValidateNPDUnhealthyNvidiaDevicePluginCondition(ctx context.Context, s *Scenario) error

func ValidateNPDUnhealthyNvidiaGridLicenseStatusAfterFailure

func ValidateNPDUnhealthyNvidiaGridLicenseStatusAfterFailure(ctx context.Context, s *Scenario) error

func ValidateNetworkInterfaceConfig

func ValidateNetworkInterfaceConfig(ctx context.Context, s *Scenario, nicConfig map[string]string) error

ValidateNetworkInterfaceConfig validates network interface configuration settings using ethtool. It identifies network interfaces with slot names matching the enP* pattern (same logic as the udev rule), then verifies that each interface has the expected configuration settings (e.g., rx buffer size). The nicConfig map specifies the ethtool settings to validate (key: setting name, value: expected value).

func ValidateNoFailedSystemdUnits

func ValidateNoFailedSystemdUnits(ctx context.Context, s *Scenario) error

func ValidateNodeAdvertisesGPUResources

func ValidateNodeAdvertisesGPUResources(ctx context.Context, s *Scenario, gpuCountExpected int64, resourceName string) error

func ValidateNodeCanRunAPod

func ValidateNodeCanRunAPod(ctx context.Context, s *Scenario) error

func ValidateNodeExporter

func ValidateNodeExporter(ctx context.Context, s *Scenario) error

func ValidateNodeHasLabel

func ValidateNodeHasLabel(ctx context.Context, s *Scenario, labelKey, expectedValue string) error

ValidateNodeHasLabel checks if the node has the expected label with the expected value

func ValidateNodeProblemDetector

func ValidateNodeProblemDetector(ctx context.Context, s *Scenario) error

func ValidateNonEmptyDirectory

func ValidateNonEmptyDirectory(ctx context.Context, s *Scenario, dirName string) error

func ValidateNvidiaDCGMExporterIsScrapable

func ValidateNvidiaDCGMExporterIsScrapable(ctx context.Context, s *Scenario) error

func ValidateNvidiaDCGMExporterScrapeCommonMetric

func ValidateNvidiaDCGMExporterScrapeCommonMetric(ctx context.Context, s *Scenario, metric string) error

func ValidateNvidiaDCGMExporterSystemDServiceRunning

func ValidateNvidiaDCGMExporterSystemDServiceRunning(ctx context.Context, s *Scenario) error

func ValidateNvidiaDevicePluginServiceRunning

func ValidateNvidiaDevicePluginServiceRunning(ctx context.Context, s *Scenario) error

func ValidateNvidiaGRIDLicenseValid

func ValidateNvidiaGRIDLicenseValid(ctx context.Context, s *Scenario) error

func ValidateNvidiaGridV20DriverInstalled

func ValidateNvidiaGridV20DriverInstalled(ctx context.Context, s *Scenario) error

ValidateNvidiaGridV20DriverInstalled asserts the node installed the grid-v20 (595.x) driver from the aks-gpu-grid-v20 image rather than falling back to a cuda/grid driver. This is the grid-v20-specific check: if SKU->driver-type selection regressed, nvidia-smi would report a different driver major.

func ValidateNvidiaModProbeInstalled

func ValidateNvidiaModProbeInstalled(ctx context.Context, s *Scenario) error

func ValidateNvidiaPersistencedRunning

func ValidateNvidiaPersistencedRunning(ctx context.Context, s *Scenario) error

func ValidateNvidiaSMIInstalled

func ValidateNvidiaSMIInstalled(ctx context.Context, s *Scenario) error

func ValidateNvidiaSMINotInstalled

func ValidateNvidiaSMINotInstalled(ctx context.Context, s *Scenario) error

func ValidatePodRunning

func ValidatePodRunning(ctx context.Context, s *Scenario, pod *corev1.Pod) error

func ValidatePodRunningWithRetry

func ValidatePodRunningWithRetry(ctx context.Context, s *Scenario, pod *corev1.Pod, maxRetries int) error

func ValidatePubkeySSHDisabled

func ValidatePubkeySSHDisabled(ctx context.Context, s *Scenario) error

ValidatePubkeySSHDisabled validates that SSH with private key authentication is disabled by checking sshd_config

func ValidateRCV1PCertMode

func ValidateRCV1PCertMode(ctx context.Context, s *Scenario) error

ValidateRCV1PCertMode validates that the rcv1p certificate endpoint mode was used during Linux node provisioning, certificates were downloaded and installed, and a refresh task was scheduled.

func ValidateRCV1PCertModeWindows

func ValidateRCV1PCertModeWindows(ctx context.Context, s *Scenario) error

ValidateRCV1PCertModeWindows validates that the rcv1p certificate endpoint mode was used during Windows node provisioning, certificates were downloaded and installed, and a refresh task was scheduled.

func ValidateRCV1PNotOptedIn

func ValidateRCV1PNotOptedIn(ctx context.Context, s *Scenario) error

ValidateRCV1PNotOptedIn validates that when the VM does NOT have the opt-in tag, wireserver returns IsOptedInForRootCerts=false and no certificates are installed, even in the RCV1P subscription with PlatformSettingsOverride registered.

func ValidateRCV1PNotOptedInWindows

func ValidateRCV1PNotOptedInWindows(ctx context.Context, s *Scenario) error

ValidateRCV1PNotOptedInWindows validates that when the Windows VM does NOT have the opt-in tag, no certificates are installed to C:\ca and no refresh scheduled task is registered, even in the RCV1P subscription with PlatformSettingsOverride registered.

func ValidateRuncVersion

func ValidateRuncVersion(ctx context.Context, s *Scenario, versions []string) error

func ValidateRxBufferDefault

func ValidateRxBufferDefault(ctx context.Context, s *Scenario) error

ValidateRxBufferDefault validates rx buffer config using default values based on VM's CPU count

func ValidateSSHServiceDisabled

func ValidateSSHServiceDisabled(ctx context.Context, s *Scenario) error

ValidateSSHServiceDisabled validates that the SSH daemon service is disabled and stopped on the node

func ValidateSSHServiceEnabled

func ValidateSSHServiceEnabled(ctx context.Context, s *Scenario) error

func ValidateScriptlessCSECmd

func ValidateScriptlessCSECmd(ctx context.Context, s *Scenario) error

ValidateScriptlessCSECmd checks if the node has scriptless cmd correctly enabled

func ValidateScriptlessNBCCSECmd

func ValidateScriptlessNBCCSECmd(ctx context.Context, s *Scenario) error

ValidateScriptlessNBCCSECmd checks if the node has scriptless NBCCSECmd correctly enabled

func ValidateScriptlessPhase3

func ValidateScriptlessPhase3(ctx context.Context, s *Scenario) error

ValidateScriptlessPhase3 validates that there are not diffs between ANC generated cse cmd NBC cse cmd vars

func ValidateSecondaryNICDualStack

func ValidateSecondaryNICDualStack(ctx context.Context, s *Scenario, ifaceName string) error

ValidateSecondaryNICDualStack checks that the given network interface is UP and has both IPv4 and IPv6 addresses.

func ValidateSecondaryNICUp

func ValidateSecondaryNICUp(ctx context.Context, s *Scenario, ifaceName string) error

ValidateSecondaryNICUp checks that the given network interface is UP and has an IPv4 address.

func ValidateServiceInSlice

func ValidateServiceInSlice(ctx context.Context, s *Scenario, service, expectedSlice string) error

ValidateServiceInSlice asserts that the given systemd service is running in the expected slice.

func ValidateServicesDoNotRestartKubelet

func ValidateServicesDoNotRestartKubelet(ctx context.Context, s *Scenario) error

func ValidateStaleCachedKubeBinariesRemoved

func ValidateStaleCachedKubeBinariesRemoved(ctx context.Context, s *Scenario) error

ValidateStaleCachedKubeBinariesRemoved validates that stale versioned kube binaries (e.g. kubelet-1.29.0, kubectl-1.29.0) have been removed from /opt/bin/ after the correct version is installed.

func ValidateSwapFileConfig

func ValidateSwapFileConfig(ctx context.Context, s *Scenario, swapFileSizeMB int32) error

func ValidateSysctlConfig

func ValidateSysctlConfig(ctx context.Context, s *Scenario, customSysctls map[string]string) error

func ValidateSystemdUnitIsNotFailed

func ValidateSystemdUnitIsNotFailed(ctx context.Context, s *Scenario, serviceName string) error

func ValidateSystemdUnitIsNotRunning

func ValidateSystemdUnitIsNotRunning(ctx context.Context, s *Scenario, serviceName string) error

func ValidateSystemdUnitIsRunning

func ValidateSystemdUnitIsRunning(ctx context.Context, s *Scenario, serviceName string) error

func ValidateSystemdWatchdogForKubernetes132Plus

func ValidateSystemdWatchdogForKubernetes132Plus(ctx context.Context, s *Scenario) error

func ValidateTLSBootstrapping

func ValidateTLSBootstrapping(ctx context.Context, s *Scenario) error

func ValidateTaints

func ValidateTaints(ctx context.Context, s *Scenario, expectedTaints string) error

ValidateTaints checks if the node has the expected taints that are set in the kubelet config with --register-with-taints flag

func ValidateTransparentHugePageConfig

func ValidateTransparentHugePageConfig(ctx context.Context, s *Scenario, thpEnabled, thpDefrag string) error

func ValidateUlimitSettings

func ValidateUlimitSettings(ctx context.Context, s *Scenario, ulimits map[string]string) error

func ValidateVulnerableKernelModulesDisabled

func ValidateVulnerableKernelModulesDisabled(ctx context.Context, s *Scenario) error

ValidateVulnerableKernelModulesDisabled verifies that kernel modules with known LPE vulnerabilities (CVE-2026-31431 / DirtyFrag / Fragnesia: algif_aead, esp4, esp6, rxrpc) are handled correctly per OS:

  • Ubuntu fixed kernels and future Ubuntu releases: assert ABSENCE of the four modprobe blacklist entries. Ubuntu 22.04 linux-azure 5.15.0-1116-azure and Ubuntu 24.04 linux-azure 6.8.0-1058-azure include the fixes, thus new VHDs must stop blocking legitimate module use. Future Ubuntu releases do not inherit this mitigation by default.
  • Ubuntu 20.04 and vulnerable/unknown 22.04 / 24.04 kernels / Mariner: full check — modprobe config entries are present, modules are NOT loaded, and modprobe refuses to load them.
  • AzureLinux 3.0: assert ABSENCE of the four modprobe blacklist entries. AzL3 is descoped from the mitigation because kernel 6.6.139.1-1.azl3 and later fix all three CVEs upstream, AND customer workloads on AzL3 require those modules (the blacklist actively blocks legitimate use cases). Newly-built AzL3 VHDs therefore no longer ship the modprobe-CIS.conf entries, and E2E runs against freshly-built VHDs. See https://github.com/Azure/AKS/issues/5753.

To add a new CVE mitigation, append the module name to BOTH lists below — the absence-check list AND the default presence + load-refusal list.

func ValidateWaagentLog

func ValidateWaagentLog(ctx context.Context, s *Scenario) error

ValidateWaagentLog checks /var/log/waagent.log for expected agent behavior: - AutoUpdate is disabled as expected - The correct version is running as ExtHandler - No errors from ExtHandler Skipped on Flatcar and OSGuard VHDs which manage WALinuxAgent independently.

func ValidateWindowsCiliumIsNotRunning

func ValidateWindowsCiliumIsNotRunning(ctx context.Context, s *Scenario) error

func ValidateWindowsCiliumIsRunning

func ValidateWindowsCiliumIsRunning(ctx context.Context, s *Scenario) error

func ValidateWindowsDisplayVersion

func ValidateWindowsDisplayVersion(ctx context.Context, s *Scenario, displayVersion string) error

func ValidateWindowsProcessContainsArgumentStrings

func ValidateWindowsProcessContainsArgumentStrings(ctx context.Context, s *Scenario, processName string, substrings []string) error

func ValidateWindowsProcessDoesNotContainArgumentStrings

func ValidateWindowsProcessDoesNotContainArgumentStrings(ctx context.Context, s *Scenario, processName string, substrings []string) error

func ValidateWindowsProcessHasCliArguments

func ValidateWindowsProcessHasCliArguments(ctx context.Context, s *Scenario, processName string, arguments []string) error

func ValidateWindowsProductName

func ValidateWindowsProductName(ctx context.Context, s *Scenario, productName string) error

func ValidateWindowsSecureTLSEnabled

func ValidateWindowsSecureTLSEnabled(ctx context.Context, s *Scenario) error

ValidateWindowsSecureTLSEnabled asserts that Enable-SecureTls (windowssecuretls.ps1) has hardened the node against protocol downgrade and the Sweet32 birthday attack (CVE-2016-2183 / CVE-2016-6329): TLS 1.2 is enabled, TLS 1.0/1.1 and SSLv2/SSLv3 are disabled, RC4 is disabled, and the configured cipher suite order does not include any 64-bit block ciphers (3DES/DES/RC2).

func ValidateWindowsServiceIsNotRunning

func ValidateWindowsServiceIsNotRunning(ctx context.Context, s *Scenario, serviceName string) error

func ValidateWindowsServiceIsRunning

func ValidateWindowsServiceIsRunning(ctx context.Context, s *Scenario, serviceName string) error

func ValidateWindowsSystemServiceRestartConfiguration

func ValidateWindowsSystemServiceRestartConfiguration(ctx context.Context, s *Scenario, serviceName string) error

func ValidateWindowsSystemServicesRestartConfiguration

func ValidateWindowsSystemServicesRestartConfiguration(ctx context.Context, s *Scenario) error

func ValidateWindowsVersionFromWindowsSettings

func ValidateWindowsVersionFromWindowsSettings(ctx context.Context, s *Scenario, windowsVersion string) error

Types

type Bastion

type Bastion struct {
	// contains filtered or unexported fields
}

func NewBastion

func NewBastion(credential *azidentity.AzureCLICredential, subscriptionID, resourceGroupName, dnsName string) *Bastion

func (*Bastion) NewTunnelSession

func (b *Bastion) NewTunnelSession(ctx context.Context, targetHost string, port uint16) (*tunnelSession, error)

type CSEProvisionTiming

type CSEProvisionTiming struct {
	ExitCode            string          `json:"ExitCode"`
	ExecDuration        string          `json:"ExecDuration"`
	KernelStartTime     string          `json:"KernelStartTime"`
	CloudInitLocalStart string          `json:"CloudInitLocalStartTime"`
	CloudInitStart      string          `json:"CloudInitStartTime"`
	CloudFinalStart     string          `json:"CloudFinalStartTime"`
	CSEStartTime        string          `json:"CSEStartTime"`
	GuestAgentStartTime string          `json:"GuestAgentStartTime"`
	SystemdSummary      string          `json:"SystemdSummary"`
	BootDatapoints      json.RawMessage `json:"BootDatapoints"`
}

CSEProvisionTiming represents the overall provisioning timing from provision.json.

type CSETaskTiming

type CSETaskTiming struct {
	TaskName  string
	StartTime time.Time
	EndTime   time.Time
	Duration  time.Duration
	Message   string
}

CSETaskTiming represents the timing of a single CSE task.

type CSETimingReport

type CSETimingReport struct {
	Tasks     []CSETaskTiming
	Provision *CSEProvisionTiming
	// contains filtered or unexported fields
}

CSETimingReport holds all parsed timing data from a VM.

func ExtractCSETimings

func ExtractCSETimings(ctx context.Context, s *Scenario) (*CSETimingReport, error)

ExtractCSETimings SSHes into the scenario VM and extracts all CSE task timings. Returns an error if no tasks could be parsed, since an empty report would make regression detection ineffective.

func ValidateCSETimings

func ValidateCSETimings(ctx context.Context, s *Scenario, thresholds CSETimingThresholds) (*CSETimingReport, error)

ValidateCSETimings extracts, logs, and validates CSE task timings. It emits one subtest per threshold so ADO can track each timing check.

func (*CSETimingReport) GetTask

func (r *CSETimingReport) GetTask(name string) *CSETaskTiming

GetTask returns the timing for a specific task, or nil if not found.

func (*CSETimingReport) LogReport

func (r *CSETimingReport) LogReport(_ context.Context, t interface{ Logf(string, ...any) })

LogReport logs all task timings to the test logger.

func (*CSETimingReport) TotalCSEDuration

func (r *CSETimingReport) TotalCSEDuration() time.Duration

TotalCSEDuration returns the duration of the cse_start task if present.

type CSETimingThresholds

type CSETimingThresholds struct {
	// TaskThresholds maps task name suffixes to maximum duration.
	// Task names are matched by suffix to allow flexible matching
	// (e.g., "installDebPackageFromFile" matches "AKS.CSE.installkubelet.installDebPackageFromFile").
	TaskThresholds map[string]time.Duration

	// TotalCSEThreshold is the maximum acceptable total CSE duration.
	TotalCSEThreshold time.Duration

	// DefaultTaskThreshold is the threshold applied to any task that exceeds it
	// but has no specific entry in TaskThresholds. This ensures that ALL slow tasks
	// appear as sub-tests in ADO Pipeline Analytics, even newly added ones.
	// Tasks below this threshold are silently skipped.
	// Set to 0 to disable dynamic tracking.
	DefaultTaskThreshold time.Duration
}

CSETimingThresholds defines maximum acceptable durations for CSE tasks.

type Cluster

type Cluster struct {
	Model *armcontainerservice.ManagedCluster

	KubeletIdentity  *armcontainerservice.UserAssignedIdentity
	SubnetID         string
	VNetResourceGUID string
	ClusterParams    *ClusterParams
	Bastion          *Bastion
	ProxyURL         string
	TenantID         string
	// contains filtered or unexported fields
}

func (*Cluster) IsAzureCNI

func (c *Cluster) IsAzureCNI() (bool, error)

Returns true if the cluster is configured with Azure CNI

func (*Cluster) MaxPodsPerNode

func (c *Cluster) MaxPodsPerNode() (int, error)

Returns the maximum number of pods per node of the cluster's agentpool

func (*Cluster) NewKubeclientForTest

func (c *Cluster) NewKubeclientForTest() (*Kubeclient, error)

NewKubeclientForTest creates an independent Kubeclient with its own rate limiter. Use this in individual tests to avoid sharing rate limiter tokens with other parallel tests hitting the same cluster.

type ClusterParams

type ClusterParams struct {
	CACert         []byte
	BootstrapToken string
	FQDN           string
}

type ClusterRequest

type ClusterRequest struct {
	Location         string
	K8sSystemPoolSKU string
}

ClusterRequest represents the parameters needed to create a cluster

type ClusterSubnetRequest

type ClusterSubnetRequest struct {
	Location    string
	ClusterName string
	DualStack   bool
}

type Config

type Config struct {
	// Cluster creates, updates or re-uses an AKS cluster for the scenario
	Cluster func(ctx context.Context, request ClusterRequest) (*Cluster, error)

	// VHD is the node image used by the scenario.
	VHD *config.Image

	// BootstrapConfigMutator is a function which mutates the base NodeBootstrappingConfig according to the scenario's requirements
	BootstrapConfigMutator func(*Cluster, *datamodel.NodeBootstrappingConfiguration)

	// BootstrapConfigMutatorWithError is used when preparing the bootstrap configuration can fail.
	// It runs after BootstrapConfigMutator.
	BootstrapConfigMutatorWithError func(context.Context, *Cluster, *datamodel.NodeBootstrappingConfiguration) error

	// PreProvisionBootstrapConfigMutator, when set, mutates the NodeBootstrappingConfig for the
	// BAKE (pre-provision) stage ONLY of a VHDCaching/TestPreProvision two-stage run. It runs after
	// BootstrapConfigMutator (and after PreProvisionOnly is set). Use it to deliberately make
	// bake-time state differ from provision-time state - e.g. inject a sentinel TLS bootstrap token -
	// so that staleness regressions in the BasePrep->NodePrep split are caught positively.
	PreProvisionBootstrapConfigMutator func(*Cluster, *datamodel.NodeBootstrappingConfiguration)

	// AKSNodeConfigMutator if defined then aks-node-controller will be used to provision nodes
	AKSNodeConfigMutator func(*Cluster, *aksnodeconfigv1.Configuration)

	// VMConfigMutator is a function which mutates the base VMSS model according to the scenario's requirements
	VMConfigMutator func(*armcompute.VirtualMachineScaleSet)

	// VMConfigMutatorWithError is used when preparing the VMSS model can fail.
	// It runs after VMConfigMutator.
	VMConfigMutatorWithError func(context.Context, *armcompute.VirtualMachineScaleSet) error

	// CustomDataWriteFiles injects additional cloud-init write_files entries into rendered customData.
	// This is for e2e-only validation scenarios.
	CustomDataWriteFiles []CustomDataWriteFile

	// Validator is a function where the scenario can perform any extra validation checks
	Validator func(ctx context.Context, s *Scenario) error

	// SkipDefaultValidation is a flag to indicate whether the common validation (like spawning a pod) should be skipped.
	// It shouldn't be used for majority of scenarios, currently only used for preparing VHD in a two-stage scenario
	SkipDefaultValidation bool

	// SkipSSHConnectivityValidation is a flag to indicate whether the ssh connectivity validation should be skipped.
	// It shouldn't be used for majority of scenarios, currently only used for scenarios where the node is not expected to be reachable via ssh
	SkipSSHConnectivityValidation bool

	// WaitForSSHAfterReboot if set to non-zero duration, SSH connectivity validation will retry with exponential backoff
	// for up to this duration when encountering reboot-related errors. This is useful for scenarios where the node
	// reboots during provisioning (e.g., MIG-enabled GPU nodes). Default (zero value) means no retry.
	WaitForSSHAfterReboot time.Duration

	// if VHDCaching is set then a VHD will be created first for the test scenario and then a VM will be created from that VHD.
	// The main purpose is to validate VHD Caching logic and ensure a reboot step between basePrep and nodePrep doesn't break anything.
	VHDCaching bool

	// ExpectedError, when set, indicates that VMSS creation is expected to fail with an error containing this substring.
	// The assertion is performed inside the scenario's subtest.
	ExpectedError string

	// UseNVMe indicates whether to use NVMe-based disk placement/controller. This is required for certain VM sizes (e.g., v6 and v7 series) which only support NVMe disk controllers.
	UseNVMe bool

	// EagerCSETimingExtraction when true causes CSE timing events to be extracted
	// immediately after SSH is established, before other validators run.
	// This prevents the Guest Agent from sweeping events before they can be read.
	// Only set this on CSE performance test scenarios.
	EagerCSETimingExtraction bool
}

Config represents the configuration of an AgentBaker E2E scenario.

type CreateGalleryImageRequest

type CreateGalleryImageRequest struct {
	ResourceGroup    string
	GalleryName      string
	Location         string
	Arch             string
	Windows          bool
	HyperVGeneration *armcompute.HyperVGeneration
}

type CreateGalleryRequest

type CreateGalleryRequest struct {
	Location      string
	ResourceGroup string
}

type CustomDataWriteFile

type CustomDataWriteFile struct {
	Path        string
	Permissions string
	Owner       string
	Content     string
}

CustomDataWriteFile defines an e2e-only cloud-init write_files entry.

type GetLatestExtensionVersionRequest

type GetLatestExtensionVersionRequest struct {
	Location  string
	ExtType   string
	Publisher string
}

GetLatestExtensionVersionRequest is the cache key for VM extension version lookups.

type GetVHDRequest

type GetVHDRequest struct {
	Location string
	Image    config.Image
}

type Kubeclient

type Kubeclient struct {
	Dynamic    client.Client
	Typed      kubernetes.Interface
	RESTConfig *rest.Config
	KubeConfig []byte
}

func NewKubeclient

func NewKubeclient(kubeconfigBytes []byte) (*Kubeclient, error)

NewKubeclient creates a Kubeclient from raw kubeconfig bytes. Each call returns an independent client with its own rate limiter, allowing concurrent operations to avoid starving each other.

func (*Kubeclient) CreateDaemonset

func (k *Kubeclient) CreateDaemonset(ctx context.Context, ds *appsv1.DaemonSet) error

func (*Kubeclient) EnsureDebugDaemonsets

func (k *Kubeclient) EnsureDebugDaemonsets(ctx context.Context, isNetworkIsolated bool, privateACRName string) error

this is a bit ugly, but we don't want to execute this piece concurrently with other tests

func (*Kubeclient) GetPodNetworkDebugPodForNode

func (k *Kubeclient) GetPodNetworkDebugPodForNode(ctx context.Context, kubeNodeName string) (*corev1.Pod, error)

GetPodNetworkDebugPodForNode returns a pod that's a member of the 'debugnonhost' daemonset running in the cluster - this will return the name of the pod that is running on the node created for specifically for the test case which is running validation checks.

func (*Kubeclient) GetProxyURL

func (k *Kubeclient) GetProxyURL(ctx context.Context) (string, error)

GetProxyURL returns the proxy URL after verifying the proxy pod and its backing node are ready on the cluster's permanent managed system pool.

func (*Kubeclient) WaitUntilNodeReady

func (k *Kubeclient) WaitUntilNodeReady(ctx context.Context, t testing.TB, vmssName string) (string, error)

func (*Kubeclient) WaitUntilPodRunning

func (k *Kubeclient) WaitUntilPodRunning(ctx context.Context, namespace string, labelSelector string, fieldSelector string) (*corev1.Pod, error)

type Scenario

type Scenario struct {
	// Description is a short description of what the scenario does and tests for
	Description string

	// Tags are used for filtering scenarios to run based on the tags provided
	Tags Tags

	// Config contains the configuration of the scenario
	Config

	// Location is the Azure location where the scenario will run. This can be
	// used to override the default location.
	Location string

	// K8sSystemPoolSKU is the VM size to use for the system nodepool. If empty,
	// a default size will be used.
	K8sSystemPoolSKU string

	// Runtime contains the runtime state of the scenario. It's populated in the beginning of the test run
	Runtime *ScenarioRuntime
	T       testing.TB
	// contains filtered or unexported fields
}

Scenario represents an AgentBaker E2E scenario.

func (*Scenario) Cleanup

func (s *Scenario) Cleanup(fn func(context.Context) error)

Cleanup registers fn to run after the scenario and its subtests finish.

func (*Scenario) GetClientPrivateKey

func (s *Scenario) GetClientPrivateKey() string

func (*Scenario) GetContainerRegistryFQDN

func (s *Scenario) GetContainerRegistryFQDN() string

GetContainerRegistryFQDN returns the container registry FQDN for the cloud environment determined by the cluster's location. Uses Runtime.Cluster.Model.Location so it works for both legacy (NBC) and scriptless (AKSNodeConfig) bootstrap paths.

func (*Scenario) GetDefaultFQDNsForValidation

func (s *Scenario) GetDefaultFQDNsForValidation() []string

GetDefaultFQDNsForValidation returns the public cloud FQDNs to validate in hosts file checks. AgentBaker e2e only runs in public cloud, so sovereign cloud branches are unnecessary.

func (*Scenario) GetK8sVersion

func (s *Scenario) GetK8sVersion() string

func (*Scenario) GetServicePrincipalSecret

func (s *Scenario) GetServicePrincipalSecret() string

func (*Scenario) GetTLSBootstrapToken

func (s *Scenario) GetTLSBootstrapToken() string

func (*Scenario) HasServicePrincipalData

func (s *Scenario) HasServicePrincipalData() bool

func (*Scenario) IsHostsPluginEnabled

func (s *Scenario) IsHostsPluginEnabled() bool

IsHostsPluginEnabled returns true if the hosts plugin is explicitly enabled via either NBC (traditional) or AKSNodeConfig (scriptless) paths.

func (*Scenario) IsLinux

func (s *Scenario) IsLinux() bool

func (*Scenario) IsWindows

func (s *Scenario) IsWindows() bool

func (*Scenario) KubeletConfigFileEnabled

func (s *Scenario) KubeletConfigFileEnabled() bool

func (*Scenario) PrepareAKSNodeConfig

func (s *Scenario) PrepareAKSNodeConfig()

func (*Scenario) PrepareVMSSModel

func (s *Scenario) PrepareVMSSModel(ctx context.Context, vmss *armcompute.VirtualMachineScaleSet) error

PrepareVMSSModel mutates the input VirtualMachineScaleSet based on the scenario's VMConfigMutator, if configured. This method will also use the scenario's configured VHD selector to modify the input VMSS to reference the correct VHD resource.

func (*Scenario) SecureTLSBootstrappingEnabled

func (s *Scenario) SecureTLSBootstrappingEnabled() bool

type ScenarioRuntime

type ScenarioRuntime struct {
	NBC                       *datamodel.NodeBootstrappingConfiguration
	AKSNodeConfig             *aksnodeconfigv1.Configuration
	Cluster                   *Cluster
	Kube                      *Kubeclient // per-test client with independent rate limiter
	VM                        *ScenarioVM
	VMSSName                  string
	EnableScriptlessNBCCSECmd bool
	CSETimingReport           *CSETimingReport // eagerly extracted before GA can sweep events
}

type ScenarioVM

type ScenarioVM struct {
	KubeName  string
	VMSS      *armcompute.VirtualMachineScaleSet
	VM        *armcompute.VirtualMachineScaleSetVM
	PrivateIP string
	SSHClient *ssh.Client
}

func ConfigureAndCreateVMSS

func ConfigureAndCreateVMSS(ctx context.Context, s *Scenario) (*ScenarioVM, error)

func CreateVMSS

func CreateVMSS(ctx context.Context, s *Scenario, resourceGroupName string) (*ScenarioVM, error)

func CreateVMSSWithRetry

func CreateVMSSWithRetry(ctx context.Context, s *Scenario) (*ScenarioVM, error)

type SharedInfra

type SharedInfra struct {
	VNetName       string
	ResourceGroup  string
	BastionDNSName string
	FirewallIP     string
	IdentityID     string // resource ID of the user-assigned managed identity
	TenantID       string // tenant ID of the user-assigned managed identity
}

type Tags

type Tags struct {
	Name                   string
	ImageName              string
	OS                     string
	Arch                   string
	NetworkIsolated        bool
	NonAnonymousACR        bool
	GPU                    bool
	WASM                   bool
	Kata                   bool
	BootstrapTokenFallback bool
	KubeletCustomConfig    bool
	Scriptless             bool
	VHDCaching             bool
	MockAzureChinaCloud    bool
	RCV1PCertMode          bool
	VMSeriesCoverageTest   bool
}

func (Tags) MatchesAnyFilter

func (t Tags) MatchesAnyFilter(filters string) (bool, error)

MatchesAnyFilter checks if the Tags struct matches at least one of the given filters. Filters are comma-separated "key=value" pairs (e.g., "gpu=true,os=x64"). Returns true if any filter matches, false if none match. Errors on invalid input.

func (Tags) MatchesFilters

func (t Tags) MatchesFilters(filters string) (bool, error)

MatchesFilters checks if the Tags struct matches all given filters. Filters are comma-separated "key=value" pairs (e.g., "gpu=true,os=x64"). Returns true if all filters match, false otherwise. Errors on invalid input.

Special case: when ALL filters use the "Name" key (e.g., "Name=foo,Name=bar"), OR semantics are used instead, matching if any name matches. This allows selecting multiple scenarios by name with a single filter string.

type VMSizeSKURequest

type VMSizeSKURequest struct {
	Location string
	VMSize   string
}

VMSizeSKURequest is the cache key for Resource SKU lookups by VM size and location.

type VNet

type VNet struct {
	// contains filtered or unexported fields
}

Directories

Path Synopsis
Package assert provides error-returning assertions in (got, want) order.
Package assert provides error-returning assertions in (got, want) order.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL