Zack Williams | 821c502 | 2020-01-15 15:11:46 -0700 | [diff] [blame] | 1 | # Copyright 2017-present Open Networking Foundation |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | |
| 15 | from __future__ import absolute_import, print_function |
| 16 | |
| 17 | import requests |
| 18 | import json |
| 19 | import os |
| 20 | |
| 21 | # These are the default values used with XOS |
| 22 | restApiDefaults = { |
| 23 | 'ATT_SERVICE': '/xosapi/v1/att-workflow-driver/attworkflowdriverservices', |
| 24 | 'ATT_SERVICEINSTANCES': '/xosapi/v1/att-workflow-driver/attworkflowdriverserviceinstances', |
| 25 | 'ATT_WHITELIST': '/xosapi/v1/att-workflow-driver/attworkflowdriverwhitelistentries', |
| 26 | 'BNG_MAP': '/xosapi/v1/fabric-crossconnect/bngportmappings', |
| 27 | 'CH_CORE_DEPLOYMENTS': '/xosapi/v1/core/deployments', |
| 28 | 'CH_CORE_FLAVORS': '/xosapi/v1/core/flavors', |
| 29 | 'CH_CORE_IMAGES': '/xosapi/v1/core/images', |
| 30 | 'CH_CORE_INSTANCES': '/xosapi/v1/core/instances', |
| 31 | 'CH_CORE_NETWORKS': '/xosapi/v1/core/networks', |
| 32 | 'CH_CORE_NETWORK_SLICES': '/xosapi/v1/core/networkslices', |
| 33 | 'CH_CORE_NETWORK_TEMPLATES': '/xosapi/v1/core/networktemplates', |
| 34 | 'CH_CORE_NODES': '/xosapi/v1/core/nodes', |
| 35 | 'CH_CORE_PORTS': '/xosapi/v1/core/ports', |
| 36 | 'CH_CORE_SERVICELINK': '/xosapi/v1/core/serviceinstancelinks', |
| 37 | 'CH_CORE_SERVICES': '/xosapi/v1/core/services', |
| 38 | 'CH_CORE_SERVICES': '/xosapi/v1/core/services', |
| 39 | 'CH_CORE_SITEDEPLOYMENTS': '/xosapi/v1/core/sitedeployments', |
| 40 | 'CH_CORE_SITES': '/xosapi/v1/core/sites', |
| 41 | 'CH_CORE_SLICES': '/xosapi/v1/core/slices', |
| 42 | 'CH_CORE_SLICES': '/xosapi/v1/core/slices', |
| 43 | 'CH_CORE_USERS': '/xosapi/v1/core/users', |
| 44 | 'CORE_DEPLOYMENTS': '/api/core/deployments/', |
| 45 | 'CORE_FLAVORS': '/api/core/flavors/', |
| 46 | 'CORE_IMAGES': '/api/core/images/', |
| 47 | 'CORE_INSTANCES': '/api/core/instances/', |
| 48 | 'CORE_NODES': '/api/core/nodes/', |
| 49 | 'CORE_SANITY_INSTANCES': '/api/core/instances/?no_hyperlinks=1', |
| 50 | 'CORE_SANITY_NODES': '/api/core/nodes/?no_hyperlinks=1', |
| 51 | 'CORE_SANITY_SLICES': '/api/core/slices/?no_hyperlinks=1', |
| 52 | 'CORE_SERVICES': '/api/core/services/', |
| 53 | 'CORE_SITEDEPLOYMENTS': '/api/core/sitedeployments', |
| 54 | 'CORE_SITES': '/api/core/sites/', |
| 55 | 'CORE_SLICES': '/api/core/slices/', |
| 56 | 'CORE_USERS': '/api/core/users/', |
| 57 | 'FABRIC_CROSSCONNECT_SERVICEINSTANCES': '/xosapi/v1/fabric-crossconnect/fabriccrossconnectserviceinstances', |
| 58 | 'FABRIC_SWITCH': '/xosapi/v1/fabric/switches', |
| 59 | 'HWVSG_TENANT': '/xosapi/v1/vsg-hw/vsghwserviceinstances', |
| 60 | 'ONU_DEVICE': '/xosapi/v1/volt/onudevices', |
| 61 | 'OSS_SERVICE': '/xosapi/v1/hippie-oss/hippieossservices', |
| 62 | 'OSS_SERVICEINSTANCE': '/xosapi/v1/hippie-oss/hippieossserviceinstances', |
| 63 | 'OSS_VOLT': '/xosapi/v1/core/servicedependencys', |
| 64 | 'PON_PORT': '/xosapi/v1/volt/ponports', |
| 65 | 'PORT_INTERFACE': '/xosapi/v1/fabric/portinterfaces', |
| 66 | 'SERVER_IP': '127.0.0.1', |
| 67 | 'SERVER_PORT': '30006', |
| 68 | 'SWITCH_PORT': '/xosapi/v1/fabric/switchports', |
| 69 | 'TENANT_SUBSCRIBER': '/api/tenant/cord/subscriber/', |
| 70 | 'TENANT_VOLT': '/api/tenant/cord/volt/', |
| 71 | 'UTILS_LOGIN': '/api/utility/login/', |
| 72 | 'UTILS_SYNCHRONIZER': '/api/utility/synchronizer/', |
| 73 | 'VOLT_DEVICE': '/xosapi/v1/volt/oltdevices', |
| 74 | 'VOLT_SERVICE': '/xosapi/v1/volt/voltservices', |
| 75 | 'VOLT_SUBSCRIBER': '/xosapi/v1/rcord/rcordsubscribers', |
| 76 | 'VOLT_TENANT': '/xosapi/v1/volt/voltserviceinstances', |
| 77 | 'VSG_TENANT': '/xosapi/v1/vsg/vsgserviceinstances', |
| 78 | 'XOS_PASSWD': 'letmein', |
| 79 | 'XOS_USER': 'admin@opencord.org', |
| 80 | } |
| 81 | |
| 82 | jsonHeader = {"Content-Type": "application/json"} |
| 83 | |
| 84 | |
| 85 | class restApi(): |
| 86 | """ |
| 87 | Functions for testing CORD API with POST, GET, PUT, DELETE method |
| 88 | """ |
| 89 | |
| 90 | def getEnvOrDefault(self, key): |
| 91 | """ |
| 92 | Find a variable in environment, or use Default value |
| 93 | """ |
| 94 | if key in os.environ: |
| 95 | value = os.environ[key] |
| 96 | elif key in restApiDefaults: |
| 97 | value = restApiDefaults[key] |
| 98 | else: |
| 99 | print("Unable to find '%s' in environment or defaults!" % key) |
| 100 | value = None |
| 101 | |
| 102 | return value |
| 103 | |
| 104 | def getURL(self, key): |
| 105 | """ |
| 106 | Get REST API suffix from key and return the full URL |
| 107 | """ |
| 108 | urlSuffix = self.getEnvOrDefault(key) |
| 109 | url = "http://" + self.getEnvOrDefault("SERVER_IP") + ":" + self.getEnvOrDefault("SERVER_PORT") + urlSuffix |
| 110 | return url |
| 111 | |
| 112 | def checkResult(self, resp, expectedStatus): |
| 113 | """ |
| 114 | Check if the status code in resp equals to the expected number. |
| 115 | Return True or False based on the check result. |
| 116 | """ |
| 117 | if resp.status_code == expectedStatus: |
| 118 | print("Test passed: " + str(resp.status_code) + ": " + resp.text) |
| 119 | return True |
| 120 | else: |
| 121 | print("Test failed: " + str(resp.status_code) + ": " + resp.text) |
| 122 | return False |
| 123 | |
| 124 | def ApiPost(self, key, jsonData): |
| 125 | url = self.getURL(key) |
| 126 | data = json.dumps(jsonData) |
| 127 | print("url, data..", url, data) |
| 128 | resp = requests.post( |
| 129 | url, data=data, headers=jsonHeader, |
| 130 | auth=(self.getEnvOrDefault("XOS_USER"), self.getEnvOrDefault("XOS_PASSWD")) |
| 131 | ) |
| 132 | print("requests.codes.....", requests.codes.created) |
| 133 | passed = self.checkResult(resp, requests.codes.created) or self.checkResult( |
| 134 | resp, requests.codes.ok |
| 135 | ) |
| 136 | return passed |
| 137 | |
| 138 | def ApiPostReturnJson(self, key, jsonData): |
| 139 | url = self.getURL(key) |
| 140 | data = json.dumps(jsonData) |
| 141 | print("url, data..", url, data) |
| 142 | resp = requests.post( |
| 143 | url, data=data, headers=jsonHeader, |
| 144 | auth=(self.getEnvOrDefault("XOS_USER"), self.getEnvOrDefault("XOS_PASSWD")) |
| 145 | ) |
| 146 | print("requests.codes.....", requests.codes.created) |
| 147 | print("posted data...", resp.json()) |
| 148 | passed = self.checkResult(resp, requests.codes.created) or self.checkResult( |
| 149 | resp, requests.codes.ok |
| 150 | ) |
| 151 | return passed, resp.json() |
| 152 | |
| 153 | def ApiGet(self, key, urlSuffix=""): |
| 154 | url = self.getURL(key) + str(urlSuffix) |
| 155 | print("get url...", url) |
| 156 | resp = requests.get(url, auth=(self.getEnvOrDefault("XOS_USER"), self.getEnvOrDefault("XOS_PASSWD"))) |
| 157 | passed = self.checkResult(resp, requests.codes.ok) |
| 158 | if not passed: |
| 159 | return None |
| 160 | else: |
| 161 | return resp.json() |
| 162 | |
| 163 | def ApiChameleonGet(self, key, urlSuffix=""): |
| 164 | url = self.getURL(key) + "/" + str(urlSuffix) |
| 165 | print("get url...", url) |
| 166 | resp = requests.get(url, auth=(self.getEnvOrDefault("XOS_USER"), self.getEnvOrDefault("XOS_PASSWD"))) |
| 167 | passed = self.checkResult(resp, requests.codes.ok) |
| 168 | if not passed: |
| 169 | return None |
| 170 | else: |
| 171 | return resp.json() |
| 172 | |
| 173 | def ApiPut(self, key, jsonData, urlSuffix=""): |
| 174 | print("urlSuffix....", type(urlSuffix)) |
| 175 | url = self.getURL(key) + str(urlSuffix) + "/" |
| 176 | data = json.dumps(jsonData) |
| 177 | resp = requests.put( |
| 178 | url, data=data, headers=jsonHeader, |
| 179 | auth=(self.getEnvOrDefault("XOS_USER"), self.getEnvOrDefault("XOS_PASSWD")) |
| 180 | ) |
| 181 | passed = self.checkResult(resp, requests.codes.ok) |
| 182 | return passed |
| 183 | |
| 184 | def ApiChameleonPut(self, key, jsonData, urlSuffix=""): |
| 185 | print("urlSuffix....", type(urlSuffix)) |
| 186 | url = self.getURL(key) + "/" + str(urlSuffix) |
| 187 | print("url", url) |
| 188 | data = json.dumps(jsonData) |
| 189 | resp = requests.put( |
| 190 | url, data=data, headers=jsonHeader, |
| 191 | auth=(self.getEnvOrDefault("XOS_USER"), self.getEnvOrDefault("XOS_PASSWD")) |
| 192 | ) |
| 193 | passed = self.checkResult(resp, requests.codes.ok) |
| 194 | return passed |
| 195 | |
| 196 | def ApiDelete(self, key, urlSuffix=""): |
| 197 | url = self.getURL(key) + str(urlSuffix) |
| 198 | print("url", url) |
| 199 | resp = requests.delete(url, auth=(self.getEnvOrDefault("XOS_USER"), self.getEnvOrDefault("XOS_PASSWD"))) |
| 200 | passed = self.checkResult(resp, requests.codes.no_content) |
| 201 | return passed |
| 202 | |
| 203 | def ApiChameleonDelete(self, key, urlSuffix=""): |
| 204 | url = self.getURL(key) + "/" + str(urlSuffix) |
| 205 | print("url", url) |
| 206 | resp = requests.delete(url, auth=(self.getEnvOrDefault("XOS_USER"), self.getEnvOrDefault("XOS_PASSWD"))) |
| 207 | passed = self.checkResult(resp, requests.codes.created) or self.checkResult( |
| 208 | resp, requests.codes.ok |
| 209 | ) |
| 210 | return passed |