Skip to content

Commit 72f399c

Browse files
committed
added upload app sample
1 parent 16cfedc commit 72f399c

File tree

11 files changed

+260
-23
lines changed

11 files changed

+260
-23
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from cloudshell.api.cloudshell_api import CloudShellAPISession
2+
3+
user = "admin"
4+
password = "admin"
5+
server = "localhost"
6+
domain = "Global"
7+
8+
SANDDBOX_ID = "37170584-46a5-4634-91aa-54c50e13b552"
9+
10+
api = CloudShellAPISession(host=server, username=user, password=password, domain=domain)
11+
12+
user_details = api.GetUserDetails()
13+
api.Domain
14+
pass
15+
16+

packaging-api-samples/__init__.py

Whitespace-only changes.
Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
from quali_utils.quali_packaging import PackageEditor, TopologyApp, AppResource
1+
from quali_utils.quali_packaging import PackageEditor, TopologyApp, AppResource, AppResourceInner, DeploymentService
22
import requests
3+
from copy import deepcopy
34

45
# Create a new package in the local file system
56
package_base_path = "C:\\quali_package_demo"
6-
package_name = "demo_apps_blueprint.zip"
7+
# package_name = "demo_apps_blueprint.zip"
8+
package_name = "packaging api dev.zip"
79
p = PackageEditor()
810

911
package_path = "{}\\{}".format(package_base_path, package_name)
@@ -15,38 +17,46 @@
1517
p.load(package_path)
1618

1719
# Edit the package: f.e add new family
18-
names = p.get_topology_names()
19-
p.change_topology_name_and_alias(topology_name=names[0], new_name="new blueprint name")
20-
names_new = p.get_topology_names()
21-
22-
new_app = TopologyApp()
23-
new_app.positionX = ""
24-
new_app.positionY = ""
25-
new_app.templateName = ""
26-
new_app.appResource = AppResource()
27-
p.add_app(topology_name=names_new[0], topology_app=)
20+
# p.add_topology(topology_name="temp_blueprint", is_public="True", image_file_path="", default_duration="15",
21+
# instructions="", categories="", diagram_zoom="0")
22+
23+
topology_name = p.get_topology_names()[0]
24+
# p.change_topology_name_and_alias(topology_name=names[0], new_name="new blueprint name")
25+
# names_new = p.get_topology_names()
26+
27+
apps = p.get_apps(topology_name)
28+
app1 = apps[0]
29+
30+
new_app_copy = deepcopy(app1)
31+
new_app_copy.templateName = "my template from api"
32+
new_app_copy.appResource.name = "my temp app"
33+
34+
# BUILD NEW APP
35+
# new_app = TopologyApp()
36+
# new_app.positionX = "0"
37+
# new_app.positionY = "0"
38+
# new_app.templateName = "my amazing app template"
39+
# new_app.appResource = AppResource()
40+
# new_app.appResource.deploymentPaths = []
41+
# new_app.appResource.logicalResource = AppResourceInner()
42+
# # x = p.convert_topology_app_to_json(new_app)
43+
# p.add_app(topology_name=names[0], topology_app=new_app)
44+
# apps = p.get_apps(names[0])
45+
46+
p.add_app(topology_name, new_app_copy)
2847
pass
2948

30-
31-
# Import the package into CloudShell
32-
49+
# ==== IMPORT PACKAGE INTO CLOUDSHELL =====
3350
# authenticate quali api
34-
3551
r = requests.put('http://localhost:9000/Api/Auth/Login', {"username": "admin", "password": "admin", "domain": "Global"})
36-
3752
authcode = "Basic " + r._content[1:-1]
3853

3954
# 2 Open the package before import
40-
41-
fileobj = open("c:\\p.zip", 'rb')
55+
fileobj = open(package_path, 'rb')
4256

4357
# 3 Send to CloudShell by calling Import Package REST API
44-
4558
r = requests.post('http://localhost:9000/API/Package/ImportPackage',
46-
4759
headers={"Authorization": authcode},
48-
4960
files={"file": fileobj})
5061
print r._content
51-
5262
print r.ok

packaging-api-samples/upload-app/__init__.py

