ansible-collections / community.vmware

Ansible Collection for VMware
GNU General Public License v3.0
348 stars 337 forks source link

vmware_tag_manager cannot find multiple tags or category + tag #622

Open coreydeli opened 3 years ago

coreydeli commented 3 years ago
SUMMARY

Creating a set of servers and tagging them yields an error that the tags cannot be found when specifying the category plus the variable like Test: "{{item.vm_tag}}". If i specify the variable only with a single tag it will find the tag and apply it, if I add another tag into the variable set it will not find it as well generating the same error output.

ISSUE TYPE
COMPONENT NAME

vmware_tag_manager

ANSIBLE VERSION
ansible 2.9.16
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/var/lib/awx/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Aug 24 2020, 17:57:11) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
OS / ENVIRONMENT

Target OS: Windows Server 2019 Target Platform: Vmware vSphere Client version 7.0.1.00200

STEPS TO REPRODUCE

Running this from AWX using up to date dependencies (checked nightly against the latest tag). In the "extra_vars" section add the following:

extra_vars:

servers:
  - vm_name: TestDeploy01
    vm_ip: 10.10.1.241
    vm_tag: TagTest1
  - vm_name: TestDeploy02
    vm_ip: 10.10.1.242
    vm_tag:
      - TagTest2
  - vm_name: TestDeploy03
    vm_ip: 10.10.1.243
    vm_tag:
      - TagTest1
      - TagTest2
site: int

playbook:

- name: Add tags to a virtual machine
  vmware_tag_manager:
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    validate_certs: no
    tag_names: "{{ item.vm_tag }}"
    object_name: "{{ item.vm_name }}"
    object_type: VirtualMachine
    state: present
  with_items: "{{ servers }}"

The above will provide you with the tag properly as shown in , however, if you write the body of the playbook as:

- name: Add tags to a virtual machine
  vmware_tag_manager:
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    validate_certs: no
    tag_names:
      -  "{{ item.vm_tag }}"
    object_name: "{{ item.vm_name }}"
    object_type: VirtualMachine
    state: present
  with_items: "{{ servers }}"

you will receive the first error listed in the Actual Results section. This would apply as well if you are using multiple tags in your variables.

Further if you define the category, as shown below, you will be met with the second error listed in Actual Resaults.

- name: Add tags to a virtual machine
  vmware_tag_manager:
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    validate_certs: no
    tag_names:
      -  Test:"{{ item.vm_tag }}"
    object_name: "{{ item.vm_name }}"
    object_type: VirtualMachine
    state: present
  with_items: "{{ servers }}"

OR

- name: Add tags to a virtual machine
  vmware_tag_manager:
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    validate_certs: no
    tag_names:
      -  tag: "{{ item.vm_tag }}"
         category: Test
    object_name: "{{ item.vm_name }}"
    object_type: VirtualMachine
    state: present
  with_items: "{{ servers }}"

OR

- name: Add tags to a virtual machine
  vmware_tag_manager:
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    validate_certs: no
    tag_names: Test:"{{ item.vm_tag }}"
    object_name: "{{ item.vm_name }}"
    object_type: VirtualMachine
    state: present
  with_items: "{{ servers }}"

In all of these tests, specifying a category then the tag will not work unless it is done all inside of the playbook without a variable.

Any assistance to fix this so that multiple tags can be used would be a great help.

