make sure you have requirements installed on your host
pip install -r requirements.txtusage:
join-sdwan-profile.py --gateway <gateway name> --profile "<profile name>"example:
join-sdwan-profile.py --gateway hq-exl-1 --profile "SD-WAN Gateways"options:
join-sdwan-profile.py --gateway hq-exl --profile "SD-WAN Gateways" [--debug <reuest | response | both> [--env /path/to/.env]Assigns a gateway to an SD-WAN profile via the Check Point Infinity Portal.
All SD-WAN GraphQL calls use the same endpoint. Only the OAuth authentication call uses a different endpoint.
./join-sdwan-profile.py --gateway "<gateway name>" --profile "SD-WAN Gateways" [--debug request|response|both] [--env /path/to/.env]Example:
./join-sdwan-profile.py --gateway "branch-gw" --profile "SD-WAN Gateways" --debug both --env .envNote
To run this automation with SD-WAN, you need to create an Account API Key with admin permission for SD-WAN.
-
Get OAuth token
- Extract
token - Extract
tenant_id
- Extract
-
Run
getAssets- Find and extract the gateway asset ID
-
Run
getSdWanProfiles- Find and extract the SD-WAN profile ID
-
Run
updateSdWanProfile-
Assign the gateway to the profile
-
If the profile is locked:
- Run
discardChanges - Retry
updateSdWanProfile
- Run
-
-
Run
publishChanges -
Run
enforcePolicy
POST https://cloudinfra-gw.portal.checkpoint.com/auth/external| Header | Value |
|---|---|
Content-Type |
application/json |
{
"clientId": "<SD_WAN_Client_ID>",
"accessKey": "<SD_WAN_Client_SecretKey>"
}{
"data": {
"token": "<jwt>"
}
}| Field | Path | Used As |
|---|---|---|
token |
data.token |
Bearer token for all subsequent requests |
tenant_id |
JWT claim tid or tenantId decoded from token |
x-tenant-id header |
POST https://cloudinfra-gw.portal.checkpoint.com/app/sd-wan/graphql/v1| Header | Value |
|---|---|
Authorization |
Bearer <token> |
Content-Type |
application/json |
Accept |
application/json |
x-tenant-id |
<tenant_id> — optional, included only when non-empty |
The script first tries to search for the gateway by name. If no match is found, it can fall back to retrieving all assets.
{
"query": "query GetAssets($matchSearch: String) { getAssets(matchSearch: $matchSearch) { assets { id name } } }",
"variables": {
"matchSearch": "<gateway-name>"
}
}{
"query": "query { getAssets { assets { id name } } }",
"variables": {}
}{
"data": {
"getAssets": {
"assets": [
{
"id": "abc-123",
"name": "hq-exl"
},
{
"id": "def-456",
"name": "branch-gw"
}
]
}
}
}| Field | Match Condition | Used As |
|---|---|---|
data.getAssets.assets[].id |
name == gateway_name or gateway_name in name |
gateway_asset_id passed to updateSdWanProfile |
{
"query": "query { getSdWanProfiles { id name } }",
"variables": {}
}{
"data": {
"getSdWanProfiles": [
{
"id": "profile-111",
"name": "SD-WAN Gateways"
},
{
"id": "profile-222",
"name": "Branch Profiles"
}
]
}
}| Field | Match Condition | Used As |
|---|---|---|
data.getSdWanProfiles[].id |
name == profile_name or profile_name in name |
profile_id passed to updateSdWanProfile |
{
"query": "mutation UpdateSdWanProfile($id: ID!, $input: SdWanProfileUpdateInput!) { updateSdWanProfile(id: $id input: $input) }",
"variables": {
"id": "<profile_id>",
"input": {
"addSdWanGateways": [
"<gateway_asset_id>"
],
"removeSdWanGateways": []
}
}
}{
"data": {
"updateSdWanProfile": true
}
}{
"errors": [
{
"message": "forbidden-status: profile is locked"
}
]
}| Field | Condition | Action |
|---|---|---|
data.updateSdWanProfile |
true |
Success. Continue to publishChanges. |
errors[0].message |
Contains lock or forbidden-status |
Run discardChanges, then retry updateSdWanProfile once. |
errors[0].message |
Any other error | Exit with error. |
This step is only used when updateSdWanProfile fails because the profile is locked.
{
"query": "mutation { discardChanges }",
"variables": {}
}The response is ignored.
After this call, updateSdWanProfile is retried once using the same request body from Step 4.
{
"query": "mutation { publishChanges { isValid } }",
"variables": {}
}{
"data": {
"publishChanges": {
"isValid": true
}
}
}| Field | Condition | Action |
|---|---|---|
data.publishChanges.isValid |
true |
Changes are valid. Continue to enforcePolicy. |
data.publishChanges.isValid |
false |
Print a warning. This is treated as non-fatal and execution continues. |
{
"query": "mutation { enforcePolicy { id status } }",
"variables": {}
}{
"data": {
"enforcePolicy": {
"id": "task-789",
"status": "pending"
}
}
}| Field | Used As |
|---|---|
data.enforcePolicy.id |
Printed as task tracking reference |
data.enforcePolicy.status |
Printed as informational status |
Important
This flow does not poll the enforce task after it has been triggered.
In some environments, it may be useful to add task polling after
enforcePolicyto verify the final result.
Create a .env file and store the SD-WAN API credentials there.
SD_WAN_CLIENT_ID="<your-client-id>"
SD_WAN_CLIENT_SECRET_KEY="<your-secret-key>"Make sure the .env file is not committed to Git.
Add it to .gitignore:
.envThe script supports optional debug output.
--debug request
--debug response
--debug both| Debug Option | Description |
|---|---|
request |
Print outgoing request details |
response |
Print API response details |
both |
Print both request and response details |
This automation performs the following actions:
- Authenticates against the Infinity Portal.
- Finds the target gateway asset.
- Finds the target SD-WAN profile.
- Adds the gateway to the SD-WAN profile.
- Handles profile lock errors by discarding pending changes and retrying.
- Publishes the changes.
- Enforces the SD-WAN policy.