def _test_default_resolver(self, import_url, rules,
                               expected_urls_to_resolve=[],
                               expected_failure=False,
                               partial_err_msg=None):

        urls_to_resolve = []

        def mock_urlopen(url):
            urls_to_resolve.append(url)
            if url in [ORIGINAL_V1_URL, ORIGINAL_V2_URL, INVALID_V1_URL]:
                raise urllib2.URLError('invalid url: {0}'.format(url))
            elif url == ILLEGAL_URL:
                raise ValueError('unknown url type: {0}'.format(url))
            elif url in [VALID_V1_URL, VALID_V2_URL]:
                return mock.MagicMock()

        resolver = DefaultImportResolver(rules=rules)
        with mock.patch('urllib2.urlopen', new=mock_urlopen):
            try:
                resolver.resolve(import_url=import_url)
                if expected_failure:
                    err_msg = 'resolve should have been failed'
                    if partial_err_msg:
                        err_msg = '{0} with error message that contains: {1}'\
                            .format(err_msg, partial_err_msg)
                    raise AssertionError(err_msg)
            except DSLParsingLogicException, ex:
                if not expected_failure:
                    raise ex
                if partial_err_msg:
                    self.assertIn(partial_err_msg, str(ex))
    def _test_default_resolver(self, import_url, rules,
                               expected_urls_to_resolve=[],
                               expected_failure=False,
                               partial_err_msg=None):

        urls_to_resolve = []
        number_of_attempts = []

        class mock_requests_get(object):

            def __init__(self, url, timeout):
                self.status_code = 200
                self.text = 200
                number_of_attempts.append(1)
                if url not in urls_to_resolve:
                    urls_to_resolve.append(url)
                if url in [ORIGINAL_V1_URL, ORIGINAL_V2_URL, INVALID_V1_URL]:
                    raise requests.URLRequired(
                        'invalid url: {0}'.format(url))
                elif url == ILLEGAL_URL:
                    raise requests.URLRequired(
                        'unknown url type: {0}'.format(
                            url))
                elif url in [VALID_V1_URL, VALID_V2_URL]:
                    return None
                elif url == TIMEOUT_URL:
                    raise requests.ConnectionError(
                        'Timeout while trying to import')
                elif url == BAD_RESPONSE_CODE_URL:
                    self.status_code = 404
                    self.text = 404
                elif url == RETRY_URL:
                    if len(number_of_attempts) < DEFAULT_NUMBER_RETRIES:
                        raise requests.ConnectionError(
                            'Timeout while trying to import')
                    else:
                        return None

        resolver = DefaultImportResolver(rules=rules)
        with mock.patch('requests.get', new=mock_requests_get,
                        create=True):
            with mock.patch(
                    'dsl_parser.import_resolver.abstract_import_resolver.'
                    'DEFAULT_RETRY_DELAY', new=RETRY_DELAY):
                try:
                    resolver.resolve(import_url=import_url)
                    if expected_failure:
                        err_msg = 'resolve should have been failed'
                        if partial_err_msg:
                            err_msg = \
                                '{0} with error message that contains: {1}'\
                                .format(err_msg, partial_err_msg)
                        raise AssertionError(err_msg)
                except DSLParsingLogicException, ex:
                    if not expected_failure:
                        raise ex
                    if partial_err_msg:
                        self.assertIn(partial_err_msg, str(ex))
