Inleiding
Dit document beschrijft een voorbeeld van het gebruik van Python voor het maken van Rest API-oproepen.
Voorwaarden
De gereedschappen en apparaten die worden gebruikt in deze handleiding zijn:
- Cisco Firepower Threat Defence (FTD)
- Cisco Firepower Device Management (FDM)
- Mac OS
- Sublime tekst
Vereisten
Cisco raadt kennis van de volgende onderwerpen aan:
- HTTPS
- API voor rustperioden
- Python
- Json
- Firepower-apparaatbeheer
- LDAP
Gebruikte componenten
De informatie in dit document is gebaseerd op de volgende software- en hardware-versies:
- Python 3.11.4
- FDM API versie 6
- FTDv 7.3.1
De informatie in dit document is gebaseerd op de apparaten in een specifieke laboratoriumomgeving. Alle apparaten die in dit document worden beschreven, hadden een opgeschoonde (standaard)configuratie. Als uw netwerk live is, moet u zorgen dat u de potentiële impact van elke opdracht begrijpt.
Achtergrondinformatie
De belangrijkste bedoeling van dit document is om u door de stappen voor het creëren van een Python script te begeleiden om API-oproepen te maken.
De specifieke functie die moet worden aangepast en gebouwd is LDAP en attribuutkaarten.
De API-aanroepen in de handleiding zijn:
GET: Verzamel informatie van de server
POST: Maak een nieuw object op de server
PUT: Een bestaand object op de server bijwerken
VERWIJDEREN: Verwijder een bestaand object van de server
Configureren
KRIJGEN
Rest API GET voorbeeld om gegevens te verzamelen over bestaande objecten:
import requests
import json
import certifi
import urllib3
from pprint import pprint
from getpass import getpass
urllib3.disable_warnings()
#Data collection
u = input ('Input username: ')
p = getpass(prompt='Input password: ')
url = input('Input Hostname or IP address: ')
protocol = 'https://'
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def auth():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
payload = {
'grant_type' : 'password',
'username' : u,
'password': p
}
response = requests.post(token_url, data=payload, verify=False)
#ONlY USE "verify=False" in a lab setting!
#Error Checking
if response.status_code == 400:
raise Exception("Error Received: {}".format(response.content))
else:
access_token = response.json()['access_token']
return access_token
token = auth()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def getactivedirectory():
uri = "/api/fdm/v6/object/realms"
ad_url = protocol+url+uri
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer {}".format(token)
}
response = requests.get(ad_url, headers=headers, verify=False)
if response.status_code == 200:
AD = response.json()
return AD
else:
print(response.status_code)
pass
pprint(getactivedirectory())
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def revoke():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer"
}
payload = {
'grant_type' : 'revoke_token',
"access_token": token,
"token_to_revoke": token,
}
response = requests.post(token_url, data=payload, verify=False)
if response.status_code == 200:
print("Access token revoked")
else:
print(response.status_code)
revoke()
POST
In deze sectie wordt een voorbeeld beschreven van het indienen van een REST API POST verzoek om een nieuw LDAP attribuut map object te maken:
import requests
import json
import certifi
import urllib3
from pprint import pprint
from getpass import getpass
urllib3.disable_warnings()
#Data collection
u = input ('Input username: ')
p = getpass(prompt='Input password: ')
url = input('Input Hostname or IP address: ')
protocol = 'https://'
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def auth():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
payload = {
'grant_type' : 'password',
'username' : u,
'password': p
}
response = requests.post(token_url, data=payload, verify=False)
#WARNING ONLY USE "verify=False" in a lab setting!
#Error Checking
if response.status_code == 400:
raise Exception("Error Received: {}".format(response.content))
else:
access_token = response.json()['access_token']
return access_token
token = auth()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def postattributemap():
uri = "/api/fdm/v6/object/ldapattributemaps"
ad_url = protocol+url+uri
name = input('Object name> ')
group_policy = input('Group-Policy> ')
base = input('LDAP DN> ')
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer {}".format(token)
}
payload = {
"name": name,
"ldapAttributeMaps": [
{
"ldapName": "memberOf",
"ciscoName": "GROUP_POLICY",
"valueMappings": [
{
"ldapValue": base,
"ciscoValue": group_policy,
"type": "ldaptociscovaluemapping"
}
],
"type": "ldapattributemapping"
}
],
"type": "ldapattributemap"
}
data = json.dumps(payload)
response = requests.post(ad_url, headers=headers, data=data, verify=False)
if response.status_code == 200:
print(response.status_code)
print("Created LDAP attribute map")
map = response.json
return map
else:
print(response.status_code)
pprint(response.content)
pass
postattributemap()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def revoke():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer"
}
payload = {
'grant_type' : 'revoke_token',
"access_token": token,
"token_to_revoke": token,
}
response = requests.post(token_url, data=payload, verify=False)
if response.status_code == 200:
print("Access token revoked")
else:
print(response.status_code)
revoke()
PUT
Deze paragraaf laat een voorbeeld zien van een Python-script dat een PUT Rest API-oproep maakt. Deze functie voegt de LDAP attributenkaart aan de bestaande actieve indexconfiguraties toe.
Opmerking: Voordat u verdergaat, moet de informatie die nodig is om het object bij te werken via de functie GET worden verzameld.
URL1 Active Directory-gebieden: /api/fdm/v6/object/realms/
URL2 LDAP attributenkaart: /api/fdm/v6/object/ldapattributemaps
import requests
import json
import certifi
import urllib3
from pprint import pprint
from getpass import getpass
urllib3.disable_warnings()
#Data collection
u = input ('Input username: ')
p = getpass(prompt='Input password: ')
url = input('Input Hostname or IP address: ')
protocol = 'https://'
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def auth():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
payload = {
'grant_type' : 'password',
'username' : u,
'password': p
}
response = requests.post(token_url, data=payload, verify=False)
#WARNING ONLY USE "verify=False" in a lab setting!
#Error Checking
if response.status_code == 400:
raise Exception("Error Received: {}".format(response.content))
else:
access_token = response.json()['access_token']
return access_token
token = auth()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def put():
objId = input('object id of active directory object> ')
uri = "/api/fdm/v6/object/realms/"
ad_url = protocol+url+uri+objId
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer {}".format(token)
}
#Place the GET response from the active directory here in "payload" along with the added "ldapAttributeMap", "id" and ""type": "ldapattributemap""
payload = {
"version": "p6ueo2w2aulkf",
"name": "Test",
"directoryConfigurations": [
{
"hostname": "{omitted}",
"port": 389,
"encryptionProtocol": "NONE",
"encryptionCert": None,
"interface": {
"version": "mjvylmnd52agk",
"name": "diagnostic",
"hardwareName": "Management0/0",
"id": "a46ef70c-06ca-11ee-9be1-bd712e622992",
"type": "physicalinterface"
},
"type": "directoryconfiguration"
}
],
"enabled": True,
"realmId": 3,
"dirUsername": "{omitted}",
"dirPassword": "*********",
"baseDN": "dc={omitted},dc=com",
"ldapAttributeMap": {
"id": "7fbf5798-27c9-11ee-a635-a1f4b2c2e66b",
"type": "ldapattributemap"
},
"adPrimaryDomain": "{omitted}.com",
"id": "5957a304-2662-11ee-a635-a5df7d28e8c4",
"type": "activedirectoryrealm"
}
data = json.dumps(payload)
response = requests.put(ad_url, headers=headers, data=data, verify=False)
if response.status_code == 200:
print("Updated Object")
else:
pprint("Error Received: {}".format(response.content))
pass
put()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def revoke():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer"
}
payload = {
'grant_type' : 'revoke_token',
"access_token": token,
"token_to_revoke": token,
}
response = requests.post(token_url, data=payload, verify=False)
if response.status_code == 200:
print("Access token revoked")
else:
print(response.status_code)
revoke()
VERWIJDEREN
Deze sectie beschrijft een Rest API VERWIJDEREN voorbeeld om het actieve directory object te verwijderen:
import requests
import json
import certifi
import urllib3
from pprint import pprint
from getpass import getpass
urllib3.disable_warnings()
#Data collection
u = input ('Input username: ')
p = getpass(prompt='Input password: ')
url = input('Input Hostname or IP address: ')
protocol = 'https://'
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def auth():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
payload = {
'grant_type' : 'password',
'username' : u,
'password': p
}
response = requests.post(token_url, data=payload, verify=False)
#ONlY USE "verify=False" in a lab setting!
#Error Checking
if response.status_code == 400:
raise Exception("Error Received: {}".format(response.content))
else:
access_token = response.json()['access_token']
return access_token
token = auth()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def delete():
objId = input('object id to delete> ')
uri = "/api/fdm/v6/object/realms/"
ad_url = protocol+url+uri+objId
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer {}".format(token)
}
response = requests.delete(ad_url, headers=headers, verify=False)
if response.status_code == 204:
print('Object removed')
else:
print("Error Received: {}".format(response.content))
pass
delete()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def revoke():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer"
}
payload = {
'grant_type' : 'revoke_token',
"access_token": token,
"token_to_revoke": token,
}
response = requests.post(token_url, data=payload, verify=False)
if response.status_code == 200:
print("Access token revoked")
else:
print(response.status_code)
revoke()
IMPLEMENTEREN
Deze sectie beschrijft een voorbeeld van het opstellen van configuratieveranderingen via een POST REST API vraag en het bevestigen van de status van plaatsingen met een GET verzoek.
import requests
import json
import certifi
import urllib3
from pprint import pprint
from getpass import getpass
urllib3.disable_warnings()
#Data collection
u = input ('Input username: ')
p = getpass(prompt='Input password: ')
url = input('Input Hostname or IP address: ')
protocol = 'https://'
x="0"
attempts=0
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def auth():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
payload = {
'grant_type' : 'password',
'username' : u,
'password': p
}
response = requests.post(token_url, data=payload, verify=False)
#ONlY USE "verify=False" in a lab setting!
#Error Checking
if response.status_code == 400:
raise Exception("Error Received: {}".format(response.content))
else:
access_token = response.json()['access_token']
return access_token
token = auth()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def deploy():
uri = '/api/fdm/v6/operational/deploy'
deploy = protocol+url+uri
headers = headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer {}".format(token)
}
payload = {
"statusMessage": "string",
"cliErrorMessage": "string",
"state": "QUEUED",
"queuedTime": 0,
"startTime": 0,
"endTime": 0,
"statusMessages": [
"string"
],
"id": "string",
"name": "string",
"modifiedObjects": {},
"forceRefreshDeploymentData": False,
"type": "deploymentstatus"
}
data = json.dumps(payload)
response = requests.get(deploy, headers=headers, data=data,verify=False)
if response.status_code == 200:
print(response.status_code)
status = response.json()['items'][0]['statusMessage']
return status
else:
print(response.status_code)
pass
status = deploy()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def deploy2():
uri = '/api/fdm/v6/operational/deploy'
deploy = protocol+url+uri
headers = headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer {}".format(token)
}
payload = {
"statusMessage": "string",
"cliErrorMessage": "string",
"state": "QUEUED",
"queuedTime": 0,
"startTime": 0,
"endTime": 0,
"statusMessages": [
"string"
],
"id": "string",
"name": "string",
"modifiedObjects": {},
"forceRefreshDeploymentData": False,
"type": "deploymentstatus"
}
data = json.dumps(payload)
response = requests.post(deploy, headers=headers, data=data,verify=False)
if response.status_code == 200:
print(response.status_code)
print('Deploying')
else:
print(response.status_code)
pass
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def revoke():
uri = '/api/fdm/v6/fdm/token'
token_url = protocol+url+uri
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization":"Bearer"
}
payload = {
'grant_type' : 'revoke_token',
"access_token": token,
"token_to_revoke": token,
}
response = requests.post(token_url, data=payload, verify=False)
if response.status_code == 200:
print("Access token revoked")
else:
print(response.status_code)
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
while True:
x = input("""
Press 1 for deployment status
Press 2 to deploy
Enter Exit to exit
> """).lower()
if x == "1":
deploy()
pprint('Status is: ' + status)
elif x == "2":
deploy2()
elif x == "exit":
break
revoke()
elif x != "1" or "2" or "exit":
attempts += 1
print("The options are 1, 2 or Exit only!")
if attempts == 3:
print('Closing the program')
revoke()
break
else:
raise Exception("Program shutting down")
Verifiëren
KRIJGEN
Met dat script wordt er een HTTP code response "200" ontvangen en wordt de output weergegeven zoals in de afbeelding hieronder.
Uitvoer van het script
PUT
Een nieuwe plaatsing is klaar op de FDM GUI met succesvolle pogingen, zoals aangetoond in het beeld.
Screenshot van de FDM-beheerpagina
De bevestiging kan ook worden bevestigd door het ontvangen van een HTTP-responscode 200.
VERWIJDEREN
Er is een nieuwe implementatie klaar op de FDM GUI met succesvolle pogingen.
De bevestiging kan ook worden bevestigd door het ontvangen van een HTTP-responscode 204.
Problemen oplossen
In deze sectie wordt beschreven hoe u problemen kunt oplossen.
De HTTP-responscode kan informatie geven over de specifieke problemen:
Clientfouten 4XX
400 - Slecht verzoek
401 - Niet geautoriseerd
403 - Verboden
404 - Niet gevonden
408 - Time-out aanvragen
415 - Niet-ondersteund mediatype
Serverfouten 5x
500 - interne serverfout
501 - Niet geïmplementeerd
502 - slechte gateway
503 - Service niet beschikbaar
Gerelateerde informatie
RFC 2616: Hypertext Transfer Protocol — HTTP/1.1
Inleiding tot FirePOWER Threat Defense REST API - FTD-API Reference v6(FTD v7.2) - Document - Cisco Developer