Provider Config File

mtv-api-tests keeps source provider definitions in .providers.json. Two shipped files describe it: providers_schema.json is a JSON Schema (draft 2020-12) that your editor can validate against, and .providers.json.example is an annotated template with one entry per provider type.

At runtime the suite only parses JSON. It reads specific fields per provider type and ignores the rest, so the schema is the reference for what each provider entry may contain.

Warning: .providers.json.example is an annotated template, not a ready-to-use .providers.json. The loader parses the file with json.loads(...), so your real file must be strict JSON: remove comments, keep valid quoting, and avoid trailing commas.

Warning: .providers.json usually contains provider passwords and guest OS passwords. Treat it as a secret file.

Note: The top-level key is the provider name you select with source_provider. It does not have to match type. For example, the example file has a key named vsphere-copy-offload, but its "type" is still "vsphere".

How the file is located

load_source_providers() resolves the path in this order:

Order Source Notes
1 --providers-json <path> Custom pytest option
2 PROVIDERS_JSON_PATH environment variable CI-friendly override
3 .providers.json Relative to the current working directory

Fail-fast behavior:

  • A path that does not exist raises FileNotFoundError.
  • An empty or whitespace-only file raises ProviderEmptyContentError.
  • A file whose top level is not a JSON object raises ValueError.
  • source_provider must match one of the top-level keys, or provider lookups fail later.

Top-Level Shape

{
  "$schema": "https://raw.githubusercontent.com/RedHatQE/mtv-api-tests/main/providers_schema.json",
  "vsphere": { "type": "vsphere", "...": "..." }
}
  • The root is an object. Every key except $schema is a provider definition.
  • $schema is optional and is used only for editor validation.
  • Each provider definition is validated against a oneOf block, one per provider type. Exactly one type block must match.

Warning: The OpenShift provider block sets additionalProperties: false. Unknown keys in an openshift entry fail schema validation, even though the runtime loader ignores extra keys on other provider types.

Fields By Provider Type

type selects the block. These tables match providers_schema.json exactly.

type: "vsphere"

Field Required Notes
type Yes Constant vsphere.
version Yes Platform version label, for example 8.0.3. Used in generated resource names.
fqdn Yes vCenter or ESXi host name or IP.
api_url Yes Provider API URL. vSphere expects a /sdk suffix.
username Yes vSphere login.
password Yes vSphere password.
endpoint_type No vcenter or esxi. Defaults to vCenter behavior when omitted.
vddk_init_image No VDDK init container image reference passed to the MTV Provider.
clone_provider No Name of a vCenter entry used for ESXi cloning.
luks_passphrase No Provider-level LUKS passphrase, used when a VM has no per-VM override.
copyoffload No Nested copy-offload block. See vSphere copy-offload.
guest_vm_linux_user / guest_vm_linux_password No Linux guest SSH credentials.
guest_vm_win_user / guest_vm_win_password No Windows guest WinRM credentials.

type: "ovirt"

Field Required Notes
type Yes Constant ovirt. Use this even for an RHV source.
version Yes Platform version label.
fqdn Yes Engine host name or IP. Also used for the CA certificate download.
api_url Yes Engine API URL. Expect an /ovirt-engine/api suffix.
username Yes RHV login.
password Yes RHV password.
guest_vm_linux_user / guest_vm_linux_password No Linux guest SSH credentials.
guest_vm_win_user / guest_vm_win_password No Windows guest WinRM credentials.

type: "openstack"

Field Required Notes
type Yes Constant openstack.
version Yes Platform version label.
fqdn Yes Host name or IP. Also used for the CA certificate download.
api_url Yes Keystone v3 endpoint, for example host:5000/v3.
username Yes OpenStack login.
password Yes OpenStack password.
user_domain_name Yes Keystone user domain name.
region_name Yes Region name.
project_name Yes Project or tenant name.
user_domain_id Yes Keystone user domain UUID.
project_domain_id Yes Keystone project domain UUID.
guest_vm_linux_user / guest_vm_linux_password No Linux guest SSH credentials.
guest_vm_win_user / guest_vm_win_password No Windows guest WinRM credentials.

