0

Running into some challenges with deploying an OVA. Been beating my head against the wall for a couple days and need to call in some help.

The goal is to deploy an OVA to a vcenter. Keep in mind this is a lab environment so there are self signed certs. Ideally i would like to create a flag that i can toggle depending on the environment its run in.

The script runs and connects - however when it goes to upload it looks like it wants to upload however it just times out and cancels itself.

The error that my script outputs is the following:

Traceback (most recent call last):
  File "/workspaces/nestedlabs/test_combine.py", line 105, in <module>
    deploy_ova(si, ova_url, cluster_name, datastore_name, vm_name, vm_config)
  File "/workspaces/nestedlabs/test_combine.py", line 71, in deploy_ova
    session.put(url, data=file, timeout=7)
  File "/home/vscode/.local/lib/python3.10/site-packages/requests/sessions.py", line 649, in put
    return self.request("PUT", url, data=data, **kwargs)
  File "/home/vscode/.local/lib/python3.10/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/vscode/.local/lib/python3.10/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
  File "/home/vscode/.local/lib/python3.10/site-packages/requests/adapters.py", line 517, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='10.10.100.10', port=443): Max retries exceeded with url: /nfc/520bbbb4-6b20-d263-041d-6492c679159a/disk-0.vmdk (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:2396)')))

The script i have so far is the following. The ips and passwords have been changed - they are bogus for this post.

from pyVmomi import vim
from pyVim.connect import SmartConnect, Disconnect
import ssl
import requests
import tempfile
import shutil
import tarfile
import os
import time

class WebHandle(object):
    def __init__(self, url):
        self.url = url
        r = requests.get(url, stream=True, verify=False)
        if r.status_code != 200:
            raise FileNotFoundError(url)
        self.file_handle = tempfile.NamedTemporaryFile(suffix='.ova', delete=False)
        shutil.copyfileobj(r.raw, self.file_handle)
        self.file_handle.flush()
        self.file_handle.seek(0)

    def __enter__(self):
        return self.file_handle

    def __exit__(self, exc_type, exc_value, traceback):
        self.file_handle.close()
        os.unlink(self.file_handle.name)

def deploy_ova(si, ova_url, cluster_name, datastore_name, vm_name, vm_config):
    with WebHandle(ova_url) as ova_file:
        tar = tarfile.open(fileobj=ova_file)
        ovf_file = [f for f in tar.getnames() if f.endswith('.ovf')][0]
        ovf_descriptor = tar.extractfile(ovf_file).read().decode()

        content = si.RetrieveContent()
        cluster = next((c for c in content.rootFolder.childEntity[0].hostFolder.childEntity if c.name == cluster_name), None)
        resource_pool = cluster.resourcePool if cluster else content.rootFolder.childEntity[0].host[0].parent.resourcePool
        datastore = next((ds for ds in (cluster.datastore if cluster else content.rootFolder.childEntity[0].host[0].datastore) if ds.name == datastore_name), None)
        vm_folder = content.rootFolder.childEntity[0].vmFolder

# Create the customization properties
        property_mappings = [
            vim.KeyValue(key='guestinfo.hostname', value=vm_config['hostname']),
            vim.KeyValue(key='guestinfo.ipaddress', value=vm_config['ipaddress']),
            vim.KeyValue(key='guestinfo.netmask', value=vm_config['netmask']),
            vim.KeyValue(key='guestinfo.gateway', value=vm_config['gateway']),
            vim.KeyValue(key='guestinfo.dns', value=vm_config['dns']),
            vim.KeyValue(key='guestinfo.ntp', value=vm_config['ntp']),
            # vim.KeyValue(key='guestinfo.ssh', value='true'),
            vim.KeyValue(key='guestinfo.password', value=vm_config['password']),
            # Add other properties here...
        ]
        spec_params = vim.OvfManager.CreateImportSpecParams(entityName=vm_name, propertyMapping=property_mappings)
        manager = content.ovfManager
        import_spec = manager.CreateImportSpec(ovf_descriptor, resource_pool, datastore, spec_params)
        lease = resource_pool.ImportVApp(import_spec.importSpec, vm_folder)

        while lease.state == vim.HttpNfcLease.State.initializing:
            time.sleep(1)

        if lease.state == vim.HttpNfcLease.State.error:
            print("Lease error: ", lease.error)
            return
        session = requests.Session()
        session.verify = False

        for device_url in lease.info.deviceUrl:
            file_path = next((f for f in import_spec.fileItem if f.deviceId == device_url.importKey), None).path
            file = tar.extractfile(file_path)
            url = device_url.url.replace('*', '10.10.100.12') # Replace with the correct IP
            session.put(url, data=file, timeout=7)

        lease.HttpNfcLeaseComplete()

        vm = lease.info.entity
        task = vm.PowerOn()
        while task.info.state == vim.TaskInfo.State.running:
            time.sleep(1)

        print(f"Deployed {vm_name} successfully!")
# Connect to the vCenter server
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE

si = SmartConnect(host="10.10.100.12", user="administrator@vsphere.local", pwd="Password1234", sslContext=ssl_context)

# Deploy the OVA
ova_url = 'https://10.10.100.147/public-archives/download/Test/Nested_ESXi6.5u3_Appliance_Template_v1.ova'
cluster_name = 'Test1'
datastore_name = 'datastore1'
vm_name = 'YourVM'
vm_config = {
    'hostname': 'your-hostname',
    'ipaddress': '10.100.100.240',
    'netmask': '255.255.255.0',
    'gateway': '10.100.100.1',
    'dns': '10.100.100.111',
    'ntp': '4.2.2.2',
    # 'ssh': 'True',
    'syslog': '10.100.100.111',
    'password': 'WhatAPassWord!!',
    # Add other properties here...
}
deploy_ova(si, ova_url, cluster_name, datastore_name, vm_name, vm_config)

# Disconnect from the vCenter server
Disconnect(si)
Jared
  • 135
  • 1
  • 13

0 Answers0