Skip to content

Commit 0abdb7c

Browse files
committed
Merge branch 'release-v5.6.0'
2 parents a4a9a0e + 53ee0a4 commit 0abdb7c

File tree

7 files changed

+390
-199
lines changed

7 files changed

+390
-199
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- name: Set up Python
2727
uses: actions/setup-python@v2
2828
with:
29-
python-version: '3.6'
29+
python-version: '3.7'
3030

3131
- name: Install dependencies
3232
run: |

netfoundry/ctl.py

Lines changed: 129 additions & 63 deletions
Large diffs are not rendered by default.

netfoundry/network.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import time
88
from unicodedata import name # enforce a timeout; sleep
99

10-
from .utility import (DC_PROVIDERS, EXCLUDED_PATCH_PROPERTIES,
11-
MAJOR_REGIONS, NETWORK_RESOURCES, STATUS_CODES, VALID_SEPARATORS,
10+
from .utility import (DC_PROVIDERS, EXCLUDED_PATCH_PROPERTIES, MAJOR_REGIONS,
11+
NETWORK_RESOURCES, STATUS_CODES, VALID_SEPARATORS,
1212
VALID_SERVICE_PROTOCOLS, Utility, docstring_parameters,
1313
eprint, http, is_uuidv4, plural, singular)
1414

@@ -337,9 +337,9 @@ def get_edge_router_data_centers(self, provider: str=None, location_code: str=No
337337

338338
if response_code == STATUS_CODES.codes.OK: # HTTP 200
339339
try:
340-
data_centers = json.loads(response.text)['_embedded']['dataCenters']
340+
data_centers = response.json()['_embedded'][NETWORK_RESOURCES['data-centers']._embedded]
341341
except ValueError as e:
342-
eprint('ERROR getting data centers')
342+
logging.error('failed to load data centers response as object from JSON')
343343
raise(e)
344344
else:
345345
raise Exception(
@@ -531,11 +531,11 @@ def get_resources(self, type: str, accept: str=None, deleted: bool=False, **kwar
531531
return([])
532532
# if there is one page of resources
533533
elif total_pages == 1:
534-
all_entities = resources['_embedded'][NETWORK_RESOURCES[type]['embedded']]
534+
all_entities = resources['_embedded'][NETWORK_RESOURCES[type]._embedded]
535535
# if there are multiple pages of resources
536536
else:
537537
# initialize the list with the first page of resources
538-
all_entities = resources['_embedded'][NETWORK_RESOURCES[type]['embedded']]
538+
all_entities = resources['_embedded'][NETWORK_RESOURCES[type]._embedded]
539539
# append the remaining pages of resources
540540
for page in range(1,total_pages):
541541
try:
@@ -554,7 +554,7 @@ def get_resources(self, type: str, accept: str=None, deleted: bool=False, **kwar
554554
if response_code == STATUS_CODES.codes.OK: # HTTP 200
555555
try:
556556
resources = json.loads(response.text)
557-
all_entities.extend(resources['_embedded'][NETWORK_RESOURCES[type]['embedded']])
557+
all_entities.extend(resources['_embedded'][NETWORK_RESOURCES[type]._embedded])
558558
except ValueError as e:
559559
eprint('ERROR: failed to load resources object from GET response')
560560
raise(e)
@@ -909,7 +909,7 @@ def create_endpoint(self, name: str, attributes: list=[], session_identity: str=
909909
started = None
910910
any_in = lambda a, b: any(i in b for i in a)
911911
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
912-
if any_in(response_code_symbols, NETWORK_RESOURCES['endpoints']['create_responses']):
912+
if any_in(response_code_symbols, NETWORK_RESOURCES['endpoints'].create_responses):
913913
try:
914914
started = json.loads(response.text)
915915
except ValueError as e:
@@ -1016,7 +1016,7 @@ def create_edge_router(self, name: str, attributes: list=[], link_listener: bool
10161016
raise
10171017
any_in = lambda a, b: any(i in b for i in a)
10181018
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
1019-
if any_in(response_code_symbols, NETWORK_RESOURCES['edge-routers']['create_responses']):
1019+
if any_in(response_code_symbols, NETWORK_RESOURCES['edge-routers'].create_responses):
10201020
try:
10211021
started = json.loads(response.text)
10221022
except ValueError as e:
@@ -1095,7 +1095,7 @@ def create_edge_router_policy(self, name: str, endpoint_attributes: list=[], edg
10951095
raise
10961096
any_in = lambda a, b: any(i in b for i in a)
10971097
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
1098-
if any_in(response_code_symbols, NETWORK_RESOURCES['edge-router-policies']['create_responses']):
1098+
if any_in(response_code_symbols, NETWORK_RESOURCES['edge-router-policies'].create_responses):
10991099
try:
11001100
started = json.loads(response.text)
11011101
except ValueError as e:
@@ -1249,7 +1249,7 @@ def create_service_simple(self, name: str, client_host_name: str, client_port: i
12491249
raise
12501250
any_in = lambda a, b: any(i in b for i in a)
12511251
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
1252-
if any_in(response_code_symbols, NETWORK_RESOURCES['services']['create_responses']):
1252+
if any_in(response_code_symbols, NETWORK_RESOURCES['services'].create_responses):
12531253
try:
12541254
started = json.loads(response.text)
12551255
except ValueError as e:
@@ -1346,7 +1346,7 @@ def create_service_policy(self, name: str, services: list, endpoints: list, type
13461346

13471347
any_in = lambda a, b: any(i in b for i in a)
13481348
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
1349-
if any_in(response_code_symbols, NETWORK_RESOURCES['service-policies']['create_responses']):
1349+
if any_in(response_code_symbols, NETWORK_RESOURCES['service-policies'].create_responses):
13501350
try:
13511351
started = json.loads(response.text)
13521352
except ValueError as e:
@@ -1435,7 +1435,7 @@ def create_service_edge_router_policy(self, name: str, services: list, edge_rout
14351435

14361436
any_in = lambda a, b: any(i in b for i in a)
14371437
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
1438-
if any_in(response_code_symbols, NETWORK_RESOURCES['service-edge-router-policies']['create_responses']):
1438+
if any_in(response_code_symbols, NETWORK_RESOURCES['service-edge-router-policies'].create_responses):
14391439
try:
14401440
started = json.loads(response.text)
14411441
except ValueError as e:
@@ -1539,7 +1539,7 @@ def create_service_with_configs(self, name: str, intercept_config_data: dict, ho
15391539

15401540
any_in = lambda a, b: any(i in b for i in a)
15411541
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
1542-
if any_in(response_code_symbols, NETWORK_RESOURCES['services']['create_responses']):
1542+
if any_in(response_code_symbols, NETWORK_RESOURCES['services'].create_responses):
15431543
try:
15441544
started = json.loads(response.text)
15451545
except ValueError as e:
@@ -1857,7 +1857,7 @@ def create_service_advanced(self, name: str, endpoints: list, client_hosts: list
18571857

18581858
any_in = lambda a, b: any(i in b for i in a)
18591859
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
1860-
if any_in(response_code_symbols, NETWORK_RESOURCES['services']['create_responses']):
1860+
if any_in(response_code_symbols, NETWORK_RESOURCES['services'].create_responses):
18611861
try:
18621862
started = json.loads(response.text)
18631863
except ValueError as e:
@@ -1937,7 +1937,7 @@ def create_app_wan(self, name: str, endpoint_attributes: list=[], service_attrib
19371937
raise
19381938
any_in = lambda a, b: any(i in b for i in a)
19391939
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
1940-
if any_in(response_code_symbols, NETWORK_RESOURCES['app-wans']['create_responses']):
1940+
if any_in(response_code_symbols, NETWORK_RESOURCES['app-wans'].create_responses):
19411941
try:
19421942
started = json.loads(response.text)
19431943
except ValueError as e:
@@ -2002,7 +2002,7 @@ def get_network_by_name(self,name: str,group: str=None):
20022002
)
20032003
hits = networks['page']['totalElements']
20042004
if hits == 1:
2005-
network = networks['_embedded'][NETWORK_RESOURCES['networks']['embedded']][0]
2005+
network = networks['_embedded'][NETWORK_RESOURCES['networks']._embedded][0]
20062006
return(network)
20072007
else:
20082008
raise Exception("ERROR: failed to find exactly one match for {}".format(name))
@@ -2210,7 +2210,6 @@ def wait_for_entity_name_exists(self, entity_name: str, entity_type: str, wait:
22102210
:param: sleep SECONDS polling interval
22112211
:param: progress print a horizontal progress meter as dots, default false
22122212
"""
2213-
22142213
now = time.time()
22152214

22162215
if not wait >= sleep:

netfoundry/network_group.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def find_latest_product_version(self, product_versions: list=[]):
199199
from distutils.version import LooseVersion
200200
return sorted(product_versions, key=LooseVersion)[-1]
201201

202-
def create_network(self, name: str, network_group_id: str=None, location: str="us-east-1", version: str=None, size: str="small"):
202+
def create_network(self, name: str, network_group_id: str=None, location: str="us-east-1", version: str=None, size: str="small", **kwargs):
203203
"""
204204
Create a network in this network group.
205205
@@ -213,11 +213,29 @@ def create_network(self, name: str, network_group_id: str=None, location: str="u
213213
if not location in my_nc_data_centers_by_location.keys():
214214
raise Exception("ERROR: unexpected Network location '{:s}'. Valid locations include: {}.".format(location, my_nc_data_centers_by_location.keys()))
215215

216+
# map incongruent api keys from kwargs to function params ("name", "size" are congruent)
217+
for param,value in kwargs.items():
218+
if param == 'networkGroupId':
219+
if network_group_id:
220+
logging.debug("clobbering param 'network_group_id' with kwarg 'networkGroupId'")
221+
network_group_id = value
222+
elif param == 'locationCode':
223+
if location:
224+
logging.debug("clobbering param 'location' with kwarg 'locationCode'")
225+
location = value
226+
elif param == 'productVersion':
227+
if version:
228+
logging.debug("clobbering param 'version' with kwarg 'productVersion'")
229+
version == value
230+
else:
231+
logging.warn("ignoring unexpected keyword argument '%s'", param)
232+
216233
request = {
217234
"name": name,
218235
"locationCode": location,
219236
"size": size,
220237
}
238+
221239
if network_group_id:
222240
request["networkGroupId"] = network_group_id
223241
else:
@@ -255,7 +273,7 @@ def create_network(self, name: str, network_group_id: str=None, location: str="u
255273

256274
any_in = lambda a, b: any(i in b for i in a)
257275
response_code_symbols = [s.upper() for s in STATUS_CODES._codes[response_code]]
258-
if any_in(response_code_symbols, RESOURCES['networks']['create_responses']):
276+
if any_in(response_code_symbols, RESOURCES['networks'].create_responses):
259277
try:
260278
network = json.loads(response.text)
261279
except ValueError as e:

netfoundry/organization.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
import time # enforce a timeout; sleep
99
from pathlib import Path
1010

11-
import jwt
1211
from platformdirs import user_cache_path, user_config_path
1312

14-
from .utility import RESOURCES, STATUS_CODES, Utility, eprint, http, is_uuidv4
1513
from .exceptions import NFAPINoCredentials
14+
from .utility import (MUTABLE_NETWORK_RESOURCES, NETWORK_RESOURCES,
15+
RESOURCES, STATUS_CODES, Utility, eprint, http,
16+
is_uuidv4)
1617

1718
utility = Utility()
1819

@@ -39,6 +40,7 @@ def __init__(self,
3940
organization_label: str=None,
4041
profile: str="default",
4142
token: str=None,
43+
authorization: dict=dict(),
4244
expiry_minimum: int=600,
4345
proxy: str=None):
4446
"""Initialize an instance of organization."""
@@ -108,9 +110,8 @@ def __init__(self,
108110
# if the token was found then extract the expiry
109111
if self.token:
110112
try:
111-
claim = jwt.decode(jwt=self.token, algorithms=["RS256"], options={"verify_signature": False})
112-
except jwt.exceptions.PyJWTError:
113-
logging.error("failed to parse bearer token as JWT")
113+
claim = utility.jwt_decode(self.token)
114+
except:
114115
raise
115116
else:
116117
self.expiry = claim['exp']
@@ -204,10 +205,10 @@ def __init__(self,
204205
# renew token if not existing or imminent expiry, else continue
205206
if not self.token or self.expiry_seconds < expiry_minimum:
206207
if self.token and self.expiry_seconds < expiry_minimum:
207-
logging.warn("token expiry %ds is less than configured minimum %ds", self.expiry_seconds, expiry_minimum)
208+
logging.debug("token expiry %ds is less than configured minimum %ds", self.expiry_seconds, expiry_minimum)
208209
if not credentials_configured:
209-
logging.error("credentials needed to renew token")
210-
raise NFAPINoCredentials
210+
logging.debug("credentials needed to renew token")
211+
raise NFAPINoCredentials("credentials needed to renew token")
211212
else:
212213
logging.debug("renewing token")
213214

@@ -243,6 +244,7 @@ def __init__(self,
243244
try:
244245
token_text = json.loads(response.text)
245246
self.token = token_text['access_token']
247+
self.expiry = token_text['expires_in']
246248
except:
247249
raise Exception(
248250
'ERROR: failed to find an access_token in the response and instead got: {}'.format(
@@ -260,7 +262,7 @@ def __init__(self,
260262

261263
# learn about the environment from the token
262264
try:
263-
claim = jwt.decode(jwt=self.token, algorithms=["RS256"], options={"verify_signature": False})
265+
claim = utility.jwt_decode(self.token)
264266
iss = claim['iss']
265267
if re.match(r'https://cognito-', iss):
266268
self.environment = re.sub(r'https://gateway\.([^.]+)\.netfoundry\.io.*',r'\1',claim['scope'])
@@ -465,7 +467,6 @@ def get_organizations(self, **kwargs):
465467
params = dict()
466468
for param in kwargs.keys():
467469
params[param] = kwargs[param]
468-
469470
try:
470471
headers = { "authorization": "Bearer " + self.token }
471472
response = http.get(
@@ -580,13 +581,13 @@ def get_network(self, network_id: str, embed: str=None, accept: str=None):
580581
headers["authorization"] = "Bearer " + self.token
581582
params = dict()
582583
if embed == "all":
583-
params['embed'] = ','.join([type for type in RESOURCES.keys() if RESOURCES[type]['domain'] == "network"])
584+
params['embed'] = ','.join(MUTABLE_NETWORK_RESOURCES)
584585
logging.debug("requesting embed all resource types in network domain: {:s}".format(params['embed']))
585586
elif embed:
586587
params['embed'] = ','.join([type for type in embed.split(',') if RESOURCES[type]['domain'] == "network"])
587588
logging.debug("requesting embed some resource types in network domain: {:s}".format(params['embed']))
588589
for type in embed.split(','):
589-
if not type in [type for type in RESOURCES.keys() if RESOURCES[type]['domain'] == "network"]:
590+
if not type in NETWORK_RESOURCES.keys():
590591
logging.debug("not requesting embed of resource type '{:s}' because not a valid resource type or not in network domain".format(type))
591592
try:
592593
response = http.get(
@@ -664,7 +665,7 @@ def get_network_groups_by_organization(self, **kwargs):
664665
if total_elements == 0:
665666
return([])
666667
else:
667-
network_groups = response_object['_embedded'][RESOURCES['network-groups']['embedded']]
668+
network_groups = response_object['_embedded'][RESOURCES['network-groups']._embedded]
668669

669670
# if there is one page of resources
670671
if total_pages == 1:
@@ -688,7 +689,7 @@ def get_network_groups_by_organization(self, **kwargs):
688689
if response_code == STATUS_CODES.codes.OK: # HTTP 200
689690
try:
690691
response_object = response.json()
691-
network_groups.extend(response_object['_embedded'][RESOURCES['network-groups']['embedded']])
692+
network_groups.extend(response_object['_embedded'][RESOURCES['network-groups']._embedded])
692693
except ValueError:
693694
logging.error('failed loading list of network groups as object')
694695
raise ValueError("response is not JSON")
@@ -761,11 +762,11 @@ def get_networks_by_organization(self, name: str=None, deleted: bool=False, **kw
761762
return([])
762763
# if there is one page of resources
763764
elif total_pages == 1:
764-
all_entities = resources['_embedded'][RESOURCES['networks']['embedded']]
765+
all_entities = resources['_embedded'][RESOURCES['networks']._embedded]
765766
# if there are multiple pages of resources
766767
else:
767768
# initialize the list with the first page of resources
768-
all_entities = resources['_embedded'][RESOURCES['networks']['embedded']]
769+
all_entities = resources['_embedded'][RESOURCES['networks']._embedded]
769770
# append the remaining pages of resources
770771
for page in range(1,total_pages):
771772
try:
@@ -784,7 +785,7 @@ def get_networks_by_organization(self, name: str=None, deleted: bool=False, **kw
784785
if response_code == STATUS_CODES.codes.OK: # HTTP 200
785786
try:
786787
resources = json.loads(response.text)
787-
all_entities.extend(resources['_embedded'][RESOURCES['networks']['embedded']])
788+
all_entities.extend(resources['_embedded'][RESOURCES['networks']._embedded])
788789
except ValueError as e:
789790
eprint('ERROR: failed to load resources object from GET response')
790791
raise(e)
@@ -864,7 +865,7 @@ def get_networks_by_group(self,network_group_id: str, deleted: bool=False, **kwa
864865
logging.error("response is not JSON")
865866
raise ValueError("response is not JSON")
866867
try:
867-
networks = embedded['_embedded'][RESOURCES['networks']['embedded']]
868+
networks = embedded['_embedded'][RESOURCES['networks']._embedded]
868869
except KeyError:
869870
networks = list()
870871
else:

0 commit comments

Comments
 (0)