type: "openshift"

Field Required Notes
type Yes Constant openshift.
version Yes Platform version label.
host Yes Cluster API host name or URL. Required by the schema.
api_url Yes Cluster API URL. Required by the schema.
username Yes Required by the schema.
password Yes Required by the schema.
storage_class Yes Default storage class for target PVCs. Required by the schema.
verify_ssl No true or false.
ca_bundle No Path to a CA bundle file for SSL verification.

This block is the strict one: additionalProperties is false, so no other keys are allowed.

Note: The runtime path for an openshift entry does not authenticate with these values. The loader rewrites api_url to the current cluster host and reuses the session's own token secret, which is always created with insecureSkipVerify: "true". See OpenShift.

type: "ova"

Field Required Notes
type Yes Constant ova.
version Yes Platform version label. Any placeholder value works; it is used for naming only.
fqdn Yes Not used for OVA connections.
api_url Yes NFS share URL. This is the field the OVA provider actually consumes.
username Yes Not used for OVA connections.
password Yes Not used for OVA connections.
guest_vm_linux_user / guest_vm_linux_password No Linux guest SSH credentials.
guest_vm_win_user / guest_vm_win_password No Windows guest WinRM credentials.

type: "hyperv"

Field Required Notes
type Yes Constant hyperv.
version Yes Platform version label.
fqdn Yes Hyper-V host address.
api_url Yes Hyper-V host address.
username Yes Hyper-V host login.
password Yes Hyper-V host password.
smb_url Yes SMB share URL used for VM disk transfer.
smb_user No SMB user, when it differs from the provider credentials.
smb_password No SMB password, when it differs from the provider credentials.
guest_vm_linux_user / guest_vm_linux_password No Linux guest SSH credentials.
guest_vm_win_user / guest_vm_win_password No Windows guest WinRM credentials.

Note: Hyper-V is the only provider that fetches its CA certificate from port 5986 instead of 443.

Fields The Runtime Always Reads

Before dispatching on type, the loader builds the provider secret and connection arguments from three fields. They must be present for every provider entry, including openshift and ova:

Field Use
api_url Becomes the url key of the provider Secret.
username Becomes the provider connection username.
password Becomes the provider connection password.

Guest Credentials

Guest credentials are separate from provider credentials.

The provider username and password fields log in to the source platform itself. The guest_vm_* fields are read later by post-migration SSH or WinRM checks when the destination VM is powered on. If those checks run and the matching guest credentials are missing, validation fails.

This matters even if the shipped example for a provider does not show guest credentials. The loader keeps extra keys, so you can add guest_vm_linux_* and guest_vm_win_* to a vsphere, ovirt, openstack, ova, or hyperv provider entry when your selected tests need them. The openshift entry is the exception: its schema block sets additionalProperties: false, so guest credential keys there fail schema validation in your editor and must be left out.

Tip: Think of guest_vm_linux_* and guest_vm_win_* as per-guest test credentials, not part of the provider login.

SSL Behavior

Source-provider SSL behavior is controlled in tests/tests_config/config.py, not inside .providers.json:

insecure_verify_skip: str = "true"  # SSL verification for OCP API connections
source_provider_insecure_skip_verify: str = "false"  # SSL verification for source provider (VMware, RHV, etc.)

Key points:

  • source_provider_insecure_skip_verify controls the source provider Secret created for vSphere, RHV, OpenStack, and Hyper-V.
  • insecure_verify_skip is for OpenShift API connections and does not control source provider validation.
  • These settings are stored as strings, so use "true" or "false". When source_provider_insecure_skip_verify is "false", the harness fetches a CA certificate from fqdn and stores it in the provider Secret for vSphere, OpenStack, and Hyper-V.

  • RHV is special: the code always fetches the CA certificate, even when verification is skipped, because the ImageIO path still needs it. It is stored under cacert by default.

  • OpenShift is also special: the source provider reuses the current cluster token Secret, which is created with insecureSkipVerify: "true".
  • OVA has no CA download step.

Note: Secure mode only works if fqdn points to a host that serves the provider certificate on the expected port. If the certificate fetch fails, provider creation fails.