EXPECTED RESULTS
TASK [Add tags to a virtual machine] *******************************************
task path: /tmp/awx_3453_q5diemb0/project/Deploy/roles/tag/tasks/main.yml:1
changed: [localhost] => (item={'vm_ip': '10.10.1.241', 'vm_name': 'TestDeploy01', 'vm_tag': 'TagTest1'}) => {"ansible_loop_var": "item", "changed": true, "item": {"vm_ip": "10.10.1.241", "vm_name": "TestDeploy01", "vm_tag": "TagTest1"}, "tag_status": {"current_tags": ["TagTest1"], "desired_tags": ["TagTest1"], "previous_tags": []}}
changed: [localhost] => (item={'vm_ip': '10.10.1.242', 'vm_name': 'TestDeploy02', 'vm_tag': ['TagTest2']}) => {"ansible_loop_var": "item", "changed": true, "item": {"vm_ip": "10.10.1.242", "vm_name": "TestDeploy02", "vm_tag": ["TagTest2"]}, "tag_status": {"current_tags": ["TagTest2"], "desired_tags": ["TagTest2"], "previous_tags": []}}
changed: [localhost] => (item={'vm_ip': '10.10.1.243', 'vm_name': 'TestDeploy03', 'vm_tag': ['TagTest1', 'TagTest2']}) => {"ansible_loop_var": "item", "changed": true, "item": {"vm_ip": "10.10.1.243", "vm_name": "TestDeploy03", "vm_tag": ["TagTest1", "TagTest2"]}, "tag_status": {"current_tags": ["TagTest2", "TagTest1"], "desired_tags": ["TagTest1", "TagTest2"], "previous_tags": []}}
ACTUAL RESULTS

First Error

TASK [Add tags to a virtual machine] *******************************************
task path: /tmp/awx_3443_x43sif5f/project/Deploy/roles/tag/tasks/main.yml:1
failed: [localhost] (item={'vm_ip': '10.10.1.241', 'vm_name': 'TestDeploy01', 'vm_tag': 'TagTest1'}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.241", "vm_name": "TestDeploy01", "vm_tag": "TagTest1"}, "msg": "Unable to find the tag \"TagTest1\""}
failed: [localhost] (item={'vm_ip': '10.10.1.242', 'vm_name': 'TestDeploy02', 'vm_tag': ['TagTest2']}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.242", "vm_name": "TestDeploy02", "vm_tag": ["TagTest2"]}, "msg": "Unable to find the tag \"['TagTest2']\""}
failed: [localhost] (item={'vm_ip': '10.10.1.243', 'vm_name': 'TestDeploy03', 'vm_tag': ['TagTest1', 'TagTest2']}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.243", "vm_name": "TestDeploy03", "vm_tag": ["TagTest1", "TagTest2"]}, "msg": "Unable to find the tag \"['TagTest1'"}

Second Error

