I'm receiving an HTTP 422 client error when attempting to run my code. I want to update properties for all rules within an access control policy at once. When I run the code, my access control policy UUID keeps getting referenced instead of the rule property that I want to change the value of which might be why I'm receiving the error. This is what it the error looks like when it populates.
422 Client Error For URL: https://ip_address/api/fmc_config/v1/domain/domainUUID/policy/accesspolicies/accesscontrolpolicyUUID/accessrules/accesscontrolpolicyUUID.
Can someone look at my code to see if there are any errors as I'm not sure what I'm doing wrong. The API authentication and GET request are successful in my logs. but I get this error for the PUT request.
PUT Request error:
The server understands the content type of the request entity and the syntax of the request entity is correct but was unable to process the contained instructions.
import requests
import config
import base64
# Retrieve the FMC URL, username, and password from the config module
fmc_url = config.url
fmc_username = config.username
fmc_password = config.password
domain_id = config.domain_id
# Encode the username and password using Base64 encoding
auth_string = f"{fmc_username}:{fmc_password}"
encoded_auth_string = base64.b64encode(auth_string.encode()).decode()
# Authenticate with the FMC API and retrieve an access token
auth_url = f"{fmc_url}/api/fmc_platform/v1/auth/generatetoken"
auth_headers = {"Authorization": f"Basic {encoded_auth_string}"}
auth_response = requests.post(auth_url, headers=auth_headers, verify=False)
access_token = auth_response.headers.get("X-auth-access-token", default=None)
if not access_token:
raise ValueError("Failed to authenticate with FMC API: {}".format(auth_response.text))
# Retrieve the policy ID and other configuration options from environment variables
policy_id = input("Enter the access control policy ID: ")
intrusion_policy_id = input("Enter the intrusion policy ID: ")
variable_set_id = input("Enter the variable set ID: ")
file_policy_id = input("Enter the file policy ID: ")
# Define the base URL for the access control policy (without the /accessrules endpoint)
access_control_policy_base_url = f'{fmc_url}/api/fmc_config/v1/domain/{domain_id}/policy/accesspolicies/{policy_id}'
# Define the API endpoint for the access control policy rules
access_control_policy_url = f'{access_control_policy_base_url}/accessrules'
# Make a GET request to retrieve the current rules for the access control policy
get_response = requests.get(access_control_policy_url, headers={'X-auth-access-token': access_token}, verify=False)
get_response.raise_for_status()
# Parse the JSON response and retrieve the access control policy name
access_control_policy = get_response.json()
# Loop through the rules and update their properties
for rule in access_control_policy['items']:
# Create a new dictionary with the desired keys and values
updated_rule = {
'id': rule['id'],
'ipsPolicy': {'id': intrusion_policy_id},
'variableSet': {'id': variable_set_id},
'FilePolicy': {'id': file_policy_id},
'logBegin': True,
'logEnd': False,
'sendEventsToFMC': True,
'enableSyslog': True
}
# Remove any null values from the dictionary
updated_rule = {k: v for k, v in updated_rule.items() if v is not None}
# Define the API endpoint for the specific rule
object_UUID = rule['id']
access_control_policy_rule_url = f'{access_control_policy_url}/{object_UUID}'
# Make a PUT request to update the access control policy with the modified rule
put_response = requests.put(access_control_policy_rule_url, headers={'X-auth-access-token': access_token, 'Content-Type': 'application/json'}, json=updated_rule, verify=False)
try:
put_response.raise_for_status()
except requests.exceptions.HTTPError as e:
print(f"Error updating rule {object_UUID}: {e}")