#Bizarre behavior with na_ontap_user_role module

1 messages · Page 1 of 1 (latest)

jagged geyser
#

I'm attempting to manage user roles with the user_role module, but seeing some really weird behavior.

Given the following variable:

user_roles:
  - name: mj-test
    vserver: ralsan-dev
    cmddir:
      - path: DEFAULT
        access: none
      - path: system health subsystem modify
        access: readonly
      - path: system health subsystem show
        access: readonly
      - path: qos workload modify
        access: readonly
      - path: qos workload delete
        access: readonly
      - path: qos workload show
        access: readonly

I get the following error:

{'message': 'duplicate entry', 'code': '1', 'target': 'path'}
#

Now, if I comment out the delete / show paths things start to work...kind of:

user_roles:
  - name: mj-test
    vserver: ralsan-dev
    cmddir:
      - path: DEFAULT
        access: none
      - path: system health subsystem modify
        access: readonly
      # - path: system health subsystem show
      #   access: readonly
      - path: qos workload modify
        access: readonly
      # - path: qos workload delete
      #   access: readonly
      # - path: qos workload show
      #   access: readonly
#

Output:

PLAY [Configure NetApp OnTap cluster play] ****************************************************************************************************************************************************************************************************

TASK [ontap_cluster_config : Set fact for netapp login parameters] ****************************************************************************************************************************************************************************
ok: [localhost]

TASK [ontap_cluster_config : Configure user roles] ********************************************************************************************************************************************************************************************
changed: [localhost] => (item={'name': 'mj-test', 'vserver': 'ralsan-dev', 'cmddir': [{'path': 'DEFAULT', 'access': 'none'}, {'path': 'system health subsystem modify', 'access': 'readonly'}, {'path': 'qos workload modify', 'access': 'readonly'}]})
[WARNING]: Create operation also affected additional related commands: [{'path': 'qos workload delete', 'access': 'readonly'}, {'path': 'qos workload modify', 'access': 'readonly'}, {'path': 'qos workload show', 'access': 'readonly'},
{'path': 'system health subsystem modify', 'access': 'readonly'}, {'path': 'system health subsystem show', 'access': 'readonly'}]

PLAY RECAP ************************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0      
#

Querying the API shows that i have the roles I want...YAY!:

{
  "records": [
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "DEFAULT",
      "access": "none"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "qos workload delete",
      "access": "readonly"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "qos workload modify",
      "access": "readonly"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "qos workload show",
      "access": "readonly"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "system health subsystem modify",
      "access": "readonly"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "system health subsystem show",
      "access": "readonly"
    }
  ],
  "num_records": 6
}
#

But when I run the task again, things start getting weird. The Ansible output shows changed and it shouldn't:

PLAY [Configure NetApp OnTap cluster play] ****************************************************************************************************************************************************************************************************

TASK [ontap_cluster_config : Set fact for netapp login parameters] ****************************************************************************************************************************************************************************
ok: [localhost]

TASK [ontap_cluster_config : Configure user roles] ********************************************************************************************************************************************************************************************
changed: [localhost] => (item={'name': 'mj-test', 'vserver': 'ralsan-dev', 'cmddir': [{'path': 'DEFAULT', 'access': 'none'}, {'path': 'system health subsystem modify', 'access': 'readonly'}, {'path': 'qos workload modify', 'access': 'readonly'}]})
[WARNING]: modify is required, desired: [{'path': 'DEFAULT', 'access': 'none'}, {'path': 'system health subsystem modify', 'access': 'readonly'}, {'path': 'qos workload modify', 'access': 'readonly'}] and new current: []

PLAY RECAP ************************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

And when I query the API, things have disappeared:

{
  "records": [
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "DEFAULT",
      "access": "none"
    }
  ],
  "num_records": 1
}
#

Running the task one more time:

PLAY [Configure NetApp OnTap cluster play] ****************************************************************************************************************************************************************************************************

TASK [ontap_cluster_config : Set fact for netapp login parameters] ****************************************************************************************************************************************************************************
ok: [localhost]

