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))
Exemple #2
0
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
Exemple #4
0
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)
Exemple #7
0
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
Exemple #9
0
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