diff --git a/README.md b/README.md
index 2d59296..8ac6756 100644
--- a/README.md
+++ b/README.md
@@ -15,11 +15,14 @@ Simplified Python library for BMC Discovery API Interface that makes use of the
"api_versions": [
"1.0",
"1.1",
- "1.2"
+ "1.2",
+ "1.3",
+ "1.4",
+ "1.5"
],
"component": "REST API",
"product": "BMC Discovery",
- "version": "12.2"
+ "version": "12.5"
}
```
@@ -33,11 +36,11 @@ Documentation can be found at [https://traversys.github.io/Tideway/](https://tra
## Releases
-| Version | Summary | Known Issues | Fixed |
-| :-----: | ------------------------------------------------------ | -------------------------------------------------------------- | ------------------------------ |
-| 0.1.0 | Initial release, compatible with API v1.1 | | |
-| 0.1.1 | Updated to API v1.2
Added `help()`, `search_bulk()` | search call retains last parameters for `offset`, `results_id` | |
-| 0.1.2 | Bug Fixes | Bulk search with larger limit than dataset will fail on missing `next_offset` | Fixed issue with `offset` and `results_id` values
Fixed issue with bulk search parameter lower limit. |
-| 0.1.3 | Bug Fixes | | Added check for `next_offset`. |
-| 0.1.4 | Search bulk update | Discovery 12.3 (21.3) enforces strict case for "Bearer" header - api calls will not current work. | Now includes headers for non-formatted search. |
-| 0.1.5 | Updated to support Discovery 12.3 (API version 1.3) | | Fixed issue with Bearer capitalisation.
Search Bulk will now return the full response on failure |
+| Version | Summary | Known Issues | Fixed |
+| :-----: | ------------------------- | -------------------------------------------------- | -------------------------------- |
+| 0.1.1 | - Updated to API v1.2
- Added `help()`, `search_bulk()` | search call retains last parameters for `offset`, `results_id` | |
+| 0.1.2 | Bug Fixes | Bulk search with larger limit than dataset will fail on missing `next_offset` | - Fixed issue with `offset` and `results_id` values
- Fixed issue with bulk search parameter lower limit. |
+| 0.1.3 | Bug Fixes | | Added check for `next_offset`. |
+| 0.1.4 | Search bulk update | Discovery 12.3 (21.3) enforces strict case for "Bearer" header - api calls will not current work. | Now includes headers for non-formatted search. |
+| 0.1.5 | Updated to support Discovery 12.3 (API version 1.3) | - Missing 'complete' parameter option on graphNode() function. | - Fixed issue with Bearer capitalisation.
- Search Bulk will now return the full response on failure |
+| 0.2.0 | Updated to include Kerberos, Models and Taxonomy endpoints.
Added new high level generic endpoint function calls
Refactored function names/decorators to match API endpoints as close as possible.
Supports Discovery 22.2 (12.5) (API version 1.5) and Outpost API version 1.0 | Not all new unctions have been tested. | Added 'complete' parameter to `get_data_nodes_graph()` (replaces `graphNode()`) |
diff --git a/docs/endpoints/admin.md b/docs/endpoints/admin.md
index e5e9ae6..ed79d36 100644
--- a/docs/endpoints/admin.md
+++ b/docs/endpoints/admin.md
@@ -1,5 +1,5 @@
---
-sort: 9
+sort: 1
---
# Admin
@@ -16,42 +16,54 @@ Initiation:
```python
>>> import tideway
->>> tw = tideway.admin('appliance-hostname','auth-token')
+>>> tw = tideway.admin('hostname','auth-token')
```
-## baseline()
+## get_admin_baseline
-- Get a summary of the appliance status, and details of which baseline checks have passed or failed.
+Get a summary of the appliance status, and details of which baseline checks have passed or failed.
Syntax:
```
-.baseline()
+.get_admin_baseline
```
Example:
```python
->>> tw.baseline().json()['results']['FAILED'][0]
+>>> tw.get_admin_baseline.json()['results']['FAILED'][0]
{'enabled': True, 'message': 'MAJOR: This appliance has insufficent resources', 'name': 'Appliance Specification', 'severity': 'MAJOR'}
```
-## about()
+## get_admin_about
Get the versions of the API supported by a BMC Discovery version.
Syntax:
```
-.about()
+.get_admin_about
```
Example:
```python
->>> tw.about().json()
+>>> tw.get_admin_about.json()
{'api_versions': ['1.0', '1.1', '1.2'], 'component': 'REST API', 'product': 'BMC Discovery', 'version': '12.2'}
```
+## baseline()
+
+[Deprecated] See [get_admin_baseline](#get_admin_baseline) for usage.
+
+Syntax: `.baseline()`
+
+## about()
+
+[Deprecated] See [get_admin_about](#get_admin_about) for usage.
+
+Syntax: `.about()`
+
## licensing()
Get the latest signed licensing report.
diff --git a/docs/endpoints/appliance.md b/docs/endpoints/appliance.md
index e6b06df..4a7d8d2 100644
--- a/docs/endpoints/appliance.md
+++ b/docs/endpoints/appliance.md
@@ -1,53 +1,101 @@
---
-sort: 1
+sort: 2
---
-# Appliance
+# Appliance or Outpost
-Initiate an Appliance object for the instance of Discovery you intend to query.
+Initiate an Appliance or Outpost object for the instance of Discovery you intend to query.
Syntax:
```
tideway.appliance(__target__, __token__ [, _api_version_ ] [, _ssl_verify_ ] [, _limit_ ] [, _offset_ ])
+tideway.outpost(__target__, __token__ [, _api_version_ ] [, _ssl_verify_ ] [, _limit_ ] [, _offset_ ])
```
Initiation:
```python
>>> import tideway
->>> tw = tideway.appliance('appliance-hostname','auth-token')
+>>> tw = tideway.appliance('hostname','auth-token')
```
-## about()
+## api_about
Get the versions of the API supported by a BMC Discovery version.
Syntax:
```
-.about()
+.api_about
```
Example:
```python
->>> tw.about().json()
+>>> tw.api_about.json()
{'api_versions': ['1.0', '1.1', '1.2'], 'component': 'REST API', 'product': 'BMC Discovery', 'version': '12.2'}
```
-## admin()
+## api_swagger
+
+Get JSON swagger file which contains the API schema.
+
+Syntax:
+
+```
+.api_swagger
+```
+
+Example:
+
+```python
+>>> swagger = tw.api_swagger
+>>> from pprint import pprint
+>>> pprint(api_swagger.json()['tags'])
+[{'description': 'Control scanning and view results', 'name': 'discovery'},
+ {'description': 'Read and import data', 'name': 'data'},
+ {'description': 'Manage the credential vault', 'name': 'vault'},
+ {'description': 'Manage credentials', 'name': 'credentials'},
+ {'description': 'Upload new TKUs and pattern modules', 'name': 'knowledge'},
+ {'description': 'Push events', 'name': 'events'},
+ {'description': 'Manage the BMC Discovery appliance', 'name': 'admin'},
+ {'description': 'Retrieve topology data from the datastore', 'name': 'topology'}]
+```
+
+## api_help
+
+Outputs full list of help methods see [help()](#help).
+
+## get_admin_baseline
+
+- Get a summary of the appliance status, and details of which baseline checks have passed or failed.
+
+Syntax:
+
+```
+.get_admin_baseline
+```
+
+Example:
+
+```python
+>>> tw.get_admin_baseline.json()['results']['FAILED'][0]
+{'enabled': True, 'message': 'MAJOR: This appliance has insufficent resources', 'name': 'Appliance Specification', 'severity': 'MAJOR'}
+```
+
+## get_admin_about
Get information about the appliance, like its version and versions of the installed packages.
Syntax:
```
-.admin()
+.get_admin_about
```
Example:
```python
->>> details = tw.admin().text
+>>> details = tw.get_admin_about.text
>>> print(details)
{
"versions": {
@@ -59,49 +107,208 @@ Example:
}
```
-## swagger()
+## get_admin_licensing
-Get JSON swagger file which contains the API schema.
+Get the latest signed licensing report in plain text.
Syntax:
```
-.swagger()
+.get_admin_licensing
```
Example:
+```python
+>>> tw.get_admin_licensing.text
+-----BEGIN LICENSE REPORT-----
+License report
+==============
+
+Report start time: 2021-01-18 23:00:00.409987+00:00
+Report end time : 2021-01-21 23:00:00.410085+00:00
+...
+```
+
+## get_admin_licensing_csv
+
+Get the latest raw license data in CSV format as a zip file for offline analysis.
+
+Syntax:
+```
+.get_admin_licensing_csv
+```
+
+Example:
```python
->>> swagger = tw.swagger()
->>> from pprint import pprint
->>> pprint(swagger.json()['tags'])
-[{'description': 'Control scanning and view results', 'name': 'discovery'},
- {'description': 'Read and import data', 'name': 'data'},
- {'description': 'Manage the credential vault', 'name': 'vault'},
- {'description': 'Manage credentials', 'name': 'credentials'},
- {'description': 'Upload new TKUs and pattern modules', 'name': 'knowledge'},
- {'description': 'Push events', 'name': 'events'},
- {'description': 'Manage the BMC Discovery appliance', 'name': 'admin'},
- {'description': 'Retrieve topology data from the datastore', 'name': 'topology'}]
+>>> tw.get_admin_licensing_csv
+
```
-## baseline()
+## get_admin_licensing_raw
-- Get a summary of the appliance status, and details of which baseline checks have passed or failed.
+Get the latest license data as encrypted raw license object for import to another appliance.
+
+Syntax:
+
+```
+.get_admin_licensing_raw
+```
+
+Example:
+```python
+>>> tw.get_admin_licensing_raw
+
+```
+
+## get()
+
+Run a direct endpoint query using GET request.
Syntax:
```
-.baseline()
+.get(__endpoint__)
```
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| endpoint | String | Yes | N/A | N/A |
+
Example:
+```python
+>>> tw.get("/vault")
+{
+ "open": true,
+ "passphrase_saved": false,
+ "passphrase_set": false
+}
+```
+## post()
+
+Run a direct endpoint query using POST.
+
+Syntax:
+
+```
+.post(__endpoint__, __body__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| endpoint | String | Yes | N/A | N/A |
+| body | JSON Object | Yes | N/A | N/A |
+
+Example:
```python
->>> tw.baseline().json()['results']['FAILED'][0]
-{'enabled': True, 'message': 'MAJOR: This appliance has insufficent resources', 'name': 'Appliance Specification', 'severity': 'MAJOR'}
+>>> tw.post("/data/search",{"query": "search Host show os_class process with unique()"})
+[
+ {
+ 'count': 3,
+ 'kind': 'Unique row',
+ 'offset': 0,
+ 'results': [
+ {
+ 'os_class': 'UNIX'
+ },
+ {
+ 'os_class': 'Windows'
+ },
+ {
+ 'os_class': 'Other'
+ }
+ ]
+ }
+]
+```
+
+## delete()
+
+Run a direct endpoint query using DELETE. The endpoint is assumed to contain a specific identifier parsed as a string query.
+
+Syntax:
+
+```
+.delete(__endpoint__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| endpoint | String | Yes | N/A | N/A |
+
+Example:
+```python
+>>> tw.delete("/discovery/runs/scheduled/{run_id}")
+
+```
+
+## patch()
+
+Run a direct endpoint query using PATCH.
+
+Syntax:
+
+```
+.patch(__endpoint__, __body__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| endpoint | String | Yes | N/A | N/A |
+| body | JSON Object | Yes | N/A | N/A |
+
+Example:
+```python
+>>> tw.patch("/discovery/runs/scheduled/{run_id}",{"enabled": true})
+
+```
+
+## put()
+
+Run a direct endpoint query using PUT.
+
+Syntax:
+
+```
+.put(__endpoint__, __body__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| endpoint | String | Yes | N/A | N/A |
+| body | JSON Object | Yes | N/A | N/A |
+
+Example:
+```python
+>>> tw.put("/vault/credentials/{cred_id}",{"enabled": true})
+
```
+## about()
+
+[Deprecated] See [api_about](#api_about) for usage.
+
+Syntax: `.about()`
+
+## admin()
+
+[Deprecated] See [get_admin_about](#get_admin_about) for usage.
+
+Syntax: `.admin()`
+
+## swagger()
+
+[Deprecated] See [api_swagger](#api_swagger) for usage.
+
+Syntax: `.swagger()`
+
+## baseline()
+
+[Deprecated] See [get_admin_baseline](#get_admin_baseline) for usage.
+
+Syntax: `.baseline()`
+
## licensing()
Get the latest signed licensing report.
@@ -137,7 +344,9 @@ Report end time : 2021-01-21 23:00:00.410085+00:00
Syntax:
-```.help(([ _endpoint_ ]))```
+```
+.help([ _endpoint_ ])
+```
| Parameters | Type | Required | Default Value | Options |
| ------------ | ------ | :------: | ------------- | ----------------------------------------------- |
@@ -154,4 +363,4 @@ Endpoint Function Description
/vault/credentials/{cred_id} updateCredential(cred_id, body) Updates partial resources of a credential. Missing properties are left unchanged.
/vault/credentials/{cred_id} replaceCredential(cred_id, body) Replaces a single credential. All required credential properties must be present.
-```
+```
\ No newline at end of file
diff --git a/docs/endpoints/credentials.md b/docs/endpoints/credentials.md
index d00cdc6..204c1b0 100644
--- a/docs/endpoints/credentials.md
+++ b/docs/endpoints/credentials.md
@@ -1,5 +1,5 @@
---
-sort: 5
+sort: 3
---
# Credentials
@@ -20,14 +20,14 @@ Initiation:
>>> credentials = tw.credentials()
```
-## listCredentialTypes()
+## get_vault_credential_type()
Get a list of all credential types and filter by group and/or category.
Syntax:
```
-.listCredentialTypes([ _group_ ] [, _category_ ])
+.get_vault_credential_type([ _group_ ] [, _category_ ])
```
| Parameters | Type | Required | Default Value | Options |
@@ -38,7 +38,7 @@ Syntax:
Example:
```python
->>> db_creds = credentials.listCredentialTypes(category="Database")
+>>> db_creds = credentials.get_vault_credential_type(category="Database")
>>> from pprint import pprint
>>> pprint(db_creds.json())
[
@@ -57,14 +57,18 @@ Example:
...
```
-## credentialType()
+## get_vault_credential_types
+
+List all credential types. See [get_vault_credential_type](#get_vault_credential_type).
+
+## get_vault_credential_type_name()
Get the properties of a specific credential type.
Syntax:
```
-.credentialType(__cred_type_name__)
+.get_vault_credential_type_name(__cred_type_name__)
```
| Parameters | Type | Required | Default Value | Options |
@@ -72,7 +76,7 @@ Syntax:
| cred_type_name | String | Yes | N/A | N/A |
```python
->>> ora_creds.credentials.credentialType("oracle").json()
+>>> ora_creds.credentials.get_vault_credential_type_name("oracle").json()
>>> from pprint import pprint
>>> pprint(ora_creds.json())
{
@@ -90,14 +94,14 @@ Syntax:
}
```
-## listCredentials()
+## get_vault_credential()
Get a list of credentials.
Syntax:
```
-.listCredentials([ _uuid_ ])
+.get_vault_credential([ _uuid_ ])
```
| Parameters | Type | Required | Default Value | Options |
@@ -107,19 +111,23 @@ Syntax:
Example:
```python
->>> creds = credentials.listCredentials("e7f00000106c1")
+>>> creds = credentials.get_vault_credential("e7f00000106c1")
>>> print(creds.json()['types'])
['ssh']
```
-## newCredential()
+## get_vault_credentials
+
+List all vault credentials. See [get_vault_credential](#get_vault_credential).
+
+## post_vault_credential()
Create a new credential.
Syntax:
```
-.newCredential(__json__)
+.post_vault_credential(__json__)
```
| Parameters | Type | Required | Default Value | Options |
@@ -129,17 +137,17 @@ Syntax:
Example:
```python
->>> credentials.newCredential({"enabled": True,"username": "discovery_service","password": "password","label": "SSH Service Account","description": "Service Account for SSH","ip_range": "0.0.0.0/0,::/0","types": ["ssh"]}).ok
+>>> credentials.post_vault_credential({"enabled": True,"username": "discovery_service","password": "password","label": "SSH Service Account","description": "Service Account for SSH","ip_range": "0.0.0.0/0,::/0","types": ["ssh"]}).ok
True
```
-## deleteCredential()
+## delete_vault_credential()
Delete a credential.
Syntax:
```
-.deleteCredential([ _uuid_ ])
+.delete_vault_credential([ _uuid_ ])
```
| Parameters | Type | Required | Default Value | Options |
@@ -149,17 +157,17 @@ Syntax:
Example:
```python
->>> credentials.deleteCredential("e7f00000106c1").ok
+>>> credentials.delete_vault_credential("e7f00000106c1").ok
True
```
-## updateCredential()
+## patch_vault_credential()
Updates partial resources of a credential. Missing properties are left unchanged.
Syntax:
```
-.updateCredential(__uuid__, __json__)
+.patch_vault_credential(__uuid__, __json__)
```
| Parameters | Type | Required | Default Value | Options |
@@ -170,11 +178,11 @@ Syntax:
Example:
```python
->>> credentials.updateCredential("a1b2c3d4e5f6",{ "enabled" : False }).ok
+>>> credentials.patch_vault_credential("a1b2c3d4e5f6",{ "enabled" : False }).ok
True
```
-## replaceCredential()
+## put_vault_credential()
Replaces a single credential.
@@ -184,7 +192,7 @@ All required credential properties must be present. Optional properties that are
Syntax:
```
-.replaceCredential(__uuid__, __json__)
+.put_vault_credential(__uuid__, __json__)
```
| Parameters | Type | Required | Default Value | Options |
@@ -195,6 +203,48 @@ Syntax:
Example:
```python
->>> tc.replaceCredential("a1b2c3d4e5f6",{"enabled": True,"username": "discovery_service","password": "password","label": "Limited SSH Discovery","description": "Limited SSH Service Account","ip_range": "192.168.1.0/24","types":["ssh"]}).ok
+>>> credentials.put_vault_credential("a1b2c3d4e5f6",{"enabled": True,"username": "discovery_service","password": "password","label": "Limited SSH Discovery","description": "Limited SSH Service Account","ip_range": "192.168.1.0/24","types":["ssh"]}).ok
True
-```
\ No newline at end of file
+```
+
+## listCredentialTypes()
+
+[Deprecated] See [get_vault_credential_type](#get_vault_credential_type) for usage.
+
+Syntax: `.listCredentialTypes([ _group_ ] [, _category_ ])`
+
+## credentialType()
+
+[Deprecated] See [get_vault_credential_type_name](#get_vault_credential_type_name) for usage.
+
+Syntax: `.credentialType(__cred_type_name__)`
+
+## listCredentials()
+
+[Deprecated] See [get_vault_credential](#get_vault_credential) for usage.
+
+Syntax: `.listCredentials([ _uuid_ ])`
+
+## newCredential()
+
+[Deprecated] See [post_vault_credential](#post_vault_credential) for usage.
+
+Syntax: `.newCredential(__json__)`
+
+## deleteCredential()
+
+[Deprecated] See [delete_vault_credential](#delete_vault_credential) for usage.
+
+Syntax: `.deleteCredential([ _uuid_ ])`
+
+## updateCredential()
+
+[Deprecated] See [patch_vault_credential](#patch_vault_credential) for usage.
+
+Syntax: `.updateCredential(__uuid__, __json__)`
+
+## replaceCredential()
+
+[Deprecated] See [put_vault_credential](#put_vault_credential) for usage.
+
+Syntax: `.replaceCredential(__uuid__, __json__)`
\ No newline at end of file
diff --git a/docs/endpoints/data.md b/docs/endpoints/data.md
index 29a1cf3..35d99e5 100644
--- a/docs/endpoints/data.md
+++ b/docs/endpoints/data.md
@@ -1,5 +1,5 @@
---
-sort: 3
+sort: 4
---
# Data
@@ -20,6 +20,30 @@ Initiation:
>>> data = tw.data()
```
+## get_data_search()
+
+Default search. See [search](#search) for usage.
+
+## post_data_search()
+
+Alternative search method. See [search](#search) for usage.
+
+## get_data_search_object()
+
+Search defaulted to 'object' format. See [search](#search) for usage.
+
+## post_data_search_object()
+
+Alternative search method defaulted to 'object' format. See [search](#search) for usage.
+
+## get_data_search_tree()
+
+Search defaulted to 'tree' format. See [search](#search) for usage.
+
+## post_data_search_tree()
+
+Alternative search method defaulted to 'tree' format. See [search](#search) for usage.
+
## search()
Run a search query, receiving paginated results.
@@ -32,7 +56,7 @@ Syntax:
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
-| query |
| Yes | N/A | - "search string"
- {"query":"search string"}
|
+| query | | Yes | N/A | N/A |
| offset | Integer | No | N/A | N/A |
| results_id | String | No | N/A | N/A |
| format | String | No | N/A | |
@@ -96,59 +120,121 @@ Example: This search_bulk() returns 500 results each time, and makes 2 additiona
1510
```
-## searchQuery()
+## post_data_condition()
-An alternative to GET /data/search, for search queries which are too long for urls.
-
-```note
-This method is deprecated. You can use search() for both JSON arguments and search strings.
-```
+Search using a condition, return tabular results as arrays.
Syntax:
```
-.search(__json__ [, _offset_ ] [, _results_id_ ] [, _format_ ] [, _limit_ ] [, _delete_ ])
+.post_data_condition(__body__ [, _offset_ ] [, _results_id_ ] [, _format_ ] [, _limit_ ] [, _delete_ ])
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
-| json | JSON Object | Yes | N/A | {"query":"search string"} |
+| body | JSON Object | Yes | N/A | N/A |
| offset | Integer | No | N/A | N/A |
| results_id | String | No | N/A | N/A |
| format | String | No | N/A | |
| limit | Integer | No | 100 | N/A |
| delete | Boolean | No | False | |
+## post_data_condition_param_values()
+
+Get possible parameter values for a condition.
+
+Syntax:
+
+```
+.post_data_condition_param_values(__body__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| body | JSON Object | Yes | N/A | N/A |
+
+## get_data_condition_template()
+
+Get a list of all available templates.
+
+Syntax:
+
+```
+.get_data_condition_template([ _template_id_ ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| template_id | String | No | N/A | N/A |
+
+Example:
+
```python
->>> data.searchQuery({"query": "search Host show os_class process with unique()"}, format="object").json()
-[
- {
- 'count': 3,
- 'kind': 'Unique row',
- 'offset': 0,
- 'results': [
- {
- 'os_class': 'UNIX'
- },
- {
- 'os_class': 'Windows'
- },
- {
- 'os_class': 'Other'
- }
- ]
- }
-]
+>>> templates = data.get_data_condition_template()
+>>> print(templates.text)
+[]
```
-## nodeLookup()
+## get_data_condition_templates
+
+Get a list of all available templates. See [get_data_condition_template](#get_data_condition_template).
+
+## post_data_candidate()
+
+The node object of the best candidate based on the provided parameters.
+
+Syntax:
+
+```
+.post_data_candidate(__json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| json | JSON Object | Yes | N/A | N/A |
+
+Example:
+
+```python
+>>> candidates = data.post_data_candidate({"hostname": "disco","kind" : "Host"})
+>>> print(candates.text)
+{
+ "#id": "30c577625e064d10300b17ea6e486f7374",
+ "__all_dns_names": [
+ "disco.local"
+ ],
+ "__all_ip_addrs": [
+ "10.16.15.99",
+ "fe80::4bcc:a31c:43a:c258"
+ ],
+ "__all_mac_addrs": [
+ "02:11:32:23:29:f0"
+ ],
+...
+```
+
+## post_data_candidates()
+
+Enter parameters to identify a device, the response is a list of candidate nodes ordered by descending score.
+
+Syntax:
+
+```
+.post_data_candidates(__json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| json | JSON Object | Yes | N/A | N/A |
+
+## get_data_nodes()
Get the state of a node with specified id.
Syntax:
```
-.nodeLookup(__node_id__ [, _relationships_ ] [, _traverse_ ] [, _flags_ ])
+.get_data_nodes(__node_id__ [, _relationships_ ] [, _traverse_ ] [, _flags_ ])
```
| Parameters | Type | Required | Default Value | Options |
@@ -161,19 +247,35 @@ Syntax:
Example:
```python
->>> node = data.nodeLookup("a1b2c3d4e5f6")
+>>> node = data.get_data_nodes("a1b2c3d4e5f6")
>>> print(node.json()['state']['os_type'])
Windows Desktop
```
-## lookupNodeKind()
+## get_data_nodes_graph()
+
+Graph data represents a set of nodes and relationships that are associated to the given node.
+
+Syntax:
+
+```
+.get_data_nodes_graph(__node_id__ [, _focus_ ] [, _apply_rules_ ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| node_id | JSON Object | Yes | N/A | N/A |
+| focus | String | No | N/A | - "software-connected"
- "software"
- "infrastructure"
|
+| apply_rules | Boolean | No | False | |
+
+## get_data_kinds()
Finds all nodes of a specified node kind.
Syntax:
```
-.lookupNodeKind(__kind__ [, _offset_ ] [, _results_id_ ] [, _format_ ] [, _limit_ ] [, _delete_ ])
+.get_data_kinds(__kind__ [, _offset_ ] [, _results_id_ ] [, _format_ ] [, _limit_ ] [, _delete_ ])
```
| Parameters | Type | Required | Default Value | Options |
@@ -188,41 +290,25 @@ Syntax:
Example: Gets result #50 from list of nodes
```python
->>> sis = data.lookupNodeKind("SoftwareInstance")
+>>> sis = data.get_data_kinds("SoftwareInstance")
>>> print(sis.json()[0]['results'][50])
['0x7761771a5876f667606e53426', 'Apache Webserver', 'Apache Webserver 2.4 on batman3', '2.4', 'batman3']
```
-## graphNode()
+## get_data_partitions
Graph data represents a set of nodes and relationships that are associated to the given node.
Syntax:
```
-.graphNode(__node_id__ [, _focus_ ] [, _apply_rules_ ])
-```
-
-| Parameters | Type | Required | Default Value | Options |
-| ------------- | ----------- | :------: | ------------- | -------- |
-| node_id | JSON Object | Yes | N/A | N/A |
-| focus | String | No | N/A | - "software-connected"
- "software"
- "infrastructure"
|
-| apply_rules | Boolean | No | False | |
-
-## partitions()
-
-Graph data represents a set of nodes and relationships that are associated to the given node.
-
-Syntax:
-
-```
-.partitions()
+.get_data_partitions()
```
Example:
```python
->>> partitions = data.partions()
+>>> partitions = data.get_data_partitions()
>>> from pprint import pprint
>>> pprint(partitions.json())
{
@@ -236,58 +322,98 @@ Example:
}
```
-## candidate()
+## searchQuery()
-The node object of the best candidate based on the provided parameters.
+[Deprecated] See [search](#search) for usage.
-Syntax:
+Syntax: `.searchQuery(__json__ [, _offset_ ] [, _results_id_ ] [, _format_ ] [, _limit_ ] [, _delete_ ])`
-```
-.candidate(__json__)
-```
+## nodeLookup()
-| Parameters | Type | Required | Default Value | Options |
-| ------------- | ----------- | :------: | ------------- | -------- |
-| json | JSON Object | Yes | N/A | N/A |
+[Deprecated] See [get_data_nodes](#get_data_nodes) for usage.
-## candidates()
+Syntax: `.nodeLookup(__node_id__ [, _relationships_ ] [, _traverse_ ] [, _flags_ ])`
-Enter parameters to identify a device, the response is a list of candidate nodes ordered by descending score.
+## lookupNodeKind()
+
+[Deprecated] See [get_data_kinds](#get_data_kinds) for usage.
+
+Syntax: `.lookupNodeKind(__kind__ [, _offset_ ] [, _results_id_ ] [, _format_ ] [, _limit_ ] [, _delete_ ])`
+
+## graphNode()
+
+[Deprecated] See [get_data_nodes_graph](#get_data_nodes_graph) for usage.
+
+Syntax: `.graphNode(__node_id__ [, _focus_ ] [, _apply_rules_ ]))`
+
+## partitions()
+
+[Deprecated] See [get_data_nodes_graph](#get_data_nodes_graph) for usage.
+
+Syntax: `.partitions()`
+
+## post_data_partitions()
+
+Create a Partition.
Syntax:
```
-.candidates(__json__)
+.post_data_partitions(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
| json | JSON Object | Yes | N/A | N/A |
-## twImport()
+## post_data_import()
Imports data. Returns the import UUID.
Syntax:
```
-.twImport(__json__)
+.post_data_import(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
| json | JSON Object | Yes | N/A | N/A |
-## twWrite()
+## post_data_write()
Perform arbitrary write operations.
Syntax:
```
-.twWrite(__json__)
+.post_data_write(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
-| json | JSON Object | Yes | N/A | N/A |
\ No newline at end of file
+| json | JSON Object | Yes | N/A | N/A |
+
+## best_candidate()
+
+[Deprecated] See [post_data_candidate](#post_data_candidate) for usage.
+
+Syntax: `.post_data_candidate(__JSON__)`
+
+## top_candidates()
+
+[Deprecated] See [post_data_candidates](#post_data_candidates) for usage.
+
+Syntax: `.post_data_candidates(__json__)`
+
+## twImport()
+
+[Deprecated] See [post_data_import](#post_data_import) for usage.
+
+Syntax: `.twImport(__json__)`
+
+## twWrite()
+
+[Deprecated] See [post_data_write](#post_data_write) for usage.
+
+Syntax: `.twWrite(__json__)`
\ No newline at end of file
diff --git a/docs/endpoints/discovery.md b/docs/endpoints/discovery.md
index 964b60f..3e154a1 100644
--- a/docs/endpoints/discovery.md
+++ b/docs/endpoints/discovery.md
@@ -1,5 +1,5 @@
---
-sort: 2
+sort: 5
---
# Discovery
@@ -20,30 +20,30 @@ Initiation:
>>> discovery = tw.discovery()
```
-## getDiscoveryStatus()
+## get_discovery
Get the current status of the discovery process.
Syntax:
```
-.getDiscoveryStatus()
+.get_discovery
```
Example:
```python
->>> >>> discovery.getDiscoveryStatus().json()
+>>> >>> discovery.get_discovery.json()
{'running': False, 'status': 'running'}
```
-## setDiscoveryStatus()
+## patch_discovery()
Start or stop the discovery process.
Syntax:
```
-.setDiscoveryStatus(__json__)
+.patch_discovery(__json__)
```
| Parameters | Type | Required | Default Value | Options |
@@ -53,87 +53,139 @@ Syntax:
Example:
```python
->>> >>> discovery.getDiscoveryStatus().json()
+>>> >>> discovery.get_discovery.json()
{'running': False, 'status': 'stopped'}
->>> discovery.setDiscoveryStatus({"status": "running"}).ok
+>>> discovery.patch_discovery({"status": "running"}).ok
True
->>> >>> discovery.getDiscoveryStatus().json()
+>>> >>> discovery.get_discovery.json()
{'running': False, 'status': 'running'}
```
-## getApiProviderMetadata()
+## get_discovery_api_provider_metadata
Get metadata for the API providers currently supported by BMC Discovery.
Syntax:
```
-.getApiProviderMetadata()
+.get_discovery_api_provider_metadata
```
```python
->>> discovery.getApiProviderMetadata().json()[0]['cred_params'][0]
+>>> discovery.get_discovery_api_provider_metadata.json()[0]['cred_params'][0]
{'allowed_values': [], 'description': 'URL of the Kubernetes/OpenShift cluster with port', 'is_list': False, 'mandatory': False, 'name': 'kubernetes.cluster_url', 'type': 'str'}
```
-## getDiscoveryCloudMetaData()
+## get_discovery_api_cloud_metadata
Get metadata for the cloud providers currently supported by BMC Discovery.
Syntax:
```
-.getDiscoveryCloudMetaData()
+.get_discovery_api_cloud_metadata
```
```python
-discovery.getDiscoveryCloudMetaData().json()[0]['cred_params'][0]
+discovery.get_discovery_api_cloud_metadata.json()[0]['cred_params'][0]
{'allowed_values': [], 'description': 'Azure Directory ID (also known as the Tenant ID)', 'is_list': False, 'mandatory': True, 'name': 'azure.tenant_id', 'type': 'str'}
```
-## discoveryRun()
+## getDiscoveryStatus()
-Create a new snapshot discovery run.
+[Deprecated] See [get_discovery](#get_discovery) for usage.
+
+Syntax: `.getDiscoveryStatus()`
+
+## setDiscoveryStatus()
+
+[Deprecated] See [patch_discovery](#patch_discovery) for usage.
+
+Syntax: `.setDiscoveryStatus(__json__)`
+
+## getApiProviderMetadata()
+
+[Deprecated] See [get_discovery_api_provider_metadata](#get_discovery_api_provider_metadata) for usage.
+
+Syntax: `.getApiProviderMetadata()`
+
+## getDiscoveryCloudMetaData()
+
+[Deprecated] See [get_discovery_api_cloud_metadata](#get_discovery_api_cloud_metadata) for usage.
+
+Syntax: `.getDiscoveryCloudMetaData()`
+
+## get_discovery_exclude()
+
+Get a list of all or specific excludes.
Syntax:
```
-.discoveryRun(__json__)
+.get_discovery_exclude([ _exclude_id_ ])
```
| Parameters | Type | Required | Default Value | Options |
| ------------ | ----------- | :------: | ------------- | --------|
-| json | JSON Object | Yes | N/A | N/A |
+| exclude_id | String | No | N/A | N/A |
+
+## get_discovery_excludes
+
+Get a list of all excludes. See [get_discovery_exclude](#get_discovery_exclude).
+
+Syntax: `.get_discovery_excludes`
+
+## post_discovery_exclude()
+
+Update an exclude list.
+
+Syntax:
-Example:
-```python
->>> discovery.discoveryRun({"ranges":[ "192.168.1.0/24" ],"label":"Network Snapshot","scan_level":"Full Discovery"}).ok
-True
```
-## getDiscoveryRuns()
+.post_discovery_exclude(__json__)
+```
-Get details of all currently processing discovery runs.
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | --------|
+| json | JSON Object | Yes | N/A | N/A |
+
+## delete_discovery_exclude()
+
+Delete an exclude list.
Syntax:
```
-.getDiscoveryRuns()
+.delete_discovery_exclude(__exclude_id__)
```
-Example:
-```python
->>> discovery.getDiscoveryRuns().json()
-[]
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | --------|
+| exclude_id | String | Yes | N/A | N/A |
+
+## patch_discovery_exclude()
+
+Update an exclude list.
+
+Syntax:
+
+```
+.patch_discovery_exclude(__json__, __exclude_id__)
```
-## getDiscoveryRun()
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | --------|
+| json | JSON Object | Yes | N/A | N/A |
+| exclude_id | String | Yes | N/A | N/A |
+
+## get_discovery_run()
Get details of specific currently processing discovery run.
Syntax:
```
-.getDiscoveryRun(__run_id__)
+.get_discovery_run(__run_id__)
```
| Parameters | Type | Required | Default Value | Options |
@@ -142,7 +194,7 @@ Syntax:
Example:
```python
->>> run = discovery.getDiscoveryRun("1234567890")
+>>> run = discovery.get_discovery_run("1234567890")
>>> from pprint import pprint
>>> pprint(run.json())
[
@@ -158,69 +210,85 @@ Example:
]
```
-## updateDiscoveryRun()
+## get_discovery_runs
-Update the state of a specific discovery run.
+Get details of all currently processing discovery runs. See [get_discovery_run](#get_discovery_run).
+
+Syntax: `.get_discovery_runs`
+
+## post_discovery_run()
+
+Create a new snapshot discovery run.
Syntax:
```
-.updateDiscoveryRun(__run_id__, __json__)
+.post_discovery_run(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------ | ----------- | :------: | ------------- | --------|
-| run_id | String | Yes | N/A | N/A |
| json | JSON Object | Yes | N/A | N/A |
Example:
```python
->>> discovery.updateDiscoveryRun("1234567890", {"cancelled": True}).ok
+>>> discovery.post_discovery_run({"ranges":[ "192.168.1.0/24" ],"label":"Network Snapshot","scan_level":"Full Discovery"}).ok
True
```
-## getDiscoveryRunResults()
+## patch_discovery_run()
-Get a summary of the results from scanning all endpoints in the run, partitioned by result type.
+Update the state of a specific discovery run.
Syntax:
```
-.getDiscoveryRunResults(__run_id__)
+.patch_discovery_run(__run_id__, __json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------ | ----------- | :------: | ------------- | --------|
| run_id | String | Yes | N/A | N/A |
+| json | JSON Object | Yes | N/A | N/A |
Example:
```python
->>> run = discovery.getDiscoveryRunResults("1234567890")
->>> print(run.text)
-{
- "Dropped": {
- "count": 204,
- "uri": "https://appliance/api/v1.2/discovery/runs/1234567890/results/Dropped"
- },
- "Skipped": {
- "count": 3,
- "uri": "https://appliance/api/v1.2/discovery/runs/1234567890/results/Skipped"
- },
- "Success": {
- "count": 47,
- "uri": "https://appliance/api/v1.2/discovery/runs/1234567890/results/Success"
- }
-}
+>>> discovery.patch_discovery_run("1234567890", {"cancelled": True}).ok
+True
```
-## getDiscoveryRunResult()
+## getDiscoveryRun()
+
+[Deprecated] See [get_discovery_run](#get_discovery_run) for usage.
+
+Syntax: `.getDiscoveryRun(__run_id__)`
+
+## getDiscoveryRuns()
+
+[Deprecated] See [get_discovery_runs](#get_discovery_runs) for usage.
+
+Syntax: `.getDiscoveryRuns()`
+
+## discoveryRun()
+
+[Deprecated] See [post_discovery_run](#post_discovery_run) for usage.
-Get a summary of the results from scanning all endpoints in the run that had a specific type of result.
+Syntax: `.discoveryRun(__json__)`
+
+## updateDiscoveryRun()
+
+[Deprecated] See [patch_discovery_run](#patch_discovery_run) for usage.
+
+Syntax: `.updateDiscoveryRun(__run_id__, __json__)`
+
+## get_discovery_run_results()
+
+Get a summary of the results from scanning all endpoints in the run, partitioned by result type that had a specific type of result.
Syntax:
```
-.getDiscoveryRunResult(__run_id__ [, result ] [, offset ] [, results_id ] [, format ] [, limit ] [, delete ])
+.get_discovery_run_results(__run_id__ [, result ] [, offset ] [, results_id ] [, format ] [, limit ] [, delete ])
```
| Parameters | Type | Required | Default Value | Options |
@@ -233,43 +301,52 @@ Syntax:
| limit | Integer | No | 100 | N/A |
| delete | Boolean | No | False | |
-Example: Retrieve DiscoveryRuns which ended with an Error, and retrieve result rows 51-100.
+Example:
```python
->>> discovery.getDiscoveryRunResult("1234567890", result="Error", offset=50, results_id="a12b3cd4e5f6", limit=50)
+>>> run = discovery.get_discovery_run_results("1234567890")
+>>> print(run.text)
+{
+ "Dropped": {
+ "count": 204,
+ "uri": "https://appliance/api/v1.2/discovery/runs/1234567890/results/Dropped"
+ },
+ "Skipped": {
+ "count": 3,
+ "uri": "https://appliance/api/v1.2/discovery/runs/1234567890/results/Skipped"
+ },
+ "Success": {
+ "count": 47,
+ "uri": "https://appliance/api/v1.2/discovery/runs/1234567890/results/Success"
+ }
+}
```
-## getDiscoveryRunInferred()
-Get a summary of all inferred devices from a discovery run, partitioned by device type.
+## getDiscoveryRunResults()
-Syntax:
+[Deprecated] See [get_discovery_run_results](#get_discovery_run_results) for usage.
-```
-.getDiscoveryRunInferred(__run_id__)
-```
+Syntax: `.getDiscoveryRunResults(__run_id__)`
-| Parameters | Type | Required | Default Value | Options |
-| ------------ | ----------- | :------: | ------------- | -------- |
-| run_id | String | Yes | N/A | N/A |
+## getDiscoveryRunResult()
-Example:
-```python
->>> discovery.getDiscoveryRunInferred("1234567890")
-```
+[Deprecated] See [get_discovery_run_results](#get_discovery_run_results) for usage.
-## getDiscoveryRunInferredKind()
+Syntax: `.getDiscoveryRunResults(__run_id__, __result__ [, offset ] [, results_id ] [, format ] [, limit ] [, delete ])`
-Get a summary of the devices inferred by a discovery run which have a specific inferred kind.
+## get_discovery_run_inferred()
+
+Get a summary of all inferred devices from a discovery run, partitioned by device type and/or which have a specific inferred kind.
Syntax:
```
-.getDiscoveryRunInferredKind(__run_id__ , __inferred_kind__ [, offset ] [, results_id ] [, format ] [, limit ] [, delete ])
+.get_discovery_run_inferred(__run_id__ [, inferred_kind ] [, offset ] [, results_id ] [, format ] [, limit ] [, delete ])
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
| run_id | String | Yes | N/A | N/A |
-| inferred_kind | String | Yes | N/A | N/A |
+| inferred_kind | String | No | N/A | N/A |
| offset | Integer | No | N/A | N/A |
| results_id | String | No | N/A | N/A |
| format | String | No | N/A | |
@@ -278,7 +355,7 @@ Syntax:
Example:
```python
->>> result = discovery.getDiscoveryRunResult("1234567890", "Host", format="object")
+>>> result = discovery.get_discovery_run_inferred("1234567890", "Host", format="object")
>>> print(result.text)
[
{
@@ -295,4 +372,79 @@ Example:
],
'#id': 'A1B2C3D4E5F6'
...
-```
\ No newline at end of file
+```
+
+## getDiscoveryRunInferred()
+
+[Deprecated] See [get_discovery_run_inferred](#get_discovery_run_inferred) for usage.
+
+Syntax: `.getDiscoveryRunInferred(__run_id__)`
+
+## getDiscoveryRunInferredKind()
+
+[Deprecated] See [get_discovery_run_inferred](#get_discovery_run_inferred) for usage.
+
+Syntax: `.getDiscoveryRunInferredKind(__run_id__ , __inferred_kind__ [, offset ] [, results_id ] [, format ] [, limit ] [, delete ])`
+
+## get_discovery_run_schedule()
+
+Get a list of all or specific scan schedules.
+
+Syntax:
+
+```
+.get_discovery_run_schedule([ _run_id_ ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | --------|
+| run_id | String | No | N/A | N/A |
+
+## get_discovery_run_schedules()
+
+Get a list of all or specific scan schedules. See [get_discovery_run_schedule](#get_discovery_run_schedule).
+
+Syntax: `.get_discovery_run_schedules`
+
+## post_discovery_run_schedule()
+
+Add a new scan schedule.
+
+Syntax:
+
+```
+.post_discovery_run_schedule(__json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | --------|
+| json | JSON Object | Yes | N/A | N/A |
+
+## delete_discovery_run_schedule()
+
+Delete a specific scan schedule.
+
+Syntax:
+
+```
+.delete_discovery_run_schedule(__run_id__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | --------|
+| run_id | String | Yes | N/A | N/A |
+
+## patch_discovery_run_schedule()
+
+Update a specific scan schedule.
+
+Syntax:
+
+```
+.patch_discovery_run_schedule(__run_id__, __json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | --------|
+| run_id | String | Yes | N/A | N/A |
+| json | JSON Object | Yes | N/A | N/A |
\ No newline at end of file
diff --git a/docs/endpoints/events.md b/docs/endpoints/events.md
index 8e6f89e..4592449 100644
--- a/docs/endpoints/events.md
+++ b/docs/endpoints/events.md
@@ -1,5 +1,5 @@
---
-sort: 7
+sort: 6
---
# Events
@@ -20,16 +20,22 @@ Initiation:
>>> events = tw.events()
```
-## status()
+## post_events()
Returns a unique ID if the event has been recorded, otherwise an empty string is returned e.g. if the event source has been disabled.
Syntax:
```
-.status(__json__)
+.post_events(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
| json | JSON Object | Yes | N/A | N/A |
+
+## status()
+
+[Deprecated] See [post_events](#post_events) for usage.
+
+Syntax: `.status(__json__)`
\ No newline at end of file
diff --git a/docs/endpoints/kerberos.md b/docs/endpoints/kerberos.md
new file mode 100644
index 0000000..cf1eb30
--- /dev/null
+++ b/docs/endpoints/kerberos.md
@@ -0,0 +1,172 @@
+---
+sort: 7
+---
+
+# Kerberos
+
+Initiate a kerberos object for the instance of Discovery you intend to query.
+
+Syntax:
+
+```
+tideway.kerberos(__target__, __token__ [, _api_version_ ] [, _ssl_verify_ ])
+```
+
+Initiation:
+
+```python
+>>> import tideway
+>>> tw = tideway.appliance('appliance-hostname','auth-token')
+>>> kerberos = tw.kerberos()
+```
+
+## get_vault_kerberos_realm()
+
+Retrieve all or specific realm.
+
+Syntax:
+
+```
+.get_vault_kerberos_realm([ _realm_name_ ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | No | N/A | N/A |
+
+## get_vault_kerberos_realms
+
+Retrieve all realms. See [get_vault_kerberos_realm](#get_vault_kerberos_realm).
+
+Syntax: `.get_vault_kerberos_realms`
+
+## post_vault_kerberos_realm()
+
+Create a realm and Test user credentials by attempting to acquire a new Kerberos Ticket Granting Ticket (TGT)
+
+Syntax:
+
+```
+.post_vault_kerberos_realm(__realm_name__, __json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+| json | JSON Object | Yes | N/A | N/A |
+
+## delete_vault_kerberos_realm()
+
+Delete a realm.
+
+Syntax:
+```
+.delete_vault_kerberos_realm(__realm_name__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+
+## patch_vault_kerberos_realm()
+
+Update a Kerberos realm.
+
+Syntax:
+```
+.patch_vault_kerberos_realm(__realm_name__, __json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+| json | JSON Object | Yes | N/A | N/A |
+
+## get_vault_kerberos_keytabs()
+
+List users with a Kerberos keytab file.
+
+Syntax:
+
+```
+.get_vault_kerberos_keytabs(__realm_name__, __username__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+| username | String | Yes | N/A | N/A |
+
+## post_vault_kerberos_keytab()
+
+Upload a Kerberos keytab file.
+
+Syntax:
+
+```
+.post_vault_kerberos_keytab(__realm_name__, __username__, __keytab_file__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+| username | String | Yes | N/A | N/A |
+| keytab_file | File Object | Yes | N/A | N/A |
+
+## delete_vault_kerberos_keytab()
+
+Delete a keytab file.
+
+Syntax:
+```
+.delete_vault_kerberos_keytab(__realm_name__, __username__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+| username | String | Yes | N/A | N/A |
+
+## get_vault_kerberos_ccaches()
+
+List users with a Kerberos credential cache file.
+
+Syntax:
+
+```
+.get_vault_kerberos_ccaches(__realm_name__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+
+## post_vault_kerberos_ccache()
+
+Upload a Kerberos credential cache file.
+
+Syntax:
+
+```
+.post_vault_kerberos_ccache(__realm_name__, __username__, __cache_file__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+| username | String | Yes | N/A | N/A |
+| cache_file | File Object | Yes | N/A | N/A |
+
+## delete_vault_kerberos_ccache()
+
+Delete a cedential cache file.
+
+Syntax:
+```
+.delete_vault_kerberos_ccache(__realm_name__, __username__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| realm_name | String | Yes | N/A | N/A |
+| username | String | Yes | N/A | N/A |
\ No newline at end of file
diff --git a/docs/endpoints/knowledge.md b/docs/endpoints/knowledge.md
index 8534e9f..0652108 100644
--- a/docs/endpoints/knowledge.md
+++ b/docs/endpoints/knowledge.md
@@ -1,5 +1,5 @@
---
-sort: 6
+sort: 8
---
# Knowledge
@@ -20,37 +20,37 @@ Initiation:
>>> knowledge = tw.knowledge()
```
-## getKnowledgeManagement()
+## get_knowledge
Get the current state of the appliance's knowledge, including TKU versions.
Syntax:
```
-.getKnowledgeManagement()
+.get_knowledge
```
Example:
```python
->>> >>> knowledge.getKnowledgeManagement().json()['latest_tku']['submission_date']
+>>> >>> knowledge.get_knowledge.json()['latest_tku']['submission_date']
'2021-05-24T23:06:00.350840+00:00'
```
-## getUploadStatus()
+## get_knowledge_status
Get the current state of a knowledge upload.
Syntax:
```
-.getUploadStatus()
+.get_knowledge_status
```
Example:
```python
->>> upload = knowledge.getUploadStatus()
+>>> upload = knowledge.get_knowledge_status
>>> from pprint import pprint
>>> pprint(upload.json())
{
@@ -68,14 +68,14 @@ Example:
}
```
-## uploadKnowledge()
+## post_knowledge()
Upload a TKU or pattern module to the appliance.
Syntax:
```
-.uploadKnowledge(__filename__, __file__ [, _activate_ ] [, _allow_restart_ ])
+.post_knowledge(__filename__, __file__ [, _activate_ ] [, _allow_restart_ ])
```
| Parameters | Type | Required | Default Value | Options |
@@ -88,6 +88,24 @@ Syntax:
Example:
```python
->>> knowledge.uploadKnowledge("TestPattern.tpl","C:/Users/User001/Documents/TestPattern.tpl").ok
+>>> knowledge.post_knowledge("TestPattern.tpl","C:/Users/User001/Documents/TestPattern.tpl").ok
True
-```
\ No newline at end of file
+```
+
+## getKnowledgeManagement()
+
+[Deprecated] See [get_knowledge](#get_knowledge) for usage.
+
+Syntax: `.getKnowledgeManagement()`
+
+## getUploadStatus()
+
+[Deprecated] See [get_knowledge_status](#get_knowledge_status) for usage.
+
+Syntax: `.getUploadStatus()`
+
+## uploadKnowledge()
+
+[Deprecated] See [post_knowledge](#post_knowledge) for usage.
+
+Syntax: `.uploadKnowledge(__filename__, __file__ [, _activate_ ] [, _allow_restart_ ])`
\ No newline at end of file
diff --git a/docs/endpoints/models.md b/docs/endpoints/models.md
new file mode 100644
index 0000000..0764365
--- /dev/null
+++ b/docs/endpoints/models.md
@@ -0,0 +1,250 @@
+---
+sort: 9
+---
+
+# Models
+
+Initiate a Model object for the instance of Discovery you intend to query.
+
+Syntax:
+
+```
+tideway.models(__target__, __token__ [, _api_version_ ] [, _ssl_verify_ ])
+```
+
+Initiation:
+
+```python
+>>> import tideway
+>>> tw = tideway.appliance('appliance-hostname','auth-token')
+>>> model = tw.models()
+```
+
+## get_model()
+
+Retrieve service and application models.
+
+Syntax:
+
+```
+.get_model([ _name_ ] [, type ] [, kind ] [, published ] [, review_suggested ] [, version ] [, favorite ] [, compatibility ] [, results_id ] [, delete ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | -------- |
+| name | String | No | N/A | N/A |
+| type | String | No | N/A | - "rules_template"
- "rules"
- "sam"
- "static"
- "instance"
- "imported"
|
+| kind | String | No | N/A | - "BusinessService"
- "TechnicalService"
- "BusinessApplicationInstance"
|
+| published | Boolean | No | N/A | |
+| review_suggested | Boolean | No | N/A | |
+| version | String | No | N/A | N/A |
+| favorite | Boolean | No | N/A | |
+| compatibility | String | No | N/A | N/A |
+| results_id | String | No | N/A | N/A |
+| delete | Boolean | No | False | |
+
+## get_models
+
+Retrieve all models. See [get_model](#get_model).
+
+Syntax: `.get_models`
+
+## post_model()
+
+Create a new model.
+
+Syntax:
+
+```
+.post_model(__json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| json | JSON Object | Yes | N/A | N/A |
+
+## post_model_multi()
+
+Create multiple new models.
+
+Syntax:
+
+```
+.post_model_multi(__json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| json | JSON Object | Yes | N/A | N/A |
+
+## get_model_key()
+
+Get model definition for the specified key.
+
+Syntax:
+
+```
+.get_model_key(__key__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| key | String | Yes | N/A | N/A |
+
+## delete_model()
+
+Delete a model.
+
+Syntax:
+```
+.delete_model(__key__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| key | String | Yes | N/A | N/A |
+
+## patch_model()
+
+Update a model.
+
+Syntax:
+```
+.patch_model(__key__, __json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| key | String | Yes | N/A | N/A |
+| json | JSON Object | Yes | N/A | N/A |
+
+## get_model_topology()
+
+Get topology for the model definition specified by key.
+
+Syntax:
+
+```
+.get_model_topology(__key__ [, attributes ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| key | String | Yes | N/A | N/A |
+| attributes | String (CSV) | No | N/A | N/A |
+
+## get_model_nodecount()
+
+Get node count for the model definition specified by key.
+
+Syntax:
+
+```
+.get_model_nodecount(__key__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| key | String | Yes | N/A | N/A |
+
+## get_model_nodes()
+
+Retrieve service and application models.
+
+Syntax:
+
+```
+.get_model_nodes(__key__ [, results_id ] [, delete ] [, kind ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | -------- |
+| key | String | Yes | N/A | N/A |
+| results_id | String | No | N/A | N/A |
+| delete | Boolean | No | False | |
+| kind | String | No | N/A | N/A |
+
+## get_model_by_node_id()
+
+Get model definition for the specified node id.
+
+Syntax:
+```
+.get_model_by_node_id(__node_id__ [, expand_related ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| node_id | String | Yes | N/A | N/A |
+| expand_related | Boolean | Yes | N/A | |
+
+## delete_model_by_node_id()
+
+Delete a model.
+
+Syntax:
+```
+.delete_model_by_node_id(__node_id__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| node_id | String | Yes | N/A | N/A |
+
+## patch_model_by_node_id()
+
+Delete a model.
+
+Syntax:
+```
+.patch_model_by_node_id(__node_id__, __json__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| node_id | String | Yes | N/A | N/A |
+| json | JSON Object | Yes | N/A | N/A |
+
+## get_topology_by_node_id()
+
+Delete a model.
+
+Syntax:
+```
+.get_topology_by_node_id(__node_id__ [, attributes ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| node_id | String | Yes | N/A | N/A |
+| attributes | String (CSV) | No | N/A | N/A |
+
+## get_nodecount_by_node_id()
+
+Get node count for the model definition specified by node id.
+
+Syntax:
+```
+.get_nodecount_by_node_id(__node_id__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| node_id | String | Yes | N/A | N/A |
+
+## get_nodes_by_node_id()
+
+Get nodes for the model definition specified by node id.
+
+Syntax:
+
+```
+.get_nodes_by_node_id(__node_id__ [, results_id ] [, delete ] [, kind ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------ | ----------- | :------: | ------------- | -------- |
+| key | String | Yes | N/A | N/A |
+| results_id | String | No | N/A | N/A |
+| delete | Boolean | No | False | |
+| kind | String | No | N/A | N/A |
\ No newline at end of file
diff --git a/docs/endpoints/taxonomy.md b/docs/endpoints/taxonomy.md
new file mode 100644
index 0000000..a311fae
--- /dev/null
+++ b/docs/endpoints/taxonomy.md
@@ -0,0 +1,98 @@
+---
+sort: 10
+---
+
+# Taxonomy
+
+Initiate a Taxonomy object for the instance of Discovery you intend to query.
+
+Syntax:
+
+```
+tideway.taxonomy(__target__, __token__ [, _api_version_ ] [, _ssl_verify_ ])
+```
+
+Initiation:
+
+```python
+>>> import tideway
+>>> tw = tideway.appliance('appliance-hostname','auth-token')
+>>> taxonomy = tw.taxonomy()
+```
+
+## get_taxonomy_sections
+
+Get list of taxonomy model sections.
+
+Syntax:
+
+```
+.get_taxonomy_sections
+```
+
+## get_taxonomy_locales
+
+Get list of known taxonomy locales.
+
+Syntax:
+
+```
+.get_taxonomy_locales
+```
+
+## get_taxonomy_nodekind()
+
+Get list of defined node kinds with kind info.
+
+Syntax:
+```
+.get_taxonomy_nodekind([ format ] [, section ] [, locale ] [, kind ] [, fieldlists ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| format | String | No | N/A | N/A |
+| section | String | No | N/A | N/A |
+| kind | String | No | N/A | N/A |
+| fieldlists | Boolean | No | False | |
+
+## get_taxonomy_nodekinds
+
+Get list of all node kinds with kind info. See [get_taxonomy_nodekind](#get_taxonomy_nodekind).
+
+Syntax: `.get_taxonomy_nodekinds`
+
+## get_taxonomy_nodekind_fieldlist()
+
+Get list of fields for a node kind field list.
+
+Syntax:
+```
+.get_taxonomy_nodekind_fieldlist(__kind__, __fieldlists__)
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| kind | String | Yes | N/A | N/A |
+| fieldlists | String | Yes | N/A | N/A |
+
+## get_taxonomy_relkind()
+
+Get list of defined node kinds with kind info.
+
+Syntax:
+```
+.get_taxonomy_relkind( [ format, locale ] [, kind ])
+```
+
+| Parameters | Type | Required | Default Value | Options |
+| ------------- | ----------- | :------: | ------------- | -------- |
+| format | String | No | N/A | N/A |
+| locale | String | No | N/A | N/A |
+| kind | String | No | N/A | N/A |
+
+## get_taxonomy_relkinds
+
+Get list of all node kinds with kind info. See [get_taxonomy_relkinds](#get_taxonomy_relkinds).
+
+Syntax: `.get_taxonomy_relkinds`
\ No newline at end of file
diff --git a/docs/endpoints/topology.md b/docs/endpoints/topology.md
index f47e96e..ac6a2df 100644
--- a/docs/endpoints/topology.md
+++ b/docs/endpoints/topology.md
@@ -1,5 +1,5 @@
---
-sort: 8
+sort: 11
---
# Topology
@@ -20,14 +20,14 @@ Initiation:
>>> topo = tw.topology()
```
-## graphNode()
+## get_data_nodes_graph()
Graph data represents a set of nodes and relationships that are associated to the given node.
Syntax:
```
-.graphNode(__node_id__ [, _focus_ ] [, _apply_rules_ ])
+.get_data_nodes_graph(__node_id__ [, _focus_ ] [, _apply_rules_ ])
```
| Parameters | Type | Required | Default Value | Options |
@@ -36,66 +36,103 @@ Syntax:
| focus | String | No | N/A | - "software-connected"
- "software"
- "infrastructure"
|
| apply_rules | Boolean | No | False | |
-## getNodes()
+## post_topology_nodes()
Get topology data from one or more starting nodes.
Syntax:
```
-.getNodes(__json__)
+.post_topology_nodes(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
| json | JSON Object | Yes | N/A | N/A |
-## getNodeKinds()
+## post_topology_nodes_kinds()
Get nodes of the specified kinds which are related to a given set of nodes.
Syntax:
```
-.getNodeKinds(__json__)
+.post_topology_nodes_kinds(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
| json | JSON Object | Yes | N/A | N/A |
-## visualizationState()
+## graphNode()
+
+[Deprecated] See [get_data_nodes_graph](#get_data_nodes_graph) for usage.
+
+Syntax: `.graphNode(__node_id__ [, _focus_ ] [, _apply_rules_ ])`
+
+## getNodes()
+
+[Deprecated] See [post_topology_nodes](#post_topology_nodes) for usage.
+
+Syntax: `.getNodes(__json__)`
+
+## getNodeKinds()
+
+[Deprecated] See [post_topology_nodes_kinds](#post_topology_nodes_kinds) for usage.
+
+Syntax: `.getNodeKinds(__json__)`
+
+## get_topology_viz_state
Get the current state of the visualization for the authenticated user.
Syntax:
```
-.visualizationState()
+.get_topology_viz_state
```
-## updateVizState()
+## patch_topology_viz_state()
Update one or more attributes of the current state of the visualization for the authenticated user.
Syntax:
```
-.updateVizState(__json__)
+.patch_topology_viz_state(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
| json | JSON Object | Yes | N/A | N/A |
-## replaceVizState()
+
+## put_topology_viz_state()
Update any or all of the attributes of the current state of the visualization for the authenticated user.
Syntax:
```
-replaceVizState(__json__)
+put_topology_viz_state(__json__)
```
| Parameters | Type | Required | Default Value | Options |
| ------------- | ----------- | :------: | ------------- | -------- |
| json | JSON Object | Yes | N/A | N/A |
+
+## visualizationState()
+
+[Deprecated] See [get_topology_viz_state](#get_topology_viz_state) for usage.
+
+Syntax: `.visualizationState()`
+
+## updateVizState()
+
+[Deprecated] See [patch_topology_viz_state](#patch_topology_viz_state) for usage.
+
+Syntax: `.updateVizState(__json__)`
+
+## replaceVizState()
+
+[Deprecated] See [put_topology_viz_state](#put_topology_viz_state) for usage.
+
+Syntax: `.replaceVizState(__json__)`
\ No newline at end of file
diff --git a/docs/endpoints/vault.md b/docs/endpoints/vault.md
index 700d85c..8bfa8bc 100644
--- a/docs/endpoints/vault.md
+++ b/docs/endpoints/vault.md
@@ -1,5 +1,5 @@
---
-sort: 4
+sort: 12
---
# Vault
@@ -20,31 +20,31 @@ Initiation:
>>> vault = tw.vault()
```
-## getVault()
+## get_vault
Get details of the state of the vault.
Syntax:
```
-.getVault()
+.get_vault
```
Example:
```python
->>> vault.getVault().json()
+>>> vault.get_vault.json()
{'open': True, 'passphrase_saved': False, 'passphrase_set': False}
```
-## updateVault()
+## patch_vault()
Change the state of the vault.
Syntax:
```
-.updateVault(__json__)
+.patch_vault(__json__)
```
| Parameters | Type | Required | Default Value | Options |
@@ -54,6 +54,18 @@ Syntax:
Example:
```python
->>> vault.updateVault({"open": True,"passphrase":"long pass phrase"}).ok
+>>> vault.patch_vault({"open": True,"passphrase":"long pass phrase"}).ok
True
-```
\ No newline at end of file
+```
+
+## getVault()
+
+[Deprecated] See [get_vault](#get_vault) for usage.
+
+Syntax: `.getVault()`
+
+## updateVault()
+
+[Deprecated] See [patch_vault](#patch_vault) for usage.
+
+Syntax: `.updateVault(__json__)`
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index c5e696e..669c3de 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -15,11 +15,14 @@ Simplified Python library for BMC Discovery API Interface that makes use of the
"api_versions": [
"1.0",
"1.1",
- "1.2"
+ "1.2",
+ "1.3",
+ "1.4",
+ "1.5"
],
"component": "REST API",
"product": "BMC Discovery",
- "version": "12.2"
+ "version": "12.5"
}
```
@@ -35,7 +38,7 @@ Tideway removes the extra layer of manually constructing a URL and parameters fo
$ python -m pip install tideway
```
-- Tideway supports BMC Discovery 11.3+, API v1.2 using Python 3.
+- Tideway supports BMC Discovery 11.3+, API v1.0-1.5 using Python 3.
## Contents
@@ -43,11 +46,11 @@ $ python -m pip install tideway
## Releases
-| Version | Summary | Known Issues | Fixed |
-| :-----: | ------------------------------------------------------ | -------------------------------------------------------------- | ------------------------------ |
-| 0.1.0 | Initial release, compatible with API v1.1 | | |
-| 0.1.1 | Updated to API v1.2
Added `help()`, `search_bulk()` | search call retains last parameters for `offset`, `results_id` | |
-| 0.1.2 | Bug Fixes | Bulk search with larger limit than dataset will fail on missing `next_offset` | Fixed issue with `offset` and `results_id` values
Fixed issue with bulk search parameter lower limit. |
-| 0.1.3 | Bug Fixes | | Added check for `next_offset`. |
-| 0.1.4 | Search bulk update | Discovery 12.3 (21.3) enforces strict case for "Bearer" header - api calls will not current work. | Now includes headers for non-formatted search. |
-| 0.1.5 | Updated to support Discovery 12.3 (API version 1.3) | | Fixed issue with Bearer capitalisation.
Search Bulk will now return the full response on failure |
+| Version | Summary | Known Issues | Fixed |
+| :-----: | ------------------------- | -------------------------------------------------- | -------------------------------- |
+| 0.1.1 | - Updated to API v1.2
- Added `help()`, `search_bulk()` | search call retains last parameters for `offset`, `results_id` | |
+| 0.1.2 | Bug Fixes | Bulk search with larger limit than dataset will fail on missing `next_offset` | - Fixed issue with `offset` and `results_id` values
- Fixed issue with bulk search parameter lower limit. |
+| 0.1.3 | Bug Fixes | | Added check for `next_offset`. |
+| 0.1.4 | Search bulk update | Discovery 12.3 (21.3) enforces strict case for "Bearer" header - api calls will not current work. | Now includes headers for non-formatted search. |
+| 0.1.5 | Updated to support Discovery 12.3 (API version 1.3) | - Missing 'complete' parameter option on graphNode() function. | - Fixed issue with Bearer capitalisation.
- Search Bulk will now return the full response on failure |
+| 0.2.0 | Updated to include Kerberos, Models and Taxonomy endpoints.
Added new high level generic endpoint function calls
Refactored function names/decorators to match API endpoints as close as possible.
Supports Discovery 22.2 (12.5) (API version 1.5) and Outpost API version 1.0 | Not all new functions have been tested. | Added 'complete' parameter to `get_data_nodes_graph()` (replaces `graphNode()`) |
diff --git a/docs/quickstart/initiation.md b/docs/quickstart/initiation.md
index 8684f16..3079ac6 100644
--- a/docs/quickstart/initiation.md
+++ b/docs/quickstart/initiation.md
@@ -6,21 +6,25 @@ sort: 1
In order to make use of an API endpoint, you will need to initiate an object representing an instance of Discovery using an authentication token (generated in the GUI) and a hostname, fqdn or ip address.
-Initiating an instance is done by creating an 'appliance' object:
+Initiating an instance is done by creating an discovery or outpost object:
-`tideway.appliance(,)`
+`tideway.appliance(,)`
+`tideway.outpost(,)`
Or you can specify one of the following top-level endpoints:
```python
-tideway.discovery()
-tideway.data()
-tideway.vault()
+tideway.admin()
tideway.credential()
-tideway.knowledge()
+tideway.data()
+tideway.discovery()
tideway.events()
-tideway.admin()
+tideway.kerberos()
+tideway.knowledge()
+tideway.models()
+tideway.taxonomy()
tideway.topology()
+tideway.vault()
```
Upon initiation the following parameters can be used:
@@ -28,5 +32,5 @@ Upon initiation the following parameters can be used:
| - | - | - | - | -
| target | Required | String | | The Hostname, FQDN or IP Address of the Discovery instance.
| token | Required | String | | The authentication token of the API user. It is not necessary to include the "bearer" pre-text.
-| api_version | | String | "1.3" | This should be the supported version of the API. Discovery 12.3 supports API versions up to 1.3.
+| api_version | | String | "1.5" | This should be the supported version of the API. Discovery 22.2 supports API versions up to 1.5 (outpost 1.0).
| ssl_verify | | Boolean | False | Choose whether to query the API using a valid SSL certificate. If you are using self-signed HTTPS then you should leave this with the default value.
\ No newline at end of file
diff --git a/docs/quickstart/responses.md b/docs/quickstart/responses.md
index 5a1f3e1..e2e5d09 100644
--- a/docs/quickstart/responses.md
+++ b/docs/quickstart/responses.md
@@ -8,7 +8,7 @@ sort: 2
## Input
```python
->>> tw = tideway.appliance('appliance-hostname','auth-token')
+>>> tw = tideway.appliance('appliance-hostname','auth-token',api_version='1.2')
>>> response = tw.about()
```
diff --git a/setup.py b/setup.py
index 132a1c2..ac5520f 100644
--- a/setup.py
+++ b/setup.py
@@ -5,10 +5,10 @@
setuptools.setup(
name="tideway",
- version="0.1.5",
+ version="0.2.0",
author="Wes Moskal-Fitzpatrick",
author_email="wes@traversys.io",
- description="library for BMC Discovery API Interface.",
+ description="Library for BMC Discovery API Interface.",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/traversys/tideway",
diff --git a/tideway/__init__.py b/tideway/__init__.py
index 3d624ab..8e6c906 100644
--- a/tideway/__init__.py
+++ b/tideway/__init__.py
@@ -9,19 +9,26 @@
credentials, \
knowledge, \
events, \
+ kerberos, \
+ models, \
+ taxonomy, \
topology
# Main declaration to create an appliance object
appliance = main.Appliance
+outpost = main.Appliance
# For the previous version classes single file - moved to main.py
# Method 1: tideway._________(appliance,token)
# method 2: tideway.________.func(appliance)
-discovery = discovery.Discovery
-data = data.Data
-vault = vault.Vault
+admin = admin.Admin
credentials = credentials.Credentials
-knowledge = knowledge.Knowledge
+data = data.Data
+discovery = discovery.Discovery
events = events.Events
-admin = admin.Admin
+kerberos = kerberos.Kerberos
+knowledge = knowledge.Knowledge
+models = models.Models
+taxonomy = taxonomy.Taxonomy
topology = topology.Topology
+vault = vault.Vault
diff --git a/tideway/admin.py b/tideway/admin.py
index 6059d95..dea98f9 100644
--- a/tideway/admin.py
+++ b/tideway/admin.py
@@ -1,15 +1,10 @@
# -*- coding: utf-8 -*-
-import requests
import tideway
dr = tideway.discoRequests
appliance = tideway.main.Appliance
-# class Test:
-# def __init__(self):
-# self.help = "Help!"
-
class Admin(appliance):
'''Manage the BMC Discovery appliance.'''
@@ -17,11 +12,13 @@ def baseline(self):
'''Get a summary of the appliance status, and details of which baseline checks have passed or failed.'''
response = dr.discoRequest(self, "/admin/baseline")
return response
+ get_admin_baseline = property(baseline)
def admin(self):
'''Get information about the appliance, like its version and versions of the installed packages.'''
response = dr.discoRequest(self, "/admin/about")
return response
+ get_admin_about = property(admin)
def licensing(self,content_type="text/plain"):
'''Get the latest signed licensing report.'''
diff --git a/tideway/credentials.py b/tideway/credentials.py
index 78c68db..84301f6 100644
--- a/tideway/credentials.py
+++ b/tideway/credentials.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
-import requests
import tideway
dr = tideway.discoRequests
@@ -9,6 +8,14 @@
class Credentials(appliance):
'''Manage credentials.'''
+ def get_vault_credential_type(self, group=None, category=None):
+ '''Altnernate API call for /vault/credential_types.'''
+ self.params['group'] = group
+ self.params['category'] = category
+ req = dr.discoRequest(self, "/vault/credential_types")
+ return req
+ get_vault_credential_types = property(get_vault_credential_type)
+
def listCredentialTypes(self, group=None, category=None):
'''Get a list of all credential types and filter by group and/or category.'''
self.params['group'] = group
@@ -16,11 +23,25 @@ def listCredentialTypes(self, group=None, category=None):
response = dr.discoRequest(self, "/vault/credential_types")
return response
+ def get_vault_credential_type_name(self, cred_type_name):
+ '''Altnernate API call for /vault/credential_types/cred_type_name.'''
+ req = dr.discoRequest(self, "/vault/credential_types/{}".format(cred_type_name))
+ return req
+
def credentialType(self, cred_type_name):
'''Get the properties of a specific credential type.'''
response = dr.discoRequest(self, "/vault/credential_types/{}".format(cred_type_name))
return response
+ def get_vault_credential(self, cred_id=None):
+ '''Altnernate API call for /vault/credentials.'''
+ if cred_id:
+ req = dr.discoRequest(self, "/vault/credentials/{}".format(cred_id))
+ else:
+ req = dr.discoRequest(self, "/vault/credentials")
+ return req
+ get_vault_credentials = property(get_vault_credential)
+
def listCredentials(self, cred_id=None):
'''Get a list of all credentials.'''
if cred_id:
@@ -29,21 +50,41 @@ def listCredentials(self, cred_id=None):
response = dr.discoRequest(self, "/vault/credentials")
return response
+ def post_vault_credential(self, body):
+ '''Altnernate API call for /vault/credentials.'''
+ req = dr.discoPost(self, "/vault/credentials", body)
+ return req
+
def newCredential(self, body):
'''Create a new credential.'''
response = dr.discoPost(self, "/vault/credentials", body)
return response
+ def delete_vault_credential(self, cred_id):
+ '''Altnernate API call for /vault/credentials.'''
+ req = dr.discoDelete(self, "/vault/credentials/{}".format(cred_id))
+ return req
+
def deleteCredential(self, cred_id):
'''Delete a credential.'''
response = dr.discoDelete(self, "/vault/credentials/{}".format(cred_id))
return response
+ def patch_vault_credential(self, cred_id, body):
+ '''Altnernate API call for /vault/credentials.'''
+ req = dr.discoPatch(self, "/vault/credentials/{}".format(cred_id), body)
+ return req
+
def updateCredential(self, cred_id, body):
'''Updates partial resources of a credential. Missing properties are left unchanged.'''
response = dr.discoPatch(self, "/vault/credentials/{}".format(cred_id), body)
return response
+ def put_vault_credential(self, cred_id, body):
+ '''Altnernate API call for /vault/credentials.'''
+ req = dr.discoPut(self, "/vault/credentials/{}".format(cred_id), body)
+ return req
+
def replaceCredential(self, cred_id, body):
'''Replaces a single credential. All required credential properties must be present. Optional properties that are missing will be reset to their defaults.'''
response = dr.discoPut(self, "/vault/credentials/{}".format(cred_id), body)
diff --git a/tideway/data.py b/tideway/data.py
index ada81c7..f3de27b 100644
--- a/tideway/data.py
+++ b/tideway/data.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
-import requests
import tideway
import warnings
import json
@@ -11,6 +10,30 @@
class Data(appliance):
'''Retrieve data from the model.'''
+ def get_data_search(self, query, offset=None, results_id=None, format=None, limit = 100, delete = False):
+ '''Alternate API call for GET /data/search.'''
+ return Data.search(self, query, offset, results_id, format, limit, delete)
+
+ def post_data_search(self, query, offset=None, results_id=None, format=None, limit = 100, delete = False):
+ '''Alternate API call for POST /data/search.'''
+ return Data.search(self, query, offset, results_id, format, limit, delete)
+
+ def get_data_search_object(self, query, offset=None, results_id=None, format="object", limit = 100, delete = False):
+ '''Alternate API call for GET /data/search?format=object.'''
+ return Data.search(self, query, offset, results_id, format, limit, delete)
+
+ def post_data_search_object(self, query, offset=None, results_id=None, format="object", limit = 100, delete = False):
+ '''Alternate API call for POST /data/search?format=object'''
+ return Data.search(self, query, offset, results_id, format, limit, delete)
+
+ def get_data_search_tree(self, query, offset=None, results_id=None, format="tree", limit = 100, delete = False):
+ '''Alternate API call for GET /data/search?format=tree.'''
+ return Data.search(self, query, offset, results_id, format, limit, delete)
+
+ def post_data_search_tree(self, query, offset=None, results_id=None, format="tree", limit = 100, delete = False):
+ '''Alternate API call for POST /data/search?format=tree.'''
+ return Data.search(self, query, offset, results_id, format, limit, delete)
+
def search(self, query, offset=None, results_id=None, format=None, limit = 100, delete = False):
'''Run a search query, receiving paginated results.'''
self.params['offset'] = offset
@@ -65,20 +88,64 @@ def search_bulk(self, query, format = None, limit = 100, delete = False):
else:
return initial
- def candidate(self, body):
+ def post_data_condition(self, body, offset=None, results_id=None, format=None, limit = 100, delete = False):
+ '''Search using a condition, retrieving tabular data as arrays'''
+ self.params['offset'] = offset
+ self.params['results_id'] = results_id
+ self.params['format'] = format
+ self.params['delete'] = delete
+ self.params['limit'] = limit
+ response = dr.discoPost(self, "/data/condition", body)
+ return response
+
+ def post_data_condition_param_values(self, body):
+ '''Get possible parameter values for a condition'''
+ response = dr.discoPost(self, "/data/condition/param_values", body)
+ return response
+
+ def get_data_condition_template(self,template_id):
+ '''Get a list of all templates'''
+ if template_id:
+ req = dr.discoRequest(self, "/data/condition/templates/{}".format(template_id))
+ else:
+ req = dr.discoRequest(self, "/data/condition/templates")
+ return req
+ get_data_condition_templates = property(get_data_condition_template)
+
+ def post_data_candidate(self, body):
+ '''Alternate API call for POST /data/candidate.'''
+ response = dr.discoPost(self, "/data/candidate", body)
+ return response
+
+ def best_candidate(self, body):
'''
- The node object of the best candidate based on the provided
- parameters.
+ The node object of the best candidate based on the provided parameters.
'''
response = dr.discoPost(self, "/data/candidate", body)
return response
- def candidates(self, body):
+ def post_data_candidates(self, body):
+ '''Alternate API call for POST /data/candidates.'''
+ response = dr.discoPost(self, "/data/candidates", body)
+ return response
+
+ def top_candidates(self, body):
'''
Enter parameters to identify a device, the response is a list of
candidate nodes ordered by descending score.
'''
- response = dr.discoPost(self, "/data/candidate", body)
+ response = dr.discoPost(self, "/data/candidates", body)
+ return response
+
+ def get_data_nodes(self, node_id, relationships=False, traverse=None, flags=None, attributes=None):
+ '''Alternate API call for /data/nodes/node_id'''
+ self.params['traverse'] = traverse
+ self.params['flags'] = flags
+ self.params['attributes'] = attributes
+ if relationships:
+ response = dr.discoRequest(self, "/data/nodes/{}?relationships=true".format(node_id))
+ else:
+ response = dr.discoRequest(self, "/data/nodes/{}".format(node_id))
return response
def nodeLookup(self, node_id, relationships=False, traverse=None, flags=None, attributes=None):
@@ -92,6 +159,14 @@ def nodeLookup(self, node_id, relationships=False, traverse=None, flags=None, at
response = dr.discoRequest(self, "/data/nodes/{}".format(node_id))
return response
+ def get_data_nodes_graph(self, node_id, focus="sofware-connected", apply_rules=True):
+ '''Alternate API call for /data/nodes/node_id/graph'''
+ self.params['focus'] = focus
+ self.params['apply_rules'] = apply_rules
+ self.params['complete'] = False
+ response = dr.discoRequest(self, "/data/nodes/{}/graph".format(node_id))
+ return response
+
def graphNode(self, node_id, focus="sofware-connected", apply_rules=True):
'''Graph data represents a set of nodes and relationships that are associated to the given node.'''
self.params['focus'] = focus
@@ -99,6 +174,16 @@ def graphNode(self, node_id, focus="sofware-connected", apply_rules=True):
response = dr.discoRequest(self, "/data/nodes/{}/graph".format(node_id))
return response
+ def get_data_kinds(self, kind, offset=None, results_id=None, format=None, limit = 100, delete = False):
+ '''Alternate API call for /data/kinds.'''
+ self.params['offset'] = offset
+ self.params['results_id'] = results_id
+ self.params['format'] = format
+ self.params['limit'] = limit
+ self.params['delete'] = delete
+ response = dr.discoRequest(self, "/data/kinds/{}".format(kind))
+ return response
+
def lookupNodeKind(self, kind, offset=None, results_id=None, format=None, limit = 100, delete = False):
'''Finds all nodes of a specified node kind.'''
self.params['offset'] = offset
@@ -113,6 +198,17 @@ def partitions(self):
'''Get names and ids of partitions.'''
response = dr.discoRequest(self, "/data/partitions")
return response
+ get_data_partitions = property(partitions)
+
+ def post_data_partitions(self, body):
+ '''Create a partition.'''
+ response = dr.discoPost(self, "/data/partitions", body)
+ return response
+
+ def post_data_import(self, body):
+ '''Alternate API call for /data/import.'''
+ response = dr.discoPost(self, "/data/import", body)
+ return response
def twImport(self, body):
'''
@@ -121,6 +217,11 @@ def twImport(self, body):
response = dr.discoPost(self, "/data/import", body)
return response
+ def post_data_write(self, body):
+ '''Alternate API call for /data/write.'''
+ response = dr.discoPost(self, "/data/write", body)
+ return response
+
def twWrite(self, body):
'''
Perform arbitrary write operations.
diff --git a/tideway/discoRequests.py b/tideway/discoRequests.py
index beb3957..ac61a29 100644
--- a/tideway/discoRequests.py
+++ b/tideway/discoRequests.py
@@ -25,6 +25,13 @@ def filePost(appliance, api_endpoint, file, response="text/html"):
req = requests.post(url, files=files, headers=heads, params=appliance.params, verify=appliance.verify)
return req
+def keytabPost(appliance, api_endpoint, file, username, response="application/json", content_type="multipart/form-data"):
+ form_data= {"keytab":open(file,'rb'),"username":username}
+ url, heads = url_and_headers(appliance.url,appliance.token,api_endpoint,response)
+ heads['Content-type']=content_type
+ req = requests.post(url, files=form_data, headers=heads, params=appliance.params, verify=appliance.verify)
+ return req
+
def discoPatch(appliance, api_endpoint, jsoncode, response="application/json"):
url, heads = url_and_headers(appliance.url,appliance.token,api_endpoint,response)
req = requests.patch(url, json=jsoncode, headers=heads, params=appliance.params, verify=appliance.verify)
diff --git a/tideway/discovery.py b/tideway/discovery.py
index ddf595f..149bf16 100644
--- a/tideway/discovery.py
+++ b/tideway/discovery.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
-import requests
import tideway
dr = tideway.discoRequests
@@ -10,17 +9,22 @@ class Discovery(appliance):
'''Control scanning and view results.'''
def getDiscoveryStatus(self):
- '''Get the current status of the discovery process.'''
+ '''Get the current status of the discovery process. JSON Output.'''
response = dr.discoRequest(self, "/discovery")
return response
+ get_discovery = property(getDiscoveryStatus)
+
+ def patch_discovery(self, body):
+ '''Alternate API call for PATCH /discovery.'''
+ response = dr.discoPatch(self, "/discovery", body)
+ return response
def setDiscoveryStatus(self, body):
'''
- Either start or stop the discovery process. Note this call can
- return before the desired state has been reached.
+ Set the Discovery status using JSON format.
'''
response = dr.discoPatch(self, "/discovery", body)
- return response
+ return response.ok
def getApiProviderMetadata(self):
'''
@@ -31,6 +35,7 @@ def getApiProviderMetadata(self):
'''
response = dr.discoRequest(self, "/discovery/api_provider_metadata")
return response
+ get_discovery_api_provider_metadata = property(getApiProviderMetadata)
def getDiscoveryCloudMetaData(self):
'''
@@ -39,6 +44,40 @@ def getDiscoveryCloudMetaData(self):
'''
response = dr.discoRequest(self, "/discovery/cloud_metadata")
return response
+ get_discovery_api_cloud_metadata = property(getDiscoveryCloudMetaData)
+
+ def get_discovery_exclude(self, exclude_id=None):
+ '''Get a list of all excludes or specific.'''
+ if exclude_id:
+ req = dr.discoRequest(self, "/discovery/excludes/{}".format(exclude_id))
+ else:
+ req = dr.discoRequest(self, "/discovery/excludes")
+ return req
+ get_discovery_excludes = property(get_discovery_exclude)
+
+ def post_discovery_exclude(self, body):
+ '''Create an exclude.'''
+ response = dr.discoPost(self, "/discovery/excludes", body)
+ return response
+
+ def delete_discovery_exclude(self, exclude_id):
+ '''Delete an exclude.'''
+ response = dr.discoDelete(self, "/discovery/excludes/{}".format(exclude_id))
+ return response
+
+ def patch_discovery_exclude(self, exclude_id, body):
+ '''Update an exclude.'''
+ response = dr.discoPatch(self, "/discovery/excludes/{}".format(exclude_id), body)
+ return response
+
+ def get_discovery_run(self, run_id=None):
+ '''Get details of all or specific currently processing discovery runs.'''
+ if run_id:
+ req = dr.discoRequest(self, "/discovery/runs/{}".format(run_id))
+ else:
+ req = dr.discoRequest(self, "/discovery/runs")
+ return req
+ get_discovery_runs = property(get_discovery_run)
def getDiscoveryRuns(self):
'''Get details of all currently processing discovery runs.'''
@@ -50,16 +89,39 @@ def getDiscoveryRun(self, runid):
response = dr.discoRequest(self, "/discovery/runs/{}".format(runid))
return response
+ def post_discovery_run(self, body):
+ '''Alternative API call for POST /discovery/runs.'''
+ response = dr.discoPost(self, "/discovery/runs", body)
+ return response
+
def discoveryRun(self, body):
'''Create a new snapshot discovery run.'''
response = dr.discoPost(self, "/discovery/runs", body)
return response
+ def patch_discovery_run(self, run_id, body):
+ '''Alternate API call for PATCH /discovery/runs.'''
+ response = dr.discoPatch(self, "/discovery/runs/{}".format(run_id), body)
+ return response
+
def updateDiscoveryRun(self, runid, body):
'''Update the state of a specific discovery run.'''
response = dr.discoPatch(self, "/discovery/runs/{}".format(runid), body)
return response
+ def get_discovery_run_results(self, run_id, result=None, offset=None, results_id=None, format=None, limit = 100, delete = False):
+ '''Get a summary of the results from scanning all endpoints in the run that had a specific type of result.'''
+ if result:
+ self.params['offset'] = offset
+ self.params['results_id'] = results_id
+ self.params['format'] = format
+ self.params['limit'] = limit
+ self.params['delete'] = delete
+ response = dr.discoRequest(self, "/discovery/runs/{}/results/{}".format(run_id,result))
+ else:
+ response = dr.discoRequest(self, "/discovery/runs/{}/results".format(run_id))
+ return response
+
def getDiscoveryRunResults(self, runid):
'''Get a summary of the results from scanning all endpoints in the run, partitioned by result type.'''
response = dr.discoRequest(self, "/discovery/runs/{}/results".format(runid))
@@ -75,6 +137,19 @@ def getDiscoveryRunResult(self, runid, result="Success", offset=None, results_id
response = dr.discoRequest(self, "/discovery/runs/{}/results/{}".format(runid,result))
return response
+ def get_discovery_run_inferred(self, run_id, inferred_kind, offset=None, results_id=None, format=None, limit = 100, delete = False):
+ '''Get a summary of the devices inferred by a discovery run which have a specific inferred kind.'''
+ if inferred_kind:
+ self.params['offset'] = offset
+ self.params['results_id'] = results_id
+ self.params['format'] = format
+ self.params['limit'] = limit
+ self.params['delete'] = delete
+ response = dr.discoRequest(self, "/discovery/runs/{}/inferred/{}".format(run_id,inferred_kind))
+ else:
+ response = dr.discoRequest(self, "/discovery/runs/{}/inferred".format(run_id))
+ return response
+
def getDiscoveryRunInferred(self, runid):
'''Get a summary of all inferred devices from a discovery run, partitioned by device type.'''
response = dr.discoRequest(self, "/discovery/runs/{}/inferred".format(runid))
@@ -89,3 +164,27 @@ def getDiscoveryRunInferredKind(self, runid, inferred_kind, offset=None, results
self.params['delete'] = delete
response = dr.discoRequest(self, "/discovery/runs/{}/inferred/{}".format(runid,inferred_kind))
return response
+
+ def get_discovery_run_schedule(self, run_id=None):
+ '''Get a list of all scheduled runs or specific.'''
+ if run_id:
+ req = dr.discoRequest(self, "/discovery/runs/scheduled/{}".format(run_id))
+ else:
+ req = dr.discoRequest(self, "/discovery/runs/scheduled")
+ return req
+ get_discovery_run_schedules = property(get_discovery_run_schedule)
+
+ def post_discovery_run_schedule(self, body):
+ '''Add a new scheduled run.'''
+ response = dr.discoPost(self, "/discovery/runs/scheduled", body)
+ return response
+
+ def delete_discovery_run_schedule(self, run_id):
+ '''Delete a specific scheduled discovery run.'''
+ response = dr.discoDelete(self, "/discovery/runs/scheduled/{}".format(run_id))
+ return response
+
+ def patch_discovery_run_schedule(self, run_id, body):
+ '''Update the parameters of a specific scheduled discovery run.'''
+ response = dr.discoPatch(self, "/discovery/runs/scheduled/{}".format(run_id), body)
+ return response
\ No newline at end of file
diff --git a/tideway/endpoints.py b/tideway/endpoints.py
index 0a1f34d..538c00b 100644
--- a/tideway/endpoints.py
+++ b/tideway/endpoints.py
@@ -5,308 +5,698 @@
docTable = [
[
- "/swagger.json",
- "swagger()",
- "Get swagger file."
+ "GET", "/swagger.json", "- swagger()\n- api_swagger", "Get swagger file."
],
[
- "/about",
- "about()",
- "Return about info for API."
+ "GET", "/about", "- about()\n- api_about", "Return about info for API."
],
[
+ "GET",
"/admin/baseline",
- "baseline()",
+ "- baseline()\n- get_admin_baseline",
"Get a summary of the appliance status, and details of which baseline checks have passed or failed."
],
[
+ "GET",
"/admin/about",
- "admin()",
+ "- admin()\n- get_admin_about",
"Get information about the appliance, like its version and versions of the installed packages."
],
[
+ "GET",
"/admin/licensing",
- "licensing()",
+ "- licensing()\n- get_admin_licensing",
"Get the latest signed licensing report."
],
[
+ "GET",
"/admin/licensing/raw",
- "licensing(content_type='raw')",
+ "- licensing(content_type='raw')\n- get_admin_licensing_raw",
"Download the encrypted raw license data on this appliance for import on another appliance."
],
[
+ "GET",
"/admin/licensing/csv",
- "licensing(content_type='csv')",
+ "- licensing(content_type='csv')\n- get_admin_licensing_csv",
"Download raw license data in CSV format as a zip file for offline analysis."
],
[
+ "GET",
"/vault/credential_types",
- "listCredentialTypes()",
+ "- listCredentialTypes()\n- get_vault_credential_type(group, cagetory)\n- get_vault_credential_types",
"Get a list of all credential types and filter by group and/or category."
],
[
+ "GET",
"/vault/credential_types/{cred_type_name}",
- "credentialType(cred_type_name)",
+ "- credentialType(cred_type_name)\n- get_vault_credential_type_name(cred_type_name)",
"Get the properties of a specific credential type."
],
[
+ "GET",
"/vault/credentials",
- "listCredentials()",
+ "- listCredentials()\n- get_vault_credential()\n- get_vault_credentials",
"Get a list of all credentials."
],
[
+ "POST",
"/vault/credentials",
- "newCredential(body)",
+ "- newCredential(body)\n- post_vault_credential(body)",
"Create a new credential."
],
[
+ "DELETE",
"/vault/credentials/{cred_id}",
- "deleteCredential(cred_id)",
+ "- deleteCredential(cred_id)\n- delete_vault_credential(cred_id)",
"Delete a credential."
],
[
+ "GET",
"/vault/credentials/{cred_id}",
- "listCredentials(cred_id)",
+ "- listCredentials(cred_id)\n- get_vault_credential(cred_id)",
"Get the properties of a specific credential."
],
[
+ "PATCH",
"/vault/credentials/{cred_id}",
- "updateCredential(cred_id, body)",
+ "- updateCredential(cred_id, body)\n- patch_vault_credential(cred_id, body)",
"Updates partial resources of a credential. Missing properties are left unchanged."
],
[
+ "PUT",
"/vault/credentials/{cred_id}",
- "replaceCredential(cred_id, body)",
+ "- replaceCredential(cred_id, body)\n- put_vault_credential(cred_id, body)",
"""Replaces a single credential. All required credential properties must be present."""
],
[
+ "GET",
"/data/search",
- "search('query')",
+ "- search('query')\n- get_data_search('query')",
"Run a search query, receiving paginated results."
],
[
+ "POST",
"/data/search",
- "search(body)",
+ "- search('query')\n- post_data_search('query')",
"An alternative to GET /data/search, for search queries which are too long for urls."
],
[
+ "GET",
"/data/search?format=object",
- "search('query',format='object')",
+ "- search('query',format='object')\n- get_data_search_object('query',format='object')",
"As /data/search but returns results as objects instead of rows of values."
],
[
+ "POST",
"/data/search?format=object",
- "search(body,format='object')",
+ "- search('query',format='object')\n- post_data_search_object('query',format='object')",
"An alternative to GET /data/search?format=object, for search queries which are too long for urls."
],
[
+ "GET",
"/data/search?format=tree",
- "search('query',format='tree')",
+ "- search('query',format='tree')\n- get_data_search_tree('query',format='tree')",
"As /data/search but returns results as a tree of objects."
],
[
+ "POST",
"/data/search?format=tree",
- "search(body,format='tree')",
+ "- search('query',format='tree')\n- post_data_search_tree('query',format='tree')",
"An alternative to GET /data/search?format=tree, for search queries which are too long for urls."
],
[
+ "GET/POST",
"/data/search",
- "search_bulk(query/body)",
+ "- search_bulk(query/body)",
"Run a bulk search query - loops through paginated results and returns a set of JSON results."
],
[
+ "POST",
+ "/data/condition",
+ "- post_data_condition('query')",
+ "Search using a condition, retrieving tabular data as arrays."
+ ],
+ [
+ "POST",
+ "/data/condition?format=object",
+ "- post_data_condition('query',format='object')",
+ "Search using a condition, returning results as objects."
+ ],
+ [
+ "POST",
+ "/data/condition?format=tree",
+ "- post_data_condition('query',format='tree')",
+ "Search using a condition, returning results as tree of objects."
+ ],
+ [
+ "POST",
+ "/data/condition/param_values",
+ "- post_data_condition_param_values(body)",
+ "Get possible parameter values for a condition."
+ ],
+ [
+ "GET",
+ "/data/condition/templates",
+ "- get_data_condition_templates\n- get_data_condition_template()",
+ "Get a list of all templates."
+ ],
+ [
+ "GET",
+ "/data/condition/templates/{template_id}",
+ "- get_data_condition_template(template_id)",
+ "Get the properties of a specific template."
+ ],
+ [
+ "POST",
"/data/candidate",
- "candidate(body)",
+ "- best_candidate(body)\n- post_data_candidate(body)",
"The node object of the best candidate based on the provided parameters."
],
[
+ "POST",
"/data/candidates",
- "candidates(body)",
+ "- top_candidates(body)\n- post_data_candidates(body)",
"Enter parameters to identify a device, the response is a list of candidate nodes ordered by descending score"
],
[
+ "GET",
"/data/nodes/{node_id}",
- "nodeLookup(node_id)",
+ "- nodeLookup(node_id)\n- get_data_nodes(node_id)",
"Get the state of a node with specified id"
],
[
+ "GET",
"/data/nodes/{node_id}?relationships=true",
- "nodeLookup(node_id,relationships=True)",
+ "- nodeLookup(node_id,relationships=True)\n- get_data_nodes(node_id,relationships=True)",
"Get the state of a node with specified id, along with the traversal specs of all current relationships it has."
],
[
+ "GET",
"/data/nodes/{node_id}?traverse={traverse_spec}",
- "nodeLookup(node_id,traverse='traverse_spec')",
+ "- nodeLookup(node_id,traverse='traverse_spec')\n- get_data_nodes(node_id,traverse='traverse_spec')",
"Get the state of a node with specified id, along with the IDs of all nodes reached by following a traversal spec."
],
[
+ "GET",
"/data/nodes/{node_id}?traverse={attributes}",
- "nodeLookup(node_id,attributes='attributes')",
+ "- nodeLookup(node_id,attributes='attributes')\n- get_data_nodes(node_id,attributes='attributes')",
"Get the state of a node with specified id, with only the attributes specified."
],
[
+ "GET",
"/data/nodes/{node_id}/graph",
- "graphNode(node_id)",
+ "- graphNode(node_id)\n- get_data_nodes_graph(node_id)",
"Graph data represents a set of nodes and relationships that are associated to the given node."
],
[
+ "GET",
"/data/kinds/{kind}",
- "lookupNodeKind(kind)",
+ "- lookupNodeKind(kind)\n- get_data_kinds(kind)",
"Finds all nodes of a specified node kind."
],
[
+ "GET",
"/data/kinds/{kind}?format=object",
- "lookupNodeKind(kind,format='object')",
+ "- lookupNodeKind(kind,format='object')\n- get_data_kinds(kind,format='object')",
"As /data/kinds/{kind} but returns found nodes as objects instead of rows of attribute values."
],
[
+ "GET",
"/data/partitions",
- "partitions()",
+ "- partitions()\n- get_data_partitions",
"Get names and ids of partitions."
],
[
+ "POST",
+ "/data/partitions",
+ "- post_data_partitions(body)",
+ "Create a partition."
+ ],
+ [
+ "POST",
"/data/import",
- "twImport(body)",
+ "- twImport(body)\n- post_data_import(body)",
"Imports data. Returns the import UUID."
],
[
+ "POST",
"/data/write",
- "twWrite(body)",
+ "- twWrite(body)\n- post_data_write(body)",
"Perform arbitrary write operations."
],
[
+ "GET",
"/discovery",
- "getDiscoveryStatus()",
+ "- getDiscoveryStatus()\n- get_discovery",
"Get the current status of the discovery process."
],
[
+ "PATCH",
"/discovery",
- "setDiscoveryStatus(body)",
+ "- setDiscoveryStatus(body)\n- patch_discovery(body)",
"Either start or stop the discovery process. Note this call can return before the desired state has been reached."
],
[
+ "GET",
"/discovery/api_provider_metadata",
- "getApiProviderMetadata()",
+ "- getApiProviderMetadata()\n- get_discovery_api_provider_metadata",
"""Get metadata for the API providers currently supported by BMC Discovery"""
],
[
+ "GET",
"/discovery/cloud_metadata",
- "getDiscoveryCloudMetaData()",
+ "- getDiscoveryCloudMetaData()\n- get_discovery_api_cloud_metadata",
"""Get metadata for the cloud providers currently supported by BMC Discovery."""
],
[
+ "GET",
+ "/discovery/excludes",
+ "- get_discovery_excludes\n- get_discovery_exclude()",
+ """Get a list of all excludes."""
+ ],
+ [
+ "POST",
+ "/discovery/excludes",
+ "- post_discovery_exclude(body)",
+ """Create an exclude."""
+ ],
+ [
+ "DELETE",
+ "/discovery/excludes/{exclude_id}",
+ "- delete_discovery_exclude(exclude_id)",
+ """Delete an exclude."""
+ ],
+ [
+ "GET",
+ "/discovery/excludes/{exclude_id}",
+ "- get_discovery_exclude(exclude_id)",
+ """Get a specific exclude."""
+ ],
+ [
+ "PATCH",
+ "/discovery/excludes/{exclude_id}",
+ "- patch_discovery_exclude(exclude_id, body)",
+ """Updates partial resources of an exclude. Missing properties are left unchanged."""
+ ],
+ [
+ "GET",
"/discovery/runs",
- "getDiscoveryRuns()",
+ "- getDiscoveryRuns()\n- get_discovery_run()\n- get_discovery_runs",
"""Get details of all currently processing discovery runs."""
],
[
+ "POST",
"/discovery/runs",
- "discoveryRun(body)",
+ "- discoveryRun(body)\n- post_discovery_run(body)",
"""Create a new snapshot discovery run."""
],
[
+ "GET",
"/discovery/runs/{run_id}",
- "getDiscoveryRun(runid)",
+ "- getDiscoveryRun(run_id)\n- get_discovery_run(run_id)",
"""Get details of specific currently processing discovery run."""
],
[
+ "PATCH",
"/discovery/runs/{run_id}",
- "updateDiscoveryRun(runid, body)",
+ "- updateDiscoveryRun(run_id, body)\n- post_discovery_run(run_id, body)",
"""Update the state of a specific discovery run"""
],
[
+ "GET",
"/discovery/runs/{run_id}/results",
- "getDiscoveryRunResults(runid):",
+ "- getDiscoveryRunResults(run_id)\n- get_discovery_run_results(run_id)",
"""Get a summary of the results from scanning all endpoints in the run, partitioned by result type."""
],
[
+ "GET",
"/discovery/runs/{run_id}/results/{result_type}",
- "getDiscoveryRunResult(runid, result='result_type')",
+ "- getDiscoveryRunResult(run_id, result='result_type')\n- get_discovery_run_results(run_id, result='result_type')",
"""Get a summary of the results from scanning all endpoints in the run that had a specific type of result."""
],
[
+ "GET",
"/discovery/runs/{run_id}/results/{result_type}?format=object",
- "getDiscoveryRunResult(runid, format='object')",
+ "- getDiscoveryRunResult(run_id, format='object')\n- get_discovery_run_results(run_id, format='object')",
"""As /discovery/runs/{run_id}/results/{result_type} but returns found nodes as objects instead of rows of attribute values."""
],
[
+ "GET",
"/discovery/runs/{run_id}/inferred",
- "getDiscoveryRunInferred(runid)",
+ "- getDiscoveryRunInferred(run_id)\n- get_discovery_run_inferred(run_id)",
"""Get a summary of all inferred devices from a discovery run, partitioned by device type."""
],
[
+ "GET",
"/discovery/runs/{run_id}/inferred/{inferred_kind}",
- "getDiscoveryRunInferredKind(runid, inferred_kind)",
+ "- getDiscoveryRunInferredKind(run_id, inferred_kind)\n- get_discovery_run_inferred(run_id, inferred_kind)",
"""Get a summary of the devices inferred by a discovery run which have a specific inferred kind."""
],
[
+ "GET",
"/discovery/runs/{run_id}/inferred/{inferred_kind}?format=object",
- "getDiscoveryRunInferredKind(runid, inferred_kind, format='object')",
+ "- getDiscoveryRunInferredKind(run_id, inferred_kind, format='object')\n- get_discovery_run_inferred(run_id, inferred_kind, format='object')",
"""As /discovery/runs/{run_id}/inferred/{inferred_kind} but returns found nodes as objects instead of rows of attribute values."""
],
[
+ "GET",
+ "/discovery/runs/scheduled",
+ "- get_discovery_run_schedules\n- get_discovery_run_schedule()",
+ """Get details of all scheduled discovery runs."""
+ ],
+ [
+ "POST",
+ "/discovery/runs/scheduled",
+ "- post_discovery_run_schedule(body)",
+ """Create a new scheduled discovery run."""
+ ],
+ [
+ "DELETE",
+ "/discovery/runs/scheduled/{run_id}",
+ "- delete_discovery_run_schedule(run_id)",
+ """Delete a specific scheduled discovery run."""
+ ],
+ [
+ "GET",
+ "/discovery/runs/scheduled/{run_id}",
+ "- get_discovery_run_schedule(run_id)",
+ """Get details of a specific scheduled discovery run."""
+ ],
+ [
+ "PATCH",
+ "/discovery/runs/scheduled/{run_id}",
+ "- patch_discovery_run_schedule(run_id, body)",
+ """Get details of a specific scheduled discovery run."""
+ ],
+ [
+ "POST",
"/events",
- "status(body)",
+ "- status(body)\n- post_events(body)",
"""Returns a unique ID if the event has been recorded, otherwise an empty string is returned e.g. if the event source has been disabled."""
],
[
+ "GET",
+ "/vault/kerberos/realms",
+ "- get_vault_kerberos_realms\n- get_vault_kerberos_realm()",
+ """Retrieve all available realms."""
+ ],
+ [
+ "DELETE",
+ "/vault/kerberos/realms/{realm_name}",
+ "- delete_vault_kerberos_realm(realm_name)",
+ """Delete a Kerberos realm."""
+ ],
+ [
+ "GET",
+ "/vault/kerberos/realms/{realm_name}",
+ "- get_vault_kerberos_realm(realm_name)",
+ """Retrieve a Kerberos realm by name."""
+ ],
+ [
+ "PATCH",
+ "/vault/kerberos/realms/{realm_name}",
+ "- patch_vault_kerberos_realm(realm_name)",
+ """Update a Kerberos realm."""
+ ],
+ [
+ "POST",
+ "/vault/kerberos/realms/{realm_name}",
+ "- post_vault_kerberos_realm(realm_name, body)",
+ """Create a Kerberos realm."""
+ ],
+ [
+ "POST",
+ "/vault/kerberos/realms/{realm_name}/test",
+ "- post_vault_kerberos_realm(realm_name, body, test=True)",
+ """Test user credentials by attempting to acquire a new Kerberos Ticket Granting Ticket (TGT)."""
+ ],
+ [
+ "GET",
+ "/vault/kerberos/realms/{realm_name}/keytabs",
+ "- get_vault_kerberos_keytabs(realm_name)",
+ """Return a list of users with a Kerberos keytab file."""
+ ],
+ [
+ "POST",
+ "/vault/kerberos/realms/{realm_name}/keytabs",
+ "- post_vault_kerberos_keytab(realm_name, username, keytab)",
+ """Upload a Kerberos keytab file."""
+ ],
+ [
+ "DELETE",
+ "/vault/kerberos/realms/{realm_name}/keytabs",
+ "- delete_vault_kerberos_keytab(realm_name, username)",
+ """Delete the keytab file for a user."""
+ ],
+ [
+ "GET",
+ "/vault/kerberos/realms/{realm_name}/ccaches",
+ "- get_vault_kerberos_ccaches(realm_name)",
+ """Return a list of users with a Kerberos credential cache file."""
+ ],
+ [
+ "POST",
+ "/vault/kerberos/realms/{realm_name}/ccaches",
+ "- post_vault_kerberos_ccache(realm_name, username, ccache)",
+ """Upload a Kerberos credential cache file."""
+ ],
+ [
+ "DELETE",
+ "/vault/kerberos/realms/{realm_name}/ccaches",
+ "- delete_vault_kerberos_ccache(realm_name, username)",
+ """Deletes the credential cache file for a user."""
+ ],
+ [
+ "GET",
"/knowledge",
- "getKnowledgeManagement()",
+ "- getKnowledgeManagement()\n- get_knowledge",
"""Get the current state of the appliance's knowledge, including TKU versions."""
],
[
+ "POST",
"/knowledge/{filename}",
- "uploadKnowledge(filename, file)",
+ "- uploadKnowledge(filename, file)\n- post_knowledge(filename, file)",
"""Upload a TKU or pattern module to the appliance."""
],
[
+ "GET",
"/knowledge/status",
- "getUploadStatus()",
- """Get the current state of a knowledge upload"""
+ "- getUploadStatus()\n- get_knowledge_status",
+ """Get the current state of a knowledge upload."""
+ ],
+ [
+ "GET",
+ "/models",
+ "- get_models\n- get_model()",
+ """Get model definitions."""
+ ],
+ [
+ "POST",
+ "/models",
+ "- post_model(body)",
+ """Create a new model."""
+ ],
+ [
+ "DELETE",
+ "/models/{key}",
+ "- delete_model(key)",
+ """Delete a model."""
+ ],
+ [
+ "GET",
+ "/models/{key}",
+ "- get_model_key(key)",
+ """Get model definition for the specified key."""
+ ],
+ [
+ "PATCH",
+ "/models/{key}",
+ "- patch_model(key, body)",
+ """Modify a model."""
+ ],
+ [
+ "GET",
+ "/models/{key}/topology",
+ "- get_model_topology(key)",
+ """Get topology for the model definition specified by key."""
+ ],
+ [
+ "GET",
+ "/models/{key}/nodecount",
+ "- get_model_nodecount(key)",
+ """Get node count for the model definition specified by key."""
+ ],
+ [
+ "GET",
+ "/models/{key}/nodes",
+ "- get_model_nodes(key)",
+ """Get nodes for the model definition specified by key."""
+ ],
+ [
+ "GET",
+ "/models/{key}/nodes/{kind}",
+ "- get_model_nodes(key, kind='kind')",
+ """Get nodes by kind for the model definition specified by key."""
+ ],
+ [
+ "DELETE",
+ "/models/by_node_id/{node_id}",
+ "- delete_model_by_node_id(node_id)",
+ """Delete a model."""
+ ],
+ [
+ "GET",
+ "/models/by_node_id/{node_id}",
+ "- get_model_by_node_id(node_id)",
+ """Get model definition for the specified node id."""
+ ],
+ [
+ "PATCH",
+ "/models/by_node_id/{node_id}",
+ "- patch_model_by_node_id(node_id, body)",
+ """Modify a model."""
+ ],
+ [
+ "GET",
+ "/models/by_node_id/{node_id}/topology",
+ "- get_topology_by_node_id(node_id)",
+ """Get topology for the model definition specified by node id."""
+ ],
+ [
+ "GET",
+ "/models/by_node_id/{node_id}/nodecount",
+ "- get_nodecount_by_node_id(node_id)",
+ """Get node count for the model definition specified by node id."""
+ ],
+ [
+ "GET",
+ "/models/by_node_id/{node_id}/nodes",
+ "- get_nodes_by_node_id(node_id)",
+ """Get nodes for the model definition specified by node id."""
+ ],
+ [
+ "GET",
+ "/models/by_node_id/{node_id}/nodes/{kind}",
+ "- get_nodes_by_node_id(node_id, kind='kind')",
+ """Get nodes by kind for the model definition specified by node id."""
+ ],
+ [
+ "POST",
+ "/models/multi",
+ "- post_model_multi(body)",
+ """Manipulate multiple models in a single request."""
+ ],
+ [
+ "GET",
+ "/taxonomy/sections",
+ "- get_taxonomy_sections",
+ """Get list of taxonomy model sections."""
+ ],
+ [
+ "GET",
+ "/taxonomy/sections",
+ "- get_taxonomy_locales",
+ """Get list of known taxonomy locales."""
+ ],
+ [
+ "GET",
+ "/taxonomy/nodekinds",
+ "- get_taxonomy_nodekinds\n- get_taxonomy_nodekind()",
+ """Get list of defined node kind names."""
+ ],
+ [
+ "GET",
+ "/taxonomy/nodekinds?format=info",
+ "- get_taxonomy_nodekind(format='info')",
+ """Get list of defined node kind names."""
+ ],
+ [
+ "GET",
+ "/taxonomy/nodekinds/{kind}",
+ "- get_taxonomy_nodekind(kind='kind')",
+ """Get defined node kind details."""
+ ],
+ [
+ "GET",
+ "/taxonomy/nodekinds/{kind}/fieldlists",
+ "- get_taxonomy_nodekind(kind='kind', fieldlists=True)",
+ """Get list of node kind field lists."""
+ ],
+ [
+ "GET",
+ "/taxonomy/nodekinds/{kind}/fieldlists/{fieldlist}",
+ "- get_taxonomy_nodekind_fieldlist(kind, fieldlist)",
+ """Get list of node kind field lists."""
+ ],
+ [
+ "GET",
+ "/taxonomy/relkinds",
+ "- get_taxonomy_relkinds\n- get_taxonomy_relkind()",
+ """Get list of defined relationship kinds."""
+ ],
+ [
+ "GET",
+ "/taxonomy/relkinds?format=info",
+ "- get_taxonomy_relkind(format='info')",
+ """Get list of defined relationship kinds with kind info."""
+ ],
+ [
+ "GET",
+ "/taxonomy/relkinds/{kind}",
+ "- get_taxonomy_relkind(kind='kind')",
+ """Get defined relationship kind details."""
],
[
+ "GET",
"/data/nodes/{node_id}/graph",
- "graphNode(node_id)",
+ "- graphNode(node_id)\n- get_data_nodes_graph(node_id)",
"""Graph data represents a set of nodes and relationships that are associated to the given node."""
],
[
+ "POST",
"/topology/nodes",
- "getNodes(body)",
+ "- getNodes(body)\n- post_topology_nodes",
"""Get topology data from one or more starting nodes."""
],
[
+ "POST",
"/topology/nodes/kinds",
- "getNodeKinds(body)",
+ "- getNodeKinds(body)\n- post_topology_nodes_kinds",
"""Get nodes of the specified kinds which are related to a given set of nodes."""
],
[
+ "GET",
"/topology/visualization_state",
- "visualizationState()",
+ "- visualizationState()\n- get_topology_viz_state",
"""Get the current state of the visualization for the authenticated user."""
],
[
+ "PATCH",
"/topology/visualization_state",
- "updateVizState(body)",
+ "- updateVizState(body)\n- patch_topology_viz_state(body)",
"""Update one or more attributes of the current state of the visualization for the authenticated user."""
],
[
+ "PUT",
"/topology/visualization_state",
- "replaceVizState(body)",
+ "- replaceVizState(body)\n- put_topology_viz_state",
"""Update any or all of the attributes of the current state of the visualization for the authenticated user."""
],
[
+ "GET",
"/vault",
- "getVault()",
+ "- getVault()\n- get_vault",
"""Get details of the state of the vault."""
],
[
+ "PATCH",
"/vault",
- "updateVault(body)",
+ "- updateVault(body)\n- patch_vault",
"""Change the state of the vault."""
]
]
-heads = [ "Endpoint", "Function", "Description" ]
+heads = [ "Method", "Endpoint", "Function Calls", "Description" ]
def docs(*endpoints):
# Endpoint Docs
@@ -314,12 +704,12 @@ def docs(*endpoints):
tab = list()
endpoint = endpoints[0]
for line in docTable:
- if line[0] == endpoint:
+ if line[1] == endpoint:
tab.append(line)
if len(tab) > 0:
- print(tabulate(tab, headers=heads))
+ print(tabulate(tab, headers=heads),"\n")
else:
- print("API endpoint not found or not yet documented.")
+ print("API endpoint not found or not yet documented.\n")
else:
# display table
- print(tabulate(docTable, headers=heads))
+ print(tabulate(docTable, headers=heads, tablefmt="fancy_grid"),"\n")
diff --git a/tideway/events.py b/tideway/events.py
index 316e67c..dbb7804 100644
--- a/tideway/events.py
+++ b/tideway/events.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
-import requests
import tideway
dr = tideway.discoRequests
@@ -9,6 +8,11 @@
class Events(appliance):
'''Push events.'''
+ def post_events(self, body):
+ '''An alternate API call for POST /events'''
+ response = dr.discoPost(self, "/events", body)
+ return response
+
def status(self, body):
'''
Returns a unique ID if the event has been recorded, otherwise an
diff --git a/tideway/kerberos.py b/tideway/kerberos.py
new file mode 100644
index 0000000..208af78
--- /dev/null
+++ b/tideway/kerberos.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+import tideway
+
+dr = tideway.discoRequests
+appliance = tideway.main.Appliance
+
+class Kerberos(appliance):
+ '''Manage Kerberos resources.'''
+
+ def get_vault_kerberos_realm(self, realm_name=None):
+ '''Retrieve all or specific realm.'''
+ req = dr.discoRequest(self, "/vault/kerberos/realms")
+ if realm_name:
+ req = dr.discoRequest(self, "/vault/kerberos/realms/{}".format(realm_name))
+ else:
+ req = dr.discoRequest(self, "/vault/kerberos/realms")
+ return req
+ get_vault_kerberos_realms = property(get_vault_kerberos_realm)
+
+ def delete_vault_kerberos_realm(self, realm_name):
+ '''Delete a realm.'''
+ req = dr.discoDelete(self, "/vault/kerberos/realms/{}".format(realm_name))
+ return req
+
+ def patch_vault_kerberos_realm(self, realm_name, body):
+ '''Update a Kerberos realm.'''
+ req = dr.discoPatch(self, "/vault/kerberos/realms/{}".format(realm_name), body)
+ return req
+
+ def post_vault_kerberos_realm(self, realm_name, body, test=False):
+ '''Create a realm and Test user credentials by attempting to acquire a new Kerberos Ticket Granting Ticket (TGT)'''
+ req = dr.discoPost(self, "/vault/kerberos/realms/{}".format(realm_name), body)
+ if test:
+ req = dr.discoPost(self, "/vault/kerberos/realms/{}/test".format(realm_name), body)
+ return req
+
+ def get_vault_kerberos_keytabs(self, realm_name):
+ '''List users with a Kerberos keytab file'''
+ req = dr.discoRequest(self, "/vault/kerberos/realms/{}/keytabs".format(realm_name))
+ return req
+
+ def post_vault_kerberos_keytab(self, realm_name, username, keytab):
+ '''Upload a Kerberos keytab file'''
+ # Not Tested
+ req = dr.keytabPost(self, "/vault/kerberos/realms/{}/keytabs".format(realm_name), keytab, username)
+ return req
+
+ def delete_vault_kerberos_keytab(self, realm_name, username):
+ '''Delete a keytab file'''
+ # Not Tested
+ req = dr.discoDelete(self, "/vault/kerberos/realms/{}/keytabs/{}".format(realm_name, username))
+ return req
+
+ def get_vault_kerberos_ccaches(self, realm_name):
+ '''List users with a Kerberos credential cache file.'''
+ req = dr.discoRequest(self, "/vault/kerberos/realms/{}/ccaches".format(realm_name))
+ return req
+
+ def post_vault_kerberos_ccache(self, realm_name, username, ccache):
+ '''Upload a Kerberos credential cache file'''
+ # Not Tested
+ req = dr.keytabPost(self, "/vault/kerberos/realms/{}/ccaches".format(realm_name), ccache, username)
+ return req
+
+ def delete_vault_kerberos_ccache(self, realm_name, username):
+ '''Delete a cedential cache file'''
+ req = dr.discoDelete(self, "/vault/kerberos/realms/{}/keytabs/{}".format(realm_name, username))
+ return req
\ No newline at end of file
diff --git a/tideway/knowledge.py b/tideway/knowledge.py
index 8dd94fe..f19850b 100644
--- a/tideway/knowledge.py
+++ b/tideway/knowledge.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
-import requests
import tideway
dr = tideway.discoRequests
@@ -13,11 +12,20 @@ def getKnowledgeManagement(self):
'''Get the current state of the appliance's knowledge, including TKU versions.'''
response = dr.discoRequest(self, "/knowledge")
return response
+ get_knowledge = property(getKnowledgeManagement)
def getUploadStatus(self):
'''Get the current state of a knowledge upload.'''
response = dr.discoRequest(self, "/knowledge/status")
return response
+ get_knowledge_status = property(getUploadStatus)
+
+ def post_knowledge(self, filename, file, activate=True, allow_restart=False):
+ '''Alternate API call for POST /knowledge/filename'''
+ self.params['activate'] = activate
+ self.params['allow_restart'] = allow_restart
+ response = dr.filePost(self, "/knowledge/{}".format(filename), file)
+ return response
def uploadKnowledge(self, filename, file, activate=True, allow_restart=False):
'''Upload a TKU or pattern module to the appliance.'''
diff --git a/tideway/main.py b/tideway/main.py
index b8f7bd9..83dfb64 100644
--- a/tideway/main.py
+++ b/tideway/main.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
+from tkinter import BASELINE
import requests
from . import discoRequests as dr
from . import endpoints
@@ -9,17 +10,43 @@
class Appliance:
'''An appliance instance.'''
- def __init__(self, target, token, limit = 100, delete = False, api_version = "1.3", ssl_verify = False):
+ def __init__(self, target, token, limit = 100, delete = False, api_version = "1.5", ssl_verify = False):
self.target = target
self.token = token
self.params = {}
self.params['limit'] = limit
self.params['delete'] = delete
self.api_version = api_version
- self.api = "https://" + str(target) + "/api"
+ self.target_url = "https://" + str(target)
+ self.api = self.target_url + "/api"
self.url = self.api + "/v" + self.api_version
self.verify = ssl_verify
+ def get(self,endpoint):
+ '''Request any endpoint.'''
+ req = dr.discoRequest(self,endpoint)
+ return req
+
+ def post(self,endpoint,body):
+ '''Post any endpoint.'''
+ req = dr.discoPost(self, endpoint, body)
+ return req
+
+ def delete(self,endpoint):
+ '''Delete any endpoint.'''
+ req = dr.discoDelete(self, endpoint)
+ return req
+
+ def patch(self,endpoint,body):
+ '''Patch any endpoint.'''
+ req = dr.discoPatch(self, endpoint, body)
+ return req
+
+ def put(self,endpoint,body):
+ '''Update any endpoint.'''
+ req = dr.discoPut(self, endpoint, body)
+ return req
+
def credentials(self):
c = tideway.credentials(self.target, self.token, api_version=self.api_version, ssl_verify=self.verify)
return c
@@ -36,10 +63,22 @@ def events(self):
e = tideway.events(self.target, self.token, api_version=self.api_version, ssl_verify=self.verify)
return e
+ def kerberos(self):
+ ks = tideway.kerberos(self.target, self.token, api_version=self.api_version, ssl_verify=self.verify)
+ return ks
+
def knowledge(self):
k = tideway.knowledge(self.target, self.token, api_version=self.api_version, ssl_verify=self.verify)
return k
+ def models(self):
+ m = tideway.models(self.target, self.token, api_version=self.api_version, ssl_verify=self.verify)
+ return m
+
+ def taxonomy(self):
+ tx = tideway.topology(self.target, self.token, api_version=self.api_version, ssl_verify=self.verify)
+ return tx
+
def topology(self):
t = tideway.topology(self.target, self.token, api_version=self.api_version, ssl_verify=self.verify)
return t
@@ -50,28 +89,72 @@ def vault(self):
### Admin ###
+ @property
+ def api_about(self):
+ '''Altnernate API call for /about.'''
+ url = self.api + "/about"
+ req = requests.get(url, verify=self.verify)
+ return req
+
def about(self):
- '''Return about info for API.'''
+ '''Return about data.'''
url = self.api + "/about"
req = requests.get(url, verify=self.verify)
return req
+ @property
+ def api_swagger(self):
+ '''Alternate API call for swagger.'''
+ url = self.url + "/swagger.json"
+ req = requests.get(url, verify=self.verify)
+ return req
+
def swagger(self):
'''Get swagger file.'''
url = self.url + "/swagger.json"
req = requests.get(url, verify=self.verify)
return req
+ @property
+ def get_admin_baseline(self):
+ '''Alternate API call for baseline.'''
+ response = dr.discoRequest(self, "/admin/baseline")
+ return response
+
def baseline(self):
'''Get a summary of the appliance status, and details of which baseline checks have passed or failed.'''
response = dr.discoRequest(self, "/admin/baseline")
return response
+ @property
+ def get_admin_about(self):
+ '''Alternate API call for /admin/about.'''
+ response = dr.discoRequest(self, "/admin/about")
+ return response
+
def admin(self):
'''Get information about the appliance, like its version and versions of the installed packages.'''
response = dr.discoRequest(self, "/admin/about")
return response
+ @property
+ def get_admin_licensing(self):
+ '''Alternate API call for licensing report.'''
+ response = dr.discoRequest(self, "/admin/licensing",response="text/plain")
+ return response
+
+ @property
+ def get_admin_licensing_csv(self):
+ '''Alternate API call for licensing report CSV.'''
+ response = dr.discoRequest(self, "/admin/licensing/csv",response="application/zip")
+ return response
+
+ @property
+ def get_admin_licensing_raw(self):
+ '''Alternate API call for licensing report raw.'''
+ response = dr.discoRequest(self, "/admin/licensing/raw",response="application/zip")
+ return response
+
def licensing(self,content_type="text/plain"):
'''Get the latest signed licensing report.'''
if content_type == "csv":
@@ -82,10 +165,16 @@ def licensing(self,content_type="text/plain"):
response = dr.discoRequest(self, "/admin/licensing",response=content_type)
return response
+ @property
+ def api_help(self):
+ '''Help on endpoints.'''
+ endpoints.docs()
+ #print("")
+
def help(*args):
'''Help on endpoints.'''
if len(args) > 1:
endpoints.docs(args[1])
else:
endpoints.docs()
- print("")
+ #print("\n")
\ No newline at end of file
diff --git a/tideway/models.py b/tideway/models.py
new file mode 100644
index 0000000..a78fb91
--- /dev/null
+++ b/tideway/models.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+
+import tideway
+
+dr = tideway.discoRequests
+appliance = tideway.main.Appliance
+
+class Models(appliance):
+ '''Manage service and application models.'''
+
+ def get_model(self,name=None,type=None,kind=None,published=None,review_suggested=None,version=None,favorite=None,compatibility=None,results_id=None,delete=False):
+ '''Get model definitions.'''
+ if name:
+ self.params['name'] = name
+ if type:
+ self.params['type'] = type
+ if kind:
+ self.params['kind'] = kind
+ if published:
+ self.params['published'] = published
+ if review_suggested:
+ self.params['review_suggested'] = review_suggested
+ if version:
+ self.params['version'] = version
+ if favorite:
+ self.params['favorite'] = favorite
+ if compatibility:
+ self.params['compatibility'] = compatibility
+ if results_id:
+ self.params['results_id'] = results_id
+ if delete:
+ self.params['delete'] = delete
+ response = dr.discoRequest(self, "/models")
+ return response
+ get_models = property(get_model)
+
+ def post_model(self, body):
+ '''Create a new model.'''
+ response = dr.discoPost(self, "/models", body)
+ return response
+
+ def post_model_multi(self, body):
+ '''Manipulate multiple models in a single request.'''
+ response = dr.discoPost(self, "/models/multi", body)
+ return response
+
+ def delete_model(self, key):
+ '''Delete a model.'''
+ response = dr.discoDelete(self, "/models/{}".format(key))
+ return response
+
+ def get_model_key(self, key):
+ '''Get model definition for the specified key.'''
+ req = dr.discoRequest(self, "/models/{}".format(key))
+ return req
+
+ def patch_model(self, key, body):
+ '''Modify a model.'''
+ response = dr.discoPatch(self, "/models/{}".format(key), body)
+ return response
+
+ def get_model_topology(self, key, attributes=None):
+ '''Get topology for the model definition specified by key.'''
+ if attributes:
+ self.params['attributes']=attributes
+ req = dr.discoRequest(self, "/models/{}/topology".format(key))
+ return req
+
+ def get_model_nodecount(self, key):
+ '''Get node count for the model definition specified by key.'''
+ req = dr.discoRequest(self, "/models/{}/nodecount".format(key))
+ return req
+
+ def get_model_nodes(self, key, format=None, limit=100, results_id=None, delete=False, kind=None):
+ '''Get nodes for the model definition specified by key.'''
+ if format:
+ self.params['format'] = format
+ if results_id:
+ self.params['results_id'] = results_id
+ self.params['limit'] = limit
+ self.params['delete'] = delete
+ if kind:
+ response = dr.discoRequest(self, "/models/{}/nodes/{}".format(key,kind))
+ else:
+ response = dr.discoRequest(self, "/models/{}/nodes".format(key))
+ return response
+
+ def delete_model_by_node_id(self, node_id):
+ '''Delete a model.'''
+ response = dr.discoDelete(self, "/models/by_node_id/{}".format(node_id))
+ return response
+
+ def get_model_by_node_id(self, node_id, expand_related=None):
+ '''Get model definition for the specified node id.'''
+ if expand_related:
+ self.params['expand_related'] = expand_related
+ response = dr.discoRequest(self, "/models/by_node_id/{}".format(node_id))
+ return response
+
+ def patch_model_by_node_id(self, node_id, body):
+ '''Modify a model.'''
+ response = dr.discoPatch(self, "/models/by_node_id/{}".format(node_id), body)
+ return response
+
+ def get_topology_by_node_id(self, node_id, attributes=None):
+ '''Get topology for the model definition specified by node id.'''
+ if attributes:
+ self.params['attributes']=attributes
+ response = dr.discoRequest(self, "/models/by_node_id/{}/topology".format(node_id))
+ return response
+
+ def get_nodecount_by_node_id(self, node_id):
+ '''Get node count for the model definition specified by node id.'''
+ response = dr.discoRequest(self, "/models/by_node_id/{}/nodecount".format(node_id))
+ return response
+
+ def get_nodes_by_node_id(self, node_id, format=None, limit=100, results_id=None, delete=False, kind=None):
+ '''Get nodes for the model definition specified by node id.'''
+ if format:
+ self.params['format'] = format
+ if results_id:
+ self.params['results_id'] = results_id
+ self.params['limit'] = limit
+ self.params['delete'] = delete
+ if kind:
+ response = dr.discoRequest(self, "/models/by_node_id/{}/nodes/{}".format(node_id,kind))
+ else:
+ response = dr.discoRequest(self, "/models/by_node_id/{}/nodes".format(node_id))
+ return response
+
\ No newline at end of file
diff --git a/tideway/taxonomy.py b/tideway/taxonomy.py
new file mode 100644
index 0000000..6ac8848
--- /dev/null
+++ b/tideway/taxonomy.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+
+import tideway
+
+dr = tideway.discoRequests
+appliance = tideway.main.Appliance
+
+class Taxonomy(appliance):
+ '''Retrieve taxonomy data.'''
+
+ @property
+ def get_taxonomy_sections(self):
+ '''Get list of taxonomy model sections.'''
+ req = dr.discoRequest(self, "/taxonomy/sections")
+ return req
+
+ @property
+ def get_taxonomy_locales(self):
+ '''Get list of known taxonomy locales.'''
+ req = dr.discoRequest(self, "/taxonomy/locales")
+ return req
+
+ def get_taxonomy_nodekind(self, format=None, section=None, locale=None, kind=None, fieldlists=False):
+ '''Get list of defined node kinds with kind info.'''
+ if format:
+ self.params['format']=format
+ self.params['section']=section
+ self.params['locale']=locale
+ req = dr.discoRequest(self, "/taxonomy/nodekinds")
+ elif kind:
+ self.params['locale']=locale
+ if fieldlists:
+ req = dr.discoRequest(self, "/taxonomy/nodekinds/{}/fieldlists".format(kind))
+ else:
+ req = dr.discoRequest(self, "/taxonomy/nodekinds/{}".format(kind))
+ else:
+ req = dr.discoRequest(self, "/taxonomy/nodekinds")
+ return req
+ get_taxonomy_nodekinds = property(get_taxonomy_nodekind)
+
+ def get_taxonomy_nodekind_fieldlist(self, kind, fieldlist):
+ '''Get list of fields for a node kind field list.'''
+ req = dr.discoRequest(self, "/taxonomy/nodekinds/{}/fieldlists/{}".format(kind,fieldlist))
+ return req
+
+ def get_taxonomy_relkind(self, format=None, locale=None, kind=None):
+ '''Get list of defined node kinds with kind info.'''
+ if format:
+ self.params['format']=format
+ self.params['locale']=locale
+ req = dr.discoRequest(self, "/taxonomy/relkinds")
+ elif kind:
+ self.params['locale']=locale
+ req = dr.discoRequest(self, "/taxonomy/relkinds/{}".format(kind))
+ else:
+ req = dr.discoRequest(self, "/taxonomy/relkinds")
+ return req
+ get_taxonomy_relkinds = property(get_taxonomy_relkind)
\ No newline at end of file
diff --git a/tideway/topology.py b/tideway/topology.py
index ce92f1a..36528b0 100644
--- a/tideway/topology.py
+++ b/tideway/topology.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
-import requests
import tideway
dr = tideway.discoRequests
@@ -9,22 +8,39 @@
class Topology(appliance):
'''Retrieve topology data from the datastore.'''
+ def get_data_nodes_graph(self, node_id, focus="sofware-connected", apply_rules=True, complete=False):
+ '''Alternate API call for /data/nodes/node_id/graph'''
+ self.params['focus'] = focus
+ self.params['apply_rules'] = apply_rules
+ self.params['complete'] = complete
+ response = dr.discoRequest(self, "/data/nodes/{}/graph".format(node_id))
+ return response
+
def graphNode(self, node_id, focus="sofware-connected", apply_rules=True):
'''
Graph data represents a set of nodes and relationships that are
associated to the given node.
'''
- # TODO: add complete attribute
self.params['focus'] = focus
self.params['apply_rules'] = apply_rules
response = dr.discoRequest(self, "/data/nodes/{}/graph".format(node_id))
return response
+ def post_topology_nodes(self, body):
+ '''Alternate API call for POST /topology/nodes.'''
+ response = dr.discoPost(self, "/topology/nodes", body)
+ return response
+
def getNodes(self, body):
'''Get topology data from one or more starting nodes.'''
response = dr.discoPost(self, "/topology/nodes", body)
return response
+ def post_topology_nodes_kinds(self, body):
+ '''Alternate API call for POST /topology/nodes/kinds.'''
+ response = dr.discoPost(self, "/topology/nodes/kinds", body)
+ return response
+
def getNodeKinds(self, body):
'''
Get nodes of the specified kinds which are related to a given set of
@@ -40,6 +56,12 @@ def visualizationState(self):
'''
response = dr.discoRequest(self, "/topology/visualization_state")
return response
+ get_topology_viz_state = property(visualizationState)
+
+ def patch_topology_viz_state(self, body):
+ '''Alternate API call for PATCH /topology/visualization_state'''
+ response = dr.discoPatch(self, "/topology/visualization_state", body)
+ return response
def updateVizState(self, body):
'''
@@ -49,6 +71,11 @@ def updateVizState(self, body):
response = dr.discoPatch(self, "/topology/visualization_state", body)
return response
+ def put_topology_viz_state(self, body):
+ '''Alternate API call for PUT /topology/visualization_state'''
+ response = dr.discoPut(self, "/topology/visualization_state", body)
+ return response
+
def replaceVizState(self, body):
'''
Update any or all of the attributes of the current state of the
diff --git a/tideway/vault.py b/tideway/vault.py
index ac2d18c..50d47e8 100644
--- a/tideway/vault.py
+++ b/tideway/vault.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
-import requests
import tideway
dr = tideway.discoRequests
@@ -13,6 +12,12 @@ def getVault(self):
'''Get details of the state of the vault.'''
response = dr.discoRequest(self, "/vault")
return response
+ get_vault = property(getVault)
+
+ def patch_vault(self, body):
+ '''Alternate API call for PATCH /vault'''
+ response = dr.discoPatch(self, "/vault", body)
+ return response
def updateVault(self, body):
'''Change the state of the vault.'''