vSphere

Example from .providers.json.example:

"vsphere": {
  "type": "vsphere",
  "version": "<SERVER VERSION>",
  "fqdn": "SERVER FQDN/IP",
  "api_url": "<SERVER FQDN/IP>/sdk",
  "username": "USERNAME",
  "password": "PASSWORD",  # pragma: allowlist secret
  "guest_vm_linux_user": "LINUX VMS USERNAME",
  "guest_vm_linux_password": "LINUX VMS PASSWORD",  # pragma: allowlist secret
  "guest_vm_win_user": "WINDOWS VMS USERNAME",
  "guest_vm_win_password": "WINDOWS VMS PASSWORD",  # pragma: allowlist secret
  "luks_passphrase": "LUKS DISK ENCRYPTION PASSPHRASE",  # pragma: allowlist secret
  "vddk_init_image": "<PATH TO VDDK INIT IMAGE>",
  "endpoint_type": "vcenter",
}

What matters for vSphere:

  • fqdn is used for the direct vSphere connection.
  • In secure mode the API URL is normalized for TLS before the certificate is downloaded.
  • vddk_init_image is passed to the MTV Provider resource when present.
  • endpoint_type maps to sdkEndpoint in the MTV Provider resource settings. Use "esxi" for direct ESXi host connections.
  • luks_passphrase here is the provider-level fallback. A per-VM luks_passphrase in the test plan config takes precedence.

ESXi cloning via clone_provider

ESXi hosts do not support the CloneVM_Task API. That is a vCenter-only operation. To enable VM cloning for test isolation when the source provider is an ESXi host, configure clone_provider so the harness can reach a vCenter entry that performs the clone.

How it works:

  • The clone_provider value must match a top-level key in .providers.json.
  • A missing key fails with a ValueError that lists the available provider names.
  • The referenced entry must be a vSphere provider.
  • When clone_provider is set, the harness creates a separate VMWareProvider connection to that vCenter and uses it for cloning operations.
  • If clone_provider is not set, the harness uses the source provider for cloning. That works for vCenter entries but will fail for ESXi.

ESXi provider example:

"vsphere-esxi": {
  "type": "vsphere",
  "version": "<SERVER VERSION>",
  "fqdn": "ESXI HOST FQDN/IP",
  "api_url": "<ESXI HOST FQDN/IP>/sdk",
  "username": "USERNAME",
  "password": "PASSWORD",
  "endpoint_type": "esxi",
  "vddk_init_image": "<PATH TO VDDK INIT IMAGE>",
  "clone_provider": "vsphere"
}

Here "clone_provider": "vsphere" references the "vsphere" entry shown earlier, which must be a vCenter that manages ESXI HOST FQDN/IP.

Tip: Keep a separate vSphere entry for copy-offload, like the example's vsphere-copy-offload. That makes it easy to switch between regular and copy-offload runs by changing only source_provider.

vSphere copy-offload

The copyoffload block is only meaningful for vSphere entries. The code validates it before copy-offload tests run, uses it to build the storage Secret, and passes that Secret into the vsphereXcopyConfig storage-map plugin configuration.

Required fields

The schema requires exactly two fields, and the copy-offload fixture re-validates both at runtime:

Field Notes
storage_vendor_product One of the supported vendor values listed below.
datastore_id Primary vSphere datastore MoRef ID, such as datastore-12345.

Supported storage_vendor_product values:

Value Storage array
ontap NetApp ONTAP
primera3par HPE Primera/3PAR
pureFlashArray Pure Storage FlashArray
powerflex Dell PowerFlex
powermax Dell PowerMax
powerstore Dell PowerStore
vantara Hitachi Vantara
infinibox Infinidat InfiniBox
flashsystem IBM FlashSystem

Warning: These values are fixed in code. Use the exact spellings above.

Vendor-specific required fields

The schema requires extra fields for some vendors, and the copy-offload fixture raises when a required vendor field is missing:

