Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

dcnm_fabric (Ready for review) #286

Merged
merged 232 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
232 commits
Select commit Hold shift + click to select a range
32976fd
initial commit (needs lots of work)
allenrobel Mar 3, 2024
059f404
Use have/want/need nomenclature and initial support class renaming
allenrobel Mar 3, 2024
0fc2698
Initial cleanup (much more work to do)
allenrobel Mar 4, 2024
9b988e4
Refactor to leverage RestSend and improve modularity.
allenrobel Mar 7, 2024
0cd8a13
Changes for modularity
allenrobel Mar 10, 2024
69db9b6
Work in progress (basic create, update, delete, query is working)
allenrobel Mar 13, 2024
24b2367
Comment out unused imports for now
allenrobel Mar 14, 2024
d217858
Add files from module_utils/common
allenrobel Mar 14, 2024
a5c5d59
Use Results() class to standardize results
allenrobel Mar 16, 2024
54a0907
FabricQuery: handle failed result. All: add doc strings
allenrobel Mar 16, 2024
36c180a
Make results more like existing module results
allenrobel Mar 18, 2024
fd68445
Forgot to commit with last commit
allenrobel Mar 18, 2024
49aa5eb
Move results.py to module_utils/common
allenrobel Mar 18, 2024
e213e4b
Use RestSend from rest_send.py
allenrobel Mar 18, 2024
36138e5
FabricQuery().commit() simplify logic, more...
allenrobel Mar 26, 2024
2707ba4
Add unit tests for FabricUpdateBulk, more...
allenrobel Mar 26, 2024
41a0b17
Move _fixup_payloads_to_commit() to FabricCommon(), more...
allenrobel Mar 27, 2024
8495983
FabricCommon()._fixup_payloads_to_commit(), simplify
allenrobel Mar 27, 2024
fee96d1
Update docstrings, more...
allenrobel Mar 27, 2024
f106a2d
Rename GenerateResponses() to ResponseGenerator(), more...
allenrobel Mar 27, 2024
471a1c6
Run unit test files through black, isort, pylint
allenrobel Mar 27, 2024
c266517
Consistent fixture file naming
allenrobel Mar 27, 2024
3cf0093
FabricCreateBulk: Add unit test for invalid FABRIC_TYPE value
allenrobel Mar 27, 2024
c1d7db2
FabricUpdateBulk: Support idempotence when payload == controller config
allenrobel Mar 28, 2024
e87f7e3
Initial cut at dynamic parameter validation from template
allenrobel Apr 1, 2024
18666bc
Fix docstring
allenrobel Apr 1, 2024
136c769
TemplateGet(): Fix crash when check_mode is True
allenrobel Apr 1, 2024
7a9001b
default_param_value_is_valid(): Fix logic
allenrobel Apr 1, 2024
27ba0f8
Fix typo in comment
allenrobel Apr 1, 2024
c6afba8
dcnm_fabric.py: run thru black/isort
allenrobel Apr 1, 2024
2fe0b5b
FabricDefaults(): remove old unused code
allenrobel Apr 1, 2024
682a6d7
Delete unused file
allenrobel Apr 1, 2024
49820d4
Debug message improvements
allenrobel Apr 1, 2024
1c21a04
Fix (hopefully) for parameter validation logic
allenrobel Apr 2, 2024
fc1f33f
Massage controller boolean values to match our comparison
allenrobel Apr 2, 2024
0e19544
Convert playbook and default boolean strings to boolean type prior to…
allenrobel Apr 2, 2024
4644d7d
VerifyPlaybookParams(): refactor, more...
allenrobel Apr 3, 2024
7d99a80
VerifyPlaybookParam: refactor eval methods
allenrobel Apr 3, 2024
f85e102
VerifyPlaybookParams(): continue refactor, update docstrings
allenrobel Apr 3, 2024
6c6379d
FabricDefaults(): Update class docstring
allenrobel Apr 3, 2024
6357708
Initial cut at handling invalid parameter values
allenrobel Apr 3, 2024
faa1c0d
VerifyPlaybookParams: Consistent terminology in error messages
allenrobel Apr 3, 2024
89c96e9
Error if the user specifies int (0,1) instead of boolean(False, True)
allenrobel Apr 3, 2024
f7812db
VerifyPlaybookParams() specify template via property
allenrobel Apr 4, 2024
65513b3
VerifyPlaybookParams() and TempateGet(): use raise instead of Ansible…
allenrobel Apr 5, 2024
204a3fb
Use Markdown in class and method docstrings.
allenrobel Apr 5, 2024
ddce714
Change ruleset key from "op" to "operator", more...
allenrobel Apr 5, 2024
2fc8f78
ParamInfo().parameter() better error handling, more...
allenrobel Apr 5, 2024
bafb33c
WIP: Disentangle AnsibleModule() from support classes, continued
allenrobel Apr 6, 2024
2743590
Remove unused file
allenrobel Apr 6, 2024
1a14032
Update unit tests for exception handling changes.
allenrobel Apr 6, 2024
957bf88
Remove AnsibleFailJson imports
allenrobel Apr 6, 2024
b77df51
FabricSummary() add rest_send property, update docstrings
allenrobel Apr 6, 2024
2c7a537
ControllerResponseError: Add custom exception
allenrobel Apr 7, 2024
0e28abf
WIP: Disentangle AnsibleModule() from support classes, continued
allenrobel Apr 8, 2024
2b6034a
RuleSet()._update_ruleset_rule_and(): Fix regex error (thanks Mike!)
allenrobel Apr 8, 2024
9b185fc
FabricCreateCommon: remove redundant assignment of FabricDetails.rest…
allenrobel Apr 8, 2024
a3e07ea
Remove commented code from last commit
allenrobel Apr 8, 2024
998dce8
FabricSummary(). Logic change and improve message
allenrobel Apr 8, 2024
d4a083a
Disable logging
allenrobel Apr 8, 2024
4dc85a1
FabricUpdateCommon() fixes, more...
allenrobel Apr 8, 2024
e442fc4
FabricUpdateBulk: test_fabric_update_bulk00025, test all mandatory keys
allenrobel Apr 8, 2024
81c960d
dcnm_fabric.py: Remove commented code
allenrobel Apr 8, 2024
05dc121
FabricCommon: Initial unit tests, more...
allenrobel Apr 9, 2024
02596c7
FabricCommon: Additional unit tests
allenrobel Apr 9, 2024
0df8db6
FabricCommon(): Additional unit tests, more...
allenrobel Apr 9, 2024
66b72b6
make_none(): Fix test conversion in conditional
allenrobel Apr 9, 2024
2c63233
FabricCommon().make_none(): 100% unit test coverage
allenrobel Apr 9, 2024
f8e9f75
FabricCommon().make_boolean(): 100% unit test coverage
allenrobel Apr 9, 2024
c97667b
FabricCreateCommon(): initial unit tests
allenrobel Apr 9, 2024
bf925ba
FabricCreateCommon().mandatory_payload_keys: Add FABRIC_TYPE
allenrobel Apr 9, 2024
3fc86df
FabricCreateCommon(): 100% unit test coverage
allenrobel Apr 9, 2024
f62a59f
FabricCreateBulk(): Verify that RestSend is set, more...
allenrobel Apr 10, 2024
dc9c52d
FabricCreate: 100% unit test coverage, more...
allenrobel Apr 10, 2024
f88d983
ConversionUtils: new class with basic conversion methods, more...
allenrobel Apr 10, 2024
9fb745a
ParamInfo(): Initial unit tests. 95% coverage.
allenrobel Apr 10, 2024
3f42bf7
ApiEndpoints(): harden fabric name verification
allenrobel Apr 11, 2024
4783980
FabricDelete: verify Results() is set prior to calling commit(), more...
allenrobel Apr 11, 2024
825a85f
Results.did_anything_change(): return True if len(diff) != 0, more...
allenrobel Apr 12, 2024
ecd4af1
ApiEndpoints()._re_valid_fabric_name: fix regex
allenrobel Apr 12, 2024
e3fde0d
FabricDelete(): Handle fabric not empty case, more...
allenrobel Apr 12, 2024
63d9239
Update some docstrings to include the method(s) being tested
allenrobel Apr 12, 2024
5a6df7e
FabricDelete: initial unit tests. 77% coverage.
allenrobel Apr 12, 2024
f44b51d
ApiEndpoints()._re_valid_fabric_name: yet another regex fix.
allenrobel Apr 12, 2024
78eb09a
FabricDefaults: Remove. Functionality is provided by ParamInfo()
allenrobel Apr 12, 2024
de6b876
ParamInfo._build_info(): refactor
allenrobel Apr 12, 2024
ec80886
FabricDelete()._send_request(): Update docstring
allenrobel Apr 12, 2024
2c6aaa6
FabricDelete. _set_fabric_delete_endpoint(): unit test, more...
allenrobel Apr 12, 2024
c3dfbd0
FabricDelete().commit(): Call register_task_result()
allenrobel Apr 12, 2024
d153eb9
FabricDelete(): Add unit test for fabric does not exist case.
allenrobel Apr 12, 2024
2cf02b0
FabricDelete(): Add unit test for failed fabric delete request
allenrobel Apr 12, 2024
282b80e
FabricDelete().fabric_names: Three unit tests
allenrobel Apr 12, 2024
9a69d56
VerifyPlaybookParams(): Reject boolean strings
allenrobel Apr 13, 2024
d2c3c67
ApiEndpoints(): minor changes to error messages and docstrings
allenrobel Apr 13, 2024
08f6247
ApiEndpoints(): initial unit tests
allenrobel Apr 13, 2024
8a2f94b
ApiEndpoints().fabric_create: unit tests
allenrobel Apr 14, 2024
d7bd122
ApiEndpoints().fabric_delete: unit tests
allenrobel Apr 14, 2024
55fcdea
ApiEndpoints.fabric_summary: unit tests, more...
allenrobel Apr 14, 2024
07567fc
ApiEndpoints.fabric_update: unit tests
allenrobel Apr 14, 2024
4b7b240
ApiEndpoints.fabric_info: unit tests
allenrobel Apr 14, 2024
e29ca37
ApiEndpoints. template_name: unit tests
allenrobel Apr 14, 2024
0c2a6df
ApiEndpoints.template: unit tests
allenrobel Apr 14, 2024
70d3a88
ApiEndpoints.templates: unit tests
allenrobel Apr 14, 2024
5b9b393
ApiEndpoints(): consistent docstrings
allenrobel Apr 14, 2024
c76e119
FabricDetails(): improve Results() update handling
allenrobel Apr 15, 2024
864f1f7
FabricDetails: initial unit tests
allenrobel Apr 15, 2024
4ce0a39
FabricDetails: Reorganize response fixtures
allenrobel Apr 15, 2024
945850f
FabricDetailsByName().filtered_data: raise ValueError if filter is no…
allenrobel Apr 15, 2024
6b8628c
FabricDetailsByName(): initial unit tests
allenrobel Apr 15, 2024
503a2e1
FabricDetails(): modify two getters to retrieve from nvPairs
allenrobel Apr 15, 2024
45556a1
FabricDetailsByName(): 100% unit test coverage
allenrobel Apr 15, 2024
731a8ad
FabricDetailsByNvPair().refresh(): improve error messages
allenrobel Apr 16, 2024
7027dba
test_fabric_details_*.py unit test files: run thru linters
allenrobel Apr 16, 2024
3540b00
FabricDetailsByNvPair: 100% unit test coverage
allenrobel Apr 16, 2024
bb0f489
Modify ruleset structure to accommodate boolean "or"
allenrobel Apr 17, 2024
fd01d71
RuleSet(): refactor
allenrobel Apr 17, 2024
fe6b240
Remove wayward print()
allenrobel Apr 17, 2024
a70c4ea
TemplateGet: Improve error handling, more...
allenrobel Apr 17, 2024
d5c7c6e
TemplateGet: 100% unit test coverage
allenrobel Apr 17, 2024
6be331c
TemplateGetAll: disentangle from AnsibleModule, more...
allenrobel Apr 18, 2024
8edb0c4
TemplateGetAll: 100% unit test coverage
allenrobel Apr 18, 2024
943d31b
FabricSummary: raise ControllerResponseError on non-200 response, mor…
allenrobel Apr 18, 2024
2d53202
FabricSummary()._update_device_counts: remove unneeded check
allenrobel Apr 18, 2024
2007e97
Remove unneeded f-string interpolation of error messages when re-rais…
allenrobel Apr 18, 2024
6557cd5
FabricSummary: 100% unit test coverage.
allenrobel Apr 18, 2024
6d9f394
test_endpoints.py 00020: verify fabric_name is set if exception is no…
allenrobel Apr 18, 2024
dfa467b
FabricDelete: Add unit test for FabricSummary 404 response.
allenrobel Apr 18, 2024
3f084b5
FabricUpdateCommon(). _can_fabric_be_deployed(): exception handling
allenrobel Apr 19, 2024
7fd3d35
FabricUpdateBulk: Add unit test for last commit's changes, more...
allenrobel Apr 19, 2024
2cf083b
FabricUpdateCommon() remove unneeded checks, more...
allenrobel Apr 19, 2024
0782c20
FabricUpdateBulk: Additional unit tests, more...
allenrobel Apr 19, 2024
9972788
FabricUpdateBulk: Populate results.diff with payload actually sent to…
allenrobel Apr 20, 2024
34f4df3
RuleSet().template: accept only dict
allenrobel Apr 20, 2024
6f2b3e9
RuleSet(): initial unit tests
allenrobel Apr 20, 2024
78fb9e8
RuleSet().refresh(): raise ValueError on missing name key, more...
allenrobel Apr 20, 2024
d85aca7
RuleSet().refresh(): unit tests complete for this method.
allenrobel Apr 20, 2024
a89cf6c
Run all unit test files thru black/isort/pylint.
allenrobel Apr 20, 2024
0c186a8
Add dcnm_fabric.py to ignore list for missing-gplv3-license
allenrobel Apr 20, 2024
66db14d
dcnm_fabric.Merged().get_need(): Fix fail_json message
allenrobel Apr 20, 2024
7d5377e
Merge branch 'develop' into dcnm_fabric
allenrobel Apr 20, 2024
68f8762
FabricCommon()__init__(): initialize _payloads_to_commit for subclasses
allenrobel Apr 21, 2024
ac0eaf8
test_fabric_delete.py: fix match in unit test 00021
allenrobel Apr 21, 2024
c79dc3c
Fix a few sanity-test issues
allenrobel Apr 21, 2024
151c834
Fix PEP8 sanity errors
allenrobel Apr 21, 2024
768a93d
Fix trailing whitespaces not caught by black.
allenrobel Apr 21, 2024
f99122c
Fix sanity-found boilerplate issues
allenrobel Apr 21, 2024
1d90d65
Fix pylint issues
allenrobel Apr 21, 2024
25c9935
Fix validate-modules issues
allenrobel Apr 21, 2024
310bbc0
FabricUpdateBulk: Add more unit tests
allenrobel Apr 21, 2024
2ccfffc
Fix PEP8 issue in unit test file
allenrobel Apr 21, 2024
cc1e72d
test_fabric_update_bulk.py: More unit tests, more...
allenrobel Apr 22, 2024
d9c8d6c
test_fabric_update_bulk.py: Add unit test
allenrobel Apr 22, 2024
c2efa87
test_fabric_update_bulk.py: Add unit test, more...
allenrobel Apr 22, 2024
db1e975
Fix dup key in dictionary error
allenrobel Apr 22, 2024
cc41eb8
Validate BGP_AS, more...
allenrobel Apr 22, 2024
3f518d7
ConversionUtils().bgp_as_is_valid(): Fix PEP8 bare except
allenrobel Apr 22, 2024
ba8caef
BGP_AS regex disallowing valid values.
allenrobel Apr 22, 2024
206d291
ConversionUtils(): Disable pylint line-to-long to allow long BGP_AS r…
allenrobel Apr 22, 2024
0bf6be3
Fix BGP_AS regex
allenrobel Apr 22, 2024
f016475
Fix PEP8 issue
allenrobel Apr 22, 2024
788088d
FabricDetails(): Get fabric_name from nvPairs.FABRIC_NAME rather than…
allenrobel Apr 22, 2024
0ddd1ac
FabricUpdateBulk(): Add unit test, more...
allenrobel Apr 22, 2024
40083f8
FabricUpdateBulk(): Add unit test
allenrobel Apr 23, 2024
f4bec17
VerifyPlaybookParams(): minor cleanup
allenrobel Apr 23, 2024
44a789e
VerifyPlaybookParams(): Unit tests for property getter/setters.
allenrobel Apr 23, 2024
7aa0089
VerifyPlaybookParams(): Additional unit tests
allenrobel Apr 23, 2024
01973ef
VerifyPlaybookParams(): Add unit tests, more...
allenrobel Apr 23, 2024
6c2ba8e
VerifyPlaybookParams: Add unit tests
allenrobel Apr 23, 2024
4903e50
VerifyPlaybookParams: Add unit tests, more...
allenrobel Apr 23, 2024
4dd3527
VerifyPlaybookParams: Add unit tests, more...
allenrobel Apr 24, 2024
57896ba
Move ApiEndpoints().validate_fabric_name() to ConversionUtils()
allenrobel Apr 24, 2024
5ae2df8
Earlier payload validation, LAN_CLASSIC support, more...
allenrobel Apr 24, 2024
c5045b7
Support for MSD fabric
allenrobel Apr 25, 2024
b4558c6
Add FabricTypes() class as single source of truth for fabric types
allenrobel Apr 25, 2024
0eb6df0
FabricTypes(): Add unit tests, update docstrings
allenrobel Apr 25, 2024
a056ff7
RuleSet(): remove commented code
allenrobel Apr 25, 2024
aa32340
RuleSet(): Update usage with more complete example
allenrobel Apr 26, 2024
dd7dd2e
Fix PEP8 whitespace issue
allenrobel Apr 26, 2024
e87ac30
Merge branch 'develop' of https://github.com/CiscoDevNet/ansible-dcnm…
allenrobel Apr 26, 2024
d6af03f
FabricCommon(). fabric_type_to_template_name - remove method
allenrobel Apr 26, 2024
c740d68
test_fabric_common.py: Remove var for a deleted unit test
allenrobel Apr 26, 2024
9d7437e
FabricCommon(): Remove unused methods, finish unit tests.
allenrobel Apr 26, 2024
bfd59df
Merge branch 'develop' into dcnm_fabric
allenrobel Apr 26, 2024
8c86919
test/sanity/ignore-2.*.txt were changed to remove dcnm_fabric. Addin…
allenrobel Apr 26, 2024
773b164
Fix PEP8 trailing-whitespace
allenrobel Apr 26, 2024
fb17b84
Add ResponseHandler() class and unit tests.
allenrobel Apr 26, 2024
d598ea0
ResponseHandler().__init__(): Fix class_name assignment.
allenrobel Apr 26, 2024
276b65b
ParamInfo(): Fix breaking issue and other improvements.
allenrobel Apr 28, 2024
8778c74
ParamInfo(): Fix PEP8 missing whitespace issue.
allenrobel Apr 28, 2024
1777ebf
FabricCommon() and FabricUpdateCommon(): refactor
allenrobel Apr 29, 2024
d2f2ad5
Initial support for replaced state. Caveats...
allenrobel Apr 29, 2024
0f684c3
FabricReplacedCommon()._update_replaced_playload(): small optimizatio…
allenrobel Apr 29, 2024
545ce44
FabricReplacedCommon()._fabric_needs_update(): refactor
allenrobel Apr 29, 2024
56d477a
FabricReplacedCommon: add parameter verification, refactor
allenrobel Apr 29, 2024
6d1d8e1
VerifyPlaybookParams(): Remove call to reject_boolean_string() for now.
allenrobel Apr 29, 2024
0be7d4d
Fix PEP8 trailing-whitespace
allenrobel Apr 29, 2024
0eee338
Remove validation of final payload in replaced state for now.
allenrobel Apr 29, 2024
3bf7fdd
FabricReplacedCommon(): validate user parameters before replaced-stat…
allenrobel Apr 29, 2024
5a66c0f
FabricCommon(): move shared code to this class.
allenrobel Apr 30, 2024
51125ee
FabricCommon(): Move more shared code into this class.
allenrobel Apr 30, 2024
23ae6a5
FabricReplacedCommon(): improve error message.
allenrobel Apr 30, 2024
3a85bf1
FabricConfigDeploy(): new class, initiate a fabric config-deploy oper…
allenrobel Apr 30, 2024
65bc262
FabricConfigSave(): new class, initiate a fabric config-save operation
allenrobel Apr 30, 2024
d5f05ad
FabricCommon(): leverage FabricConfigDeploy() and FabricConfigSave()
allenrobel Apr 30, 2024
28894e1
test_fabric_update_bulk_00080: Remove unit test
allenrobel Apr 30, 2024
207d17c
FabricConfigDeploy(): 100% unit test coverage.
allenrobel Apr 30, 2024
adfe088
FabricConfigSave(): 100% unit test coverage.
allenrobel Apr 30, 2024
fbcebf8
FabricReplacedBulk(): initial unit tests. 36% coverage.
allenrobel May 1, 2024
2ed3f19
FabricReplacedBulk(): add unit test. 44% coverage.
allenrobel May 1, 2024
5d866d6
Guard against deploying read-only and frozen fabrics
allenrobel May 2, 2024
14172c2
ParamInfo()._build_properties(): rename to _init_properties()
allenrobel May 2, 2024
2f89b7c
Last commit for module code (still need to commit IT)
allenrobel May 2, 2024
d35b6ca
dcnm_fabric IT: Add dcnm_fabric_deleted_basic and initial boilerplate…
allenrobel May 2, 2024
c9a7f61
Fix yamllint (empty-lines)
allenrobel May 2, 2024
52426af
FabricConfigSave() / FabricConfigDeploy() changes
allenrobel May 3, 2024
d1a8d9e
dcnm_fabric IT: Add dcnm_fabric_merged_basic, more...
allenrobel May 3, 2024
e2451ae
FabricConfigSave().commit(): Fix guard conditional, more...
allenrobel May 3, 2024
37e0f60
Merge branch 'develop' of https://github.com/CiscoDevNet/ansible-dcnm…
allenrobel May 3, 2024
dc01556
Fix dcnm_fabric entries after pulling develop branch commit 25bd65b
allenrobel May 3, 2024
85f11be
ParamInfo().parameter(): Improve error message.
allenrobel May 3, 2024
9314dfe
RuleSet().refresh(): was not resetting self.ruleset prior to updating…
allenrobel May 3, 2024
26ad0fb
dcnm_fabric.py: Merged().get_need(): minor cleanup.
allenrobel May 3, 2024
6596651
dcnm_fabric IT: Add dcnm_fabric_replaced_basic
allenrobel May 4, 2024
28b0cae
dcnm_fabric: IT dcnm_fabric_merged_basic: run through YAML formatter.
allenrobel May 4, 2024
7522275
dcnm_fabric: IT dcnm_fabric_deleted_basic: run through YAML formatter.
allenrobel May 4, 2024
c61072a
dcnm_fabric IT: dcnm_fabric_replaced_basic, add idempotence test
allenrobel May 4, 2024
488233c
dcnm_fabric IT: dcnm_fabric_merged_basic, add idempotence test
allenrobel May 4, 2024
bfe9dc9
dcnm_fabric IT: Add dcnm_fabric_merged_save_deploy
allenrobel May 5, 2024
0f50472
FabricDetails(): change a couple debug statements.
allenrobel May 5, 2024
cea30ec
dcnm_fabric IT: rename fabric_name and fabric_type vars.
allenrobel May 5, 2024
1e4858b
dcnm_fabric IT: Add dcnm_fabric_replaced_save_deploy
allenrobel May 6, 2024
548bc04
ApiEndpoints(): Remove inclAllMSDSwitches from config-deploy endpoint
allenrobel May 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions plugins/module_utils/common/conversion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Copyright (c) 2024 Cisco and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import, division, print_function

