Merging upstream version 1.4.1+dfsg.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
419af0eb9f
commit
a9eef38502
9 changed files with 167 additions and 44 deletions
6
.arista/secret_allowlist.yaml
Normal file
6
.arista/secret_allowlist.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
version: v1.0
|
||||
allowed_secrets:
|
||||
- filepath_literal: "docs/labs/lab07-aaa/svc_account_misc.py"
|
||||
secret_literal: "9bfb39ff892c81d6ac9f25ff95d0389719595feb"
|
||||
category: FALSE_POSITIVE
|
||||
reason: Example token in documentation example file
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -54,3 +54,6 @@ docs/_build/
|
|||
docs/_modules/modules_by_category.rst
|
||||
docs/_modules/list_of_*.rst
|
||||
docs/_modules/*_module.rst
|
||||
|
||||
# .DS_Store
|
||||
.DS_Store
|
||||
|
|
|
@ -20,3 +20,4 @@ exclude Jenkinsfile
|
|||
exclude pre-commit.sh
|
||||
exclude report
|
||||
exclude htmlcov
|
||||
recursive-exclude .arista *.yaml
|
||||
|
|
|
@ -75,9 +75,10 @@ using the API methods.
|
|||
|
||||
### Requirements
|
||||
|
||||
- Python 2.7 or later
|
||||
- Python 3.7 or later
|
||||
- Python logging module
|
||||
- Python requests module version 1.0.0 or later
|
||||
- Python requests module with socks version 2.27.0 or later
|
||||
- Python packaging module version 23.2 or later
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
1.4.0
|
||||
1.4.1
|
||||
|
|
|
@ -32,5 +32,5 @@
|
|||
''' RESTful API Client class for Cloudvision(R) Portal
|
||||
'''
|
||||
|
||||
__version__ = '1.4.0'
|
||||
__version__ = '1.4.1'
|
||||
__author__ = 'Arista Networks, Inc.'
|
||||
|
|
|
@ -3930,6 +3930,15 @@ class CvpApi():
|
|||
'time': '2022-05-03T15:38:53.725014447Z', 'type': 'INITIAL'}, ...]
|
||||
'''
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
url = '/api/resources/serviceaccount/v1/Token/all'
|
||||
self.log.debug(f"v14 {url}")
|
||||
# Pull list of tokens out of data key of return for new resource APIs
|
||||
resp = self.clnt.get(url)
|
||||
tokens = []
|
||||
if "data" in resp:
|
||||
tokens = resp["data"]
|
||||
return tokens
|
||||
if self.cvp_version_compare('>=', 7.0, msg):
|
||||
url = '/api/v3/services/arista.serviceaccount.v1.TokenService/GetAll'
|
||||
self.log.debug(f"v7 {url}")
|
||||
|
@ -3939,6 +3948,8 @@ class CvpApi():
|
|||
def svc_account_token_get_one(self, token_id):
|
||||
''' Get a service account token's state using Resource APIs
|
||||
Supported versions: CVP 2021.3.0 or newer and CVaaS.
|
||||
Args:
|
||||
token_id (string): The id of the service account token.
|
||||
Returns:
|
||||
response (list): Returns a list of dict that contains...
|
||||
Ex: [{'value': {'key': {'id': 'randomId'}, 'user': 'string',
|
||||
|
@ -3947,11 +3958,16 @@ class CvpApi():
|
|||
'time': '2022-05-03T15:38:53.725014447Z', 'type': 'INITIAL'}]
|
||||
'''
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
endpoint = '/api/resources/serviceaccount/v1/Token'
|
||||
query_param = f"?key.id={token_id}"
|
||||
self.log.debug(f'v14 {endpoint + query_param}')
|
||||
return self.clnt.get(endpoint + query_param)
|
||||
if self.cvp_version_compare('>=', 7.0, msg):
|
||||
endpoint = '/api/v3/services/arista.serviceaccount.v1.TokenService/GetOne'
|
||||
payload = {"key": {"id": token_id}}
|
||||
url = '/api/v3/services/arista.serviceaccount.v1.TokenService/GetOne'
|
||||
self.log.debug(f"v7 {url} {payload}")
|
||||
return self.clnt.post(url, data=payload)
|
||||
self.log.debug(f'v7 {endpoint} {payload}')
|
||||
return self.clnt.post(endpoint, data=payload)
|
||||
return None
|
||||
|
||||
def svc_account_token_delete(self, token_id):
|
||||
|
@ -3965,11 +3981,15 @@ class CvpApi():
|
|||
'time': '2022-07-26T15:29:03.687167871Z'}]
|
||||
'''
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
endpoint = f'/api/resources/serviceaccount/v1/TokenConfig?key.id={token_id}'
|
||||
self.log.debug(f'v14 {endpoint}')
|
||||
return self.clnt.delete(endpoint)
|
||||
if self.cvp_version_compare('>=', 7.0, msg):
|
||||
endpoint = '/api/v3/services/arista.serviceaccount.v1.TokenConfigService/Delete'
|
||||
payload = {"key": {"id": token_id}}
|
||||
url = '/api/v3/services/arista.serviceaccount.v1.TokenConfigService/Delete'
|
||||
self.log.debug(f"v7 {url} {payload}")
|
||||
return self.clnt.post(url, data=payload)
|
||||
self.log.debug(f'v7 {endpoint} {payload}')
|
||||
return self.clnt.post(endpoint, data=payload)
|
||||
return None
|
||||
|
||||
def svc_account_token_set(self, username, duration, description):
|
||||
|
@ -3987,14 +4007,31 @@ class CvpApi():
|
|||
'description': 'cvprac test',
|
||||
'valid_for': '550s', 'token': '<ey...>'}]
|
||||
'''
|
||||
payload = {'value': {'description': description,
|
||||
'user': username,
|
||||
'valid_for': duration}}
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
payload = {
|
||||
'key': {
|
||||
'id': ''
|
||||
},
|
||||
'description': description,
|
||||
'user': username,
|
||||
'validFor': duration,
|
||||
'token': ''
|
||||
}
|
||||
endpoint = '/api/resources/serviceaccount/v1/TokenConfig'
|
||||
self.log.debug(f'v14 {endpoint} {payload}')
|
||||
return self.clnt.post(endpoint, data=payload)
|
||||
if self.cvp_version_compare('>=', 7.0, msg):
|
||||
url = '/api/v3/services/arista.serviceaccount.v1.TokenConfigService/Set'
|
||||
self.log.debug(f"v7 {url} {payload}")
|
||||
return self.clnt.post(url, data=payload)
|
||||
payload = {
|
||||
'value': {
|
||||
'description': description,
|
||||
'user': username,
|
||||
'valid_for': duration
|
||||
}
|
||||
}
|
||||
endpoint = '/api/v3/services/arista.serviceaccount.v1.TokenConfigService/Set'
|
||||
self.log.debug(f'v7 {endpoint} {payload}')
|
||||
return self.clnt.post(endpoint, data=payload)
|
||||
return None
|
||||
|
||||
def svc_account_get_all(self):
|
||||
|
@ -4005,13 +4042,21 @@ class CvpApi():
|
|||
Ex: [{'value': {'key': {'name': 'ansible'}, 'status': 'ACCOUNT_STATUS_ENABLED',
|
||||
'description': 'lab-tests', 'groups': {'values': ['network-admin']}},
|
||||
'time': '2022-02-10T04:28:14.251684869Z', 'type': 'INITIAL'}, ...]
|
||||
|
||||
'''
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
endpoint = '/api/resources/serviceaccount/v1/Account/all'
|
||||
self.log.debug(f"v14 {endpoint}")
|
||||
# Pull list of accounts out of data key of return for new resource APIs
|
||||
resp = self.clnt.get(endpoint)
|
||||
svc_accounts = []
|
||||
if "data" in resp:
|
||||
svc_accounts = resp["data"]
|
||||
return svc_accounts
|
||||
if self.cvp_version_compare('>=', 7.0, msg):
|
||||
url = '/api/v3/services/arista.serviceaccount.v1.AccountService/GetAll'
|
||||
self.log.debug(f"v7 {url}")
|
||||
return self.clnt.post(url)
|
||||
endpoint = '/api/v3/services/arista.serviceaccount.v1.AccountService/GetAll'
|
||||
self.log.debug(f"v7 {endpoint}")
|
||||
return self.clnt.post(endpoint)
|
||||
return None
|
||||
|
||||
def svc_account_get_one(self, username):
|
||||
|
@ -4026,13 +4071,35 @@ class CvpApi():
|
|||
'time': '2022-02-10T04:28:14.251684869Z'}]
|
||||
'''
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
endpoint = '/api/resources/serviceaccount/v1/Account'
|
||||
query_param = f"?key.name={username}"
|
||||
self.log.debug(f"v14 {endpoint + query_param}")
|
||||
return self.clnt.get(endpoint + query_param)
|
||||
if self.cvp_version_compare('>=', 7.0, msg):
|
||||
endpoint = '/api/v3/services/arista.serviceaccount.v1.AccountService/GetOne'
|
||||
payload = {"key": {"name": username}}
|
||||
url = '/api/v3/services/arista.serviceaccount.v1.AccountService/GetOne'
|
||||
self.log.debug(f"v7 {url} {payload}")
|
||||
return self.clnt.post(url, data=payload)
|
||||
self.log.debug(f"v7 {endpoint} {payload}")
|
||||
return self.clnt.post(endpoint, data=payload)
|
||||
return None
|
||||
|
||||
def _get_valid_role_ids(self, roles):
|
||||
''' Helper function to validate and retrieve role IDs based on provided roles.
|
||||
Args:
|
||||
roles (list): The list of role names.
|
||||
Returns:
|
||||
role_ids (list): The list of role IDs.
|
||||
'''
|
||||
role_ids = []
|
||||
all_roles = self.get_roles()
|
||||
for role in all_roles['roles']:
|
||||
if role['key'] in roles or role['name'] in roles:
|
||||
role_ids.append(role['key'])
|
||||
if len(roles) != len(role_ids):
|
||||
self.log.warning(f"Not all provided roles {roles} are valid. "
|
||||
f"Only using the found valid roles {role_ids}")
|
||||
return role_ids
|
||||
|
||||
def svc_account_set(self, username, description, roles, status):
|
||||
''' Create a service account using Resource APIs.
|
||||
Supported versions: CVP 2021.3.0 or newer and CVaaS.
|
||||
|
@ -4056,23 +4123,26 @@ class CvpApi():
|
|||
'time': '2022-07-26T18:19:55.392173445Z'}]
|
||||
'''
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
# Retrieve valid role IDs
|
||||
role_ids = self._get_valid_role_ids(roles)
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
payload = {
|
||||
'description': description,
|
||||
'groups': {'values': role_ids},
|
||||
'key': {'name': username},
|
||||
'status': status
|
||||
}
|
||||
endpoint = '/api/resources/serviceaccount/v1/AccountConfig'
|
||||
self.log.debug(f"v14 {endpoint} {payload}")
|
||||
return self.clnt.post(endpoint, data=payload)
|
||||
if self.cvp_version_compare('>=', 7.0, msg):
|
||||
role_ids = []
|
||||
all_roles = self.get_roles()
|
||||
for role in all_roles['roles']:
|
||||
if role['key'] in roles or role['name'] in roles:
|
||||
role_ids.append(role['key'])
|
||||
if len(roles) != len(role_ids):
|
||||
self.log.warning(f"Not all provided roles {roles} are valid. "
|
||||
f"Only using the found valid roles {role_ids}")
|
||||
|
||||
payload = {'value': {'description': description,
|
||||
'groups': {'values': role_ids},
|
||||
'key': {'name': username},
|
||||
'status': status}}
|
||||
url = '/api/v3/services/arista.serviceaccount.v1.AccountConfigService/Set'
|
||||
self.log.debug(f"v7 {url} {payload}")
|
||||
return self.clnt.post(url, data=payload)
|
||||
endpoint = '/api/v3/services/arista.serviceaccount.v1.AccountConfigService/Set'
|
||||
self.log.debug(f"v7 {endpoint} {payload}")
|
||||
return self.clnt.post(endpoint, data=payload)
|
||||
return None
|
||||
|
||||
def svc_account_delete(self, username):
|
||||
|
@ -4086,11 +4156,15 @@ class CvpApi():
|
|||
'time': '2022-07-26T18:26:53.637425846Z'}]
|
||||
'''
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
endpoint = f'/api/resources/serviceaccount/v1/AccountConfig?key.name={username}'
|
||||
self.log.debug(f"v14 {endpoint}")
|
||||
return self.clnt.delete(endpoint)
|
||||
if self.cvp_version_compare('>=', 7.0, msg):
|
||||
payload = {"key": {"name": username}}
|
||||
url = '/api/v3/services/arista.serviceaccount.v1.AccountConfigService/Delete'
|
||||
self.log.debug(f"v7 {url} {payload}")
|
||||
return self.clnt.post(url, data=payload)
|
||||
endpoint = '/api/v3/services/arista.serviceaccount.v1.AccountConfigService/Delete'
|
||||
self.log.debug(f"v7 {endpoint} {payload}")
|
||||
return self.clnt.post(endpoint, data=payload)
|
||||
return None
|
||||
|
||||
def svc_account_delete_expired_tokens(self):
|
||||
|
@ -4105,11 +4179,21 @@ class CvpApi():
|
|||
'time': '2022-07-26T18:30:28.022504853Z','type': 'INITIAL'},
|
||||
{'value': {'key': {'id': '2f6325d9c'},...]
|
||||
'''
|
||||
msg = 'Service Account Resource APIs are supported from 2021.3.0+.'
|
||||
valid_until_format = "valid_until"
|
||||
resource_api_schema = False
|
||||
if self.cvp_version_compare('>=', 14.0, msg):
|
||||
resource_api_schema = True
|
||||
valid_until_format = "validUntil"
|
||||
tokens = self.svc_account_token_get_all()
|
||||
expired_tokens = []
|
||||
for tok in tokens:
|
||||
token = tok['value']
|
||||
if datetime.strptime(token['valid_until'], "%Y-%m-%dT%H:%M:%SZ") < datetime.utcnow():
|
||||
self.svc_account_token_delete(token['key']['id'])
|
||||
if resource_api_schema:
|
||||
token_data = tok['result']['value']
|
||||
else:
|
||||
token_data = tok['value']
|
||||
if (datetime.strptime(token_data[valid_until_format], "%Y-%m-%dT%H:%M:%SZ") <
|
||||
datetime.utcnow()):
|
||||
self.svc_account_token_delete(token_data['key']['id'])
|
||||
expired_tokens.append(tok)
|
||||
return expired_tokens
|
||||
|
|
|
@ -123,7 +123,7 @@ class CvpClient():
|
|||
# Maximum number of times to retry a get or post to the same
|
||||
# CVP node.
|
||||
NUM_RETRY_REQUESTS = 3
|
||||
LATEST_API_VERSION = 9.0
|
||||
LATEST_API_VERSION = 14.0
|
||||
|
||||
def __init__(self, logger='cvprac', syslog=False, filename=None,
|
||||
log_level='INFO'):
|
||||
|
@ -213,7 +213,13 @@ class CvpClient():
|
|||
For CVP versions 2020.2.4 through 2021.1.x, use api version 5.0
|
||||
For CVP versions 2021.2.x, use api version 6.0
|
||||
For CVP versions 2021.3.x, use api version 7.0
|
||||
For CVP versions 2022.1.0 and beyond, use api version 8.0
|
||||
For CVP versions 2022.x.x, use api version 8.0
|
||||
For CVP versions 2023.1.x, use api version 9.0
|
||||
For CVP versions 2023.2.x, use api version 10.0
|
||||
For CVP versions 2023.3.x, use api version 11.0
|
||||
For CVP versions 2024.1.x, use api version 12.0
|
||||
For CVP versions 2024.2.x, use api version 13.0
|
||||
For CVP versions 2024.3.x and beyond, use api version 14.0
|
||||
|
||||
Args:
|
||||
version (str): The CVP version in use.
|
||||
|
@ -221,6 +227,11 @@ class CvpClient():
|
|||
self.version = version
|
||||
self.log.info('Version %s', version)
|
||||
# Set apiversion to latest available API version for CVaaS
|
||||
# Set apiversion to 14.0 for 2024.3.x
|
||||
# Set apiversion to 13.0 for 2024.2.x
|
||||
# Set apiversion to 12.0 for 2024.1.x
|
||||
# Set apiversion to 11.0 for 2023.3.x
|
||||
# Set apiversion to 10.0 for 2023.2.x
|
||||
# Set apiversion to 9.0 for 2023.1.x
|
||||
# Set apiversion to 8.0 for 2022.1.x - 2022.3.x
|
||||
# Set apiversion to 7.0 for 2021.3.x
|
||||
|
@ -242,7 +253,13 @@ class CvpClient():
|
|||
' Appending 0. Updated Version String - %s',
|
||||
".".join(version_components))
|
||||
full_version = ".".join(version_components)
|
||||
if parse(full_version) >= parse('2024.1.0'):
|
||||
if parse(full_version) >= parse('2024.3.0'):
|
||||
self.log.info('Setting API version to v14')
|
||||
self.apiversion = 14.0
|
||||
elif parse(full_version) >= parse('2024.2.0'):
|
||||
self.log.info('Setting API version to v13')
|
||||
self.apiversion = 13.0
|
||||
elif parse(full_version) >= parse('2024.1.0'):
|
||||
self.log.info('Setting API version to v12')
|
||||
self.apiversion = 12.0
|
||||
elif parse(full_version) >= parse('2023.3.0'):
|
||||
|
|
11
docs/release-notes-1.4.1.rst
Normal file
11
docs/release-notes-1.4.1.rst
Normal file
|
@ -0,0 +1,11 @@
|
|||
######
|
||||
v1.4.1
|
||||
######
|
||||
|
||||
2025-5-8
|
||||
|
||||
Enhancements
|
||||
^^^^^^^^^^^^
|
||||
|
||||
* Add support new service account resource APIs. (`281 <https://github.com/aristanetworks/cvprac/pull/281>`_) [`noredistribution <https://github.com/noredistribution>`_]
|
||||
* Updates for CVP 2024.3.0 suppot. (`282 <https://github.com/aristanetworks/cvprac/pull/282/>`_) [`mharista <https://github.com/mharista>`_]
|
Loading…
Add table
Add a link
Reference in a new issue