def create_account(self, account_info=None, api_key=None, expected_status_code=None): """ Create a new account (tier 0 by default) :param account_info: Account info payload :param api_key: Authentication key :param expected_status_code: Asserts the result in the function :return: POST /accounts response """ random_str = utils.build_random_string(10) api_url = '/{}/accounts'.format(self.api_version) payload = { "tier": "0", "display_name": "SystestCompanyOy", "admin_name": random_str, "company": "SystestCompanyOy", "country": "Finland", "state": "Pohjois-Pohjanmaa", "address_line1": "Torikatu 18B", "address_line2": "Floor 3-5", "postal_code": "90100", "city": "Oulu", "admin_email": "testuser199+{}@systest-emailserver-789877574.eu-west-1.elb.amazonaws.com".format( random_str), "email": "testuser199+{}@systest-emailserver-789877574.eu-west-1.elb.amazonaws.com".format(random_str), "end_market": "Agriculture", "aliases": ["SystestCompanyOy_{}".format(random_str)] } if account_info is not None: payload = account_info r = self.cloud_api.post(api_url, api_key, payload, expected_status_code=expected_status_code) return r
def create_user(self, user_info=None, root_user=False, api_key=None, expected_status_code=None): """ Create a new user :param user_info: Override the 'default' generated user info :param root_user: Set true if creating root user :param api_key: Authentication key :param expected_status_code: Asserts the result in the function :return: POST /users response """ random_str = utils.build_random_string(10) if root_user: api_url = '/{}/accounts/%2F/users'.format(self.api_version) else: api_url = '/{}/users'.format(self.api_version) payload = {'username': '******'.format(random_str), 'full_name': random_str, 'email': "testuser199+{}@systest-emailserver-789877574.eu-west-1.elb.amazonaws.com".format( random_str), 'address': 'Torikatu, Oulu, 90100, Finland', 'phone_number': '+123456789'} if root_user: payload['username'] = '******'.format(random_str) if user_info is not None: payload = user_info r = self.cloud_api.post(api_url, api_key, payload, expected_status_code=expected_status_code) return r
def open(self): """ Open WebSocket threads """ if self.run: log.warning('WebSocket threads are already running!') return log.info('Starting WebSocket threads') self.exit = False self.run = True _it = threading.Thread(target=self._input_thread, args=(self._api_url, self._api_key), name='websocket_{}'.format( build_random_string(3))) _ht = threading.Thread(target=self._handle_thread, name='messages_{}'.format( build_random_string(3))) _it.setDaemon(True) _ht.setDaemon(True) _it.start() _ht.start()
def async_request(self, device_id, resource, async_id=None, method='GET', payload=None, accept='text/plain', content_type='text/plain', api_key=None): """ Helper to send async request to the device without complex payload building :param device_id: Device ID as 01751b38556200000000000100108a2f :param resource: Resource path as /3201/0/5853 :param async_id: Async_ID string or None when random string will be used :param method: GET/PUT/POST/DELETE, defaults to GET :param payload: Payload string :param accept: The content type that the requesting client will accept :param content_type: Describes the content type of the base-64 encoded payload-b64 field :param api_key: Specific API key or None when one from config will be used :return: async_id used to do the request Examples: r = cloud_api.connect.async_request('01751b38556200000000000100108a2f', '/3201/0/5853') r = cloud_api.connect.async_request('01751b38556200000000000100108a2f', '/3201/0/5853', method='PUT', payload='1:2:3:4') """ # This looks stupid. Payload is given as a string, b64encode takes bytes and gives bytes though it is ascii # string, so it needs to be decoded back. For binary payload something else has to be invented but that's rare. # Payload is usually not given for GET, use try-catch to set it None. try: payload_b64 = b64encode(payload.encode('utf-8')).decode('utf-8') except AttributeError: payload_b64 = None request_data = { 'method': method, 'uri': resource, 'payload-b64': payload_b64, 'accept': accept, 'content-type': content_type } if async_id is None: async_id = utils.build_random_string(5) self.send_async_request_to_device(device_id, request_data=request_data, async_id=async_id, api_key=api_key) return async_id
def create_access_key(self, application_id, access_key_name=None, access_key=None, expected_status_code=None): """ Generate access key :param application_id: Application ID :param access_key_name: Name for access key :param access_key: Authentication key :param expected_status_code: Asserts the result in the function :return: POST /applications/{application_id}/access-keys response """ api_url = '/{}/applications/{}/access-keys'.format(self.api_version, application_id) if access_key_name is None: temp_name = 'local_{}'.format(utils.build_random_string(5, use_digits=True)) access_key_name = 'Syte_dynamic_{}_access_key'.format(os.getenv('JOB_NAME', temp_name)[:70]) payload = {'name': access_key_name} r = self.cloud_api.post(api_url, access_key, payload, expected_status_code=expected_status_code) return r
def write_kubectl_config(self, server_url, api_key): try: # Try to write configuration in current directory first kube_config_path = self._write_config(os.getcwd(), server_url, api_key) except Exception as err: log.warning( 'Cannot use current folder for kube config, using temp folder, {}' .format(err)) # Use also custom name, to make this work more reliable kube_config_path = self._write_config( tempfile.gettempdir(), server_url, api_key, '{}_kube_config.yaml'.format(build_random_string(5))) # Take configuration in use log.debug( 'Kube config successfully added in {}'.format(kube_config_path)) return kube_config_path
def send_async_device_and_wait_for_response(cloud_api, channel_type, ep_id, apikey, payload, async_id=None, timeout=30, expiry_seconds=None): """ Send a get rest request to specific resource and wait for the async response from device :param payload: The request we want to send to device for example: {"method": "GET", "uri": "/1000/0/1"} :param expiry_seconds: The time period during which the delivery is attempted, in seconds. :param async_id: Use provided async id with request or generate a random one for the request :param cloud_api: :param channel_type: websocket or callback :param ep_id: device id :param apikey: api key fixture. :param timeout: timeout for the async wait :return: dict / False (if received from cloud) """ if async_id is None: async_id = utils.build_random_string(30) cloud_api.connect.send_async_request_to_device( ep_id, payload, async_id=async_id, expiry_seconds=expiry_seconds, expected_status_code=202, api_key=apikey) async_response = channel_type.wait_for_async_response( async_response_id=async_id, timeout=timeout, assert_errors=True) log.info('get async response {}'.format(async_response)) # check if we get async response and it contains payload if async_response and 'payload' in async_response: # decode original payload and append in received async response async_response['decoded_payload'] = base64.b64decode( async_response['payload']).decode('utf-8') return async_response return False
def change_resource_value(self, device_id, resource_path, value, api_key=None, expected_status_code=None): """ Change resource value of the device :param device_id: device id :param resource_path: Path to resource value to be changed "/<object>/0/<resource>" :param value: Value to set in string format :param api_key: Api key to use in query :param expected_status_code: Asserts the result in the function :return: POST /device-requests/{device_id} response """ api_url = '/{}/device-requests/{}'.format(self.api_version, device_id) async_params = { 'async-id': '{}-{}'.format(device_id, utils.build_random_string(6)) } # Set payload payload_b64 = b64encode(value.encode('utf-8')).decode('utf-8') payload = { "method": "PUT", "uri": resource_path, "accept": "text/plain", "content-type": "text/plain", "payload-b64": payload_b64 } r = self.cloud_api.post(api_url, api_key, payload, params=async_params, expected_status_code=expected_status_code) return r