__metaclass__ = type
__author__ = "Allen Robel"

import inspect
import re


class ConversionUtils:
"""
Utility methods for converting, translating, and validating values.

- bgp_asn_is_valid: Return True if value is a valid BGP ASN, False otherwise.
- make_boolean: Return value converted to boolean, if possible.
- make_int: Return value converted to int, if possible.
- make_none: Return None if value is a string representation of a None type.
- reject_boolean_string: Reject quoted boolean values e.g. "False", "true"
- translate_mac_address: Convert mac address to dotted-quad format expected by the controller.
- validate_fabric_name: Validate the fabric name meets the requirements of the controller.
"""

def __init__(self):
self.class_name = self.__class__.__name__

re_asn_str = "^(((\\+)?[1-9]{1}[0-9]{0,8}|(\\+)?[1-3]{1}[0-9]{1,9}|(\\+)?[4]"
re_asn_str += "{1}([0-1]{1}[0-9]{8}|[2]{1}([0-8]{1}[0-9]{7}|[9]{1}([0-3]{1}"
re_asn_str += "[0-9]{6}|[4]{1}([0-8]{1}[0-9]{5}|[9]{1}([0-5]{1}[0-9]{4}|[6]"
re_asn_str += "{1}([0-6]{1}[0-9]{3}|[7]{1}([0-1]{1}[0-9]{2}|[2]{1}([0-8]{1}"
re_asn_str += "[0-9]{1}|[9]{1}[0-5]{1})))))))))|([1-5]\\d{4}|[1-9]\\d{0,3}|6"
re_asn_str += "[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])"
re_asn_str += "(\\.([1-5]\\d{4}|[1-9]\\d{0,3}|6[0-4]\\d{3}|65[0-4]"
re_asn_str += "\\d{2}|655[0-2]\\d|6553[0-5]|0))?)$"
self.re_asn = re.compile(re_asn_str)
self.re_valid_fabric_name = re.compile(r"[a-zA-Z]+[a-zA-Z0-9_-]*")

