VOL-264: REST Channel ( External REST Client <==> Chameleon) needs to be Secured
These are voltha itest and documentation updates after enforcing a https based
REST server implementation from the chameleon.
The chameleon related changes are already available as part of another review
https://gerrit.opencord.org/#/c/4478/ .
Change-Id: Icd585bb0403524c2e7a0f46fddcf3046876042b4
diff --git a/tests/itests/ofagent/test_ofagent_multicontroller_failover.py b/tests/itests/ofagent/test_ofagent_multicontroller_failover.py
index 89228a8..27eb41e 100644
--- a/tests/itests/ofagent/test_ofagent_multicontroller_failover.py
+++ b/tests/itests/ofagent/test_ofagent_multicontroller_failover.py
@@ -49,9 +49,9 @@
onos1_ip="docker inspect --format '{{ .NetworkSettings.Networks.compose_default.IPAddress }}' onos1",
onos2_ip ="docker inspect --format '{{ .NetworkSettings.Networks.compose_default.IPAddress }}' onos2",
onos3_ip="docker inspect --format '{{ .NetworkSettings.Networks.compose_default.IPAddress }}' onos3",
- add_olt='''curl -s -X POST -d '{"type": "simulated_olt", "mac_address": "01:0c:e2:31:40:00"}' \
- http://localhost:8881/api/v1/local/devices''',
- enable_olt="curl -s -X POST http://localhost:8881/api/v1/local/devices/",
+ add_olt='''curl -k -s -X POST -d '{"type": "simulated_olt", "mac_address": "01:0c:e2:31:40:00"}' \
+ https://localhost:8881/api/v1/local/devices''',
+ enable_olt="curl -k -s -X POST https://localhost:8881/api/v1/local/devices/",
onos1_devices="curl -u karaf:karaf http://localhost:8181/onos/v1/devices",
onos2_devices="curl -u karaf:karaf http://localhost:8182/onos/v1/devices",
onos3_devices="curl -u karaf:karaf http://localhost:8183/onos/v1/devices")
diff --git a/tests/itests/voltha/rest_base.py b/tests/itests/voltha/rest_base.py
index 3b880d6..b400283 100644
--- a/tests/itests/voltha/rest_base.py
+++ b/tests/itests/voltha/rest_base.py
@@ -1,10 +1,15 @@
from unittest import TestCase
from requests import get, post, put, patch, delete
+import urllib3
+
+# This is to suppress the insecure request warning when using
+# self signed ssl certificates
+urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class RestBase(TestCase):
- base_url = 'http://localhost:8881'
+ base_url = 'https://localhost:8881'
def url(self, path):
while path.startswith('/'):
@@ -26,31 +31,29 @@
return response.content
def get(self, path, expected_code=200,
- expected_content_type='application/json', headers=None):
- r = get(self.url(path), headers=headers)
+ expected_content_type='application/json', headers=None, verify=False):
+ r = get(self.url(path), headers=headers, verify=verify)
self.assertEqual(r.status_code, expected_code,
msg='Code %d!=%d; msg:%s' % (
r.status_code, expected_code, r.content))
return self.verify_content_type_and_return(r, expected_content_type)
- def post(self, path, json_dict=None, expected_code=201):
- r = post(self.url(path), json=json_dict)
+ def post(self, path, json_dict=None, expected_code=201, verify=False):
+ r = post(self.url(path), json=json_dict, verify=verify)
self.assertEqual(r.status_code, expected_code,
msg='Code %d!=%d; msg:%s' % (
r.status_code, expected_code, r.content))
return self.verify_content_type_and_return(r, 'application/json')
- def put(self, path, json_dict, expected_code=200):
- r = put(self.url(path), json=json_dict)
+ def put(self, path, json_dict, expected_code=200, verify=False):
+ r = put(self.url(path), json=json_dict, verify=verify)
self.assertEqual(r.status_code, expected_code,
msg='Code %d!=%d; msg:%s' % (
r.status_code, expected_code, r.content))
return self.verify_content_type_and_return(r, 'application/json')
- def delete(self, path, expected_code=209):
- r = delete(self.url(path))
+ def delete(self, path, expected_code=209, verify=False):
+ r = delete(self.url(path), verify=verify)
self.assertEqual(r.status_code, expected_code,
msg='Code %d!=%d; msg:%s' % (
r.status_code, expected_code, r.content))
-
-
diff --git a/tests/itests/voltha/test_cold_activation_sequence.py b/tests/itests/voltha/test_cold_activation_sequence.py
index 9a780f5..fc93ce8 100644
--- a/tests/itests/voltha/test_cold_activation_sequence.py
+++ b/tests/itests/voltha/test_cold_activation_sequence.py
@@ -17,7 +17,7 @@
rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
# Construct the base_url
- base_url = 'http://' + rest_endpoint
+ base_url = 'https://' + rest_endpoint
def wait_till(self, msg, predicate, interval=0.1, timeout=5.0):
deadline = time() + timeout
diff --git a/tests/itests/voltha/test_device_state_changes.py b/tests/itests/voltha/test_device_state_changes.py
index 9b3bc76..9cc62b7 100644
--- a/tests/itests/voltha/test_device_state_changes.py
+++ b/tests/itests/voltha/test_device_state_changes.py
@@ -27,7 +27,7 @@
rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
# Construct the base_url
- base_url = 'http://' + rest_endpoint
+ base_url = 'https://' + rest_endpoint
def wait_till(self, msg, predicate, interval=0.1, timeout=5.0):
deadline = time() + timeout
diff --git a/tests/itests/voltha/test_dispatcher.py b/tests/itests/voltha/test_dispatcher.py
index 0f6ba73..71f6c8a 100644
--- a/tests/itests/voltha/test_dispatcher.py
+++ b/tests/itests/voltha/test_dispatcher.py
@@ -271,7 +271,7 @@
def set_rest_endpoint(self):
self.rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL,
'chameleon-rest')
- self.base_url = 'http://' + self.rest_endpoint
+ self.base_url = 'https://' + self.rest_endpoint
def set_kafka_endpoint(self):
self.kafka_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'kafka')
diff --git a/tests/itests/voltha/test_persistence.py b/tests/itests/voltha/test_persistence.py
index 1111c1e..29b084a 100644
--- a/tests/itests/voltha/test_persistence.py
+++ b/tests/itests/voltha/test_persistence.py
@@ -250,7 +250,7 @@
def set_rest_endpoint(self):
self.rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL,
'chameleon-rest')
- self.base_url = 'http://' + self.rest_endpoint
+ self.base_url = 'https://' + self.rest_endpoint
def set_kafka_endpoint(self):
self.kafka_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'kafka')
diff --git a/tests/itests/voltha/test_self_signed_cert_auth_failure.py b/tests/itests/voltha/test_self_signed_cert_auth_failure.py
new file mode 100644
index 0000000..5857417
--- /dev/null
+++ b/tests/itests/voltha/test_self_signed_cert_auth_failure.py
@@ -0,0 +1,99 @@
+from time import time, sleep
+from unittest import main, TestCase
+from nose.tools import *
+from requests import get
+from tests.itests.voltha.rest_base import RestBase
+from common.utils.consulhelpers import get_endpoint_from_consul
+from common.utils.consulhelpers import verify_all_services_healthy
+from tests.itests.docutests.test_utils import \
+ run_command_to_completion_with_raw_stdout, \
+ run_command_to_completion_with_stdout_in_list
+
+LOCAL_CONSUL = "localhost:8500"
+DOCKER_COMPOSE_FILE = "compose/docker-compose-system-test.yml"
+
+command_defs = dict(
+ docker_ps="docker ps",
+ docker_compose_start_all="docker-compose -f {} up -d "
+ .format(DOCKER_COMPOSE_FILE),
+ docker_stop_and_remove_all_containers="docker-compose -f {} down"
+ .format(DOCKER_COMPOSE_FILE),
+)
+
+
+class SelfSignedSSLCertAuthFail(RestBase):
+
+ t0 = [time()]
+
+ def pt(self, msg=''):
+ t1 = time()
+ print '%20.8f ms - %s' % (1000 * (t1 - SelfSignedSSLCertAuthFail.t0[0]),
+ msg)
+ SelfSignedSSLCertAuthFail.t0[0] = t1
+
+
+ def wait_till(self, msg, predicate, interval=0.1, timeout=5.0):
+ deadline = time() + timeout
+ while time() < deadline:
+ if predicate():
+ return
+ sleep(interval)
+ self.fail('Timed out while waiting for condition: {}'.format(msg))
+
+
+ def test_01_self_signed_ssl_cert_auth_failure(self):
+ # Start the voltha ensemble with a single voltha instance
+ self._stop_and_remove_all_containers()
+ sleep(5) # A small wait for the system to settle down
+ self.start_all_containers()
+ self.set_rest_endpoint()
+
+ self._get_health()
+
+ def _stop_and_remove_all_containers(self):
+ # check if there are any running containers first
+ cmd = command_defs['docker_ps']
+ out, err, rc = run_command_to_completion_with_stdout_in_list(cmd)
+ self.assertEqual(rc, 0)
+ if len(out) > 1: # not counting docker ps header
+ cmd = command_defs['docker_stop_and_remove_all_containers']
+ out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
+ self.assertEqual(rc, 0)
+
+ def start_all_containers(self):
+ t0 = time()
+
+ # start all the containers
+ self.pt("Starting all containers ...")
+ cmd = command_defs['docker_compose_start_all']
+ out, err, rc = run_command_to_completion_with_raw_stdout(cmd)
+ self.assertEqual(rc, 0)
+
+ self.pt("Waiting for voltha and chameleon containers to be ready ...")
+ self.wait_till('voltha services HEALTHY',
+ lambda: verify_all_services_healthy(
+ LOCAL_CONSUL, service_name='voltha-grpc') == True,
+ timeout=10)
+ self.wait_till('chameleon services HEALTHY',
+ lambda: verify_all_services_healthy(
+ LOCAL_CONSUL,service_name='chameleon-rest') == True,
+ timeout=10)
+
+ # Chameleon takes some time to compile the protos and make them
+ # available. So let's wait 10 seconds
+ sleep(10)
+
+ def set_rest_endpoint(self):
+ self.rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL,
+ 'chameleon-rest')
+ self.base_url = 'https://' + self.rest_endpoint
+
+ @raises(Exception)
+ def _get_health(self):
+ # Raises SSLError exception because "verify" set to true and
+ # we use self-signed certificates
+ res = self.get('/health', verify=True)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/itests/voltha/test_voltha_alarm_events.py b/tests/itests/voltha/test_voltha_alarm_events.py
index c5e2858..5e8b8ec 100644
--- a/tests/itests/voltha/test_voltha_alarm_events.py
+++ b/tests/itests/voltha/test_voltha_alarm_events.py
@@ -47,7 +47,7 @@
rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
# Construct the base_url
- base_url = 'http://' + rest_endpoint
+ base_url = 'https://' + rest_endpoint
# Start by querying consul to get the endpoint details
kafka_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'kafka')
diff --git a/tests/itests/voltha/test_voltha_alarm_filters.py b/tests/itests/voltha/test_voltha_alarm_filters.py
index 4b73509..e9d67a2 100644
--- a/tests/itests/voltha/test_voltha_alarm_filters.py
+++ b/tests/itests/voltha/test_voltha_alarm_filters.py
@@ -29,7 +29,7 @@
rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
# Construct the base_url
- base_url = 'http://' + rest_endpoint
+ base_url = 'https://' + rest_endpoint
# Start by querying consul to get the endpoint details
kafka_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'kafka')
diff --git a/tests/itests/voltha/test_voltha_rest_apis.py b/tests/itests/voltha/test_voltha_rest_apis.py
index b1f66d6..0760fca 100644
--- a/tests/itests/voltha/test_voltha_rest_apis.py
+++ b/tests/itests/voltha/test_voltha_rest_apis.py
@@ -25,7 +25,7 @@
rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
# Construct the base_url
- base_url = 'http://' + rest_endpoint
+ base_url = 'https://' + rest_endpoint
def test_01_global_rest_apis(self):
# ~~~~~~~~~~~~~~~~~~~ GLOBAL TOP-LEVEL SERVICES~ ~~~~~~~~~~~~~~~~~~~~~~
@@ -283,7 +283,7 @@
rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
# Construct the base_url
- base_url = 'http://' + rest_endpoint
+ base_url = 'https://' + rest_endpoint
def test_02_local_rest_apis(self):
# ~~~~~~~~~~~~~~~~ VOLTHA INSTANCE LEVEL OPERATIONS ~~~~~~~~~~~~~~~~~~~
@@ -447,7 +447,7 @@
rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
# Construct the base_url
- base_url = 'http://' + rest_endpoint
+ base_url = 'https://' + rest_endpoint
# ~~~~~~~~~~~~~~~~~~~~~~~~~~ NEGATIVE TEST CASES ~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/itests/voltha/test_voltha_retrieve_software_info.py b/tests/itests/voltha/test_voltha_retrieve_software_info.py
index ddb5909..22d58bf 100644
--- a/tests/itests/voltha/test_voltha_retrieve_software_info.py
+++ b/tests/itests/voltha/test_voltha_retrieve_software_info.py
@@ -1,5 +1,6 @@
from unittest import main
from time import time, sleep
+from common.utils.consulhelpers import get_endpoint_from_consul
from tests.itests.voltha.rest_base import RestBase
from google.protobuf.json_format import MessageToDict
from voltha.protos.device_pb2 import Device
@@ -42,6 +43,7 @@
"type": "object"
}
+LOCAL_CONSUL = "localhost:8500"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -55,10 +57,10 @@
class VolthaDeviceManagementRetrieveSoftwareInfo(RestBase):
# Retrieve details on the REST entry point
- rest_endpoint = "127.0.0.1:8881"
+ rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
# Construct the base_url
- base_url = 'http://' + rest_endpoint
+ base_url = 'https://' + rest_endpoint
def wait_till(self, msg, predicate, interval=0.1, timeout=5.0):
deadline = time() + timeout