storage_vendor_product Additional required fields Secret keys added
ontap ontap_svm ONTAP_SVM
vantara vantara_storage_id, vantara_storage_port, vantara_hostgroup_id_list STORAGE_ID, STORAGE_PORT, HOSTGROUP_ID_LIST
primera3par none none
pureFlashArray pure_cluster_prefix PURE_CLUSTER_PREFIX
powerflex powerflex_system_id POWERFLEX_SYSTEM_ID
powermax powermax_symmetrix_id POWERMAX_SYMMETRIX_ID
powerstore none none
infinibox none none
flashsystem none none

Optional fields

Field Notes
default_vm_name Overrides the source VM name for cloned copy-offload tests. Applied only to VMs with clone: true.
storage_hostname Storage array management host. Required at runtime unless COPYOFFLOAD_STORAGE_HOSTNAME is set.
storage_username Storage array user. Required at runtime unless COPYOFFLOAD_STORAGE_USERNAME is set.
storage_password Storage array password. Required at runtime unless COPYOFFLOAD_STORAGE_PASSWORD is set.
secondary_datastore_id Second XCOPY-capable datastore, for multi-datastore tests.
non_xcopy_datastore_id Datastore without XCOPY support, for fallback and negative tests.
storage_secret_extra Object of extra Kubernetes Secret stringData keys for vendor configuration.
dedicated_migration_hosts Array of ESXi host MoRef IDs used for XCOPY extraction. Required for dedicated-host tests.
resource_pool vSphere resource pool for clone placement. See the priority order below.
esxi_clone_method vib or ssh. vib is the default.
esxi_host / esxi_user / esxi_password Required by the schema and at runtime when esxi_clone_method is ssh.
rdm_lun_uuid NAA-format LUN identifier for RDM tests. Must match the ^naa\. pattern.

resource_pool selection priority order:

  1. The configured resource_pool value.
  2. The target ESXi host's pool, when target_esxi_host is set on the clone options.
  3. The source VM's or template's pool.
  4. A cluster-wide search with a datastore compatibility check.

dedicated_migration_hosts must be a non-empty list of non-empty strings. When more than one host is listed, Forklift selects one at random per disk. Dedicated-host tests raise a ValueError when this field is missing.

Tip: Every copy-offload credential can come from an environment variable instead of the file, and environment variables win. Names are built as COPYOFFLOAD_<FIELD_IN_UPPERCASE>, so examples include COPYOFFLOAD_STORAGE_HOSTNAME, COPYOFFLOAD_STORAGE_USERNAME, COPYOFFLOAD_STORAGE_PASSWORD, COPYOFFLOAD_ONTAP_SVM, COPYOFFLOAD_ESXI_HOST, COPYOFFLOAD_ESXI_USER, and COPYOFFLOAD_ESXI_PASSWORD. storage_secret_extra has its own JSON-object override, COPYOFFLOAD_STORAGE_SECRET_EXTRA.

RHV / oVirt

The RHV source path uses type: "ovirt".

Example from .providers.json.example:

"ovirt": {
  "type": "ovirt",
  "version": "<SERVER VERSION>",
  "fqdn": "SERVER FQDN/IP",
  "api_url": "<SERVER FQDN/IP>/ovirt-engine/api",
  "username": "USERNAME",
  "password": "PASSWORD"  # pragma: allowlist secret
}

What matters for RHV:

  • Use type: "ovirt" even if you think of the source as RHV.
  • fqdn should point to the engine host, because the CA certificate is fetched from it.
  • The RHV provider also expects a data center named MTV-CNV to exist with status up. That is not configurable in .providers.json, but it is enforced during connection.

Note: RHV is the one provider where the harness always downloads the CA certificate. In secure mode it is used for SDK validation; in insecure mode it is still carried because the ImageIO flow needs it.

OpenStack

Example from .providers.json.example:

"openstack": {
  "type": "openstack",
  "version": "SERVER VERSION",
  "fqdn": "SERVER FQDN/IP",
  "api_url": "<SERVER FQDN/IP>:<PORT>/v3",
  "username": "USERNAME",
  "password": "PASSWORD",  # pragma: allowlist secret
  "user_domain_name": "<DOMAIN>",
  "region_name": "<REGION>",
  "project_name": "<PROJECT>",
  "user_domain_id": "<USER DOMAIN ID>",
  "project_domain_id": "PROJECT DOMAIN ID",
  "guest_vm_linux_user": "LINUX VMS USERNAME",
  "guest_vm_linux_password": "LINUX VMS PASSWORD"  # pragma: allowlist secret
}

