Skip to content

Commit 38c4f42

Browse files
committed
remove packaging api dependency from update services script
1 parent cdf55eb commit 38c4f42

File tree

6 files changed

+135
-11
lines changed

6 files changed

+135
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import xml.etree.ElementTree as ET
2+
from xml.etree.ElementTree import ElementTree
3+
4+
5+
def get_element_tree_from_str(xml_str: str) -> ElementTree:
6+
"""
7+
https://stackoverflow.com/a/18281386
8+
"""
9+
return ET.ElementTree(ET.fromstring(xml_str))
10+
11+
12+
def get_element_tree_from_file_path(file_path: str) -> ElementTree:
13+
return ET.parse(file_path)
14+
15+
16+
def edit_vlan_id_in_tree(element_tree: ElementTree, target_service_model: str, new_vlan_id: str) -> ElementTree:
17+
"""
18+
Iterate over services, find ServiceName that matches service model
19+
Iterate over the attributes, update the VLAN ID attribute
20+
write to tree
21+
"""
22+
root_element = element_tree.getroot()
23+
for curr_service in root_element.iter("Service"):
24+
service_data: dict = curr_service.attrib
25+
if service_data["ServiceName"] != target_service_model:
26+
continue
27+
for curr_attr in curr_service.iter("Attribute"):
28+
attr_data: dict = curr_attr.attrib
29+
if attr_data["Name"] == "VLAN ID":
30+
attr_data["Value"] = new_vlan_id
31+
return element_tree
32+
raise ValueError("Target Service not found in Element Tree")
33+
34+
35+
def update_xml_tree(xml_path: str, target_service_model: str, new_vlan_id: str):
36+
element_tree = get_element_tree_from_file_path(xml_path)
37+
element_tree = edit_vlan_id_in_tree(element_tree, target_service_model, new_vlan_id)
38+
element_tree.write(xml_path)
39+
40+
41+
if __name__ == "__main__":
42+
TEST_TOPOLOGY_XML = """
43+
<TopologyInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
44+
<Details Name="vlan dev" Alias="vlan dev" Driver="Python Setup &amp; Teardown" SetupDuration="10" TeardownDuration="10" Public="false" DefaultDuration="120" EnableSandboxSave="true" AbstractOnSavePolicy="Default" IsPersistentSandbox="false" TopologyId="f36c4723-8496-4d5b-9b61-8374d01c0fe2" BaseTopologyId="">
45+
<Description>Blueprint with preconfigured setup &amp; teardown processes.Deploys Apps and resolves connections on Setup, and deletes App VMs on Teardown</Description>
46+
<Categories />
47+
<Scripts>
48+
<Script Name="Default Sandbox Setup 4.0" />
49+
</Scripts>
50+
<Diagram Zoom="1" NodeSize="Medium" />
51+
</Details>
52+
<Services>
53+
<Service PositionX="1034.09091186523" PositionY="169.01136779785202" Alias="VLAN Manual" ServiceName="VLAN Manual">
54+
<Attributes>
55+
<Attribute Name="VLAN ID" Value="169" />
56+
<Attribute Name="Dummy Attr" Value="Hi" />
57+
</Attributes>
58+
</Service>
59+
<Service PositionX="100" PositionY="100" Alias="Dummy Service" ServiceName="DummyService">
60+
<Attributes>
61+
<Attribute Name="Dummy Attr 5" Value="179" />
62+
<Attribute Name="Dummy Attr" Value="Hi" />
63+
</Attributes>
64+
</Service>
65+
</Services>
66+
<Apps />
67+
</TopologyInfo>
68+
"""
69+
element_tree = get_element_tree_from_str(TEST_TOPOLOGY_XML)
70+
element_tree = edit_vlan_id_in_tree(element_tree, "VLAN Manual", "66")
71+
root = element_tree.getroot()
72+
ET.indent(root)
73+
print(ET.tostring(root, encoding="unicode"))

packaging-api-samples/update-services/process_blueprint.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22

33
import update_package
4+
import update_xml_topology
45
from quali_api import QualiAPISession
56
from timeit import default_timer
67

