HC Test: support testing using ipv6 management interface and https
[csit.git] / resources / libraries / python / HTTPRequest.py
index f94318d..5f87484 100644 (file)
@@ -18,13 +18,17 @@ The HTTP requests are implemented in the class HTTPRequest which uses
 requests.request.
 """
 
+from ipaddress import IPv6Address, AddressValueError
 from enum import IntEnum, unique
 
 from robot.api.deco import keyword
 from robot.api import logger
+from robot.libraries.BuiltIn import BuiltIn
 
 from requests import request, RequestException, Timeout, TooManyRedirects, \
     HTTPError, ConnectionError
+from requests.packages.urllib3 import disable_warnings
+from requests.packages.urllib3.exceptions import InsecureRequestWarning
 from requests.auth import HTTPBasicAuth
 
 
@@ -32,9 +36,12 @@ from requests.auth import HTTPBasicAuth
 class HTTPCodes(IntEnum):
     """HTTP status codes"""
     OK = 200
+    ACCEPTED = 201
     UNAUTHORIZED = 401
     FORBIDDEN = 403
     NOT_FOUND = 404
+    CONFLICT = 409
+    INTERNAL_SERVER_ERROR = 500
     SERVICE_UNAVAILABLE = 503
 
 
@@ -71,6 +78,9 @@ class HTTPRequestError(Exception):
             logger.error(self._msg)
             logger.debug(self._details)
 
+        # suppress warnings about disabled SSL verification
+        disable_warnings(InsecureRequestWarning)
+
     def __repr__(self):
         return repr(self._msg)
 
@@ -111,8 +121,16 @@ class HTTPRequest(object):
         :return: Full url.
         :rtype: str
         """
-        return "http://{ip}:{port}{path}".format(ip=ip_addr, port=port,
-                                                 path=path)
+
+        try:
+            IPv6Address(unicode(ip_addr))
+            # IPv6 address must be in brackets
+            ip_addr = "[{0}]".format(ip_addr)
+        except (AttributeError, AddressValueError):
+            pass
+
+        return "https://{ip}:{port}{path}".format(ip=ip_addr, port=port,
+                                                  path=path)
 
     @staticmethod
     def _http_request(method, node, path, enable_logging=True, **kwargs):
@@ -165,13 +183,28 @@ class HTTPRequest(object):
         5. there is any other unexpected HTTP request exception.
         """
         timeout = kwargs["timeout"]
+
+        if BuiltIn().get_variable_value("${use_odl_client}"):
+            # TODO: node["honeycomb"]["odl_port"]
+            port = 8181
+            odl_url_part = "/network-topology:network-topology/topology/" \
+                           "topology-netconf/node/vpp/yang-ext:mount"
+        else:
+            port = node["honeycomb"]["port"]
+            odl_url_part = ""
+
+        try:
+            path = path.format(odl_url_part=odl_url_part)
+        except KeyError:
+            pass
+
         url = HTTPRequest.create_full_url(node['host'],
-                                          node['honeycomb']['port'],
+                                          port,
                                           path)
         try:
             auth = HTTPBasicAuth(node['honeycomb']['user'],
                                  node['honeycomb']['passwd'])
-            rsp = request(method, url, auth=auth, **kwargs)
+            rsp = request(method, url, auth=auth, verify=False, **kwargs)
 
             logger.debug("Status code: {0}".format(rsp.status_code))
             logger.debug("Response: {0}".format(rsp.content))
@@ -252,7 +285,8 @@ class HTTPRequest(object):
 
     @staticmethod
     @keyword(name="HTTP Post")
-    def post(node, path, headers=None, payload=None, json=None, timeout=10):
+    def post(node, path, headers=None, payload=None, json=None, timeout=10,
+             enable_logging=True):
         """Sends a POST request and returns the response and status code.
 
         :param node: Honeycomb node.
@@ -263,18 +297,23 @@ class HTTPRequest(object):
         :param json: JSON formatted string to send in the body of the Request.
         :param timeout: How long to wait for the server to send data before
         giving up, as a float, or a (connect timeout, read timeout) tuple.
+        :param enable_logging: Used to suppress errors when checking ODL
+        state during suite setup and teardown. When True, logging is enabled,
+        otherwise logging is disabled.
         :type node: dict
         :type path: str
         :type headers: dict
         :type payload: dict, bytes, or file-like object
         :type json: str
         :type timeout: float or tuple
+        :type enable_logging: bool
         :return: Status code and content of response.
         :rtype: tuple
         """
-        return HTTPRequest._http_request('POST', node, path, headers=headers,
-                                         data=payload, json=json,
-                                         timeout=timeout)
+        return HTTPRequest._http_request('POST', node, path,
+                                         enable_logging=enable_logging,
+                                         headers=headers, data=payload,
+                                         json=json, timeout=timeout)
 
     @staticmethod
     @keyword(name="HTTP Delete")