What matters for OpenStack:

  • project_name, user_domain_name, region_name, user_domain_id, and project_domain_id are all passed to the provider. All five are required by the schema.
  • fqdn still matters in secure mode because the harness fetches a CA certificate from it.

OpenShift

Example from .providers.json.example:

"openshift": {
  "type": "openshift",
  "version": "<SERVER VERSION>",
  "host": "<CLUSTER API URL>",
  "api_url": "<CLUSTER API URL>",
  "username": "<USERNAME>",
  "password": "<PASSWORD>",  # pragma: allowlist secret
  "storage_class": "<STORAGE CLASS NAME>"
}

What matters for OpenShift:

  • Keep the placeholder shape from the example; openshift entries allow no extra keys.
  • The OpenShift source provider does not use these values to log in. The code rewrites api_url to the current cluster host and reuses the current cluster token Secret.
  • Because this provider block sets additionalProperties: false, do not add guest credential keys here. Use a separate source provider entry if your tests need them.
  • The schema requires host and storage_class, but the loader never reads them. Target storage comes from the runtime storage_class value passed with --tc.

Note: The reused OpenShift Secret is created with insecureSkipVerify: "true", so source_provider_insecure_skip_verify does not affect OpenShift the same way it affects vSphere, RHV, OpenStack, or Hyper-V.

OVA

Example from .providers.json.example:

"ova": {
  "type": "ova",
  "version": "<SERVER VERSION>", # Can be anything, just placeholder
  "fqdn": "",
  "api_url": "<NFS SHARE URL>",
  "username": "<USERNAME>",
  "password": ""  # pragma: allowlist secret
}

What matters for OVA:

  • api_url is the NFS share URL and the only field the OVA provider consumes for its connection.
  • version is used for naming, not protocol negotiation.
  • fqdn, username, and password must still be present because the loader reads them for every provider type.
  • OVA source VMs are never cloned. The test flow requires each plan VM name to match an existing OVA file.
  • There is no CA download step for OVA.

Hyper-V

Example from .providers.json.example:

"hyperv": {
  "type": "hyperv",
  "version": "2025",
  "fqdn": "hyperv-host.example.com",
  "api_url": "hyperv-host.example.com",
  "username": "Administrator",
  "password": "PASSWORD",  # pragma: allowlist secret
  "smb_url": "//hyperv-host.example.com/VMShare",
  "smb_user": "",  # Optional: SMB username if different from provider credentials
  "smb_password": "",  # pragma: allowlist secret  # Optional: SMB password if different from provider credentials
  "guest_vm_linux_user": "root",
  "guest_vm_linux_password": "PASSWORD",  # pragma: allowlist secret
  "guest_vm_win_user": "Administrator",
  "guest_vm_win_password": "PASSWORD"  # pragma: allowlist secret
}

What matters for Hyper-V:

  • smb_url is required by the schema and is what the provider uses to transfer VM disks.
  • smb_user and smb_password are optional. When present and non-empty they become the smbUser and smbPassword Secret keys.
  • In secure mode the CA certificate is fetched from fqdn on port 5986.
  • Hyper-V guest OS detection can be overridden per VM with the win_os key in the test plan config.

Practical Checklist

  • Start from .providers.json.example, then remove all comments before saving the real .providers.json.
  • Validate your editor against the providers_schema.json URL in the $schema key.
  • Make sure your source_provider setting matches a top-level key in the file.
  • Keep fqdn accurate for vSphere, RHV, OpenStack, and Hyper-V, especially if SSL verification is enabled.
  • Add guest credentials for any provider entry whose powered-on guests will be validated over SSH or WinRM.
  • For vSphere copy-offload, populate both the common storage credentials and the vendor-specific fields required by your chosen storage_vendor_product.
  • Remember that OpenShift is the only provider type that rejects unknown keys.