@@ -15,11 +16,14 @@ def process_blueprint_flow(quali_api: QualiAPISession, blueprint_name: str, targ
1516
quali_api.export_package(blueprint_full_names=[blueprint_name],
1617
file_path=zip_name)
1718

18-
# remove unneeded files
19-
update_package.clean_bp_archive(zip_name)
19+
# with packaging api, commented out to remove dependency
20+
# update_package.edit_vlan_id_in_package(zip_name, target_service, new_vlan_id)
2021

21-
# update target attribute
22-
update_package.edit_vlan_id_in_package(zip_name, target_service, new_vlan_id)
22+
# with Etree xml manipulation
23+
update_xml_topology.edit_vlan_id_in_xml(bp_name=blueprint_name,
24+
package_path=zip_name,
25+
target_service=target_service,
26+
new_vlan_id=new_vlan_id)
2327

2428
# re-upload
2529
quali_api.import_package(zip_name)
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
cloudshell-automation-api
2-
quali-utils # from cloudshell download center
32
requests
4-
cloudshell-scriptfoundry
3+
cloudshell-scriptfoundry
4+
5+
6+
# Quali Utils not on pypi - get from cloudshell download center and pip install manually
7+
# quali-utils

packaging-api-samples/update-services/update_package.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22
import shutil
33
import zipfile
4-
54
from quali_utils.quali_packaging import PackageEditor
65
import constants
76

@@ -20,7 +19,7 @@ def _clean_bp_package(base_path: str):
2019
shutil.rmtree(full_path)
2120

2221

23-
def clean_bp_archive(package_path: str):
22+
def _clean_bp_archive(package_path: str):
2423
"""
2524
1. unzip the package
2625
2. clean out package for everything except Topology xml
@@ -44,6 +43,7 @@ def clean_bp_archive(package_path: str):
4443

4544

4645
def edit_vlan_id_in_package(package_path: str, target_service: str, new_vlan_id: str):
46+
_clean_bp_archive(package_path)
4747
p = PackageEditor()
4848
p.load(package_path)
4949
bp_names = p.get_topology_names()
@@ -55,11 +55,9 @@ def edit_vlan_id_in_package(package_path: str, target_service: str, new_vlan_id:
5555
attribute_name=constants.VLAN_ID_ATTR,
5656
attribute_value=new_vlan_id,
5757
publish=False)
58-
pass
5958

6059

6160
if __name__ == "__main__":
6261
TARGET_PACKAGE = "vlan dev.zip"
6362
TARGET_SERVICE = "VLAN Manual"
64-
clean_bp_archive(TARGET_PACKAGE)
6563
edit_vlan_id_in_package(TARGET_PACKAGE, TARGET_SERVICE, "42")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import os
2+
import shutil
3+
import zipfile
4+
from etree_xml_handler import update_xml_tree
5+
6+
7+
def _clean_bp_package(base_path: str):
8+
"""
9+
clean out unwanted folders
10+
"""
11+
dir_contents = os.listdir(base_path)
12+
for item in dir_contents:
13+
if item.endswith(".xml"):
14+
continue
15+
if item == "Topologies":
16+
continue
17+
full_path = os.path.join(base_path, item)
18+
shutil.rmtree(full_path)
19+
20+
21+
def edit_vlan_id_in_xml(bp_name: str, package_path: str, target_service: str, new_vlan_id: str):
22+
"""
23+
1. unzip the package to temp folder
24+
2. clean out package for everything except Topology xml
25+
3. update xml tree
26+
4. zip up extracted folders
27+
5. delete temp extracted content
28+
"""
29+
temp_folder = "temp_bp_extracted"
30+
31+
# UNZIP PACKAGE TO TEMP FOLDER
32+
with zipfile.ZipFile(package_path, 'r') as zip_ref:
33+
zip_ref.extractall(temp_folder)
34+
35+
# CLEAR OUT EVERYTHING EXCEPT TOPOLOGIES FOLDER AND METADATA XML
36+
_clean_bp_package(temp_folder)
37+
38+
xml_path = os.path.join(temp_folder, "Topologies", f"{bp_name}.xml")
39+
update_xml_tree(xml_path=xml_path, target_service_model=target_service, new_vlan_id=new_vlan_id)
40+
41+
# REZIP TEMP FOLDER BACK TO ZIP PACKAGE
42+
package_file_name = package_path.split("/")[-1].split(".zip")[0] # handle full path and remove zip extension
43+
shutil.make_archive(package_file_name, 'zip', temp_folder)
44+
45+
# clean up temp folder
46+
shutil.rmtree(temp_folder)
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0
1+
1.1

0 commit comments

Comments
 (0)