示例#3
0
    def _test_default_resolver(self,
                               import_url,
                               rules,
                               expected_urls_to_resolve=[],
                               expected_failure=False,
                               partial_err_msg=None,
                               fallback=False):

        urls_to_resolve = []
        number_of_attempts = []

        class mock_requests_get(object):
            def __init__(self, url, timeout):
                self.status_code = 200
                self.text = 200
                number_of_attempts.append(1)
                if url not in urls_to_resolve:
                    urls_to_resolve.append(url)
                if url in [ORIGINAL_V1_URL, ORIGINAL_V2_URL, INVALID_V1_URL]:
                    raise requests.URLRequired('invalid url: {0}'.format(url))
                elif url == ILLEGAL_URL:
                    raise requests.URLRequired(
                        'unknown url type: {0}'.format(url))
                elif url in [VALID_V1_URL, VALID_V2_URL]:
                    return None
                elif url == TIMEOUT_URL:
                    raise requests.ConnectionError(
                        'Timeout while trying to import')
                elif url == BAD_RESPONSE_CODE_URL:
                    self.status_code = 404
                    self.text = 404
                elif url == RETRY_URL:
                    if len(number_of_attempts) < MAX_NUMBER_RETRIES:
                        raise requests.ConnectionError(
                            'Timeout while trying to import')
                    else:
                        return None

        resolver = DefaultImportResolver(rules=rules, fallback=fallback)
        with mock.patch('requests.get', new=mock_requests_get, create=True):
            with mock.patch(
                    'dsl_parser.import_resolver.abstract_import_resolver.'
                    'DEFAULT_RETRY_DELAY',
                    new=RETRY_DELAY):
                try:
                    resolver.resolve(import_url=import_url)
                    if expected_failure:
                        err_msg = 'resolve should have been failed'
                        if partial_err_msg:
                            err_msg = \
                                '{0} with error message that contains: {1}'\
                                .format(err_msg, partial_err_msg)
                        raise AssertionError(err_msg)
                except DSLParsingLogicException, ex:
                    if not expected_failure:
                        raise ex
                    if partial_err_msg:
                        self.assertIn(partial_err_msg, str(ex))
示例#4
0
    def _test_using_import_resolver(self,
                                    command,
                                    blueprint_path,
                                    mocked_module,
                                    mock_get_resolver):
        cfy.invoke('cfy init -r')

        # create an import resolver
        parameters = {
            'rules':
                [{'rule1prefix': 'rule1replacement'}]
        }
        resolver = DefaultImportResolver(**parameters)
        # set the return value of mock_get_resolver -
        # this is the resolver we expect to be passed to
        # the parse_from_path method.
        mock_get_resolver.return_value = resolver

        # run the cli command and check that
        # parse_from_path was called with the expected resolver
        cli_command = 'cfy {0} {1}'.format(command, blueprint_path)
        kwargs = {
            'dsl_file_path': blueprint_path,
            'resolver': resolver,
            'validate_version': True
        }
        self.assert_method_called(
            cli_command, mocked_module, 'parse_from_path', kwargs=kwargs)
        cfy.purge_dot_cloudify()
示例#5
0
def _resolve_blueprint_imports(dsl_location, dsl_string, resolver,
                               resources_base_path, validate_version):
    """
    Goes over all the blueprint's imports and constructs a merged blueprint
    from them.
    """
    parsed_dsl_holder = utils.load_yaml(raw_yaml=dsl_string,
                                        error_message='Failed to parse DSL',
                                        filename=dsl_location)
    if not resolver:
        resolver = DefaultImportResolver()
    # validate version schema and extract actual version used
    result = parser.parse(parsed_dsl_holder,
                          element_cls=blueprint.BlueprintVersionExtractor,
                          inputs={'validate_version': validate_version},
                          strict=False)
    version = result['plan_version']
    # handle imports
    result = parser.parse(value=parsed_dsl_holder,
                          inputs={
                              'main_blueprint_holder': parsed_dsl_holder,
                              'resources_base_path': resources_base_path,
                              'blueprint_location': dsl_location,
                              'version': version,
                              'resolver': resolver,
                              'validate_version': validate_version
                          },
                          element_cls=blueprint.BlueprintImporter,
                          strict=False)

    return result['resource_base'],\
        result['merged_blueprint']