TASK [Add tags to a virtual machine] *******************************************
task path: /tmp/awx_3467_19cigu0g/project/Deploy/roles/tag/tasks/main.yml:1
failed: [localhost] (item={'vm_ip': '10.10.1.241', 'vm_name': 'TestDeploy01', 'vm_tag': 'TagTest1'}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.241", "vm_name": "TestDeploy01", "vm_tag": "TagTest1"}, "msg": "Unable to find the tag {'Test': 'TagTest1'}"}
failed: [localhost] (item={'vm_ip': '10.10.1.242', 'vm_name': 'TestDeploy02', 'vm_tag': ['TagTest2']}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.242", "vm_name": "TestDeploy02", "vm_tag": ["TagTest2"]}, "msg": "Unable to find the tag {'Test': ['TagTest2']}"}
failed: [localhost] (item={'vm_ip': '10.10.1.243', 'vm_name': 'TestDeploy03', 'vm_tag': ['TagTest1', 'TagTest2']}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.243", "vm_name": "TestDeploy03", "vm_tag": ["TagTest1", "TagTest2"]}, "msg": "Unable to find the tag {'Test': ['TagTest1', 'TagTest2']}"}

This also differs from how the documentation works for defining these on. It can find the tags but it cannot define the category or list them out below it seems.

ansibullbot commented 3 years ago

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 3 years ago

cc @Akasurde @GBrawl @Tomorrow9 @goneri @lparkes @pgbidkar @warthog9 click here for bot help

coreydeli commented 3 years ago

Further issue discovered!

Wrapping the category and variable, as shown below, fails to find the categroy that exists.

- name: Add tags to a virtual machine
  vmware_tag_manager:
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    validate_certs: no
    tag_names: ("Test:{{ item.vm_tag }}")
    object_name: "{{ item.vm_name }}"
    object_type: VirtualMachine
    state: present
  with_items: "{{ servers }}"

error output:

TASK [Add tags to a virtual machine] *******************************************
task path: /tmp/awx_3473_mpehwkwt/project/Deploy/roles/tag/tasks/main.yml:1
failed: [localhost] (item={'vm_ip': '10.10.1.241', 'vm_name': 'TestDeploy01', 'vm_tag': 'TagTest1'}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.241", "vm_name": "TestDeploy01", "vm_tag": "TagTest1"}, "msg": "Unable to find the category (\"Test"}
failed: [localhost] (item={'vm_ip': '10.10.1.242', 'vm_name': 'TestDeploy02', 'vm_tag': ['TagTest2']}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.242", "vm_name": "TestDeploy02", "vm_tag": ["TagTest2"]}, "msg": "Unable to find the category (\"Test"}
failed: [localhost] (item={'vm_ip': '10.10.1.243', 'vm_name': 'TestDeploy03', 'vm_tag': ['TagTest1', 'TagTest2']}) => {"ansible_loop_var": "item", "changed": false, "item": {"vm_ip": "10.10.1.243", "vm_name": "TestDeploy03", "vm_tag": ["TagTest1", "TagTest2"]}, "msg": "Unable to find the category (\"Test"}
coreydeli commented 3 years ago

This should also be labeled as vSphere7 instead of Cloud as well.

Akasurde commented 3 years ago

@Iwifia Thanks for reporting this. ~I am suspecting this is similar to https://github.com/ansible-collections/community.vmware/issues/579.~

coreydeli commented 3 years ago

@Akasurde no problem. I do believe that the issue you added would actually tie in with this one, though not the same, they are parts of the same issue.

Akasurde commented 3 years ago

@Iwifia Data received by vmware_tag_manager is str

 0.0s ensure_state: '"TagTest1"', <class 'str'>

 0.1s ensure_state: '"[\'TagTest2\']"', <class 'str'>

 0.1s ensure_state: '"[\'TagTest1\', \'TagTest2\']"', <class 'str'>

You need provide data as

...
    servers:
      - vm_name: TestDeploy01
        vm_ip: 10.10.1.241
        vm_tag: TagTest1
      - vm_name: TestDeploy02
        vm_ip: 10.10.1.242
        vm_tag: TagTest2
      - vm_name: TestDeploy03
        vm_ip: 10.10.1.243
        vm_tag: TagTest1
      - vm_name: TestDeploy03
        vm_ip: 10.10.1.243
        vm_tag: TagTest2
...
      - name: Assign tag to given virtual machine
        vmware_tag_manager:
          hostname: '{{ vcenter_hostname }}'
          username: '{{ vcenter_username }}'
          password: '{{ vcenter_password }}'
          validate_certs: no
          tag_names:
            - "Test:{{ item.vm_tag }}"   #   <--- enclose both category and tags in double quotes
          object_name: "{{ item.vm_name }}"
          object_type: VirtualMachine
          state: add
        delegate_to: localhost
        with_items: "{{ servers }}"

needs_info

coreydeli commented 3 years ago

So if I am reading that correct, there would be no way to create multiple tags then? This seems to differ from how I would normally add multiple items.

I have more recently found that if I do not put in the category within the playbook and let the playbook autoseledt the category matching the tag, the system allows me to put multiple tags on the system.

Akasurde commented 3 years ago

You can assign multiple tags

      - name: Assign tag to given virtual machine
        vmware_tag_manager:
          hostname: '{{ vcenter_hostname }}'
          username: '{{ vcenter_username }}'
          password: '{{ vcenter_password }}'
          validate_certs: no
          tag_names:
            - "sample_cat_0001:sample_tag_0001"
            - "sample_cat_0002:sample_tag_0002"
            - "sample_cat_0003:sample_tag_0003"
          object_name: "{{ item.vm_name }}"
          object_type: VirtualMachine
          state: add
        delegate_to: localhost
        with_items: "{{ servers }}"

But with the data structure you are using it is possible to assign a single tag at a time.

If you don't provide a category, then we use the category for the associated tag. This may lead to unwanted results.

coreydeli commented 3 years ago

That is where this is failing though. I am assigning the category in the playbook followed by a variable that would inject the tag itself based on the parameters. Since this is a server deploy its possible that I need 3 different types of servers that have a similar setup but one would differ, thus where the tags come into play.

  - name: Assign tag to given virtual machine
    vmware_tag_manager:
      hostname: '{{ vcenter_hostname }}'
      username: '{{ vcenter_username }}'
      password: '{{ vcenter_password }}'
      validate_certs: no
      tag_names:
        - "sample_cat_0001:"{{item.vmtag}}""
        - "sample_cat_0002:"{{item.vmtag}}""
        - "sample_cat_0003:"{{item.vmtag}}""
      object_name: "{{ item.vm_name }}"
      object_type: VirtualMachine
      state: add
    delegate_to: localhost
    with_items: "{{ servers }}"
Akasurde commented 3 years ago

There is no need for additional double quotes -

- name: Assign tag to given virtual machine
        vmware_tag_manager:
          hostname: '{{ vcenter_hostname }}'
          username: '{{ vcenter_username }}'
          password: '{{ vcenter_password }}'
          validate_certs: no
          tag_names:
            - "sample_cat_0001:{{item.vmtag}}" # <- Removed additional double quotes
            - "sample_cat_0002:{{item.vmtag}}" # <- Removed additional double quotes
            - "sample_cat_0003:{{item.vmtag}}" # <- Removed additional double quotes
          object_name: "{{ item.vm_name }}"
          object_type: VirtualMachine
          state: add
        delegate_to: localhost
        with_items: "{{ servers }}"
coreydeli commented 3 years ago

Let me open a new branch in my work and give it a shot. I feel like I tried this and it still failed but let me try and again and see if I am wrong on that

Akasurde commented 3 years ago

@Iwifia Could you please confirm if this works for you? Thanks.

needs_info

coreydeli commented 3 years ago

This does not work. I ran multiple tests with this method and it fails each time. I cannot predict the tags each time to add multiple sections so I am needing this to be:

- name: Add tags to a virtual machine
  vmware_tag_manager:
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    validate_certs: no
    tag_names:
      - "Ansible:{{item.vm_tag}}"
    object_name: "{{ item.vm_name }}"
    object_type: VirtualMachine
    state: present
  with_items: "{{ servers }}"

If I remove the category it will add each tag regardless of being 1 tag or 40 tags.

Akasurde commented 3 years ago

@Iwifia I think I am not following you here. Could you please provide details as to what you tried and the respective failures? Thanks.

Akasurde commented 3 years ago

What is the value {{ servers }}? is it the same as old or changed?

coreydeli commented 3 years ago

The code above is what I tried. I cannot make the code like this:

- name: Add tags to a virtual machine
  vmware_tag_manager:
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    validate_certs: no
    tag_names:
      - "Ansible:{{item.vm_tag}}"
      - "Ansible:{{item.vm_tag}}"
      - "Ansible:{{item.vm_tag}}"
    object_name: "{{ item.vm_name }}"
    object_type: VirtualMachine
    state: present
  with_items: "{{ servers }}"

Because we could be adding 1 or 10 entries, not all may have the same number of tags so its not possible for me add tag entries equal to the number needed as this needs to be flexible. Leaving the category out will allow me to add as many tags to the system as I want.

As for the {{servers}} question, servers includes three items

servers:
   - vm_name
     vm_ip
     vm_tag

So Servers has not changed in any way. We could have multiple entries in servers such as below:

servers:
   - vm_name
     vm_ip
     vm_tag
  - vm_name
     vm_ip
     vm_tag
  - vm_name
     vm_ip
     vm_tag