Whitespace-only changes.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from build_app_xml import app_template
2+
from upload_to_cloudshell import upload_app_to_cloudshell
3+
4+
deploy_paths = [
5+
{
6+
"name": "my deployment path 1",
7+
"is_default": True,
8+
"service_name": "VMware vCenter Cloud Provider 2G.vCenter VM From Linked Clone 2G",
9+
"attributes": {
10+
"VMware vCenter Cloud Provider 2G.vCenter VM From Linked Clone 2G.vCenter VM": "Natti.k\Clones\Ubuntu-18",
11+
"VMware vCenter Cloud Provider 2G.vCenter VM From Linked Clone 2G.vCenter VM Snapshot": "clean_snap",
12+
}
13+
},
14+
{
15+
"name": "my deployment path 2",
16+
"is_default": False,
17+
"service_name": "VMware vCenter Cloud Provider 2G.vCenter VM From Linked Clone 2G",
18+
"attributes": {
19+
"VMware vCenter Cloud Provider 2G.vCenter VM From Linked Clone 2G.vCenter VM": "Natti.k\Clones\Ubuntu-18",
20+
"VMware vCenter Cloud Provider 2G.vCenter VM From Linked Clone 2G.vCenter VM Snapshot": "clean_snap",
21+
}
22+
}
23+
]
24+
25+
app_attributes = {
26+
"App Deploy Order": "N/A",
27+
"Execution Server Selector": "my ES"
28+
}
29+
30+
# CREATE APP XML
31+
app_xml = app_template(app_name="test",
32+
deploy_paths=deploy_paths,
33+
categories=["category1", "category 2"],
34+
app_attributes=app_attributes,
35+
model="Generic App Model",
36+
driver="",
37+
cloud_provider="my vcenter 2G",
38+
image_name="vm.png")
39+
40+
# UPLOAD APP TEMPLATE
41+
upload_app_to_cloudshell(app_name="my api app test",
42+
app_xml_content=app_xml,
43+
server="localhost",
44+
user="admin",
45+
password="admin")
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
def attribute(name, value, overwrite=False):
2+
xml = """
3+
<Attribute Name="{Name}" Value="{Value}" {overwrite}/>
4+
"""
5+
return xml.format(Name=name, Value=value, overwrite='Override="true"' if overwrite else "")
6+
7+
8+
def deployment_path(deploy_path, cloud_provider):
9+
xml = """
10+
<DeploymentPath Name="{dn}" Default="false">
11+
<DeploymentService Name="{dsn}" CloudProvider="{cp}">
12+
<Attributes>
13+
{DeployAttributes}
14+
</Attributes>
15+
</DeploymentService>
16+
</DeploymentPath>
17+
"""
18+
return xml.format(
19+
DeployAttributes="\n".join([attribute(x, y, True) for x, y in deploy_path['attributes'].iteritems()]),
20+
cp=cloud_provider, dn=deploy_path['name'], dsn=deploy_path['service_name'])
21+
22+
23+
def deployment_paths(deploy_paths, cloud_provider):
24+
xml = """
25+
{DeployPaths}
26+
"""
27+
return xml.format(DeployPaths="\n".join([deployment_path(x, cloud_provider) for x in deploy_paths]))
28+
29+
30+
def app_resource(attributes, model, driver):
31+
xml = """
32+
<AppResources>
33+
<AppResource ModelName="{model}" Driver="{driver}">
34+
<Attributes>
35+
{Attributes}
36+
</Attributes>
37+
</AppResource>
38+
</AppResources>
39+
40+
"""
41+
return xml.format(Attributes="\n".join(attribute(x, y, True) for x, y in attributes.iteritems()), model=model,
42+
driver=driver)
43+
44+
45+
def app_resource_info(app_name, deploy_paths, app_attributes, model, driver, cloud_provider, image_name):
46+
xml = """
47+
<AppResourceInfo Name="{AppName}" ImagePath="{img}">
48+
{AppResource}
49+
<DeploymentPaths>
50+
{DeploymentPath}
51+
52+
</DeploymentPaths>
53+
</AppResourceInfo>
54+
"""
55+
return xml.format(AppName=app_name, img=image_name, AppResource=app_resource(app_attributes, model, driver),
56+
DeploymentPath=deployment_paths(deploy_paths, cloud_provider))
57+
58+
59+
def add_category(category):
60+
xml = """
61+
<Category>{Category}</Category>
62+
"""
63+
return xml.format(Category=category)
64+
65+
66+
def categories_info(categories):
67+
xml = """
68+
<Categories>
69+
{Categories}
70+
</Categories>
71+
72+
"""
73+
return xml.format(Categories="\n".join([add_category(x) for x in categories]))
74+
75+
76+
def app_template(app_name, deploy_paths, categories, app_attributes, model, driver, cloud_provider, image_name):
77+
"""
78+
79+
:return:
80+
"""
81+
xml = """<?xml version="1.0" encoding="utf-8"?>
82+
<AppTemplateInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
83+
{AppResourceInfo}
84+
85+
{Categories}
86+
</AppTemplateInfo>
87+
"""
88+
app_resource = app_resource_info(app_name, deploy_paths, app_attributes, model, driver, cloud_provider, image_name)
89+
categories = categories_info(categories)
90+
91+
return xml.format(AppResourceInfo=app_resource, Categories=categories if categories else "")
4.29 KB
Binary file not shown.

