summaryrefslogtreecommitdiffstats
path: root/ansible_collections/cisco/mso/plugins/httpapi/mso.py
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/cisco/mso/plugins/httpapi/mso.py')
-rw-r--r--ansible_collections/cisco/mso/plugins/httpapi/mso.py117
1 files changed, 48 insertions, 69 deletions
diff --git a/ansible_collections/cisco/mso/plugins/httpapi/mso.py b/ansible_collections/cisco/mso/plugins/httpapi/mso.py
index 5d69c8a64..286e9dbd0 100644
--- a/ansible_collections/cisco/mso/plugins/httpapi/mso.py
+++ b/ansible_collections/cisco/mso/plugins/httpapi/mso.py
@@ -1,5 +1,6 @@
# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com>
# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com>
+# Copyright: (c) 2023, Akini Ross (@akinross) <akinross@cisco.com>
#
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -16,19 +17,32 @@ description:
a connection to MSO, send API requests and process the
response.
version_added: "1.2.0"
+options:
+ login_domain:
+ description:
+ - The login domain name to use for authentication.
+ - The default value is Local.
+ type: string
+ env:
+ - name: ANSIBLE_HTTPAPI_LOGIN_DOMAIN
+ vars:
+ - name: ansible_httpapi_login_domain
"""
import json
import re
-import pickle
-
-# import ipaddress
import traceback
from ansible.module_utils.six import PY3
from ansible.module_utils._text import to_text
from ansible.module_utils.connection import ConnectionError
from ansible.plugins.httpapi import HttpApiBase
+from copy import copy
+
+
+CONNECTION_MAP = {"username": "remote_user", "timeout": "persistent_command_timeout"}
+RESET_KEYS = ["username", "password", "login_domain", "host", "port"]
+CONNECTION_KEYS = RESET_KEYS + ["use_proxy", "use_ssl", "timeout", "validate_certs"]
class HttpApi(HttpApiBase):
@@ -47,6 +61,8 @@ class HttpApi(HttpApiBase):
self.status = -1
self.info = {}
+ self.connection_parameters = {}
+
def get_platform(self):
return self.platform
@@ -70,20 +86,14 @@ class HttpApi(HttpApiBase):
path = "/mso/api/v1/auth/login"
full_path = self.connection.get_option("host") + path
- if (self.params.get("login_domain") is not None) and (self.params.get("login_domain") != "Local"):
- domain_id = self._get_login_domain_id(self.params.get("login_domain"))
- payload = {"username": self.connection.get_option("remote_user"), "password": self.connection.get_option("password"), "domainId": domain_id}
- else:
- payload = {"username": self.connection.get_option("remote_user"), "password": self.connection.get_option("password")}
-
- # Override the global username/password with the ones specified per task
- if self.params.get("username") is not None:
- payload["username"] = self.params.get("username")
- if self.params.get("password") is not None:
- payload["password"] = self.params.get("password")
+ payload = {"username": username, "password": password}
+ if self.connection_parameters["login_domain"] is not None and self.connection_parameters["login_domain"] != "Local":
+ payload["domainId"] = self._get_login_domain_id(self.connection_parameters["login_domain"])
+
data = json.dumps(payload)
try:
- self.connection.queue_message("vvvv", "login() - connection.send({0}, {1}, {2}, {3})".format(path, data, method, self.headers))
+ payload.pop("password")
+ self.connection.queue_message("vvvv", "login() - connection.send({0}, {1}, {2}, {3})".format(path, payload, method, self.headers))
response, response_data = self.connection.send(path, data, method=method, headers=self.headers)
# Handle MSO response
self.status = response.getcode()
@@ -107,7 +117,7 @@ class HttpApi(HttpApiBase):
path = "/mso/api/v1/auth/logout"
try:
- response, response_data = self.connection.send(path, {}, method=method, headers=self.headers)
+ self.connection.send(path, {}, method=method, headers=self.headers)
except Exception as e:
self.error = dict(code=self.status, message="Error on attempt to logout from MSO. {0}".format(e))
raise ConnectionError(json.dumps(self._verify_response(None, method, self.connection.get_option("host") + path, None)))
@@ -126,47 +136,8 @@ class HttpApi(HttpApiBase):
data = {}
self.connection.queue_message("vvvv", "send_request method called")
- # # Case1: List of hosts is provided
- # self.backup_hosts = self.set_backup_hosts()
- # if not self.backup_hosts:
- if self.connection._connected is True and self.params.get("host") != self.connection.get_option("host"):
- self.connection._connected = False
- self.connection.queue_message(
- "vvvv",
- "send_request reseting connection as host has changed from {0} to {1}".format(self.connection.get_option("host"), self.params.get("host")),
- )
-
- if self.params.get("host") is not None:
- self.connection.set_option("host", self.params.get("host"))
-
- else:
- try:
- with open("my_hosts.pk", "rb") as fi:
- self.host_counter = pickle.load(fi)
- except FileNotFoundError:
- pass
- try:
- self.connection.set_option("host", self.backup_hosts[self.host_counter])
- except (IndexError, TypeError):
- pass
-
- if self.params.get("port") is not None:
- self.connection.set_option("port", self.params.get("port"))
-
- if self.params.get("username") is not None:
- self.connection.set_option("remote_user", self.params.get("username"))
-
- if self.params.get("password") is not None:
- self.connection.set_option("password", self.params.get("password"))
-
- if self.params.get("use_proxy") is not None:
- self.connection.set_option("use_proxy", self.params.get("use_proxy"))
-
- if self.params.get("use_ssl") is not None:
- self.connection.set_option("use_ssl", self.params.get("use_ssl"))
-
- if self.params.get("validate_certs") is not None:
- self.connection.set_option("validate_certs", self.params.get("validate_certs"))
+
+ self.set_connection_parameters()
# Perform some very basic path input validation.
path = str(path)
@@ -187,18 +158,26 @@ class HttpApi(HttpApiBase):
raise ConnectionError(json.dumps(self._verify_response(None, method, full_path, None)))
return self._verify_response(response, method, full_path, rdata)
- def handle_error(self):
- self.host_counter += 1
- if self.host_counter == len(self.backup_hosts):
- raise ConnectionError("No hosts left in cluster to continue operation")
- with open("my_hosts.pk", "wb") as host_file:
- pickle.dump(self.host_counter, host_file)
- try:
- self.connection.set_option("host", self.backup_hosts[self.host_counter])
- except IndexError:
- pass
- self.login(self.connection.get_option("remote_user"), self.connection.get_option("password"))
- return True
+ def set_connection_parameters(self):
+ connection_parameters = {}
+ for key in CONNECTION_KEYS:
+ if key == "login_domain":
+ value = self.params.get(key) if self.params.get(key) is not None else self.get_option(CONNECTION_MAP.get(key, key))
+ self.set_option(key, value)
+ else:
+ value = self.params.get(key) if self.params.get(key) is not None else self.connection.get_option(CONNECTION_MAP.get(key, key))
+ self.connection.set_option(CONNECTION_MAP.get(key, key), value)
+
+ connection_parameters[key] = value
+ if value != self.connection_parameters.get(key) and key in RESET_KEYS:
+ self.connection._connected = False
+ self.connection.queue_message("vvvv", "set_connection_parameters() - resetting connection due to '{0}' change".format(key))
+
+ if self.connection_parameters != connection_parameters:
+ self.connection_parameters = copy(connection_parameters)
+ connection_parameters.pop("password")
+ msg = "set_connection_parameters() - changed connection parameters {0}".format(connection_parameters)
+ self.connection.queue_message("vvvv", msg)
def _verify_response(self, response, method, path, data):
"""Process the return code and response object from MSO"""