Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: check for scheduled update jobs #106

Merged
merged 16 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,5 @@ sidebar.json
.python-version
requirements.txt
.coverage
openssl.cnf
coverage.xml
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ check_line_length:
done < "$$FILE"; \
done

all: lint format security test_coverage documentation
all: format lint security test_coverage documentation
81 changes: 81 additions & 0 deletions docs/panos-upgrade-assurance/api/check_firewall.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,87 @@ __Returns__
* [`CheckStatus.ERROR`](/panos/docs/panos-upgrade-assurance/api/utils#class-checkstatus) when the certificate's
properties (installed or required) are not supported.

### `CheckFirewall.check_non_finished_jobs`

```python
def check_non_finished_jobs() -> CheckResult
```

Check for any job with status different than FIN.

__Returns__


`CheckResult`: Object of [`CheckResult`](/panos/docs/panos-upgrade-assurance/api/utils#class-checkresult) class taking value of:

* [`CheckStatus.SUCCESS`](/panos/docs/panos-upgrade-assurance/api/utils#class-checkstatus) when all jobs are in FIN state.
* [`CheckStatus.FAIL`](/panos/docs/panos-upgrade-assurance/api/utils#class-checkstatus) otherwise, `CheckResult.reason`
field contains information about the 1<sup>st</sup> job found with status different than FIN (job ID and the actual
status).

### `CheckFirewall._calculate_time_distance`

```python
def _calculate_time_distance(schedule_type: str, schedule: dict) -> (int, str)
```

A method that calculates the time distance between two `datetime` objects.

:::note
This method is used only by [`CheckFirewall.check_scheduled_updates()`](/panos/docs/panos-upgrade-assurance/api/check_firewall#checkfirewallcheck_scheduled_updates) method and it expects some information
to be already available.
:::

__Parameters__


- __schedule_type__ (`str`): A schedule type returned by PanOS, can be one of: `every-*`, `hourly`, `daily`, `weekly`,
`real-time`.
- __schedule__ (`dict`): Value of the `recurring` key in the API response, see [`FirewallProxy.get_update_schedules()`](/panos/docs/panos-upgrade-assurance/api/firewall_proxy#firewallproxyget_update_schedules)
documentation for details.

__Raises__


- `MalformedResponseException`: Thrown then the `schedule_type` is not recognizable.

__Returns__


`tuple(int, str)`: A tuple containing the calculated time difference (in minutes) and human-readable description.

### `CheckFirewall.check_scheduled_updates`

```python
def check_scheduled_updates(test_window: int = 60) -> CheckResult
```

Check if any Dynamic Update job is scheduled to run within the specified time window.

__Parameters__


- __test_window__ (`int, optional`): (defaults to 60 minutes). A time window in minutes to look for an update job occurrence.
Has to be a value between `60` and `10080` (1 week equivalent). The time window is calculated based on the device's
local time (taken from the management plane).

__Raises__


- `MalformedResponseException`: Thrown in case API response does not meet expectations.

__Returns__


`CheckResult`: Object of [`CheckResult`](/panos/docs/panos-upgrade-assurance/api/utils#class-checkresult) class taking value of:

* [`CheckStatus.SUCCESS`](/panos/docs/panos-upgrade-assurance/api/utils#class-checkstatus) when there is no update job
planned within the test time window.
* [`CheckStatus.FAIL`](/panos/docs/panos-upgrade-assurance/api/utils#class-checkstatus) otherwise, `CheckResult.reason`
field contains information about the planned jobs with next occurrence time provided if possible.
* [`CheckStatus.ERROR`](/panos/docs/panos-upgrade-assurance/api/utils#class-checkstatus) when the `test_window` parameter
does not meet criteria.

### `CheckFirewall.get_content_db_version`

```python
Expand Down
120 changes: 95 additions & 25 deletions docs/panos-upgrade-assurance/api/firewall_proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ __Returns__
### `FirewallProxy.get_mp_clock`

```python
def get_mp_clock() -> dict
def get_mp_clock() -> datetime
```

Get the clock information from management plane.
Expand All @@ -864,18 +864,7 @@ The actual API command is `show clock`.
__Returns__


`dict`: The clock information represented as a dictionary.

```python showLineNumbers title="Sample output"
{
'time': '00:41:36',
'tz': 'PDT',
'day': '19',
'month': 'Apr',
'year': '2023',
'day_of_week': 'Wed'
}
```
`datetime`: The clock information represented as a `datetime` object.

### `FirewallProxy.get_dp_clock`

Expand All @@ -890,18 +879,7 @@ The actual API command is `show clock more`.
__Returns__


`dict`: The clock information represented as a dictionary.

```python showLineNumbers title="Sample output"
{
'time': '00:41:36',
'tz': 'PDT',
'day': '19',
'month': 'Apr',
'year': '2023',
'day_of_week': 'Wed'
}
```
`datetime`: The clock information represented as a `datetime` object.

### `FirewallProxy.get_certificates`

Expand Down Expand Up @@ -956,3 +934,95 @@ __Returns__
}
```

### `FirewallProxy.get_jobs`

```python
def get_jobs() -> dict
```

Get details on all jobs.

This method retrieves all jobs and their details, this means running, pending, finished, etc.

The actual API command is `show jobs all`.

__Returns__


`dict`: All jobs found on the device, indexed by the ID of a job.

```python showLineNumbers title="Sample output"
{'1': {'description': None,
'details': {'line': ['ID population failed',
'Client logrcvr registered in the middle of a '
'commit/validate. Aborting current '
'commit/validate.',
'Commit failed',
'Failed to commit policy to device']},
'positionInQ': '0',
'progress': '100',
'queued': 'NO',
'result': 'FAIL',
'status': 'FIN',
'stoppable': 'no',
'tdeq': '00:28:32',
'tenq': '2023/08/01 00:28:32',
'tfin': '2023/08/01 00:28:36',
'type': 'AutoCom',
'user': None,
'warnings': None},
'2': {'description': None,
'details': {'line': ['Configuration committed successfully',
'Successfully committed last configuration']},
'positionInQ': '0',
'progress': '100',
'queued': 'NO',
'result': 'OK',
'status': 'FIN',
'stoppable': 'no',
'tdeq': '00:28:40',
'tenq': '2023/08/01 00:28:40',
'tfin': '2023/08/01 00:29:20',
'type': 'AutoCom',
'user': None,
'warnings': None},
'3': {'description': None,
'details': None,
'positionInQ': '0',
'progress': '30',
'queued': 'NO',
'result': 'PEND',
'status': 'ACT',
'stoppable': 'yes',
'tdeq': '00:58:59',
'tenq': '2023/08/01 00:58:59',
'tfin': None,
'type': 'Downld',
'user': None,
'warnings': None}}
```

### `FirewallProxy.get_update_schedules`

```python
def get_update_schedules() -> dict
```

Get schedules for all dynamic updates.

This method gets all scheduled running on a device. This includes the ones pushed from Panorama.

The actual API command is `<show><config><effective-running><xpath>devices/entry/deviceconfig/system/update-schedule</xpath></effective-running></config></show>`.

__Returns__


`dict`: All dynamic updates schedules, key is the entity type to update, like: threats, wildfire, etc.

```python showLineNumbers title="Sample output"
{'threats': {'recurring': {'weekly': {'action': 'download-only',
'at': '01:02',
'day-of-week': 'wednesday'}}},
'wildfire': {'recurring': {'real-time': None}}}
```

4 changes: 4 additions & 0 deletions examples/low_level_methods/run_low_level_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,8 @@

print(f"\n certificates: {firewall.get_certificates()}")

print(f"\n jobs: {firewall.get_jobs()}")

print(f"\n dynamic schedules: {firewall.get_update_schedules()}")

print()
42 changes: 22 additions & 20 deletions examples/readiness_checks/run_readiness_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,13 @@
check_node = CheckFirewall(firewall)

checks = [
# "all",
# "panorama",
# "ntp_sync",
# "candidate_config",
# "active_support",
# # checks below have optional configuration
# {"ha": {"skip_config_sync": True, "ignore_non_functional": True}},
# {"content_version": {"version": "8635-7675"}},
# {"expired_licenses": {"skip_licenses": ["Threat Prevention"]}},
# {"planes_clock_sync": {"diff_threshold": 2}},
# {"free_disk_space": {"image_version": "10.1.6-h6"}},
"all",
"panorama",
"ntp_sync",
"candidate_config",
"check_non_finished_jobs",
FoSix marked this conversation as resolved.
Show resolved Hide resolved
"active_support",
# checks below have optional configuration
{
"certificates_requirements": {
"ecdsa": {
Expand All @@ -101,16 +97,22 @@
}
}
},
{"content_version": {"version": "8635-7675"}},
{"dynamic_updates": {"test_window": 500}},
{"expired_licenses": {"skip_licenses": ["Threat Prevention"]}},
{"ha": {"skip_config_sync": True, "ignore_non_functional": True}},
{"free_disk_space": {"image_version": "10.1.6-h6"}},
{"planes_clock_sync": {"diff_threshold": 2}},
# checks below require additional configuration
# {
# "session_exist": {
# "source": "134.238.135.137",
# "destination": "10.1.0.4",
# "dest_port": "80",
# }
# },
# {"arp_entry_exist": {"ip": "10.0.1.1"}},
# {"ip_sec_tunnel_status": {"tunnel_name": "ipsec_tun"}},
{
"session_exist": {
"source": "134.238.135.137",
"destination": "10.1.0.4",
"dest_port": "80",
}
},
{"arp_entry_exist": {"ip": "10.0.1.1"}},
{"ip_sec_tunnel_status": {"tunnel_name": "ipsec_tun"}},
]

check_readiness = check_node.run_readiness_checks(
Expand Down
Loading
Loading