def get_resource(blueprint_id, deployment_id, tenant_name, resource_path): """ Get resource from the manager file server with path relative to the deployment or blueprint denoted by ``deployment_id`` or ``blueprint_id``. An attempt will first be made for getting the resource from the deployment folder. If not found, an attempt will be made for getting the resource from the blueprint folder. :param blueprint_id: the blueprint id of the blueprint to download the resource from :param deployment_id: the deployment id of the deployment to download the resource from :param tenant_name: tenant name :param resource_path: path to resource relative to blueprint folder :returns: resource content """ tried_paths = [] for path in _resource_paths(blueprint_id, deployment_id, tenant_name, resource_path): try: return get_resource_from_manager(path) except HttpException as e: if e.code != 404: raise tried_paths.append(path) raise HttpException(','.join(tried_paths), 404, 'Resource not found: {0}'.format(resource_path))
def get_resource_directory_index(blueprint_id, deployment_id, tenant_name, resource_path): tried_paths = [] resource_files = set() for path in _resource_paths(blueprint_id, deployment_id, tenant_name, resource_path, use_global=False): try: directory_index = get_resource_from_manager(path) for f in json.loads(directory_index)['files']: resource_files.add(f) except (ValueError, KeyError, NonRecoverableError): tried_paths.append(path) except HttpException as e: if e.code != 404: raise if not resource_files: raise HttpException( ','.join(tried_paths), 404, 'No valid resource directory listing at found: {0}'.format( resource_path)) return list(resource_files)
def get_resource(blueprint_id, deployment_id, tenant_name, resource_path): """ Get resource from the manager file server with path relative to the deployment or blueprint denoted by ``deployment_id`` or ``blueprint_id``. An attempt will first be made for getting the resource from the deployment folder. If not found, an attempt will be made for getting the resource from the blueprint folder. :param blueprint_id: the blueprint id of the blueprint to download the resource from :param deployment_id: the deployment id of the deployment to download the resource from :param tenant_name: tenant name :param resource_path: path to resource relative to blueprint folder :returns: resource content """ def _get_resource(base_url): try: return get_resource_from_manager(resource_path, base_url=base_url) except HttpException as e: if e.code != 404: raise return None resource = None if deployment_id is not None: relative_deployment_path = os.path.join( constants.FILE_SERVER_RESOURCES_FOLDER, constants.FILE_SERVER_DEPLOYMENTS_FOLDER, tenant_name, deployment_id) deployment_base_url = urljoin(utils.get_manager_file_server_url(), relative_deployment_path).replace( '\\', '/') resource = _get_resource(deployment_base_url) if resource is None: client = get_rest_client() blueprint = client.blueprints.get(blueprint_id) if blueprint['visibility'] == VisibilityState.GLOBAL: tenant_name = blueprint['tenant_name'] relative_blueprint_path = os.path.join( constants.FILE_SERVER_RESOURCES_FOLDER, constants.FILE_SERVER_BLUEPRINTS_FOLDER, tenant_name, blueprint_id) blueprint_base_url = urljoin(utils.get_manager_file_server_url(), relative_blueprint_path).replace( '\\', '/') resource = _get_resource(blueprint_base_url) if resource is None: if deployment_id is None: url = blueprint_base_url else: url = ','.join([deployment_base_url, blueprint_base_url]) raise HttpException( url, 404, 'Resource not found: {0}'.format(resource_path)) return resource
def get_resource_from_manager(resource_path, base_url=None, base_urls=None): """Get resource from the manager file server. :param resource_path: path to resource on the file server :param base_url: The base URL to manager file server. Deprecated. :param base_urls: A list of base URL to cluster manager file servers. :param resource_path: path to resource on the file server. :returns: resource content """ base_urls = base_urls or [] base_urls += utils.get_manager_file_server_url() if base_url is not None: base_urls.insert(0, base_url) # if we have multiple managers to try, set connect_timeout so that # we're not waiting forever for a single non-responding manager if len(base_urls) > 1: timeout = (10, None) else: timeout = None verify = utils.get_local_rest_certificate() headers = {} try: headers[constants.CLOUDIFY_EXECUTION_TOKEN_HEADER] = \ ctx.execution_token except NotInContext: headers[constants.CLOUDIFY_EXECUTION_TOKEN_HEADER] = \ workflow_ctx.execution_token for ix, next_url in enumerate(base_urls): url = '{0}/{1}'.format(next_url.rstrip('/'), resource_path.lstrip('/')) try: response = requests.get(url, verify=verify, headers=headers, timeout=timeout) except requests.ConnectionError: continue if not response.ok: is_last = (ix == len(base_urls) - 1) if not is_last: # if there's more managers to try, try them: due to filesystem # replication lag, they might have files that the previous # manager didn't continue raise HttpException(url, response.status_code, response.reason) return response.content raise NonRecoverableError( 'Failed to download {0}: unable to connect to any manager (tried: {1})' .format(resource_path, ', '.join(base_urls)))
def get_resource(resource_path, base_url=None): """ Get resource from the manager file server. :param resource_path: path to resource on the file server :returns: resource content """ if base_url is None: base_url = utils.get_manager_file_server_url() try: url = '{0}/{1}'.format(base_url, resource_path) response = urllib2.urlopen(url) return response.read() except urllib2.HTTPError as e: raise HttpException(e.url, e.code, e.msg)
def test_handle_source_from_string(self): # Mock the download resource when passing fake inventory with patch('cloudify.mocks.MockCloudifyContext.download_resource') \ as mock_download: mock_download.side_effect = HttpException(FAKE_INVENTORY, '404', 'File not found') f1 = NamedTemporaryFile(delete=False) self.addCleanup(remove, f1.name) result = handle_source_from_string(FAKE_INVENTORY, ctx, f1.name) self.assertTrue(path.exists(result)) self.assertTrue(FAKE_INVENTORY in open(result).read()) f2 = NamedTemporaryFile(delete=False) self.addCleanup(remove, f2.name) result = handle_source_from_string(f2.name, ctx, f1.name) self.assertTrue(path.exists(result)) self.assertRaises(RuntimeError, handle_source_from_string, 'bad/file/path', ctx, f1.name)
def register(user): """A helper method to take care of the registration process and store all necessary information into the node instance's runtime properties. """ ctx.logger.info('Registration process started') # Get destination URL. host = ctx.node.properties['stream']['destination_url'] # Get proper scheme, verify host, and prepare headers, if applicable. if ctx.node.properties['stream']['secure']: scheme = 'https' else: scheme = 'http' if not host: raise NonRecoverableError('No destination_url specified') if urlparse.urlparse(host).scheme: raise NonRecoverableError('Malformed destination_url. ' 'It must be in the form of: "example.com"') headers = {} if user.get('exists'): if not user.get('token'): NonRecoverableError('An existing user is about to be used, but ' 'no authorization token was specified') headers = {'Authorization': user.pop('token')} else: for key in ('email', 'name'): if not user.get(key): raise NonRecoverableError('Required input missing: "%s"' % key) url = '%s://%s/api/v1/insights/register' % (scheme, host) reg = requests.post(url, data=json.dumps(user), headers=headers) if not reg.ok: raise HttpException(url=url, code=reg.status_code, message=reg.content) response = reg.json() ctx.instance.runtime_properties.update({ 'insights_url': response['url'], '_meta': { 'token': response['token'], 'manager_id': response['uuid'], 'read_only_token': response['read_only_token'], } })
def download(self, url, output_path=None, certificate_file=None, **attributes): headers = {CLOUDIFY_TOKEN_AUTHENTICATION_HEADER: str(ctx.rest_token)} response = requests.get( url, stream=True, verify=certificate_file, headers=headers) if not response.ok: raise HttpException(url, response.status_code, response.reason) if output_path: destination_file = open(output_path, 'wb') destination = output_path else: destination_file = tempfile.NamedTemporaryFile(delete=False) destination = destination_file.name with destination_file: for chunk in response.iter_content(chunk_size=8192): destination_file.write(chunk) return destination
def configure_tenant(manager): """Configure the current tenant. For now, just provide the Insights authentication token via the Cloudify Manager's Secret Storage.""" # Construct base URL. scheme = 'https' if manager['ssl_enabled'] else 'http' base_url = '%s://%s/api/v3' % (scheme, manager['host']) # Setup session. session = requests.Session() session.auth = (manager['username'], manager['password']) session.verify = manager['ca_certs'] if manager['verify'] else False session.headers.update({ 'Tenant': manager['tenant'], 'Content-Type': 'application/json' }) ctx.logger.info('Will store authentication token as insights_token secret') token = ctx.instance.runtime_properties['_meta']['read_only_token'] url = '%s/secrets/insights_token' % base_url req = session.put(url, data=json.dumps({'value': token})) if not req.ok: raise HttpException(url=url, code=req.status_code, message=req.content)
def get_resource_from_manager(resource_path, base_url=None): """ Get resource from the manager file server. :param resource_path: path to resource on the file server :returns: resource content """ if base_url is None: base_url = utils.get_manager_file_server_url() url = '{0}/{1}'.format(base_url, resource_path) verify = utils.get_local_rest_certificate() headers = {} try: headers[constants.CLOUDIFY_TOKEN_AUTHENTICATION_HEADER] = \ ctx.rest_token except NotInContext: headers[constants.CLOUDIFY_TOKEN_AUTHENTICATION_HEADER] = \ workflow_ctx.rest_token response = requests.get(url, verify=verify, headers=headers) if not response.ok: raise HttpException(url, response.status_code, response.reason) return response.content