summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDileep Ranganathan <dileep.ranganathan@intel.com>2018-09-14 11:29:39 -0700
committerDileep Ranganathan <dileep.ranganathan@intel.com>2018-09-14 11:39:31 -0700
commit11dbe76c38a9628fec4072a3b520ed02b3ccfac2 (patch)
treed581ade99d42ed8f6b3590ae6c861c34d7842e46
parent3ab841597bd7fbfa4de41791c9d7e6335c8afeb9 (diff)
Secret Management Service feature
Added supporting library required for enabling SMS integration. Added Unit tests and manual tests for store/retrieve/delete secrets. Added AAF cacert, preload_secrets config for testing. Integration with application NOT Done in this patch. Change-Id: Ic2be41f825b327064127fbf83f9e1057a68f19c2 Issue-ID: OPTFRA-343 Signed-off-by: Dileep Ranganathan <dileep.ranganathan@intel.com>
-rwxr-xr-xconfig/osdf_config.yaml6
-rwxr-xr-xconfig/preload_secrets.yaml43
-rw-r--r--osdf/adapters/aaf/sms.py97
-rw-r--r--requirements.txt1
-rw-r--r--ssl_certs/aaf_root_ca.cer31
-rw-r--r--test/adapters/test_sms.py89
-rw-r--r--test/test-requirements.txt1
7 files changed, 268 insertions, 0 deletions
diff --git a/config/osdf_config.yaml b/config/osdf_config.yaml
index 022104d..4ef11f8 100755
--- a/config/osdf_config.yaml
+++ b/config/osdf_config.yaml
@@ -50,3 +50,9 @@ aaf_cache_expiry_hrs: 3
aaf_url: https://aaftest.simpledemo.onap.org:8095
aaf_user_roles:
- /api/oof/v1/placement:org.onap.osdf.access|*|read ALL
+
+# Secret Management Service from AAF
+aaf_sms_url: https://aaf-sms.onap:10443
+aaf_sms_timeout: 30
+secret_domain: osdf #Replace with the UUID
+aaf_ca_certs: ssl_certs/aaf_root_ca.cer
diff --git a/config/preload_secrets.yaml b/config/preload_secrets.yaml
new file mode 100755
index 0000000..6e877e7
--- /dev/null
+++ b/config/preload_secrets.yaml
@@ -0,0 +1,43 @@
+---
+domain: osdf
+secrets:
+- name: so
+ values:
+ UserName: ''
+ Password: ''
+- name: conductor
+ values:
+ UserName: admin1
+ Password: plan.15
+- name: policy_platform
+ values:
+ UserName: testpdp
+ Password: alpha123
+- name: policy_client
+ values:
+ UserName: python
+ Password: test
+- name: dmaap
+ values:
+ UserName: NA
+ Password: NA
+- name: sdc
+ values:
+ UserName: NA
+ Password: NA
+- name: osdfPlacement
+ values:
+ UserName: test
+ Password: testpwd
+- name: osdfPlacementSO
+ values:
+ UserName: so_test
+ Password: so_testpwd
+- name: osdfPlacementVFC
+ values:
+ UserName: vfc_test
+ Password: vfc_testpwd
+- name: osdfCMScheduler
+ values:
+ UserName: test1
+ Password: test_pwd1
diff --git a/osdf/adapters/aaf/sms.py b/osdf/adapters/aaf/sms.py
new file mode 100644
index 0000000..976eb61
--- /dev/null
+++ b/osdf/adapters/aaf/sms.py
@@ -0,0 +1,97 @@
+#
+# -------------------------------------------------------------------------
+# Copyright (c) 2018 Intel Corporation Intellectual Property
+#
+# 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.
+#
+# -------------------------------------------------------------------------
+#
+
+'''Secret Management Service Integration'''
+
+from onapsmsclient import Client
+
+import osdf.config.loader as config_loader
+from osdf.config.base import osdf_config
+from osdf.logging.osdf_logging import debug_log
+
+config_spec = {
+ "preload_secrets": "config/preload_secrets.yaml"
+}
+
+secret_cache = {}
+
+
+def preload_secrets():
+ """ This is intended to load the secrets required for testing Application
+ Actual deployment will have a preload script. Make sure the config is
+ in sync"""
+ preload_config = config_loader.load_config_file(
+ config_spec.get("preload_secrets"))
+ domain = preload_config.get("domain")
+ config = osdf_config.deployment
+ sms_url = config["aaf_sms_url"]
+ timeout = config["aaf_sms_timeout"]
+ cacert = config["aaf_ca_certs"]
+ sms_client = Client(url=sms_url, timeout=timeout, cacert=cacert)
+ domain = sms_client.createDomain(domain)
+ config["secret_domain"] = domain # uuid
+ secrets = preload_config.get("secrets")
+ for secret in secrets:
+ sms_client.storeSecret(domain, secret.get('name'),
+ secret.get('values'))
+ debug_log.debug("Preload secrets complete")
+
+
+def retrieve_secrets():
+ """Get all secrets under the domain name"""
+ secret_dict = dict()
+ config = osdf_config.deployment
+ sms_url = config["aaf_sms_url"]
+ timeout = config["aaf_sms_timeout"]
+ cacert = config["aaf_ca_certs"]
+ domain = config["secret_domain"]
+ sms_client = Client(url=sms_url, timeout=timeout, cacert=cacert)
+ secrets = sms_client.getSecretNames(domain)
+ for secret in secrets:
+ values = sms_client.getSecret(domain, secret)
+ secret_dict[secret] = values
+ debug_log.debug("Secret Dictionary Retrieval Success")
+ return secret_dict
+
+
+def delete_secrets():
+ """ This is intended to delete the secrets for a clean initialization for
+ testing Application. Actual deployment will have a preload script.
+ Make sure the config is in sync"""
+ config = osdf_config.deployment
+ sms_url = config["aaf_sms_url"]
+ timeout = config["aaf_sms_timeout"]
+ cacert = config["aaf_ca_certs"]
+ domain = config["secret_domain"]
+ sms_client = Client(url=sms_url, timeout=timeout, cacert=cacert)
+ ret_val = sms_client.deleteDomain(domain)
+ debug_log.debug("Clean up complete")
+ return ret_val
+
+
+if __name__ == "__main__":
+ # Initialize Secrets from SMS
+ preload_secrets()
+
+ # Retrieve Secrets from SMS and load to secret cache
+ # Use the secret_cache instead of config files
+ secret_cache = retrieve_secrets()
+
+ # Clean up Delete secrets and domain
+ delete_secrets()
diff --git a/requirements.txt b/requirements.txt
index 351f97e..f05dadf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,3 +11,4 @@ requests>=2.14.2
schematics>=2.0.0
docopt>=0.6.2
pydevd>=1.0.0
+onapsmsclient>=0.0.3
diff --git a/ssl_certs/aaf_root_ca.cer b/ssl_certs/aaf_root_ca.cer
new file mode 100644
index 0000000..e9a50d7
--- /dev/null
+++ b/ssl_certs/aaf_root_ca.cer
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFPjCCAyagAwIBAgIJAJ6u7cCnzrWdMA0GCSqGSIb3DQEBCwUAMCwxDjAMBgNV
+BAsMBU9TQUFGMQ0wCwYDVQQKDARPTkFQMQswCQYDVQQGEwJVUzAeFw0xODA0MDUx
+NDE1MjhaFw0zODAzMzExNDE1MjhaMCwxDjAMBgNVBAsMBU9TQUFGMQ0wCwYDVQQK
+DARPTkFQMQswCQYDVQQGEwJVUzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBAMA5pkgRs7NhGG4ew5JouhyYakgYUyFaG121+/h8qbSdt0hVQv56+EA41Yq7
+XGie7RYDQK9NmAFF3gruE+6X7wvJiChp+Cyd7sFMnb65uWhxEdxWTM2BJFrgfzUn
+H8ZCxgaCo3XH4PzlKRy2LQQJEJECwl/RZmRCXijMt5e9h8XoZY/fKkKcZZUsWNCM
+pTo266wjvA9MXLmdgReRj0+vrCjrNqy+htwJDztoiHWiYPqT6o8EvGcgjNqjlZx7
+NUNf8MfLDByqKF6+wRbHv1GKjn3/Vijd45Fv8riyRYROiFanvbV6jIfBkv8PZbXg
+2VDWsYsgp8NAvMxK+iV8cO+Ck3lBI2GOPZbCEqpPVTYbLUz6sczAlCXwQoPzDIZY
+wYa3eR/gYLY1gP2iEVHORag3bLPap9ZX5E8DZkzTNTjovvLk8KaCmfcaUMJsBtDd
+ApcUitz10cnRyZc1sX3gE1f3DpzQM6t9C5sOVyRhDcSrKqqwb9m0Ss04XAS9FsqM
+P3UWYQyqDXSxlUAYaX892u8mV1hxnt2gjb22RloXMM6TovM3sSrJS0wH+l1nznd6
+aFXftS/G4ZVIVZ/LfT1is4StoyPWZCwwwly1z8qJQ/zhip5NgZTxQw4mi7ww35DY
+PdAQOCoajfSvFjqslQ/cPRi/MRCu079heVb5fQnnzVtnpFQRAgMBAAGjYzBhMB0G
+A1UdDgQWBBRTVTPyS+vQUbHBeJrBKDF77+rtSTAfBgNVHSMEGDAWgBRTVTPyS+vQ
+UbHBeJrBKDF77+rtSTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAN
+BgkqhkiG9w0BAQsFAAOCAgEAPx/IaK94n02wPxpnYTy+LVLIxwdq/kawNd6IbiMz
+L87zmNMDmHcGbfoRCj8OkhuggX9Lx1/CkhpXimuYsZOFQi5blr/u+v4mIbsgbmi9
+7j+cUHDP0zLycvSvxKHty51LwmaX9a4wkJl5zBU4O1sd/H9tWcEmwJ39ltKoBKBx
+c94Zc3iMm5ytRWGj+0rKzLDAXEWpoZ5bE5PLJauA6UDCxDLfs3FwhbS7uDggxYvf
+jySF5FCNET94oJ+m8s7VeHvoa8iPGKvXrIqdd7XDHnqJJlVKr7m9S0fMbyEB8ci2
+RtOXDt93ifY1uhoEtEykn4dqBSp8ezvNMnwoXdYPDvTd9uCAFeWFLVreBAWxd25h
+PsBTkZA5hpa/rA+mKv6Af4VBViYr8cz4dZCsFChuioVebe9ighrfjB//qKepFjPF
+CyjzKN1u0JKm/2x/ORqxkTONG8p3uDwoIOyimUcTtTMv42bfYD88RKakqSFXE9G+
+Z0LlaKABqfjK49o/tsAp+c5LoNlYllKhnetO3QAdraHwdmC36BhoghzR1jpX751A
+cZn2VH3Q4XKyp01cJNCJIrua+A+bx6zh3RyW6zIIkbRCbET+UD+4mr8WIcSE3mtR
+ZVlnhUDO4z9//WKMVzwS9Rh8/kuszrGFI1KQozXCHLrce3YP6RYZfOed79LXaRwX
+dYY=
+-----END CERTIFICATE-----
diff --git a/test/adapters/test_sms.py b/test/adapters/test_sms.py
new file mode 100644
index 0000000..ed6c9c9
--- /dev/null
+++ b/test/adapters/test_sms.py
@@ -0,0 +1,89 @@
+#
+# -------------------------------------------------------------------------
+# Copyright (c) 2018 Intel Corporation Intellectual Property
+#
+# 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.
+#
+# -------------------------------------------------------------------------
+#
+import unittest
+from uuid import uuid4
+
+import requests_mock
+
+import osdf.adapters.aaf.sms as SMS
+from osdf.config.base import osdf_config
+
+
+class TestSMS(unittest.TestCase):
+
+ def setUp(self):
+ self.config = osdf_config.deployment
+ self.base_domain_url = '{}/v1/sms/domain'
+ self.domain_url = '{}/v1/sms/domain/{}'
+ self.secret_url = self.domain_url + '/secret'
+
+ @requests_mock.mock()
+ def test_sms(self, mock_sms):
+ ''' NOTE: preload_secret generate the uuid for the domain
+ Create Domain API is called during the deployment using a
+ preload script. So the application oly knows the domain_uuid.
+ All sub-sequent SMS API calls needs the uuid.
+ For test purposes we need to do preload ourselves'''
+ sms_url = self.config["aaf_sms_url"]
+
+ # JSON Data responses
+ secretnames = {'secretnames': ['s1', 's2', 's3', 's4']}
+ secretvalues = {'values': {'Password': '', 'UserName': ''}}
+ expecect_secret_dict = dict()
+ for secret in secretnames['secretnames']:
+ expecect_secret_dict[secret] = secretvalues['values']
+
+ # Part 1 : Preload Secrets ONLY FOR TEST
+ # Mock requests for preload_secret
+ cd_url = self.base_domain_url.format(sms_url)
+ domain_uuid1 = str(uuid4())
+ s_url = self.secret_url.format(sms_url, domain_uuid1)
+ mock_sms.post(cd_url, status_code=200, json={'uuid': domain_uuid1})
+ mock_sms.post(s_url, status_code=200)
+ # Initialize Secrets from SMS
+ SMS.preload_secrets()
+
+ # Part 2: Retrieve Secret Test
+ # Mock requests for retrieve_secrets
+ # IMPORTANT: Read the config again as the preload_secrets has
+ # updated the config with uuid
+ domain_uuid2 = self.config["secret_domain"]
+ self.assertEqual(domain_uuid1, domain_uuid2)
+
+ d_url = self.domain_url.format(sms_url, domain_uuid2)
+ s_url = self.secret_url.format(sms_url, domain_uuid2)
+
+ # Retrieve Secrets from SMS and load to secret cache
+ # Use the secret_cache instead of config files
+ mock_sms.get(s_url, status_code=200, json=secretnames)
+ for secret in secretnames['secretnames']:
+ mock_sms.get('{}/{}'.format(s_url, secret),
+ status_code=200, json=secretvalues)
+ secret_cache = SMS.retrieve_secrets()
+ self.assertDictEqual(expecect_secret_dict, secret_cache,
+ 'Failed to retrieve secrets')
+
+ # Part 3: Clean up Delete secrets and domain
+ # Mock requests for delete_secrets
+ mock_sms.delete(d_url, status_code=200)
+ self.assertTrue(SMS.delete_secrets())
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/test/test-requirements.txt b/test/test-requirements.txt
index b16a37e..043d87a 100644
--- a/test/test-requirements.txt
+++ b/test/test-requirements.txt
@@ -2,3 +2,4 @@ coverage
moto
pytest
pytest-tap
+requests-mock