Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 134 additions & 20 deletions plugins/module_utils/aci.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,43 @@

def aci_argument_spec():
return dict(
host=dict(type="str", required=True, aliases=["hostname"], fallback=(env_fallback, ["ACI_HOST"])),
host=dict(
type="str",
required=True,
aliases=["hostname"],
fallback=(env_fallback, ["ACI_HOST"]),
),
port=dict(type="int", required=False, fallback=(env_fallback, ["ACI_PORT"])),
username=dict(type="str", default="admin", aliases=["user"], fallback=(env_fallback, ["ACI_USERNAME", "ANSIBLE_NET_USERNAME"])),
password=dict(type="str", no_log=True, fallback=(env_fallback, ["ACI_PASSWORD", "ANSIBLE_NET_PASSWORD"])),
username=dict(
type="str",
default="admin",
aliases=["user"],
fallback=(env_fallback, ["ACI_USERNAME", "ANSIBLE_NET_USERNAME"]),
),
password=dict(
type="str",
no_log=True,
fallback=(env_fallback, ["ACI_PASSWORD", "ANSIBLE_NET_PASSWORD"]),
),
# Beware, this is not the same as client_key !
private_key=dict(type="str", aliases=["cert_key"], no_log=True, fallback=(env_fallback, ["ACI_PRIVATE_KEY", "ANSIBLE_NET_SSH_KEYFILE"])),
private_key=dict(
type="str",
aliases=["cert_key"],
no_log=True,
fallback=(env_fallback, ["ACI_PRIVATE_KEY", "ANSIBLE_NET_SSH_KEYFILE"]),
),
# Beware, this is not the same as client_cert !
certificate_name=dict(type="str", aliases=["cert_name"], fallback=(env_fallback, ["ACI_CERTIFICATE_NAME"])),
output_level=dict(type="str", default="normal", choices=["debug", "info", "normal"], fallback=(env_fallback, ["ACI_OUTPUT_LEVEL"])),
certificate_name=dict(
type="str",
aliases=["cert_name"],
fallback=(env_fallback, ["ACI_CERTIFICATE_NAME"]),
),
output_level=dict(
type="str",
default="normal",
choices=["debug", "info", "normal"],
fallback=(env_fallback, ["ACI_OUTPUT_LEVEL"]),
),
timeout=dict(type="int", default=30, fallback=(env_fallback, ["ACI_TIMEOUT"])),
use_proxy=dict(type="bool", default=True, fallback=(env_fallback, ["ACI_USE_PROXY"])),
use_ssl=dict(type="bool", default=True, fallback=(env_fallback, ["ACI_USE_SSL"])),
Expand All @@ -103,7 +131,11 @@ def aci_argument_spec():

def aci_annotation_spec():
return dict(
annotation=dict(type="str", default="orchestrator:ansible", fallback=(env_fallback, ["ACI_ANNOTATION"])),
annotation=dict(
type="str",
default="orchestrator:ansible",
fallback=(env_fallback, ["ACI_ANNOTATION"]),
),
)


Expand Down Expand Up @@ -159,7 +191,18 @@ def netflow_spec():
def expression_spec():
return dict(
key=dict(type="str", required=True, no_log=False),
operator=dict(type="str", choices=["not_in", "in", "equals", "not_equals", "has_key", "does_not_have_key"], required=True),
operator=dict(
type="str",
choices=[
"not_in",
"in",
"equals",
"not_equals",
"has_key",
"does_not_have_key",
],
required=True,
),
value=dict(type="str"),
)

Expand Down Expand Up @@ -195,11 +238,20 @@ def aci_contract_dscp_spec(direction=None):
"CS7",
"EF",
"VA",
"unspecified"
"unspecified",
],
)


def route_control_profile_spec():
return dict(
profile=dict(type="str", required=True),
l3out=dict(type="str"),
direction=dict(type="str", required=True),
tenant=dict(type="str", required=True),
)


class ACIModule(object):
def __init__(self, module):
self.module = module
Expand Down Expand Up @@ -272,7 +324,12 @@ def iso8601_format(self, dt):
return dt.isoformat(timespec="milliseconds")
except Exception:
tz = dt.strftime("%z")
return "%s.%03d%s:%s" % (dt.strftime("%Y-%m-%dT%H:%M:%S"), dt.microsecond / 1000, tz[:3], tz[3:])
return "%s.%03d%s:%s" % (
dt.strftime("%Y-%m-%dT%H:%M:%S"),
dt.microsecond / 1000,
tz[:3],
tz[3:],
)

