def aggregated_report(self, payload): """ Return aggregated data report Args: payload (dict): dict containing iotkit REST API advanced-search parameters. Returns: JSON message containing returned data set See the Aggregated Report interface page on the iotkit REST API wiki for request and response message formats. https://github.com/enableiot/iotkit-api/wiki/Aggregated-Report-Interface """ url = "{0}/accounts/{1}/data/report".format(globals.base_url, self.id) data = json.dumps(payload) # print url, data resp = requests.post(url, data=data, headers=get_auth_headers(self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js
def advanced_data_query(self, payload): """ Advanced data query supports multiple filters and sorting options Args: payload (dict): dict containing iotkit REST API advanced-search parameters. Returns: JSON message containing returned data set See the Advanced Data Inquiry page on the iotkit REST API wiki for request and response message formats https://github.com/enableiot/iotkit-api/wiki/Advanced-Data-Inquiry """ url = "{0}/accounts/{1}/data/search/advanced".format( globals.base_url, self.id) data = json.dumps(payload) resp = requests.post(url, data=data, headers=get_auth_headers(self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js
def update_account(self, acct_info): """ Update account attributes for current account instance Args: account_info (dict): A dict containing updated account attributes Returns: JSON message containing account attributes """ data = json.dumps(acct_info) if acct_info: url = "{0}/accounts/{1}".format(globals.base_url, self.id) resp = requests.put(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() #update_properties(self, js) # save account properties self.info = js return js else: raise ValueError("Invalid account info given.")
def get_user_tokeninfo(self): """ Get user token details Returns: -------- JSON message containing access token details e.g., Response 200 OK (application/json) { "header": { "typ": "JWT", "alg": "RS256" }, "payload": { "jti": "7b1430a2-dd61-4a47-919c-495cadb1ea7b", "iss": "http://enableiot.com", "sub": "53fdff4418b547e4241b8358", "exp": "2014-10-02T07:53:25.361Z" } } """ url = "{0}/auth/tokenInfo".format(self.base_url) resp = requests.get(url, headers=get_auth_headers(self.user_token), proxies=self.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js
def list_account_users(self): """ List all users associated with this account Returns: A list of user-attribute JSON messages Example, [ { "id": "54e7cf2399fe4c41202e5b2f", "accounts": { "88f741fe-4087-42ef-a042-93c021e0148e": "admin" }, "created": 1424477987329, "email": "*****@*****.**", "termsAndConditions": true, "updated": 1424478023196, "verified": true } ] """ url = "{0}/accounts/{1}/users".format(globals.base_url, self.id) resp = requests.get(url, headers=get_auth_headers(self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js
def get_attributes(self): url = "{0}/accounts/{1}/devices".format( self.client.base_url, self.account_id) resp = requests.get(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js
def get_user_info(self, user_id=None): # Get the user's info url = "{0}/users/{1}".format(globals.base_url, user_id) resp = requests.get(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() self.id = js["id"] return js
def get_comp_types(self, full=False): url = "{0}/accounts/{1}/cmpcatalog".format(self.client.base_url, self.account.id) if full == True: url += "?full=true" resp = requests.get(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js
def update_user(self, user_info): if user_info: # given a user_id, get the user's info url = "{0}/users/{1}".format(globals.base_url, self.id) data = json.dumps(user_info) resp = requests.put(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) else: raise ValueError("No user info given.") return None
def get_account_invites(self): if self.account: url = "{0}/accounts/{1}/invites".format( self.client.base_url, self.account.id) resp = requests.get(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js else: raise ValueError("No account provided.")
def get_user_invites(self, email): if email: url = "{0}/invites/{1}".format( self.client.base_url, urllib.quote(email)) resp = requests.get(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js else: raise ValueError("No email provided.")
def add_comp_type(self, component_info=None): if component_info: url = "{0}/accounts/{1}/cmpcatalog".format(self.client.base_url, self.account.id) data = json.dumps(component_info) resp = requests.post(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 201) js = resp.json() return js else: raise ValueError("No component info given.")
def send_data(self, dataSeries): url = "{0}/data/{1}".format(self.client.base_url, self.device_id) payload = { "on": time.time(), "accountId": self.account_id, "data": dataSeries } data = json.dumps(payload) resp = requests.post(url, data=data, headers=get_auth_headers( self.device_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 201) return resp.text
def update_device(self, device_info, device_id=None): if not device_id: device_id = self.device_id url = "{0}/accounts/{1}/devices/{2}".format( self.client.base_url, self.account_id, device_id) data = json.dumps(device_info) resp = requests.put(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() self.info = js return js
def delete_device(self, device_id=None): if not device_id: device_id = self.device_id if device_id: url = "{0}/accounts/{1}/devices/{2}".format( self.client.base_url, self.account_id, device_id) resp = requests.delete(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 204) self.device_id = None self.info = None else: raise ValueError("No active device selected.")
def activate_new_device(self, activation_code): url = "{0}/accounts/{1}/devices/{2}/activation".format( self.client.base_url, self.account_id, self.device_id) activation = { "activationCode": activation_code } data = json.dumps(activation) resp = requests.put(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() self.device_token = js["deviceToken"] return self.device_token
def verify_restservice(url): """To verify that the REST service is working, GET the blueprints list. There's nothing special about the blueprints endpoint, it's simply one that also requires the storage backend to be up, so if it works, there's a good chance everything is configured correctly. """ blueprints_url = urlparse.urljoin(url, 'api/v2.1/blueprints') headers = utils.get_auth_headers(True) if utils.is_upgrade or utils.is_rollback: # if we're doing an upgrade, we're in maintenance mode - this request # is safe to perform in maintenance mode, so let's bypass the check headers = utils.create_maintenance_headers() else: headers = utils.get_auth_headers(True) req = urllib2.Request(blueprints_url, headers=headers) try: response = urllib2.urlopen(req) except urllib2.URLError as e: ctx.abort_operation( 'REST service returned an invalid response: {0}'.format(e)) if response.code == 401: ctx.abort_operation('Could not connect to the REST service: ' '401 unauthorized. Possible access control ' 'misconfiguration') if response.code != 200: ctx.abort_operation( 'REST service returned an unexpected response: {0}'.format( response.code)) try: json.load(response) except ValueError as e: ctx.abort_operation( 'REST service returned malformed JSON: {0}'.format(e))
def verify_restservice(url): """To verify that the REST service is working, GET the blueprints list. There's nothing special about the blueprints endpoint, it's simply one that also requires the storage backend to be up, so if it works, there's a good chance everything is configured correctly. """ blueprints_url = urlparse.urljoin(url, 'api/v2.1/blueprints') headers = utils.get_auth_headers(True) if utils.is_upgrade or utils.is_rollback: # if we're doing an upgrade, we're in maintenance mode - this request # is safe to perform in maintenance mode, so let's bypass the check headers = utils.create_maintenance_headers() else: headers = utils.get_auth_headers(True) req = urllib2.Request(blueprints_url, headers=headers) try: response = urllib2.urlopen(req) except urllib2.URLError as e: ctx.abort_operation('REST service returned an invalid response: {0}' .format(e)) if response.code == 401: ctx.abort_operation('Could not connect to the REST service: ' '401 unauthorized. Possible access control ' 'misconfiguration') if response.code != 200: ctx.abort_operation('REST service returned an unexpected response: {0}' .format(response.code)) try: json.load(response) except ValueError as e: ctx.abort_operation('REST service returned malformed JSON: {0}' .format(e))
def get_comp_type(self, component_id): if component_id: url = "{0}/accounts/{1}/cmpcatalog/{2}".format(self.client.base_url, self.account.id, component_id) resp = requests.get(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) #check(resp, 200) if resp.status_code == 404: return None js = resp.json() return js else: raise ValueError("No component ID given.")
def accept_invite(self, email): if email: url = "{0}/invites/{1}/status".format( self.client.base_url, email) payload = { "accept": True } data = json.dumps(dict(payload)) resp = requests.put(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js else: raise ValueError("No email provided.")
def change_password(self, username, oldpassword, newpassword): if username and oldpassword and newpassword: # given a user_id, get the user's info url = "{0}/users/{1}/change_password".format( globals.base_url, username) payload = { "currentpwd": oldpassword, "password": newpassword } data = json.dumps(payload) resp = requests.put(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) else: raise ValueError("No username, old or new password given.") return None
def create_device(self, device_info, activate=False): if device_info: url = "{0}/accounts/{1}/devices".format( self.client.base_url, self.account_id) data = json.dumps(device_info) resp = requests.post(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 201) js = resp.json() self.device_id = js["deviceId"] self.info = js if activate: activation_code = self.account.renew_activation_code() self.activate_new_device(activation_code) return js else: raise ValueError("No account name given.")
def create_account(self, account_name): """ Create a new account. Args: account_name (str): alias/name for account Returns: JSON message containing account attributes. Example: { "name":"AccountName", "healthTimePeriod":86400, "created":1406919627586, "updated":1406919627586, "exec_interval":300, "base_line_exec_interval":86400, "cd_model_frequency":604800, "cd_execution_frequency":600, "data_retention":0, "id":"321ef007-8449-477f-9ea0-d702d77e64b9" } """ if account_name: url = "{0}/accounts".format(globals.base_url) payload = {"name": account_name} data = json.dumps(payload) resp = requests.post(url, data=data, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 201) js = resp.json() self.id = js["id"] #update_properties(self, js) # save account properties self.info = js return js else: raise ValueError("No account name given.")
def delete_account(self, account_id): """ Delete account with given account ID Args: account_id (str): account ID of account to delete Returns: No value is returned. A ValueError will be thrown if the device ID is invalid """ if account_id: url = "{0}/accounts/{1}".format(globals.base_url, account_id) resp = requests.delete(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 204) else: raise ValueError("Invalid account ID.")
def renew_activation_code(self): """ Return new activation code Returns: JSON message containing activation code and expiration time. Example, { "activationCode": "5nLyMJrh", "timeLeft": 1424731140 } """ url = "{0}/accounts/{1}/activationcode/refresh".format( globals.base_url, self.id) resp = requests.put(url, headers=get_auth_headers(self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js["activationCode"]
def verify_restservice(url): """To verify that the REST service is working, GET the blueprints list. There's nothing special about the blueprints endpoint, it's simply one that also requires the storage backend to be up, so if it works, there's a good chance everything is configured correctly. """ security_config = runtime_props['security_configuration'] headers = utils.get_auth_headers( username=security_config['admin_username'], password=security_config['admin_password']) utils.verify_service_http(SERVICE_NAME, url, headers=headers) blueprints_url = urlparse.urljoin(url, 'api/v2.1/blueprints') req = urllib2.Request(blueprints_url, headers=headers) try: response = urllib2.urlopen(req) # keep an erroneous HTTP response to examine its status code, but still # abort on fatal errors like being unable to connect at all except urllib2.HTTPError as e: response = e except urllib2.URLError as e: ctx.abort_operation( 'REST service returned an invalid response: {0}'.format(e)) if response.code == 401: ctx.abort_operation('Could not connect to the REST service: ' '401 unauthorized. Possible access control ' 'misconfiguration') if response.code != 200: ctx.abort_operation( 'REST service returned an unexpected response: {0}'.format( response.code)) try: json.load(response) except ValueError as e: ctx.abort_operation( 'REST service returned malformed JSON: {0}'.format(e))
def get_account(self, account_name, account_id=None): """ Look up account attributes for a given account and load instance attributes with returned values Args: account_name (str): alias/name of account to lookup (first match will be returned) account_id (str): use account ID (GUID) of account to help match Returns: account ID (str): Account ID (GUID) or matching account """ if account_name: # given a user_id, get the account_id of the associated account with account_name # if there are multiple accounts with the same name, return one of # them url = "{0}/users/{1}".format(globals.base_url, self.client.user_id) resp = requests.get(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() if 'accounts' in js: accounts = js["accounts"] for key, value in accounts.iteritems(): if 'name' in value and value["name"] == account_name: # if account_id is given, verify its value also if account_id and account_id == key or not account_id: self.id = key return self.id msg = "Account name {0} not found.".format(account_name) msg = msg + "Available accounts are: {0}".format( [value["name"] for key, value in accounts.iteritems()]) raise ValueError(msg) else: raise ValueError("No account name given.")
def get_activation_code(self): """ Return previous activation code if it is still valid Returns: JSON message containing activation code and expiration time. Values will be "None" if the code has expired. Example, { "activationCode": "5nLyMJrh", "timeLeft": 1424731140 } """ url = "{0}/accounts/{1}/activationcode".format(globals.base_url, self.id) resp = requests.get(url, headers=get_auth_headers(self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js["activationCode"]
def get_info(self): """ Return account attributes for a given account. Args: account_name (str): alias/name of account to lookup (first match will be returned) account_id (str): use account ID (GUID) of account to help match Returns: JSON message containing account information. Example: { "name": "AccountName", "healthTimePeriod": 86400, "created": 1404415261310, "updated": 1404415261310, "exec_interval": 120, "base_line_exec_interval": 86400, "cd_model_frequency": 604800, "cd_execution_frequency": 600, "data_retention": 0, "attributes":{ "phone":"123456789", "another_attribute":"another_value" }, "id": "321ef007-8449-477f-9ea0-d702d77e64b9" } """ url = "{0}/accounts/{1}".format(globals.base_url, self.id) resp = requests.get(url, headers=get_auth_headers(self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() #update_properties(self, js) # save account properties self.info = js return js
def get_devices(self): """ List all users associated with this account Returns: A list of device-attribute JSON messages Example, [ { "attributes": { "agent_version": "1.5.1", "hardware_vendor": "Genuine Intel(R) CPU 4000 @ 500MHz", "hardware_model": "linux", "Model Name": "ia32", "Firmware Version": "3.10.17-poky-edison+" }, "created": 1424713173378, "components": [ { "name": "temp", "type": "temperature.v1.0", "cid": "f4f942c1-7d6f-4771-bbd4-9cfa9717ba5a" } ], "deviceId": "jumbo-edison", "gatewayId": "jumbo-edison", "name": "jumbo-edison-NAME", "status": "active" } ] """ url = "{0}/accounts/{1}/devices".format( self.client.base_url, self.account_id) resp = requests.get(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) js = resp.json() return js
ctx.download_resource( join('components', 'utils.py'), join(dirname(__file__), 'utils.py')) import utils # NOQA NGINX_SERVICE_NAME = 'nginx' def check_response(response): """Check if the response looks like a correct REST service response. We can get a 200, or a 401 in case auth is enabled. We don't expect a 502, though, as this would mean nginx isn't correctly proxying to the REST service. """ return response.code in {200, 401} utils.start_service(NGINX_SERVICE_NAME, append_prefix=False) utils.systemd.verify_alive(NGINX_SERVICE_NAME, append_prefix=False) nginx_url = 'http://127.0.0.1/api/v2.1/blueprints' if utils.is_upgrade or utils.is_rollback: headers = utils.create_maintenance_headers() else: headers = utils.get_auth_headers(True) utils.verify_service_http(NGINX_SERVICE_NAME, nginx_url, check_response, headers=headers)
def delete_user(self, user_id): # Get the user's info url = "{0}/users/{1}".format(globals.base_url, user_id) resp = requests.delete(url, headers=get_auth_headers( self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 204)
def search_data(self, time0, time1, devices, components, csv=None): """ Retrieve data for a list of devices and components in a given time period. Args: time0 (int): beginning time time1 (int): ending time (None = current timestamp) devices (list of strings): list of devices IDs to return data for components (list of strings): list of component IDs to return data for csv (bool): return results in JSON or CSV format Returns: JSON or CSV message { "from": 1234567890, "to": 1234567890, "maxPoints": 100, "series": [ { "deviceId": "D1", "deviceName": "D1", "componentId": "e3a48caa-e4c5-46bb-951e-8f9d0a4be516", "componentName": "temp", "componentType": "temperature.v1.0", "points": [ {"ts":9874569871, "value":25}, {"ts":9874569899, "value":24} ] }, { "deviceId": "D2", "deviceName": "D2", "componentId": "76a95112-2159-4ee6-8e91-6a69b9c51edc", "componentName": "Humidity 1", "componentType": "humidity.v1.0", "points": [ {"ts":9874569871,"value":"55"}, {"ts":9874569899,"value":"65"} ] } ] } """ url = "{0}/accounts/{1}/data/search".format(globals.base_url, self.id) if csv: url = url + "?output=csv" payload = { "from": time0, "targetFilter": { "deviceList": devices }, "metrics": [] } if time1: payload["to"] = time1 for c in components: payload["metrics"].append({"id": c, "op": "none"}) payload["targetFilter"]["deviceList"] = devices data = json.dumps(payload) resp = requests.post(url, data=data, headers=get_auth_headers(self.client.user_token), proxies=self.client.proxies, verify=globals.g_verify) check(resp, 200) if csv: return resp.text else: js = resp.json() return js["series"]