示例#6
0
 def test_specified_default_class_path_no_params(self):
     resolver_configuration = {
         RESOLVER_IMPLEMENTATION_KEY: default_resolver_class_path
     }
     self._test_create_import_resolver(
         resolver_configuration=resolver_configuration,
         expected_resolver=DefaultImportResolver(),
         expected_params_name=DEFAULT_RESLOVER_RULES_KEY)
 def test_illegal_default_resolver_rules_type(self):
     # wrong rules configuration - string instead of list
     params = {'rules': 'this should be a list'}
     try:
         DefaultImportResolver(**params)
     except DefaultResolverValidationException as ex:
         self.assertIn(
             'The `rules` parameter must be a list but it is of type str',
             str(ex))
 def test_illegal_default_resolver_parameters(self):
     # illegal initialization of the default resolver
     params = {'wrong_param_name': ''}
     try:
         DefaultImportResolver(**params)
     except TypeError as ex:
         self.assertIn(
             'got an unexpected keyword argument \'wrong_param_name\'',
             str(ex))
 def test_get_default_resolver_illegal_rule_size(self):
     # wrong rule dictionary size - should be only one pair of key, value
     rules = [{'rule1_1': 'rule1_value1', 'rule1_2': 'rule1_value2'}]
     params = {'rules': rules}
     try:
         DefaultImportResolver(**params)
     except DefaultResolverValidationException as ex:
         self.assertIn(
             'Each rule must be a dictionary with one (key,value) '
             'pair but the rule {0} has 2 keys'.format(rules), str(ex))
示例#10
0
 def parse_from_path(self,
                     dsl_path,
                     resources_base_path=None,
                     resolver=None):
     if not resolver:
         resolver = DefaultImportResolver(
             rules=self._local_resolver_rules())
     return dsl_parse_from_path(dsl_path,
                                resources_base_path,
                                resolver=resolver)
示例#11
0
 def test_specified_params_no_class_path(self):
     parameters = {
         DEFAULT_RESLOVER_RULES_KEY: [{
             'rules1key': 'rules1value'
         }]
     }
     resolver_configuration = {RESLOVER_PARAMETERS_KEY: parameters}
     self._test_create_import_resolver(
         resolver_configuration=resolver_configuration,
         expected_resolver=DefaultImportResolver(**parameters),
         expected_params_name=DEFAULT_RESLOVER_RULES_KEY)
 def test_illegal_default_resolver_rule_type(self):
     # wrong rule type - should be dictionary
     rule = 'this should be a dict'
     rules = [rule]
     params = {'rules': rules}
     try:
         DefaultImportResolver(**params)
     except DefaultResolverValidationException as ex:
         self.assertIn(
             'Each rule must be a dictionary but the rule '
             '[{0}] is of type {1}'.format(rule,
                                           type(rule).__name__), str(ex))
示例#13
0
 def parse(self, dsl_string,
           resources_base_path=None,
           dsl_version=BASIC_VERSION_SECTION_DSL_1_0,
           resolver=None,
           validate_version=True):
     # add dsl version if missing
     if DSL_VERSION_PREFIX not in dsl_string:
         dsl_string = dsl_version + dsl_string
         if not resolver:
             resolver = DefaultImportResolver()
     return dsl_parse(dsl_string,
                      resources_base_path=resources_base_path,
                      resolver=resolver,
                      validate_version=validate_version)
示例#14
0
def create_import_resolver(resolver_configuration):
    if resolver_configuration:
        resolver_class_path = resolver_configuration.get(
            RESOLVER_IMPLEMENTATION_KEY)
        parameters = resolver_configuration.get(RESLOVER_PARAMETERS_KEY, {})
        if parameters and not isinstance(parameters, dict):
            raise ResolverInstantiationError(
                'Invalid parameters supplied for the resolver ({0}): '
                'parameters must be a dictionary and not {1}'.format(
                    resolver_class_path or 'DefaultImportResolver',
                    type(parameters).__name__))
        try:
            if resolver_class_path:
                # custom import resolver
                return get_class_instance(resolver_class_path, parameters)
            else:
                # default import resolver
                return DefaultImportResolver(**parameters)
        except Exception as ex:
            raise ResolverInstantiationError(
                'Failed to instantiate resolver ({0}). {1}'.format(
                    resolver_class_path or 'DefaultImportResolver', str(ex)))
    return DefaultImportResolver()
