diff --git a/ansible_collections/arista/cvp/docs/modules/cv_device_v3.rst.md b/ansible_collections/arista/cvp/docs/modules/cv_device_v3.rst.md
index 34cad8002..9df45b345 100644
--- a/ansible_collections/arista/cvp/docs/modules/cv_device_v3.rst.md
+++ b/ansible_collections/arista/cvp/docs/modules/cv_device_v3.rst.md
@@ -36,7 +36,7 @@ The following options may be specified for this module:
loose |
|
- Set how configlets are attached/detached on device. If set to strict all configlets not listed in your vars are detached.
+ Set how configlets are attached/detached on device. If set to strict all configlets and image bundles not listed in your vars are detached.
|
@@ -47,7 +47,7 @@ The following options may be specified for this module:
|
|
- List of devices with their container and configlets information
+ List of devices with their container, configlet and image bundle information
|
@@ -91,6 +91,7 @@ The following options may be specified for this module:
parentContainerName: ANSIBLE
configlets:
- 'CV-EOS-ANSIBLE01'
+ imageBundle: leaf_image_bundle
tasks:
- name: "Configure devices on {{inventory_hostname}}"
arista.cvp.cv_device_v3:
diff --git a/ansible_collections/arista/cvp/examples/README.md b/ansible_collections/arista/cvp/examples/README.md
deleted file mode 100644
index e69de29bb..000000000
diff --git a/ansible_collections/arista/cvp/examples/cv_image_v3/assign-image-bundle-to-device.yaml b/ansible_collections/arista/cvp/examples/cv_image_v3/assign-image-bundle-to-device.yaml
new file mode 100644
index 000000000..ea08bbeb4
--- /dev/null
+++ b/ansible_collections/arista/cvp/examples/cv_image_v3/assign-image-bundle-to-device.yaml
@@ -0,0 +1,21 @@
+---
+- name: Device Image Management in Cloudvision
+ hosts: cv_server
+ connection: local
+ gather_facts: false
+ collections:
+ - arista.cvp
+ vars:
+ CVP_DEVICES:
+ - serialNumber: JPE504a004ea054
+ parentContainerName: L2_Leaf
+ configlets:
+ - 'AVD_Ipmi3'
+ imageBundle: leaf_bundle
+ tasks:
+ - name: "Configure devices on {{inventory_hostname}}"
+ arista.cvp.cv_device_v3:
+ devices: '{{CVP_DEVICES}}'
+ state: present
+ search_key: serialNumber
+ apply_mode: strict
diff --git a/ansible_collections/arista/cvp/examples/cv_image_v3/remove-image-bundle-to-device.yaml b/ansible_collections/arista/cvp/examples/cv_image_v3/remove-image-bundle-to-device.yaml
new file mode 100644
index 000000000..c4a96c4d9
--- /dev/null
+++ b/ansible_collections/arista/cvp/examples/cv_image_v3/remove-image-bundle-to-device.yaml
@@ -0,0 +1,20 @@
+---
+- name: Device Image Management in Cloudvision
+ hosts: cv_server
+ connection: local
+ gather_facts: false
+ collections:
+ - arista.cvp
+ vars:
+ CVP_DEVICES:
+ - serialNumber: JPE504a004ea054
+ parentContainerName: L2_Leaf
+ configlets:
+ - 'AVD_Ipmi3'
+ tasks:
+ - name: "Configure devices on {{inventory_hostname}}"
+ arista.cvp.cv_device_v3:
+ devices: '{{CVP_DEVICES}}'
+ state: present
+ search_key: serialNumber
+ apply_mode: strict
diff --git a/ansible_collections/arista/cvp/plugins/module_utils/device_tools.py b/ansible_collections/arista/cvp/plugins/module_utils/device_tools.py
index 0f09598cf..8aedff2d2 100644
--- a/ansible_collections/arista/cvp/plugins/module_utils/device_tools.py
+++ b/ansible_collections/arista/cvp/plugins/module_utils/device_tools.py
@@ -62,10 +62,11 @@ def __init__(self, data: dict):
self.__serial = self.__data.get(Api.device.SERIAL)
self.__mgmtip = self.__data.get(Api.device.MGMTIP)
self.__container = self.__data[Api.generic.PARENT_CONTAINER_NAME]
- # self.__image_bundle = [] # noqa # pylint: disable=unused-variable
self.__current_parent_container_id = None
- # if Api.device.IMAGE_BUNDLE in self.__data:
- # self.__image_bundle = data[Api.device.IMAGE_BUNDLE]
+ self.__image_bundle = self.__data.get(Api.device.BUNDLE)
+
+ if Api.device.BUNDLE in self.__data:
+ self.__image_bundle = data[Api.device.BUNDLE]
if Api.device.SYSMAC in data:
self.__sysmac = data[Api.device.SYSMAC]
if Api.device.SERIAL in data:
@@ -225,6 +226,18 @@ def parent_container_id(self):
"""
return self.__current_parent_container_id
+ @property
+ def image_bundle(self):
+ """
+ image_bundle Getter for image bundle info
+
+ Returns
+ -------
+ dict
+ Dict with name, ID and type of bundle
+ """
+ return self.__image_bundle
+
@parent_container_id.setter
def parent_container_id(self, id):
"""
@@ -263,6 +276,8 @@ def info(self):
else:
res[Api.generic.CONFIGLETS] = []
# res[Api.generic.PARENT_CONTAINER_ID] = self.__current_parent_container_id
+ if Api.generic.IMAGE_BUNDLE_NAME in self.__data:
+ res[Api.generic.IMAGE_BUNDLE_NAME] = self.__data[Api.generic.IMAGE_BUNDLE_NAME]
return res
@@ -420,6 +435,12 @@ def __get_device(self, search_value: str, search_by: str = Api.device.HOSTNAME):
cv_data = self.__cv_client.api.get_device_by_mac(device_mac=search_value)
elif search_by == Api.device.SERIAL:
cv_data = self.__cv_client.api.get_device_by_serial(device_serial=search_value)
+
+ if cv_data is not None and len(cv_data) > 0:
+ cv_data[Api.device.BUNDLE] = self.__cv_client.api.get_device_image_info(cv_data['key'])
+ else:
+ cv_data[Api.device.BUNDLE] = None
+
MODULE_LOGGER.debug('Got following data for %s using %s: %s', str(search_value), str(search_by), str(cv_data))
return cv_data
@@ -558,6 +579,8 @@ def __state_present(self, user_inventory: DeviceInventory, apply_mode: str = Mod
cv_move = CvManagerResult(builder_name=DeviceResponseFields.DEVICE_MOVED)
cv_configlets_attach = CvManagerResult(builder_name=DeviceResponseFields.CONFIGLET_ATTACHED)
cv_configlets_detach = CvManagerResult(builder_name=DeviceResponseFields.CONFIGLET_DETACHED)
+ cv_bundle_attach = CvManagerResult(builder_name=DeviceResponseFields.BUNDLE_ATTACHED)
+ cv_bundle_detach = CvManagerResult(builder_name=DeviceResponseFields.BUNDLE_DETACHED)
response = CvAnsibleResponse()
# Check if all devices are present on CV
@@ -584,6 +607,12 @@ def __state_present(self, user_inventory: DeviceInventory, apply_mode: str = Mod
for update in action_result:
cv_configlets_attach.add_change(change=update)
+ # Apply image bundle as set in inventory
+ action_result = self.apply_bundle(user_inventory=user_inventory)
+ if action_result is not None:
+ for update in action_result:
+ cv_bundle_attach.add_change(change=update)
+
# Remove configlets configured on CVP and if module runs in strict mode
if apply_mode == ModuleOptionValues.APPLY_MODE_STRICT:
action_result = self.detach_configlets(
@@ -592,6 +621,12 @@ def __state_present(self, user_inventory: DeviceInventory, apply_mode: str = Mod
for update in action_result:
cv_configlets_detach.add_change(change=update)
+ action_result = self.detach_bundle(
+ user_inventory=user_inventory)
+ if action_result is not None:
+ for update in action_result:
+ cv_bundle_detach.add_change(change=update)
+
# Generate result output
response.add_manager(cv_move)
MODULE_LOGGER.debug('AnsibleResponse updated, new content with cv_move: %s', str(response.content))
@@ -599,8 +634,12 @@ def __state_present(self, user_inventory: DeviceInventory, apply_mode: str = Mod
MODULE_LOGGER.debug('AnsibleResponse updated, new content with cv_deploy: %s', str(response.content))
response.add_manager(cv_configlets_attach)
MODULE_LOGGER.debug('AnsibleResponse updated, new content with cv_configlets_attach: %s', str(response.content))
+ response.add_manager(cv_bundle_attach)
+ MODULE_LOGGER.debug('AnsibleResponse updated, new content with cv_bundle_attach: %s', str(response.content))
response.add_manager(cv_configlets_detach)
MODULE_LOGGER.debug('AnsibleResponse updated, new content with cv_configlets_detach: %s', str(response.content))
+ response.add_manager(cv_bundle_detach)
+ MODULE_LOGGER.debug('AnsibleResponse updated, new content with cv_bundle_detach: %s', str(response.content))
return response
@@ -887,6 +926,37 @@ def get_device_container(self, device_lookup: str):
}
return None
+ def get_device_image_bundle(self, device_lookup: str):
+ """
+ get_device_image_bundle Retrieve image bundle attached to the device
+
+ Parameters
+ ----------
+ device_lookup : str
+ Device name to look for
+
+ Returns
+ -------
+ dict
+ A dict with key and name
+ """
+ cv_data = self.get_device_facts(device_lookup=device_lookup)
+ MODULE_LOGGER.debug('cv_data lookup returned: %s', str(cv_data))
+ if cv_data is not None and Api.generic.IMAGE_BUNDLE_NAME in cv_data:
+ if cv_data[Api.generic.IMAGE_BUNDLE_NAME][Api.image.NAME] is None:
+ return {
+ Api.generic.IMAGE_BUNDLE_NAME: None,
+ Api.image.ID: None,
+ Api.image.TYPE: None
+ }
+ else:
+ return {
+ Api.generic.IMAGE_BUNDLE_NAME: cv_data['imageBundle'][Api.image.NAME],
+ Api.image.ID: cv_data['imageBundle'][Api.image.ID],
+ Api.image.TYPE: cv_data['imageBundle']['imageBundleMapper'][cv_data['imageBundle'][Api.image.ID]][Api.image.TYPE]
+ }
+ return None
+
def get_container_info(self, container_name: str):
"""
get_container_info Retrieve container information from Cloudvision
@@ -1159,6 +1229,161 @@ def move_device(self, user_inventory: DeviceInventory):
results.append(result_data)
return results
+ def apply_bundle(self, user_inventory: DeviceInventory):
+ """
+ apply_bundle - apply an image bundle to a device
+
+ Execute the API calls to attach an image bundle to a device.
+ Note that only 1 image bundle can be attached to a device.
+
+ If an image bundle is already attached to the device (type: netelement)
+ the new image bundle will replace the old.
+
+ Our behaviour is as follows;
+ * Bundle already attached to the device - update if different, skip if the same
+ * Bundle inherited from container (type: container) - attach bundle to device, regardless
+ of whether or not it is the same
+
+ Parameters
+ ----------
+ user_inventory : DeviceInventory
+ Ansible inventory to configure on Cloudvision
+
+ Returns
+ -------
+ list
+ List of CvApiResult for all API calls
+ """
+ results = []
+
+ for device in user_inventory.devices:
+ MODULE_LOGGER.debug("Applying image bundle for device: %s", str(device.fqdn))
+ result_data = CvApiResult(action_name=device.fqdn + '_image_bundle_attached')
+
+ # We can't attach/detach an image to a device in the undefined container
+ current_container_info = self.get_container_current(device_mac=device.system_mac)
+ if (device.configlets is None or current_container_info[Api.generic.NAME] == Api.container.UNDEFINED_CONTAINER_ID):
+ continue
+
+ # GET IMAGE BUNDLE
+ MODULE_LOGGER.debug("Get image bundle for %s", str(device.serial_number))
+ current_image_bundle = self.get_device_image_bundle(device_lookup=device.serial_number)
+ MODULE_LOGGER.debug("Current image bundle assigned is: %s", str(current_image_bundle))
+ MODULE_LOGGER.debug("User assigned image bundle is: %s", str(device.image_bundle))
+
+ if device.image_bundle is not None:
+ if device.image_bundle == current_image_bundle[Api.generic.IMAGE_BUNDLE_NAME] \
+ and current_image_bundle[Api.image.TYPE] == 'netelement':
+ MODULE_LOGGER.debug("No actions needed for device: %s", str(device.fqdn))
+ MODULE_LOGGER.debug("%s has %s assigned and applied", str(device.fqdn), current_image_bundle[Api.generic.IMAGE_BUNDLE_NAME])
+ pass
+ # Nothing to do
+ else:
+ MODULE_LOGGER.debug("Updating %s to use image bundle: %s", str(device.fqdn), str(device.image_bundle))
+
+ device_facts = {}
+ if self.__search_by == Api.device.FQDN:
+ device_facts = self.__cv_client.api.get_device_by_name(
+ fqdn=device.fqdn, search_by_hostname=False)
+ elif self.__search_by == Api.device.HOSTNAME:
+ device_facts = self.__cv_client.api.get_device_by_name(
+ fqdn=device.fqdn, search_by_hostname=True)
+ elif self.__search_by == Api.device.SERIAL:
+ device_facts = self.__cv_client.api.get_device_by_serial(device_serial=device.serial_number)
+
+ assigned_image_facts = self.__cv_client.api.get_image_bundle_by_name(device.image_bundle)
+ if assigned_image_facts is None:
+ MODULE_LOGGER.error('Error image bundle %s not found', str(device.image_bundle))
+ self.__ansible.fail_json(msg='Error applying bundle to device' + device.fqdn + ': ' + str(device.image_bundle) + 'not found')
+
+ MODULE_LOGGER.debug("%s image bundle facts are: %s", str(device.image_bundle), str(assigned_image_facts))
+ try:
+ resp = self.__cv_client.api.apply_image_to_element(
+ assigned_image_facts,
+ device_facts,
+ device.hostname,
+ 'netelement'
+ )
+
+ except CvpApiError as catch_error:
+ MODULE_LOGGER.error('Error applying bundle to device: %s', str(catch_error))
+ self.__ansible.fail_json(msg='Error applying bundle to device' + device.fqdn + ': ' + catch_error)
+ else:
+ if resp['data']['status'] == 'success':
+ result_data.changed = True
+ result_data.success = True
+ result_data.taskIds = resp['data'][Api.task.TASK_IDS]
+
+ results.append(result_data)
+
+ return results
+
+ def detach_bundle(self, user_inventory: DeviceInventory):
+ """
+ detach_bundle - detach an image bundle from a device
+
+ Execute the API calls to detach an image bundle from a device.
+
+ Parameters
+ ----------
+ user_inventory : DeviceInventory
+ Ansible inventory to configure on Cloudvision
+
+ Returns
+ -------
+ list
+ List of CvApiResult for all API calls
+ """
+ results = []
+
+ for device in user_inventory.devices:
+ MODULE_LOGGER.debug("Detaching image bundle from device: %s", str(device.fqdn))
+ result_data = CvApiResult(action_name=device.fqdn + '_image_bundle_detached')
+
+ # We can't attach/detach an image to a device in the undefined container
+ current_container_info = self.get_container_current(device_mac=device.system_mac)
+ if (device.configlets is None or current_container_info[Api.generic.NAME] == Api.container.UNDEFINED_CONTAINER_ID):
+ continue
+
+ # GET IMAGE BUNDLE
+ current_image_bundle = self.get_device_image_bundle(device_lookup=device.serial_number)
+
+ # Check to make sure that the assigned image isn't inherited from the container
+ if current_image_bundle is not None and current_image_bundle[Api.image.TYPE] == 'netelement':
+ if device.image_bundle is None:
+
+ device_facts = {}
+ if self.__search_by == Api.device.FQDN:
+ device_facts = self.__cv_client.api.get_device_by_name(
+ fqdn=device.fqdn, search_by_hostname=False)
+ elif self.__search_by == Api.device.HOSTNAME:
+ device_facts = self.__cv_client.api.get_device_by_name(
+ fqdn=device.fqdn, search_by_hostname=True)
+ elif self.__search_by == Api.device.SERIAL:
+ device_facts = self.__cv_client.api.get_device_by_serial(device_serial=device.serial_number)
+
+ assigned_image_facts = self.__cv_client.api.get_image_bundle_by_name(current_image_bundle[Api.generic.IMAGE_BUNDLE_NAME])
+ try:
+ resp = self.__cv_client.api.remove_image_from_element(
+ assigned_image_facts,
+ device_facts,
+ device.hostname,
+ 'netelement'
+ )
+
+ except CvpApiError as catch_error:
+ MODULE_LOGGER.error('Error removing bundle from device: %s', str(catch_error))
+ self.__ansible.fail_json(msg='Error removing bundle from device' + device.fqdn + ': ' + catch_error)
+ else:
+ if resp['data']['status'] == 'success':
+ result_data.changed = True
+ result_data.success = True
+ result_data.taskIds = resp['data'][Api.task.TASK_IDS]
+
+ results.append(result_data)
+
+ return results
+
def apply_configlets(self, user_inventory: DeviceInventory):
"""
apply_configlets Entry point to a list of configlets to device
diff --git a/ansible_collections/arista/cvp/plugins/module_utils/facts_tools.py b/ansible_collections/arista/cvp/plugins/module_utils/facts_tools.py
index d4e849dda..a629067ca 100644
--- a/ansible_collections/arista/cvp/plugins/module_utils/facts_tools.py
+++ b/ansible_collections/arista/cvp/plugins/module_utils/facts_tools.py
@@ -81,7 +81,7 @@ def __shorten_device_facts(self, device_fact: dict):
Api.device.SERIAL,
Api.device.SYSMAC,
Api.generic.CONFIGLETS,
- Api.generic.IMAGE_BUNDLE,
+ Api.generic.IMAGE_BUNDLE_NAME,
Api.device.MGMTIP,
]
}
@@ -139,7 +139,7 @@ def _get_container(self):
return {entry[Api.generic.NAME]: {
Api.generic.PARENT_CONTAINER_NAME: entry[Api.container.PARENT_NAME],
Api.generic.CONFIGLETS: entry[Api.generic.CONFIGLETS],
- Api.generic.IMAGE_BUNDLE: entry[Api.generic.IMAGE_BUNDLE]}
+ Api.generic.IMAGE_BUNDLE_NAME: entry[Api.generic.IMAGE_BUNDLE_NAME]}
for entry in self._cache if Api.generic.NAME in entry.keys()}
def _get_device(self, verbose: bool = False):
@@ -492,7 +492,7 @@ def __fact_devices(self, filter: str = '.*', verbose: bool = False):
facts_builder.add(self.__device_update_info(device=device))
else:
device[Api.generic.CONFIGLETS] = self.__device_get_configlets(netid=device[Api.generic.KEY])
- device[Api.generic.IMAGE_BUNDLE] = self.__device_get_image_bundle_name(device[Api.generic.KEY])
+ device[Api.generic.IMAGE_BUNDLE_NAME] = self.__device_get_image_bundle_name(device[Api.generic.KEY])
facts_builder.add(device)
self._facts[FactsResponseFields.DEVICE] = facts_builder.get(resource_model='device', verbose=verbose)
@@ -510,7 +510,7 @@ def __fact_containers(self):
if container[Api.generic.NAME] != 'Tenant':
MODULE_LOGGER.debug('Got following information for container: %s', str(container))
container[Api.generic.CONFIGLETS] = self.__containers_get_configlets(container_id=container[Api.container.KEY])
- container[Api.generic.IMAGE_BUNDLE] = self.__container_get_image_bundle_name(container_id=container[Api.container.KEY])
+ container[Api.generic.IMAGE_BUNDLE_NAME] = self.__container_get_image_bundle_name(container_id=container[Api.container.KEY])
facts_builder.add(container)
self._facts[FactsResponseFields.CONTAINER] = facts_builder.get(resource_model='container')
diff --git a/ansible_collections/arista/cvp/plugins/module_utils/resources/api/fields.py b/ansible_collections/arista/cvp/plugins/module_utils/resources/api/fields.py
index 9fac00097..64d47bc98 100644
--- a/ansible_collections/arista/cvp/plugins/module_utils/resources/api/fields.py
+++ b/ansible_collections/arista/cvp/plugins/module_utils/resources/api/fields.py
@@ -47,7 +47,7 @@ class ApiGeneric():
NAME: str = 'name'
PARENT_CONTAINER_ID: str = 'parentContainerId'
PARENT_CONTAINER_NAME: str = 'parentContainerName'
- IMAGE_BUNDLE: str = 'image_bundle'
+ IMAGE_BUNDLE_NAME: str = 'imageBundle'
# @dataclass
@@ -76,6 +76,7 @@ class ApiDevice():
SYSMAC: str = 'systemMacAddress'
PARENT_CONTAINER_KEY: str = 'parentContainerKey'
MGMTIP: str = 'ipAddress'
+ BUNDLE: str = 'imageBundle'
# @dataclass
diff --git a/ansible_collections/arista/cvp/plugins/module_utils/resources/modules/fields.py b/ansible_collections/arista/cvp/plugins/module_utils/resources/modules/fields.py
index 68a87cb5a..457e68ce0 100644
--- a/ansible_collections/arista/cvp/plugins/module_utils/resources/modules/fields.py
+++ b/ansible_collections/arista/cvp/plugins/module_utils/resources/modules/fields.py
@@ -60,5 +60,7 @@ class DeviceResponseFields():
DEVICE_DEPLOYED: str = 'devices_deployed'
DEVICE_MOVED: str = 'devices_moved'
DEVICE_RESET: str = 'devices_reset'
+ BUNDLE_ATTACHED: str = 'bundle_attached'
+ BUNDLE_DETACHED: str = 'bundle_detached'
DEVICE_DECOMMISSIONED: str = 'devices_decommissioned'
DEVICE_REMOVED: str = 'devices_removed'
diff --git a/ansible_collections/arista/cvp/plugins/module_utils/resources/schemas/v3.py b/ansible_collections/arista/cvp/plugins/module_utils/resources/schemas/v3.py
index ff0d0bee0..89e3dc9b0 100644
--- a/ansible_collections/arista/cvp/plugins/module_utils/resources/schemas/v3.py
+++ b/ansible_collections/arista/cvp/plugins/module_utils/resources/schemas/v3.py
@@ -89,7 +89,7 @@
"01TRAINING-01",
"CV-EOS-ANSIBLE01"
],
- "imageBundle": []
+ "imageBundle": "test_bundle"
}
],
"anyOf": [
@@ -190,16 +190,13 @@
},
"imageBundle": {
"$id": "#/items/anyOf/0/properties/imageBundle",
- "type": "array",
- "title": "The imageBundle schema",
- "description": "An explanation about the purpose of this instance.",
+ "type": "string",
+ "title": "The imageBundle name",
+ "description": "The imageBundle is the name of the image bundle applied to a container or device.",
"default": [],
"examples": [
- []
- ],
- "items": {
- "$id": "#/items/anyOf/0/properties/imageBundle/items"
- }
+ "spine_image_bundle"
+ ]
}
},
}
diff --git a/tests/lib/json_data.py b/tests/lib/json_data.py
index 922bec51f..b9c6100c3 100644
--- a/tests/lib/json_data.py
+++ b/tests/lib/json_data.py
@@ -217,7 +217,7 @@
"AVD_DC1-SPINE1",
"01TRAINING-01"
],
- "imageBundle": []
+ "imageBundle": "test_bundle"
}],
[{
"fqdn": "DC1-SPINE1",
@@ -237,7 +237,7 @@
"fqdn": "DC1-SPINE1",
"systemMacAddress": "ccccccc",
"parentContainerName": "DC1_SPINES",
- "imageBundle": []
+ "imageBundle": "test_bundle"
}],
[{
"fqdn": "DC1-SPINE1.eve.emea.lab",
@@ -248,7 +248,7 @@
"AVD_DC1-SPINE1",
"01TRAINING-01"
],
- "imageBundle": []
+ "imageBundle": "test_bundle"
}],
[{
"fqdn": "DC1-SPINE2",
@@ -268,7 +268,7 @@
"fqdn": "DC1-SPINE4",
"systemMacAddress": "ccccccc",
"parentContainerName": "DC1_SPINES",
- "imageBundle": []
+ "imageBundle": "test_bundle"
}]
]
@@ -280,7 +280,7 @@
"AVD_DC1-SPINE1",
"01TRAINING-01"
],
- "imageBundle": []
+ "imageBundle": "test_bundle"
}]
]
diff --git a/tests/system/constants_data.py b/tests/system/constants_data.py
index 8c9526341..7e62672d3 100644
--- a/tests/system/constants_data.py
+++ b/tests/system/constants_data.py
@@ -54,7 +54,7 @@
"01TRAINING-01",
"CV-EOS-ANSIBLE01"
],
- "imageBundle": []
+ "imageBundle": "test_image_bundle"
},
{
"fqdn": "TEST.ire.aristanetworks.com",
@@ -75,7 +75,7 @@
"AVD_DC1-SPINE1",
"01TRAINING-01"
],
- "imageBundle": []
+ "imageBundle": "test_image_bundle"
}],
[{
"fqdn": "DC1-SPINE1",
@@ -95,7 +95,7 @@
"fqdn": "DC1-SPINE1",
"systemMacAddress": "ccccccc",
"parentContainerName": "DC1_SPINES",
- "imageBundle": []
+ "imageBundle": "test_image_bundle"
}]
]