self.bgp_as_invalid_reason = None

def bgp_as_is_valid(self, value):
"""
- Return True if value is a valid BGP ASN.
- Return False, otherwise.
- Set ConversionUtils().bgp_as_invalid_reason to a string with the
reason why the value is not a valid BGP ASN.

Usage example:

```python
conversion = ConversionUtils()
if not conversion.bgp_as_is_valid(value):
print(conversion.bgp_as_invalid_reason)
```
"""
if isinstance(value, float):
msg = f"BGP ASN ({value}) cannot be type float() due to "
msg += "loss of trailing zeros. "
msg += "Use a string or integer instead."
self.bgp_as_invalid_reason = msg
return False
try:
asn = str(value)
except UnicodeEncodeError:
msg = f"BGP ASN ({value}) could not be converted to a string."
self.bgp_as_invalid_reason = msg
return False
if not self.re_asn.match(asn):
msg = f"BGP ASN {value} failed regex validation."
self.bgp_as_invalid_reason = msg
return False
return True

@staticmethod
def make_boolean(value):
"""
- Return value converted to boolean, if possible.
- Return value, otherwise.
"""
if str(value).lower() in ["true", "yes"]:
return True
if str(value).lower() in ["false", "no"]:
return False
return value

@staticmethod
def make_int(value):
"""
- Return value converted to int, if possible.
- Return value, otherwise.
"""
# Don't convert boolean values to integers
if isinstance(value, bool):
return value
try:
return int(value)
except (ValueError, TypeError):
return value