packaging-api-samples/upload-app/images.py

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
16.2 KB
Binary file not shown.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import tempfile
2+
import os
3+
import zipfile
4+
import requests
5+
import shutil
6+
7+
from images import vm_image
8+
9+
10+
def upload_app_to_cloudshell(app_name, app_xml_content, server, user="admin", password="admin", display_image_result=None, display_image_name='vm.png'):
11+
"""
12+
:param string app_name:
13+
:param string app_xml_content:
14+
:param string server:
15+
:param string user:
16+
:param string password:
17+
:param image display_image_result
18+
:param string display_image_name
19+
:return:
20+
"""
21+
metadata = """<?xml version="1.0" encoding="utf-8"?>
22+
<Metadata xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.qualisystems.com/PackageMetadataSchema.xsd">
23+
<CreationDate>9/13/2019 4:45:59 PM</CreationDate>
24+
<ServerVersion>9.2.0</ServerVersion>
25+
<PackageType>CloudShellPackage</PackageType>
26+
</Metadata>
27+
"""
28+
29+
# script_working_dir = os.path.dirname(os.path.abspath(__file__))
30+
working_dir = tempfile.mkdtemp()
31+
app_template_file = "{}/{}".format(working_dir, app_name)
32+
blueprint_zip_file = "{}/Blueprint.zip".format(working_dir)
33+
34+
display_image_file = os.path.join(working_dir, display_image_name)
35+
36+
metadata_file = "{}/metadata.xml".format(working_dir)
37+
with open(app_template_file, "w") as app_xml:
38+
app_xml.write(app_xml_content)
39+
40+
if os.path.exists(blueprint_zip_file):
41+
os.remove(blueprint_zip_file)
42+
43+
if os.path.exists(display_image_file):
44+
os.remove(display_image_file)
45+
46+
fh = open(display_image_file, "wb")
47+
if display_image_result is not None:
48+
fh.write(display_image_result.decode('base64'))
49+
else:
50+
fh.write(vm_image.decode('base64'))
51+
fh.close()
52+
53+
zip_file = zipfile.ZipFile(blueprint_zip_file, "w")
54+
zip_file.write(app_template_file, arcname="App Templates\\{}.xml".format(app_name))
55+
56+
zip_file.write(display_image_file, arcname="App Templates\\{}".format(display_image_name))
57+
58+
open(metadata_file, "w").write(metadata)
59+
zip_file.write(metadata_file, arcname="metadata.xml")
60+
zip_file.close()
61+
zip_content = open(blueprint_zip_file, "rb").read()
62+
# shutil.rmtree(working_dir)
63+
authentication_code = requests.put("http://{}:9000/Api/Auth/Login".format(server),
64+
{"username": user, "password": password, "domain": "Global"}).content
65+
66+
result = requests.post("http://{}:9000/API/Package/ImportPackage".format(server),
67+
headers={"Authorization": "Basic {}".format(authentication_code[1:-1])},
68+
files={"QualiPackage": zip_content})
69+
if 'false' in result.content:
70+
raise Exception('Issue importing App XML into Cloudshell: ' + result.content)
71+
if result.status_code >= 300:
72+
return result.content
73+
else:
74+
return None

0 commit comments

Comments
 (0)