Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add value key to return data #359

Closed

Conversation

valkiriaaquatica
Copy link

SUMMARY

When receiving objetct that contain a dictionary with display_value, link and value, just the display_value was returned, now it returns also the value that is the sys_id.

ISSUE TYPE
  • Feature Pull Request
COMPONENT NAME

now.py

ADDITIONAL INFORMATION

In relation with this issue #317 , with the actual plugin inventory it just returns the display_value of objects, with the change the value (the sys_id) is also returned.
This has been usefull to me when working with server inventories I wanted to get the email associated from the user (columns assigned_to and owneed_by) but just the name was returned so I couldn't resolve it to email (excepto for using LDAP modules), so with the change now the sys_id of the Persona (object) is returned so I can use the api_info module fetching with the sys_id and get the data like in my case the emaill

Before with one example

    "_meta": {
        "hostvars": {
            "Poller": {
                "assigned_to": "Mathuew",
                "owned_by": "Steven",
                "u_server_id": "i-123456"
            }
        }
    },
plugin: servicenow.itsm.now
table: cmdb_ci_server
sysparm_query: 'name=Poller'
columns: assigned_to, owned_by, u_server_id

AFTER

    "_meta": {
        "hostvars": {
            "Poller": {
                "assigned_to": "Mathuew",
                "assigned_to_value": "123456789101123145",
                "owned_by": "Steven",
                "owned_by_value": "987654321",
                "u_server_id": "i-123456"
            }
        }
    },

Inventory adding the show_values argument

plugin: servicenow.itsm.now
table: cmdb_ci_server
sysparm_query: 'name=Poller'
columns: assigned_to, owned_by, u_server_id
show_values: true

When receiving objetct that contain a dictionary with display_value, link and value, just the display_value was returned, now it returns also the value that is the sys_id
Copy link

@valkiriaaquatica
Copy link
Author

Hi,
I'am checking the CI errors and there is an error in black format in test_service_catalog_info.py which is not in my PR, shoudl i fix it?
The other error in unit _"AttributeError: 'InventoryModule' object has no attribute 'load_name'" which in a first seen I do no know how to fix it

Thanks in advance for the help

Copy link

@tupyy
Copy link
Contributor

tupyy commented May 21, 2024

Hi, I'am checking the CI errors and there is an error in black format in test_service_catalog_info.py which is not in my PR, shoudl i fix it?

Thanks in advance for the help

No. the lint is broken. it's checks out the main branch just lint your code with the black version in the workflow.

@tupyy tupyy self-requested a review May 21, 2024 15:01
@tupyy tupyy self-assigned this May 21, 2024
@@ -364,7 +369,7 @@ def construct_sysparm_query(query, is_encoded_query):
def fetch_records(table_client, table, query, fields=None, is_encoded_query=False):
snow_query = dict(
# Make references and choice fields human-readable
sysparm_display_value=True,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the value of show_values to set this parameter. You risk breaking the inventories of other users.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default it needs to be True. Change it to all only if show_values is true

@@ -426,6 +431,13 @@ def add_host(self, record, name_source):
raise AnsibleParserError(msg.format(name_source))

inventory_hostname = record[name_source]
if isinstance(inventory_hostname, dict):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this. You already set default: false for display_value. Even if the user does not explicitly use display_value, it will always be present in the module.

sub_value = value.get(sub_key)
if sub_value and sub_value != main_value:
self.inventory.set_variable(
host, f"{k}_{sub_key}", sub_value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use format. We need to be py2.8 compatible.

@@ -50,21 +50,21 @@ def test_no_query(self, table_client):
now.fetch_records(table_client, "table_name", None)

table_client.list_records.assert_called_once_with(
"table_name", dict(sysparm_display_value=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the tests need to take into account the new option display_value and not hard coded value for sysparm_display_value

)

def test_query(self, table_client):
now.fetch_records(table_client, "table_name", [dict(my="!= value")])

table_client.list_records.assert_called_once_with(
"table_name", dict(sysparm_display_value=True, sysparm_query="my!=value")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

)

def test_no_query_with_fields(self, table_client):
now.fetch_records(table_client, "table_name", None, fields=["a", "b", "c"])

table_client.list_records.assert_called_once_with(
"table_name", dict(sysparm_display_value=True, sysparm_fields="a,b,c")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

@@ -442,8 +454,23 @@ def set_hostvars(self, host, record, columns):
"Invalid column names: {0}.".format(", ".join(missing))
)

show_values = self.get_option("show_values")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please pass show_values to set_hostvars instead of looking into the module.

I will advise passing a default value like def set_hostvars(self, host, record, columns, show_values=False)

for k in columns:
self.inventory.set_variable(host, k.replace(".", "_"), record[k])
value = record.get(k)
if isinstance(value, dict):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if the value is not a dict? Where do you set the value to host_var if value is str?

self.inventory.set_variable(host, k.replace(".", "_"), record[k])
value = record.get(k)
if isinstance(value, dict):
main_value = value.get("display_value") or value.get("value") or value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either use display_value or value but like this is dangerous. You imply that you can use the whole dict if display_value or value are not present but I don't think you need this.

The problem with this code is that you hardcoded sysparam_display_value to all, which means you'll always get display_value and value therefore the first and second or are useless.
Also, in the if block the for is useless because, as you'll always have a value for display_value, you only need the value value.
Am I right or I'm missing something here?

Copy link
Contributor

@tupyy tupyy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thank you for your work. We do appreciate the effort you put into this.

We really need this option to change sysparm_display_value but I think we need to make it more flexible like show_values has 3 possible values: true, false, all (basically maps the sysparm_display_value).
In this way, the user can choose what value should be added to the inventory.

Another thing, you need tests: unit tests and integration. Also, you need to document your change with a fragment.

@mhjacks WDYT

@valkiriaaquatica valkiriaaquatica closed this by deleting the head repository Dec 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants