PyPANRestV2 2.1.3__tar.gz → 2.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyPANRestV2
3
- Version: 2.1.3
3
+ Version: 2.1.4
4
4
  Summary: Python tools for interacting with Palo Alto Networks REST API.
5
5
  License: MIT
6
6
  Author: Mark Rzepa
@@ -224,25 +224,13 @@ class TemplateStacks(PanoramaTab):
224
224
  ``devices.entry[*].variable.entry``.
225
225
  """
226
226
 
227
- # Ensure we have stack-level variable definitions
228
- if not self.variable or 'entry' not in self.variable:
229
- raise ValueError(
230
- f"No stack-level variables defined on template stack {self.name}; "
231
- f"cannot infer type for {variable_name!r}."
232
- )
233
-
234
- # Find the variable definition to determine its type key
235
- var_type_key: Optional[str] = None
236
- for var_def in self.variable['entry']:
237
- if var_def.get('@name') == variable_name and isinstance(var_def.get('type'), dict):
238
- if var_def['type']:
239
- var_type_key = next(iter(var_def['type']))
240
- break
227
+ # Infer the variable type (from stack-level block or existing devices)
228
+ var_type_key = self._infer_variable_type(variable_name)
241
229
 
242
230
  if not var_type_key:
243
231
  raise ValueError(
244
- f"Variable definition {variable_name!r} not found on template stack {self.name}; "
245
- "define it first on the outer 'variable' block."
232
+ f"Variable definition {variable_name!r} not found for template stack {self.name}; "
233
+ "define it at the stack level or ensure another device has it assigned."
246
234
  )
247
235
 
248
236
  # Optionally create the device entry if it does not exist yet
@@ -257,6 +245,37 @@ class TemplateStacks(PanoramaTab):
257
245
  # Delegate to the lower-level helper that knows about types
258
246
  self.update_device_variable(device_serial, variable_name, var_type_key, value)
259
247
 
248
+ def _infer_variable_type(self, variable_name: str) -> Optional[str]:
249
+ """Return the variable type key for a given variable name, if known.
250
+
251
+ The lookup order is:
252
+
253
+ 1. Stack-level ``variable.entry`` definitions.
254
+ 2. Existing device-level ``devices.entry[*].variable.entry`` blocks.
255
+ """
256
+
257
+ # 1) Look at stack-level variable definitions, if present
258
+ if self.variable and isinstance(self.variable, dict) and 'entry' in self.variable:
259
+ for var_def in self.variable.get('entry', []):
260
+ if var_def.get('@name') == variable_name and isinstance(var_def.get('type'), dict):
261
+ if var_def['type']:
262
+ return next(iter(var_def['type']))
263
+
264
+ # 2) Fallback: inspect variables from existing devices in the stack
265
+ if self.devices and isinstance(self.devices, dict):
266
+ for dev in self.devices.get('entry', []):
267
+ if not isinstance(dev, dict):
268
+ continue
269
+ dev_var = dev.get('variable')
270
+ if not isinstance(dev_var, dict):
271
+ continue
272
+ for var in dev_var.get('entry', []):
273
+ if var.get('@name') == variable_name and isinstance(var.get('type'), dict):
274
+ if var['type']:
275
+ return next(iter(var['type']))
276
+
277
+ return None
278
+
260
279
  def update_variable(self, name: str, variable_type: str, variable_value: str):
261
280
  if variable_type in self.variable_types:
262
281
  variable_entry = {'@name': name, 'type': {variable_type: variable_value}}
@@ -3,7 +3,7 @@ requires = ["poetry-core>=1.0.0"]
3
3
  build-backend = "poetry.core.masonry.api"
4
4
  [tool.poetry]
5
5
  name = "PyPANRestV2"
6
- version = "2.1.3"
6
+ version = "2.1.4"
7
7
  description = "Python tools for interacting with Palo Alto Networks REST API."
8
8
  authors = [
9
9
  "Mark Rzepa <mark@rzepa.com>"
File without changes