|
| 1 | +""" |
| 2 | +Use the Nutanix v4 API SDKs to demonstrate AI Ops report configuration creation |
| 3 | +Requires Prism Central 2024.3 or later and AOS 7.0 or later |
| 4 | +""" |
| 5 | + |
| 6 | +import urllib3 |
| 7 | +import uuid |
| 8 | + |
| 9 | +from ntnx_opsmgmt_py_client.rest import ApiException as ReportingException |
| 10 | +# there's no need to import the namespace's configuration and client modules |
| 11 | +# as that is all handled by the tme.ApiClient module |
| 12 | + |
| 13 | +# reporting-specific libraries |
| 14 | +from ntnx_opsmgmt_py_client import ReportConfig, ReportSchedule |
| 15 | +from ntnx_opsmgmt_py_client import EntityType |
| 16 | +from ntnx_opsmgmt_py_client import ( |
| 17 | + Widget, |
| 18 | + WidgetType, |
| 19 | + WidgetConfig, |
| 20 | + WidgetSize, |
| 21 | + WidgetField, |
| 22 | +) |
| 23 | +from ntnx_opsmgmt_py_client import ScheduleInterval |
| 24 | +from ntnx_opsmgmt_py_client import Row |
| 25 | +from ntnx_opsmgmt_py_client import Section |
| 26 | +from ntnx_opsmgmt_py_client import RepeatCriteria, DataCriteria |
| 27 | +from ntnx_opsmgmt_py_client import AggregateFunction |
| 28 | +from ntnx_opsmgmt_py_client.models.opsmgmt.v4.config.ReportFormat import ReportFormat |
| 29 | +from ntnx_opsmgmt_py_client.models.opsmgmt.v4.config.SortOrder import SortOrder |
| 30 | +from ntnx_opsmgmt_py_client.models.opsmgmt.v4.config.NotificationPolicy import ( |
| 31 | + NotificationPolicy, |
| 32 | +) |
| 33 | +from ntnx_opsmgmt_py_client.models.opsmgmt.v4.config.Recipient import Recipient |
| 34 | + |
| 35 | +# utilities functions and classes e.g. environment management |
| 36 | +from tme.utils import Utils |
| 37 | + |
| 38 | +# functions and classes for Prism Central connection management |
| 39 | +from tme.apiclient import ApiClient |
| 40 | + |
| 41 | + |
| 42 | +def main(): |
| 43 | + """ |
| 44 | + suppress warnings about insecure connections |
| 45 | + please consider the security implications before |
| 46 | + doing this in a production environment |
| 47 | + """ |
| 48 | + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) |
| 49 | + |
| 50 | + utils = Utils() |
| 51 | + config = utils.get_environment() |
| 52 | + |
| 53 | + default_start = "2025-01-01T00:00:00Z" |
| 54 | + default_end = "2025-01-02T00:00:00Z" |
| 55 | + |
| 56 | + # prompt for report start and end time |
| 57 | + # include sensible defaults |
| 58 | + print("You will now be prompted for the report start and end times.") |
| 59 | + print("Press enter at each prompt if you want to accept the defaults.") |
| 60 | + print(f"Default start time: {default_start}") |
| 61 | + print(f"Default end time: {default_end}") |
| 62 | + |
| 63 | + start_time = input("Enter the report start time in ISO-8601 format: ") |
| 64 | + if not start_time: |
| 65 | + start_time = default_start |
| 66 | + print("Default start time used ...") |
| 67 | + end_time = input("Enter the report end time in ISO-8601 format: ") |
| 68 | + if not end_time: |
| 69 | + end_time = default_end |
| 70 | + print("Default end time used ...") |
| 71 | + |
| 72 | + try: |
| 73 | + # setup the instance of our ApiClient class |
| 74 | + # this handles all Prism Central connections and provides |
| 75 | + # access to the chosen namespace's APIs, when required |
| 76 | + # this demo requires the OpsMgmt namespace i.e. ntnx_opsmgmt_py_client |
| 77 | + reporting_client = ApiClient(config=config, sdk_module="ntnx_opsmgmt_py_client") |
| 78 | + |
| 79 | + # with the client setup, specify the Nutanix v4 API we want to use |
| 80 | + # this section requires use of the ReportConfigApi |
| 81 | + reporting_instance = reporting_client.imported_module.api.ReportConfigApi( |
| 82 | + api_client=reporting_client.api_client |
| 83 | + ) |
| 84 | + |
| 85 | + input( |
| 86 | + "\nThis demo uses the Nutanix v4 API `opsmgmt` namespace's \ |
| 87 | +reporting APIs to create an AIOps report configuration. \ |
| 88 | +The new report configuration can be used to run a manual or scheduled \ |
| 89 | +report. You will now be prompted for some report-specific details.\n\nPress ENTER to continue." |
| 90 | + ) |
| 91 | + |
| 92 | + # get a list of existing report configurations |
| 93 | + print("Building list of existing report configurations ...") |
| 94 | + |
| 95 | + config_list = reporting_instance.list_report_configs(async_req=False) |
| 96 | + |
| 97 | + if config_list.data: |
| 98 | + print(f"{len(config_list.data)} report configurations found.") |
| 99 | + else: |
| 100 | + print("No report configurations found.") |
| 101 | + |
| 102 | + recipient_name = input("Enter the report recipient name: ") |
| 103 | + recipient_email = input("Enter the report recipient email address: ") |
| 104 | + |
| 105 | + # dates must be ISO-8601 compliant |
| 106 | + report_config_name = f"sdk_chrisr_config_{str(uuid.uuid4())}" |
| 107 | + |
| 108 | + print("Report configuration will be as follows:") |
| 109 | + print(f" Configuration name: {report_config_name}") |
| 110 | + print(f" Start time: {start_time}") |
| 111 | + print(f" End time: {end_time}") |
| 112 | + print(" Report interval: Yearly") |
| 113 | + |
| 114 | + # report format: PDF or CSV |
| 115 | + PDF = ReportFormat.PDF |
| 116 | + # DAILY, WEEKLY, MONTHLY, YEARLY |
| 117 | + YEARLY = ScheduleInterval.YEARLY |
| 118 | + |
| 119 | + new_config = ReportConfig( |
| 120 | + name=f"{report_config_name}", |
| 121 | + description="report configuration created from v4 python SDK", |
| 122 | + schedule=ReportSchedule( |
| 123 | + # internal as above i.e. daily/weekly/monthly/yearly |
| 124 | + schedule_interval=YEARLY, |
| 125 | + # how often the report should run |
| 126 | + frequency=1, |
| 127 | + # required: when the schedule should end |
| 128 | + start_time=start_time, |
| 129 | + # optional: the last time the report should run |
| 130 | + end_time=end_time, |
| 131 | + ), |
| 132 | + sections=[ |
| 133 | + Section( |
| 134 | + name="First Section", |
| 135 | + description="This is the first section in the report", |
| 136 | + rows=[ |
| 137 | + Row( |
| 138 | + widgets=[ |
| 139 | + Widget( |
| 140 | + widget_info=WidgetConfig( |
| 141 | + fields=[ |
| 142 | + WidgetField( |
| 143 | + label="CPU usage", |
| 144 | + name="hypervisor_cpu_usage_ppm", |
| 145 | + aggregate_function=AggregateFunction.AVG, |
| 146 | + ) |
| 147 | + ], |
| 148 | + entity_type=EntityType.VM, |
| 149 | + heading="VM CPU Usage (%)", |
| 150 | + size=WidgetSize.FULLSPAN, |
| 151 | + type=WidgetType.LINE_CHART, |
| 152 | + data_criteria=DataCriteria( |
| 153 | + sort_column="hypervisor_cpu_usage_ppm", |
| 154 | + sort_order=SortOrder.ASCENDING, |
| 155 | + ), |
| 156 | + ) |
| 157 | + ) |
| 158 | + ] |
| 159 | + ) |
| 160 | + ], |
| 161 | + repeat_criteria=RepeatCriteria(entity_type=EntityType.VM), |
| 162 | + ) |
| 163 | + ], |
| 164 | + supported_formats=[PDF], |
| 165 | + timezone="UTC", |
| 166 | + notification_policy=NotificationPolicy( |
| 167 | + recipient_formats=[PDF], |
| 168 | + email_body="Nutanix Prism Central Report; this report \ |
| 169 | +was generated from a report created using the Nutanix \ |
| 170 | +v4 Python SDK.", |
| 171 | + email_subject="Nutanix Prism Central Report", |
| 172 | + recipients=[ |
| 173 | + Recipient( |
| 174 | + email_address=f"{recipient_email}", |
| 175 | + recipient_name=f"{recipient_name}", |
| 176 | + ) |
| 177 | + ], |
| 178 | + ), |
| 179 | + default_section_entity_type=EntityType.VM, |
| 180 | + ) |
| 181 | + |
| 182 | + print("Submitting report config creation request ...") |
| 183 | + |
| 184 | + create_new_config = reporting_instance.create_report_config( |
| 185 | + async_req=False, body=new_config |
| 186 | + ) |
| 187 | + |
| 188 | + reporting_ext_id = create_new_config.data.ext_id |
| 189 | + utils.monitor_task( |
| 190 | + task_ext_id=reporting_ext_id, |
| 191 | + prefix="", |
| 192 | + task_name="Report config creation", |
| 193 | + pc_ip=config.pc_ip, |
| 194 | + username=config.pc_username, |
| 195 | + password=config.pc_password, |
| 196 | + poll_timeout=1, |
| 197 | + ) |
| 198 | + |
| 199 | + print("Report config created.") |
| 200 | + |
| 201 | + except ReportingException as reporting_exception: |
| 202 | + print( |
| 203 | + f"Unable to authenticate using the supplied credentials. \ |
| 204 | +Check your username and/or password, then try again. \ |
| 205 | +Exception details: {reporting_exception}" |
| 206 | + ) |
| 207 | + |
| 208 | + |
| 209 | +if __name__ == "__main__": |
| 210 | + main() |
0 commit comments