@staticmethod
def make_none(value):
"""
- Return None if value is a string representation of a None type
- Return value, otherwise.
"""
if str(value).lower() in {"", "none", "null"}:
return None
return value

@staticmethod
def reject_boolean_string(parameter, value) -> None:
"""
- Reject quoted boolean values e.g. "False", "true"
- Raise ``ValueError`` with informative message if the value is
a string representation of a boolean.
"""
if isinstance(value, int):
return
if isinstance(value, bool):
return
if str(value).lower() in ["true", "false"]:
msg = f"Parameter {parameter}, value '{value}', "
msg += "is a quoted string representation of a boolean. "
msg += "Please remove the quotes and try again "
msg += "(e.g. True/False or true/false, instead of "
msg += "'True'/'False' or 'true'/'false')."
raise ValueError(msg)

@staticmethod
def translate_mac_address(mac_addr):
"""
- Accept mac address with any (or no) punctuation and convert it
into the dotted-quad format that the controller expects.
- On success, return translated mac address.
- On failure, raise ``ValueError``.
"""
mac_addr = re.sub(r"[\W\s_]", "", mac_addr)
if not re.search("^[A-Fa-f0-9]{12}$", mac_addr):
raise ValueError(f"Invalid MAC address: {mac_addr}")
return "".join((mac_addr[:4], ".", mac_addr[4:8], ".", mac_addr[8:]))

