As part of an Ansible Installation Process, we need to import some ISO, OVA files or template files up to a datastore so we can use them in the installation proces. We have an existing token for the API access already, so we we would like to use that authentication to move the file up. To avoid dependencies, we are only using Ansible URI calls to the vCenter API, and hope we can continue that method.
We see where govc is capable of uploading files to datastores (VMDKs as an example), and we see were the GUI can upload OVAs and other files through the vCenter without requiring root authentication, but we have not been able to find an API call that works to upload the files we need. I now we could do this with ssh or govc, but we are trying to avoid multiple authentication methods (ssh / root access to hosts as an example) and would like to limit the dependencies on other tools where ever possible. Can this be done through the API?
So far we have tried:
- name: Upload File
uri:
url: "https://{{ vcenter_hostname }}/folder/{{ upload_datastore }}/Some-test-file.iso"
method: PUT
src: ISOs/debian/11/debian-11.9.0-amd64-DVD-1.iso
force_basic_auth: yes
validate_certs: no
headers:
Cookie: "{{ auth_cookie.set_cookie }}"
We have also tried to write to an ESXi host using the same token we got from vCenter during the auth process
- name: Upload File
uri:
url: "https://{{ esxi_hostname }}/folder/{{ upload_datastore }}/Some-test-file.iso"
method: PUT
src: ISOs/debian/11/debian-11.9.0-amd64-DVD-1.iso
force_basic_auth: yes
validate_certs: no
headers:
Cookie: "{{ auth_cookie.set_cookie }}"
I was able to work this out. A few key points:
- Everything about the destination of the file will be in the URL that gets called
- I was trying to use the cookie that I was using for other API calls. That cookie will not work here and I had to resend authentication credentials to send the file.
This should be a working example:
- name: Transfer a File
hosts: localhost
gather_facts: false
vars:
vcenter_hostname: "your.vcenter.local"
vcenter_user: "administrator@vsphere.local"
src_file_path: "./testfile.txt"
dst_file_name: "SomeNewFileName.txt"
dst_folder_name: "AnExistingFolder"
datastore_name: "TheNameOfTheDatastore"
datacenter_name: "TheNameOfTheDatacenterInVCenter"
tasks:
- name: Transfer a File Test
uri:
url: "https://{{ vcenter_hostname }}/folder/{{ dst_folder_name }}/{{ dst_file_name }}?dsName={{ datastore_name }}&dcPath={{ datacenter_name }}"
force_basic_auth: yes
validate_certs: no
user: "{{ vcenter_user }}"
password: "{{ lookup('ansible.builtin.env', 'ANSIBLE_PASSWORD') }}"
method: PUT
src: "{{ src_file_path }}"
smash karts Can you explain the vCenter authentication process
This is the method I am using for authentication.
- name: Get a cookie for vCenter Access
uri:
url: https://{{ vcenter_hostname }}/rest/com/vmware/cis/session
force_basic_auth: yes
validate_certs: no
method: POST
user: "{{ vcenter_user }}"
password: "{{ lookup('ansible.builtin.env', 'ANSIBLE_PASSWORD') }}"
register: auth_cookie
I was able to work this out. A few key points:
- Everything about the destination of the file will be in the URL that gets called
- I was trying to use the cookie that I was using for other API calls. That cookie will not work here and I had to resend authentication credentials to send the file.
This should be a working example:
- name: Transfer a File
hosts: localhost
gather_facts: false
vars:
vcenter_hostname: "your.vcenter.local"
vcenter_user: "administrator@vsphere.local"
src_file_path: "./testfile.txt"
dst_file_name: "SomeNewFileName.txt"
dst_folder_name: "AnExistingFolder"
datastore_name: "TheNameOfTheDatastore"
datacenter_name: "TheNameOfTheDatacenterInVCenter"
tasks:
- name: Transfer a File Test
uri:
url: "https://{{ vcenter_hostname }}/folder/{{ dst_folder_name }}/{{ dst_file_name }}?dsName={{ datastore_name }}&dcPath={{ datacenter_name }}"
force_basic_auth: yes
validate_certs: no
user: "{{ vcenter_user }}"
password: "{{ lookup('ansible.builtin.env', 'ANSIBLE_PASSWORD') }}"
method: PUT
src: "{{ src_file_path }}"