def define_protocol(self):
"""Set protocol based on use_ssl parameter"""
Expand All @@ -295,9 +352,21 @@ def login(self):
url = "%(protocol)s://%(host)s:%(port)s/api/aaaLogin.json" % self.params
else:
url = "%(protocol)s://%(host)s/api/aaaLogin.json" % self.params
payload = {"aaaUser": {"attributes": {"name": self.params.get("username"), "pwd": self.params.get("password")}}}
payload = {
"aaaUser": {
"attributes": {
"name": self.params.get("username"),
"pwd": self.params.get("password"),
}
}
}
resp, auth = fetch_url(
self.module, url, data=json.dumps(payload), method="POST", timeout=self.params.get("timeout"), use_proxy=self.params.get("use_proxy")
self.module,
url,
data=json.dumps(payload),
method="POST",
timeout=self.params.get("timeout"),
use_proxy=self.params.get("use_proxy"),
)

# Handle APIC response
Expand Down Expand Up @@ -491,7 +560,13 @@ def query(self, path):

# Perform request
resp, query = fetch_url(
self.module, self.url, data=None, headers=self.headers, method="GET", timeout=self.params.get("timeout"), use_proxy=self.params.get("use_proxy")
self.module,
self.url,
data=None,
headers=self.headers,
method="GET",
timeout=self.params.get("timeout"),
use_proxy=self.params.get("use_proxy"),
)

# Handle APIC response
Expand Down Expand Up @@ -576,7 +651,12 @@ def _deep_url_path_builder(self, obj):
self.url = "{protocol}://{host}/{path}".format(path=self.path, **self.module.params)

if self.child_classes:
self.update_qs({"rsp-subtree": "full", "rsp-subtree-class": ",".join(sorted(self.child_classes))})
self.update_qs(
{
"rsp-subtree": "full",
"rsp-subtree-class": ",".join(sorted(self.child_classes)),
}
)

def _deep_url_parent_object(self, parent_objects, parent_class):

Expand Down Expand Up @@ -718,7 +798,15 @@ def construct_deep_url(self, target_object, parent_objects=None, child_classes=N
self._deep_url_path_builder(url_path_object)

def construct_url(
self, root_class, subclass_1=None, subclass_2=None, subclass_3=None, subclass_4=None, subclass_5=None, child_classes=None, config_only=True
self,
root_class,
subclass_1=None,
subclass_2=None,
subclass_3=None,
subclass_4=None,
subclass_5=None,
child_classes=None,
config_only=True,
):

"""
Expand Down Expand Up @@ -746,7 +834,15 @@ def construct_url(
self.child_classes = set(child_classes)

if subclass_5 is not None:
self._construct_url_6(root_class, subclass_1, subclass_2, subclass_3, subclass_4, subclass_5, config_only)
self._construct_url_6(
root_class,
subclass_1,
subclass_2,
subclass_3,
subclass_4,
subclass_5,
config_only,
)
elif subclass_4 is not None:
self._construct_url_5(root_class, subclass_1, subclass_2, subclass_3, subclass_4, config_only)
elif subclass_3 is not None:
Expand All @@ -765,7 +861,12 @@ def construct_url(

if self.child_classes:
# Append child_classes to filter_string if filter string is empty
self.update_qs({"rsp-subtree": "full", "rsp-subtree-class": ",".join(sorted(self.child_classes))})
self.update_qs(
{
"rsp-subtree": "full",
"rsp-subtree-class": ",".join(sorted(self.child_classes)),
}
)

def _construct_url_1(self, obj, config_only=True):
"""
Expand Down Expand Up @@ -1090,7 +1191,12 @@ def delete_config(self):
self.cert_auth(method="DELETE")

resp, info = fetch_url(
self.module, self.url, headers=self.headers, method="DELETE", timeout=self.params.get("timeout"), use_proxy=self.params.get("use_proxy")
self.module,
self.url,
headers=self.headers,
method="DELETE",
timeout=self.params.get("timeout"),
use_proxy=self.params.get("use_proxy"),
)

self.response = info.get("msg")
Expand Down Expand Up @@ -1201,7 +1307,10 @@ def get_diff_children(self, aci_class, proposed_obj=None, existing_obj=None):
# Loop through proposed child configs and compare against existing child configuration
for child in proposed_children:
child_class, proposed_child, existing_child = self.get_nested_config(child, existing_children)
proposed_child_children, existing_child_children = self.get_nested_children(child, existing_children)
(
proposed_child_children,
existing_child_children,
) = self.get_nested_children(child, existing_children)

if existing_child is None:
child_update = child
Expand Down Expand Up @@ -1236,7 +1345,12 @@ def get_existing(self):
self.cert_auth(path=self.path + self.filter_string, method="GET")

resp, info = fetch_url(
self.module, uri, headers=self.headers, method="GET", timeout=self.params.get("timeout"), use_proxy=self.params.get("use_proxy")
self.module,
uri,
headers=self.headers,
method="GET",
timeout=self.params.get("timeout"),
use_proxy=self.params.get("use_proxy"),
)
self.response = info.get("msg")
self.status = info.get("status")
Expand Down
Loading