def validate_fabric_name(self, value):
"""
- Validate the fabric name meets the requirements of the controller.
- Raise ``TypeError`` if value is not a string.
- Raise ``ValueError`` if value does not meet the requirements.
"""
method_name = inspect.stack()[0][3] # pylint: disable=unused-variable

if not isinstance(value, str):
msg = f"{self.class_name}.{method_name}: "
msg += f"Invalid fabric name. Expected string. Got {value}."
raise TypeError(msg)

if re.fullmatch(self.re_valid_fabric_name, value) is not None:
return
msg = f"{self.class_name}.{method_name}: "
msg += f"Invalid fabric name: {value}. "
msg += "Fabric name must start with a letter A-Z or a-z and "
msg += "contain only the characters in: [A-Z,a-z,0-9,-,_]."
raise ValueError(msg)
22 changes: 22 additions & 0 deletions plugins/module_utils/common/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (c) 2024 Cisco and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import, division, print_function

__metaclass__ = type
__author__ = "Allen Robel"


class ControllerResponseError(Exception):
pass
2 changes: 1 addition & 1 deletion plugins/module_utils/common/params_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def _ipaddress_guard(self, expected_type, value: Any, param: str) -> None:

The ipaddress module accepts int and bool types and converts
them to IP addresses or networks. E.g. True becomes 0.0.0.1,
False becomes 0.0.0.0, 1 becomse 0.0.0.1, etc. Because of
False becomes 0.0.0.0, 1 becomes 0.0.0.1, etc. Because of
this, we need to fail int and bool values if expected_type is
one of ipv4, ipv6, ipv4_subnet, or ipv6_subnet.
"""
Expand Down
Loading
Loading