Simple REST-client for Pensando DSS PSM
Project description
simple_pensando_dss is a simplified REST Client for the AMD Pensando DSS PSM. As I don’t like the autogenerated SDK provided by Pensando, I wrote a more straight forward one.
Features
- simple_pensando_dss has following features:
manage login
CRUD interface for all possible API URLs
Installation
Install simple_pensando_dss by running:
pip3 install simple_pensando_dss
Examples
Add IPs to ipcollections
from simple_pensando_dss import PensandoDSSClient
from getpass import getpass
from pprint import pprint
import os
username = os.environ.get("psm_username", "admin")
password = os.environ.get("psm_password") or getpass()
url = os.environ.get("psm_url") or input("PSM URL:")
psm = PensandoDSSClient(url, username=username, password=password, ssl_verify=False)
psm.login()
for ipcollection in psm.api.configs.network.v1.tenant.default.ipcollections.list().body["items"]:
ipcollection["spec"]["addresses"].append("1.1.1.1")
print(f"Adding 1.1.1.1 to {ipcollection['meta']['name']}")
result = psm.api.configs.network.v1.tenant.default.ipcollections.update(
ipcollection["meta"]["name"], body=ipcollection
)
print(result.status_code)
pprint(result.headers)
pprint(result.body)
Sync ACI endpoints to ip_collections
from simple_pensando_dss import PensandoDSSClient
from simple_pensando_dss.rest_client.exceptions import ClientError
try:
from acitoolkit.acisession import Session as aci_session
except ImportError:
print("please install acitoolkit by running pip3 install aci-toolkit")
from getpass import getpass
from pprint import pprint
import os
import logging
import json
# logging.basicConfig(level=logging.DEBUG)
#
# !!!Warning!!! this is just for POC, as for production this should use APIC subscriptions and use logging and so on, but it shows the create/update/delete functions of the psm api
#
username=os.environ.get('psm_username','admin')
password=os.environ.get('psm_password') or getpass("PSM Password")
url=os.environ.get('psm_url') or input("PSM URL:")
aci_username=os.environ.get('aci_username','admin')
aci_password=os.environ.get('aci_password') or getpass("ACI Password (!v3G@!4@Y):") or "!v3G@!4@Y"
aci_url=os.environ.get('aci_url') or input("ACI URL (https://sandboxapicdc.cisco.com/):") or "https://sandboxapicdc.cisco.com/"
aci_tn_name=os.environ.get('aci_tenant') or input("ACI Tenant (demo):") or "demo"
aci_ap_name=os.environ.get('aci_application_profile') or input("ACI AP (Infrastructure):") or "Infrastructure"
collection_name_sep="_"
psm_tn_name="default"
psm=PensandoDSSClient(url,username=username,password=password,ssl_verify=False)
psm.login(tenant=psm_tn_name)
apic = aci_session(
aci_url,
aci_username,
aci_password,
subscription_enabled=True,
)
apic.login()
print(f'Sync ACI AP {aci_ap_name}')
for epg in json.loads(apic.get(f'/api/node/class/fvAEPg.json?query-target-filter=and(wcard(fvAEPg.dn,"tn-{aci_tn_name}/ap-{aci_ap_name}"))&order-by=fvAEPg.modTs|desc').text).get('imdata',[]):
epg_name=epg['fvAEPg']['attributes']['name']
print(f"\tSyncing EPG:{epg_name}")
IPs=[]
ip_collection_name=f"{aci_ap_name}{collection_name_sep}{epg_name}"
ep_request_ok=False
for ep in json.loads(apic.get (f'/api/node/mo/uni/tn-{aci_tn_name}/ap-{aci_ap_name}/epg-{epg_name}.json?query-target=children&target-subtree-class=fvCEp&rsp-subtree=full&rsp-subtree-class=fvIp').text).get('imdata',[]):
ep_request_ok=True
for ip in ep.get("fvCEp").get("children",{}):
IPs.append(ip['fvIp']['attributes']['addr'])
if IPs:
print(f"\t\t Found {','.join(IPs)}")
try:
psm.api.configs.network.v1.tenant.default.ipcollections.update(ip_collection_name,body={
"meta": {
"name": ip_collection_name,
"tenant": psm_tn_name,
},
"spec": {
"addresses": IPs
}
}
)
except ClientError as e:
if e.response.status_code == 404:
psm.api.configs.network.v1.tenant.default.ipcollections.create(body={
"meta": {
"name": ip_collection_name,
"tenant": psm_tn_name,
},
"spec": {
"addresses": IPs
}
}
)
else:
# Empty result for epg -> try to delete group
print(f"\t\tNo endpoints trying to delete {epg_name} {ip_collection_name}")
try:
psm.api.configs.network.v1.tenant.default.ipcollections.delete(ip_collection_name)
except ClientError as e:
if e.response.status_code == 404:
# if it does not exist, failing to delete is ok
continue
elif e.response.status_code == 400 and "has references from other object" in str(e.response.body['message']):
# ipcollection is in use, so set it to something useless, because ipcollections cannot be empty and we do not touch security policies for saftey reasons here.
psm.api.configs.network.v1.tenant.default.ipcollections.update(ip_collection_name,body={
"meta": {
"name": ip_collection_name,
"tenant": psm_tn_name,
},
"spec": {
"addresses": ["127.0.0.255"]
}
}
)
else:
print(e)
Contribute
Issue Tracker: https://github.com/jinjamator/simple_pensando_dss/issues
Source Code: https://github.com/jinjamator/simple_pensando_dss
Roadmap
- Selected Roadmap items:
add more documentation
add some more examples
For documentation please refer to https://simple_pensando_dss.readthedocs.io/en/latest/
License
This project is licensed under the Apache License Version 2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file simple_pensando_dss-0.2-py3-none-any.whl
.
File metadata
- Download URL: simple_pensando_dss-0.2-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.12
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1dc2547a16b015933063f1b6d8df17b3aeba3bcbddf6f4e224a00684d408b955 |
|
MD5 | 51d2b78c91bdc6a4b25303046cb78da2 |
|
BLAKE2b-256 | 6024bc4781bc7f2a5f5c1c2824e4a9acb175dbaebe33094aa48f040f87fde546 |