示例#15
0
def _parse(dsl_string,
           resources_base_path,
           dsl_location=None,
           resolver=None,
           validate_version=True,
           additional_resource_sources=()):
    parsed_dsl_holder = utils.load_yaml(raw_yaml=dsl_string,
                                        error_message='Failed to parse DSL',
                                        filename=dsl_location)

    if not resolver:
        resolver = DefaultImportResolver()

    # validate version schema and extract actual version used
    result = parser.parse(parsed_dsl_holder,
                          element_cls=blueprint.BlueprintVersionExtractor,
                          inputs={'validate_version': validate_version},
                          strict=False)
    version = result['plan_version']

    # handle imports
    result = parser.parse(value=parsed_dsl_holder,
                          inputs={
                              'main_blueprint_holder': parsed_dsl_holder,
                              'resources_base_path': resources_base_path,
                              'blueprint_location': dsl_location,
                              'version': version,
                              'resolver': resolver,
                              'validate_version': validate_version
                          },
                          element_cls=blueprint.BlueprintImporter,
                          strict=False)
    resource_base = [result['resource_base']]
    if additional_resource_sources:
        resource_base.extend(additional_resource_sources)

    merged_blueprint_holder = result['merged_blueprint']

    # parse blueprint
    plan = parser.parse(value=merged_blueprint_holder,
                        inputs={
                            'resource_base': resource_base,
                            'validate_version': validate_version
                        },
                        element_cls=blueprint.Blueprint)

    functions.validate_functions(plan)
    return plan
    def test_marking(self):
        main_yaml = self.BASIC_VERSION_SECTION_DSL_1_3 + """
imports:
    -   http://www.getcloudify.org/spec/cloudify/4.5/types.yaml

node_types:
  test_type:
    properties:
      prop1:
        default: value
"""
        resolver = DefaultImportResolver()
        merged_blueprint = parse_from_import_blueprint(
            dsl_location=None,
            dsl_string=main_yaml,
            resolver=resolver,
            resources_base_path=None)
        _, node_types = merged_blueprint.get_item(constants.NODE_TYPES)
        _, root_type = node_types.get_item('cloudify.nodes.Root')
        _, test_type = node_types.get_item('test_type')
        self.assertEqual(root_type.is_cloudify_type, True)
        self.assertEqual(test_type.is_cloudify_type, False)
示例#17
0
 def test_no_configuration_specified(self):
     self._test_create_import_resolver(
         expected_resolver=DefaultImportResolver(),
         expected_params_name=DEFAULT_RESLOVER_RULES_KEY)
示例#18
0
 def test_parse_dsl_from_file_bad_path(self):
     self.assertRaises(EnvironmentError, parse_from_path, 'fake-file.yaml',
                       DefaultImportResolver())
示例#19
0
                'parameters must be a dictionary and not {1}'
                .format(resolver_class_path or 'DefaultImportResolver',
                        type(parameters).__name__))
        try:
            if resolver_class_path:
                # custom import resolver
                return get_class_instance(resolver_class_path, parameters)
            else:
                # default import resolver
                return DefaultImportResolver(**parameters)
        except Exception, ex:
            raise ResolverInstantiationError(
                'Failed to instantiate resolver ({0}). {1}'
                .format(resolver_class_path or 'DefaultImportResolver',
                        str(ex)))
    return DefaultImportResolver()


def get_class_instance(class_path, properties):
    """Returns an instance of a class from a string formatted as module:class
    the given *args, **kwargs are passed to the instance's __init__"""
    if not properties:
        properties = {}
    try:
        cls = get_class(class_path)
        instance = cls(**properties)
    except Exception as e:
        exc_type, exc, traceback = sys.exc_info()
        raise RuntimeError('Failed to instantiate {0}, error: {1}'
                           .format(class_path, e)), None, traceback