TASK [ontap_cluster_config : Configure user roles] ********************************************************************************************************************************************************************************************
changed: [localhost] => (item={'name': 'mj-test', 'vserver': 'ralsan-dev', 'cmddir': [{'path': 'DEFAULT', 'access': 'none'}, {'path': 'system health subsystem modify', 'access': 'readonly'}, {'path': 'qos workload modify', 'access': 'readonly'}]})
[WARNING]: modify is required, desired: [{'path': 'DEFAULT', 'access': 'none'}, {'path': 'system health subsystem modify', 'access': 'readonly'}, {'path': 'qos workload modify', 'access': 'readonly'}] and new current: [{'path': 'qos
workload delete', 'access': 'readonly'}, {'path': 'qos workload modify', 'access': 'readonly'}, {'path': 'qos workload show', 'access': 'readonly'}, {'path': 'system health subsystem modify', 'access': 'readonly'}, {'path': 'system health
subsystem show', 'access': 'readonly'}]

PLAY RECAP ************************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
#

And querying the API, my roles are back:

{
  "records": [
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "DEFAULT",
      "access": "none"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "qos workload delete",
      "access": "readonly"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "qos workload modify",
      "access": "readonly"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "qos workload show",
      "access": "readonly"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "system health subsystem modify",
      "access": "readonly"
    },
    {
      "vserver": "ralsan-dev",
      "role": "mj-test",
      "cmddirname": "system health subsystem show",
      "access": "readonly"
    }
  ],
  "num_records": 6
}

So there are two issues as I see it:

  • I can't define modify/delete/show together (leaving out the modify gets you the same error in the first example)
  • There is no idempotency when creating
lone hinge
jagged geyser
#

@lone hinge I'm actually using the na_ontap_user_role module which doesn't seem to respect the feature_flags parameter. Do I need to convert my task to use then ontap_rest module for the purpose of this test or is there a way to get an api trace from the non ontap_rest modules?

lone hinge
#

Either you can use the parameter inside the task like below:

    - name: Create user role - REST
      netapp.ontap.na_ontap_user_role:
        state: present
        name: mj-test
        privileges:
          - path: DEFAULT
            access: none
          - path: system health subsystem modify
            access: readonly
          - path: system health subsystem show
            access: readonly
          - path: qos workload modify
            access: readonly
          - path: qos workload delete
            access: readonly
          - path: qos workload show
            access: readonly
        feature_flags:
          trace_apis: true
      register: info

or under module_defaults like below:

  module_defaults:
    group/netapp.ontap.netapp_ontap:
      hostname: '{{ admin_ip }}'
      username: '{{ admin_username }}'
      password: '{{ admin_password }}'
      https: true
      validate_certs: false
      feature_flags:
        trace_apis: true
jagged geyser
#

@lone hinge Log was too long to paste here, but I'm attching it (with a redacted cluster name):

lone hinge
jagged geyser
#

@lone hinge Will do. I'll get back to you as soon as I can early next week

jagged geyser
lone hinge
pliant mountain
#

I posted about this a while ago. https://discord.com/channels/855068651522490400/1241972744971747400

It seems to be related to entries where the CLI warns "This operation will also affect the following commands".

With the help of some others we worked out if you shorten the path to the parent CLI command (such as just "system health" instead of individual commands underneath) then the error doesn't appear.

I've worked around it for now by using the "netapp.ontap.na_ontap_ssh_command" module and passing each command. It took me a while to get the quoting of the cmddirname just right and also had to add "set -privilege diagnostic; " before each command as some commands are only visible in diag mode. But it seems to work. The issue now is parsing the stdout to ensure I capture real errors correctly.

jagged geyser
#

@lone hinge My role did not exist because of the errors I was receiving trying to get it added as i mentioned previously. I added it again with the max number of roles before it would fail. I'll attach the command output again.

#

@pliant mountain do you have a detailed example of what you did to work around this? Is there already a formal request to getting this working via the API or should I work on submitting one?

pliant mountain
#

@jagged geyser this is the task I ended up using. I was trying to create a user for ONTAP Tools for VMware vSphere and don't want to give it the admin role, so was creating a specific role with the permissions required for OTV.

- name: Create OTV ONTAP Role netapp.ontap.na_ontap_ssh_command: <<: *clusterlogin command: "set -privilege diagnostic; security login role create -role {{ vsc_ontap_role }} -access {{ item.access }} -cmddirname {{ item.path }}" privilege: diagnostic accept_unknown_host_keys: true with_items: "{{ vsc_role_permissions }}" when: - vsc_ontap_role | default (false) - vsc_role_permissions | default (false) - add_cluster_to_otv | default(false) tags: otv_role

The {{ vsc_role_permissions }} variable looks like this:

vsc_role_permissions: - { path: '"DEFAULT"', access: none } - { path: '"cluster application-record create"', access: all } - { path: '"cluster application-record delete"', access: all } - { path: '"cluster application-record modify"', access: all } - { path: '"cluster application-record show"', access: all } - { path: '"cluster identity modify"', access: all } - { path: '"cluster identity show"', access: all } - { path: '"cluster modify"', access: all } - { path: '"cluster peer show"', access: all } - { path: '"cluster show"', access: all } - { path: '"job"', access: all } - { path: '"lun comment"', access: all } - { path: '"lun create"', access: all } - { path: '"lun delete"', access: all } - { path: '"lun geometry"', access: readonly } - { path: '"lun igroup add"', access: all }

And so on ...

I really wish there was an API to import the OTV Role json file that you can via System Manager, and you could just call that API and specify the json file. I did look but couldn't find one. Perhaps there is one somewhere.

jagged geyser
#

Thanks, Chris. @lone hinge Anything else from your side?