示例#1
0
    def test_translate_storage_notation1(self):
        '''TOSCA template with single BlockStorage and Attachment.'''
        tosca_tpl = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "../toscalib/tests/data/storage/"
            "tosca_blockstorage_with_attachment_notation1.yaml")

        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, self.parsed_params)
        output = translate.translate()

        expected_resource_1 = {'type': 'OS::Cinder::VolumeAttachment',
                               'properties':
                               {'instance_uuid': 'my_web_app_tier_1',
                                'location': '/default_location',
                                'volume_id': 'my_storage'}}
        expected_resource_2 = {'type': 'OS::Cinder::VolumeAttachment',
                               'properties':
                               {'instance_uuid': 'my_web_app_tier_2',
                                'location': '/some_other_data_location',
                                'volume_id': 'my_storage'}}

        output_dict = translator.toscalib.utils.yamlparser.simple_parse(output)

        resources = output_dict.get('resources')
        self.assertIn('myattachto_1', resources.keys())
        self.assertIn('myattachto_2', resources.keys())
        self.assertIn(expected_resource_1, resources.values())
        self.assertIn(expected_resource_2, resources.values())
示例#2
0
    def test_translate_server_existing_network(self):
        '''TOSCA template with 1 server attached to existing network.'''
        tosca_tpl = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "../toscalib/tests/data/network/"
            "tosca_server_on_existing_network.yaml")

        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, self.parsed_params)
        output = translate.translate()

        expected_resource_1 = {'type': 'OS::Neutron::Port',
                               'properties':
                               {'network': {'get_param': 'network_name'}
                                }}

        expected_resource_2 = [{'port': {'get_resource': 'my_port'}}]

        output_dict = translator.toscalib.utils.yamlparser.simple_parse(output)

        resources = output_dict.get('resources')

        self.assertItemsEqual(resources.keys(), ['my_server', 'my_port'])

        self.assertEqual(resources.get('my_port'), expected_resource_1)

        self.assertIn('properties', resources.get('my_server'))
        self.assertIn('networks', resources.get('my_server').get('properties'))
        translated_resource = resources.get('my_server').\
            get('properties').get('networks')
        self.assertEqual(translated_resource, expected_resource_2)
示例#3
0
文件: engine.py 项目: dot-Sean/xos
    def __init__(self, tosca_yaml, parent_dir=None, log_to_console=False):
        # TOSCA will look for imports using a relative path from where the
        # template file is located, so we have to put the template file
        # in a specific place.
        if not parent_dir:
            parent_dir = os.getcwd()

        tmp_pathname = None
        try:
            (tmp_handle, tmp_pathname) = tempfile.mkstemp(dir=parent_dir)
            os.write(tmp_handle, tosca_yaml)
            os.close(tmp_handle)

            self.template = ToscaTemplate(tmp_pathname)
        except:
            traceback.print_exc()
            raise
        finally:
            if tmp_pathname:
                os.remove(tmp_pathname)

        self.log_to_console = log_to_console
        self.log_msgs = []

        self.compute_dependencies()

        self.deferred_sync = []

        self.ordered_nodetemplates = []
        self.ordered_names = self.topsort_dependencies()
        print "ordered_names", self.ordered_names
        for name in self.ordered_names:
            if name in self.nodetemplates_by_name:
                self.ordered_nodetemplates.append(
                    self.nodetemplates_by_name[name])
示例#4
0
    def test_template_requirements(self):
        """Test different formats of requirements

        The requirements can be defined in few different ways,
        1. Requirement expressed as a capability with an implicit relationship.
        2. Requirement expressed with explicit relationship.
        3. Requirement expressed with a relationship template.
        4. Requirement expressed via TOSCA types to provision a node
           with explicit relationship.
        5. Requirement expressed via TOSCA types with a filter.
        """
        tosca_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 "data/test_requirements.yaml")
        tosca = ToscaTemplate(tosca_tpl)
        for node_tpl in tosca.nodetemplates:
            if node_tpl.name == 'my_app':
                expected_relationship = [
                    ('tosca.relationships.ConnectsTo', 'mysql_database'),
                    ('tosca.relationships.HostedOn', 'my_webserver')
                ]
                actual_relationship = sorted([
                    (relation.type, node.name)
                    for relation, node in node_tpl.relationships.items()
                ])
                self.assertEqual(expected_relationship, actual_relationship)
            if node_tpl.name == 'mysql_database':
                self.assertEqual(
                    [('tosca.relationships.HostedOn', 'my_dbms')],
                    [(relation.type, node.name)
                     for relation, node in node_tpl.relationships.items()])
            if node_tpl.name == 'my_server':
                self.assertEqual(
                    [('tosca.relationships.AttachesTo', 'my_storage')],
                    [(relation.type, node.name)
                     for relation, node in node_tpl.relationships.items()])
示例#5
0
    def test_translate_multi_storage(self):
        '''TOSCA template with multiple BlockStorage and Attachment.'''
        tosca_tpl = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "../toscalib/tests/data/storage/"
            "tosca_multiple_blockstorage_with_attachment.yaml")
        tosca = ToscaTemplate(tosca_tpl)
        translated_volume_attachment = []
        translate = TOSCATranslator(tosca, self.parsed_params)
        output = translate.translate()

        expected_resource_1 = {'type': 'OS::Cinder::VolumeAttachment',
                               'properties':
                               {'instance_uuid': 'my_server',
                                'location': {'get_param': 'storage_location'},
                                'volume_id': 'my_storage'}}

        expected_resource_2 = {'type': 'OS::Cinder::VolumeAttachment',
                               'properties':
                               {'instance_uuid': 'my_server2',
                                'location': {'get_param': 'storage_location'},
                                'volume_id': 'my_storage2'}}

        output_dict = translator.toscalib.utils.yamlparser.simple_parse(output)
        resources = output_dict.get('resources')
        translated_volume_attachment.append(resources.get('attachesto_1'))
        translated_volume_attachment.append(resources.get('attachesto_2'))
        self.assertIn(expected_resource_1, translated_volume_attachment)
        self.assertIn(expected_resource_2, translated_volume_attachment)
示例#6
0
    def test_translate_output(self):
        tosca_tpl = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "../../toscalib/tests/data/"
            "tosca_nodejs_mongodb_two_instances.yaml")
        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, [])
        hot_translation = translate.translate()

        expected_output = {'nodejs_url':
                           {'description': 'URL for the nodejs '
                            'server, http://<IP>:3000',
                            'value':
                            {'get_attr':
                             ['app_server', 'networks', 'private', 0]}},
                           'mongodb_url':
                           {'description': 'URL for the mongodb server.',
                            'value':
                            {'get_attr':
                             ['mongo_server', 'networks', 'private', 0]}}}

        hot_translation_dict = \
            translator.toscalib.utils.yamlparser.simple_parse(hot_translation)

        outputs = hot_translation_dict.get('outputs')
        for resource_name in outputs:
            translated_value = outputs.get(resource_name)
            expected_value = expected_output.get(resource_name)
            self.assertEqual(translated_value, expected_value)
示例#7
0
    def _load_template(self, filename):
        """Load a Tosca template from tests data folder.

        :param filename: Tosca template file name to load.
        :return: ToscaTemplate
        """
        return ToscaTemplate(os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            'data',
            filename))
示例#8
0
    def test_translate_three_networks_single_server(self):
        '''TOSCA template with three Networks and single Compute.'''
        tosca_tpl = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "../toscalib/tests/data/network/"
            "tosca_one_server_three_networks.yaml")

        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, self.parsed_params)
        output = translate.translate()

        output_dict = translator.toscalib.utils.yamlparser.simple_parse(output)

        resources = output_dict.get('resources')

        for net_num in range(1, 4):
            net_name = 'my_network%d' % (net_num)
            subnet_name = '%s_subnet' % (net_name)
            port_name = 'my_port%d' % (net_num)

            expected_resource_net = {'type': 'OS::Neutron::Net',
                                     'properties':
                                     {'name': 'net%d' % (net_num)
                                      }}

            expected_resource_subnet = {'type': 'OS::Neutron::Subnet',
                                        'properties':
                                       {'cidr': '192.168.%d.0/24' % (net_num),
                                        'ip_version': 4,
                                        'network': {'get_resource': net_name}
                                        }}

            expected_resource_port = {'type': 'OS::Neutron::Port',
                                      'depends_on': [net_name],
                                      'properties':
                                      {'network': {'get_resource': net_name}
                                       }}
            self.assertIn(net_name, resources.keys())
            self.assertIn(subnet_name, resources.keys())
            self.assertIn(port_name, resources.keys())

            self.assertEqual(resources.get(net_name), expected_resource_net)
            self.assertEqual(resources.get(subnet_name),
                             expected_resource_subnet)
            self.assertEqual(resources.get(port_name), expected_resource_port)

        self.assertIn('properties', resources.get('my_server'))
        self.assertIn('networks', resources.get('my_server').get('properties'))
        translated_resource = resources.get('my_server').\
            get('properties').get('networks')

        expected_srv_networks = [{'port': {'get_resource': 'my_port1'}},
                                 {'port': {'get_resource': 'my_port2'}},
                                 {'port': {'get_resource': 'my_port3'}}]
        self.assertEqual(translated_resource, expected_srv_networks)
示例#9
0
    def test_translate_single_network_single_server(self):
        '''TOSCA template with single Network and single Compute.'''
        tosca_tpl = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "../toscalib/tests/data/network/"
            "tosca_one_server_one_network.yaml")

        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, self.parsed_params)
        output = translate.translate()

        expected_resource_1 = {'type': 'OS::Neutron::Net',
                               'properties':
                               {'name': {'get_param': 'network_name'}
                                }}

        expected_resource_2 = {'type': 'OS::Neutron::Subnet',
                               'properties':
                               {'cidr': '192.168.0.0/24',
                                'ip_version': 4,
                                'allocation_pools': [{'start': '192.168.0.50',
                                                     'end': '192.168.0.200'}],
                                'gateway_ip': '192.168.0.1',
                                'network': {'get_resource': 'my_network'}
                                }}

        expected_resource_3 = {'type': 'OS::Neutron::Port',
                               'depends_on': ['my_network'],
                               'properties':
                               {'network': {'get_resource': 'my_network'}
                                }}

        expected_resource_4 = [{'port': {'get_resource': 'my_port'}}]

        output_dict = translator.toscalib.utils.yamlparser.simple_parse(output)

        resources = output_dict.get('resources')

        self.assertIn('my_network', resources.keys())
        self.assertIn('my_network_subnet', resources.keys())
        self.assertIn('my_port', resources.keys())
        self.assertIn('my_server', resources.keys())

        self.assertEqual(resources.get('my_network'), expected_resource_1)
        self.assertEqual(resources.get('my_network_subnet'),
                         expected_resource_2)
        self.assertEqual(resources.get('my_port'), expected_resource_3)

        self.assertIn('properties', resources.get('my_server'))
        self.assertIn('networks', resources.get('my_server').get('properties'))
        translated_resource = resources.get('my_server').\
            get('properties').get('networks')
        self.assertEqual(translated_resource, expected_resource_4)
示例#10
0
 def test_relationship_interface(self):
     template = ToscaTemplate(self.tosca_elk_tpl)
     for node_tpl in template.nodetemplates:
         if node_tpl.name == 'nodejs':
             config_interface = 'tosca.interfaces.relationship.Configure'
             relation = node_tpl.relationships
             for key in relation.keys():
                 rel_tpl = relation.get(key).get_relationship_template()
                 interfaces = rel_tpl[0].interfaces
                 for interface in interfaces:
                     self.assertEqual(config_interface, interface.type)
                     self.assertEqual('pre_configure_source',
                                      interface.name)
                     self.assertEqual('nodejs/pre_configure_source.sh',
                                      interface.implementation)
示例#11
0
    def test_translate_output_order(self):
        tosca_yaml_file = "data/tosca_single_server.yaml"
        tosca_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 tosca_yaml_file)
        parsed_params = {'cpus': 2}
        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, parsed_params)
        hot_translated_output = translate.translate()

        #load expected hot yaml file
        hot_yaml_file = "data/hot_output/hot_single_server.yaml"
        hot_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                               hot_yaml_file)
        with open(hot_tpl) as f:
            hot_expected_output = f.read()

        #compare generated and expected hot templates
        status = CompareUtils.compare_hot_yamls(hot_translated_output,
                                                hot_expected_output)
        self.assertEqual(status, True)
示例#12
0
def parse_metafile(tmpdir):
    # Parse the TOSCA.meta file looking for yaml definitions
    # TODO This may be unnecessary if/when toscalib does it
    if not os.path.isfile(tmpdir + "/TOSCA-Metadata/TOSCA.meta"):
        print "Error: TOSCA.meta not found in CSAR file"
        sys.exit(1)
    try:
        tfile = open(tmpdir + '/TOSCA-Metadata/TOSCA.meta', 'r')
    except (IOError, OSError):
        print "Error: Couldn't open Tosca metafile"
        sys.exit(1)
    tlines = tfile.readlines()
    for line in tlines:
        if (line.startswith("Name")):
            attr, value = line.split(":", 2)
            # if it's a yaml file pointer, need to find it here, and parse it?
            logger.debug("Found yaml file: " + tmpdir + "/" + value.strip())
            # TODO Need to handle multiple yaml files
            tosca_tpl = os.path.join(tmpdir + "/" + value.strip())
            yamlcontent = ToscaTemplate(tosca_tpl)
            return yamlcontent
示例#13
0
    def test_normative_type_by_short_name(self):
        #test template with a short name Compute
        template = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "data/test_tosca_normative_type_by_shortname.yaml")

        tosca_tpl = ToscaTemplate(template)
        expected_type = "tosca.nodes.Compute"
        for tpl in tosca_tpl.nodetemplates:
            self.assertEqual(tpl.type, expected_type)
        for tpl in tosca_tpl.nodetemplates:
            compute_type = NodeType(tpl.type)
            self.assertEqual(
                sorted([
                    'tosca.capabilities.Container',
                    'tosca.capabilities.OperatingSystem',
                    'tosca.capabilities.network.Bindable',
                    'tosca.capabilities.Scalable'
                ]),
                sorted(
                    [c.type for c in compute_type.get_capabilities_objects()]))
示例#14
0
    def test_single_template_objectstore(self):
        tosca_yaml_file = "../toscalib/tests/data/storage/" + \
            "tosca_single_object_store.yaml"
        tosca_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 tosca_yaml_file)
        parsed_params = {'objectstore_name': 'test_obj_store'}
        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, parsed_params)
        hot_translated_output = translate.translate()

        #load expected hot yaml file
        hot_yaml_file = "../toscalib/tests/data/hot_output/" + \
            "hot_single_object_store.yaml"
        hot_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                               hot_yaml_file)
        with open(hot_tpl) as f:
            hot_expected_output = f.read()

        #compare generated and expected hot templates
        status = CompareUtils.compare_hot_yamls(hot_translated_output,
                                                hot_expected_output)
        self.assertEqual(status, True)
示例#15
0
    def test_translate_single_storage(self):
        '''TOSCA template with single BlockStorage and Attachment.'''
        tosca_tpl = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "../toscalib/tests/data/storage/"
            "tosca_blockstorage_with_attachment.yaml")
        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, self.parsed_params)
        output = translate.translate()

        expected_resouce = {'attachesto_1':
                            {'type': 'OS::Cinder::VolumeAttachment',
                             'properties':
                             {'instance_uuid': 'my_server',
                              'location': {'get_param': 'storage_location'},
                              'volume_id': 'my_storage'}}}

        output_dict = translator.toscalib.utils.yamlparser.simple_parse(output)

        resources = output_dict.get('resources')
        translated_value = resources.get('attachesto_1')
        expected_value = expected_resouce.get('attachesto_1')
        self.assertEqual(translated_value, expected_value)

        outputs = output_dict['outputs']
        self.assertIn('private_ip', outputs)
        self.assertEqual(
            'Private IP address of the newly created compute instance.',
            outputs['private_ip']['description'])
        self.assertEqual({'get_attr': ['my_server', 'networks', 'private', 0]},
                         outputs['private_ip']['value'])
        self.assertIn('volume_id', outputs)
        self.assertEqual('The volume id of the block storage instance.',
                         outputs['volume_id']['description'])
        self.assertEqual({'get_resource': 'my_storage'},
                         outputs['volume_id']['value'])
示例#16
0
    def test_translate_storage_notation2(self):
        '''TOSCA template with single BlockStorage and Attachment.'''
        tosca_tpl = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "../toscalib/tests/data/storage/"
            "tosca_blockstorage_with_attachment_notation2.yaml")

        tosca = ToscaTemplate(tosca_tpl)
        translate = TOSCATranslator(tosca, self.parsed_params)
        output = translate.translate()

        expected_resource_1 = {'type': 'OS::Cinder::VolumeAttachment',
                               'properties':
                               {'instance_uuid': 'my_web_app_tier_1',
                                'location': '/my_data_location',
                                'volume_id': 'my_storage'}}
        expected_resource_2 = {'type': 'OS::Cinder::VolumeAttachment',
                               'properties':
                               {'instance_uuid': 'my_web_app_tier_2',
                                'location': '/some_other_data_location',
                                'volume_id': 'my_storage'}}

        output_dict = translator.toscalib.utils.yamlparser.simple_parse(output)

        resources = output_dict.get('resources')
        # Resource name suffix depends on nodetemplates order in dict, which is
        # not certain. So we have two possibilities of resources name.
        if resources.get('storage_attachesto_1_1'):
            self.assertIn('storage_attachesto_1_1', resources.keys())
            self.assertIn('storage_attachesto_2_2', resources.keys())
        else:
            self.assertIn('storage_attachesto_1_2', resources.keys())
            self.assertIn('storage_attachesto_2_1', resources.keys())

        self.assertIn(expected_resource_1, resources.values())
        self.assertIn(expected_resource_2, resources.values())
示例#17
0
class ToscaTemplateTest(TestCase):
    '''TOSCA template.'''
    tosca_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             "data/tosca_single_instance_wordpress.yaml")
    tosca = ToscaTemplate(tosca_tpl)

    tosca_elk_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 "data/tosca_elk.yaml")

    def test_version(self):
        self.assertEqual(self.tosca.version, "tosca_simple_yaml_1_0_0")

    def test_description(self):
        expected_description = "TOSCA simple profile with wordpress, " \
                               "web server and mysql on the same server."
        self.assertEqual(self.tosca.description, expected_description)

    def test_inputs(self):
        self.assertEqual(
            ['cpus', 'db_name', 'db_port', 'db_pwd', 'db_root_pwd', 'db_user'],
            sorted([input.name for input in self.tosca.inputs]))

        input_name = "db_port"
        expected_description = "Port for the MySQL database."
        for input in self.tosca.inputs:
            if input.name == input_name:
                self.assertEqual(input.description, expected_description)

    def test_node_tpls(self):
        '''Test nodetemplate names.'''
        self.assertEqual([
            'mysql_database', 'mysql_dbms', 'server', 'webserver', 'wordpress'
        ], sorted([tpl.name for tpl in self.tosca.nodetemplates]))

        tpl_name = "mysql_database"
        expected_type = "tosca.nodes.Database"
        expected_properties = ['db_name', 'db_password', 'db_user']
        expected_capabilities = ['database_endpoint']
        expected_requirements = [{'host': 'mysql_dbms'}]
        expected_relationshp = ['tosca.relationships.HostedOn']
        expected_host = ['mysql_dbms']
        expected_interface = [ifaces.LIFECYCLE]

        for tpl in self.tosca.nodetemplates:
            if tpl_name == tpl.name:
                '''Test node type.'''
                self.assertEqual(tpl.type, expected_type)
                '''Test properties.'''
                self.assertEqual(expected_properties,
                                 sorted(tpl.get_properties().keys()))
                '''Test capabilities.'''
                self.assertEqual(expected_capabilities,
                                 sorted(tpl.get_capabilities().keys()))
                '''Test requirements.'''
                self.assertEqual(expected_requirements, tpl.requirements)
                '''Test relationship.'''
                self.assertEqual(expected_relationshp,
                                 [x.type for x in tpl.relationships.keys()])
                self.assertEqual(expected_host,
                                 [y.name for y in tpl.relationships.values()])
                '''Test interfaces.'''
                self.assertEqual(expected_interface,
                                 [x.type for x in tpl.interfaces])

            if tpl.name == 'server':
                '''Test property value'''
                props = tpl.get_properties()
                if props and 'mem_size' in props.keys():
                    self.assertEqual(props['mem_size'].value, '4096 MB')
                '''Test capability'''
                caps = tpl.get_capabilities()
                self.assertIn('os', caps.keys())
                os_props_objs = None
                os_props = None
                os_type_prop = None
                if caps and 'os' in caps.keys():
                    capability = caps['os']
                    os_props_objs = capability.get_properties_objects()
                    os_props = capability.get_properties()
                    os_type_prop = capability.get_property_value('type')
                    break
                self.assertEqual(
                    ['Linux'],
                    [p.value for p in os_props_objs if p.name == 'type'])
                self.assertEqual(
                    'Linux',
                    os_props['type'].value if 'type' in os_props else '')
                self.assertEqual('Linux', os_props['type'].value)
                self.assertEqual('Linux', os_type_prop)

    def test_outputs(self):
        self.assertEqual(['website_url'],
                         sorted([output.name
                                 for output in self.tosca.outputs]))

    def test_interfaces(self):
        wordpress_node = [
            node for node in self.tosca.nodetemplates
            if node.name == 'wordpress'
        ][0]
        interfaces = wordpress_node.interfaces
        self.assertEqual(2, len(interfaces))
        for interface in interfaces:
            if interface.name == 'create':
                self.assertEqual(ifaces.LIFECYCLE, interface.type)
                self.assertEqual('wordpress/wordpress_install.sh',
                                 interface.implementation)
                self.assertIsNone(interface.inputs)
            elif interface.name == 'configure':
                self.assertEqual(ifaces.LIFECYCLE, interface.type)
                self.assertEqual('wordpress/wordpress_configure.sh',
                                 interface.implementation)
                self.assertEqual(4, len(interface.inputs))
                wp_db_port = interface.inputs['wp_db_port']
                self.assertTrue(isinstance(wp_db_port, GetProperty))
                self.assertEqual('get_property', wp_db_port.name)
                self.assertEqual(['SELF', 'database_endpoint', 'port'],
                                 wp_db_port.args)
                result = wp_db_port.result()
                self.assertTrue(isinstance(result, GetInput))
            else:
                raise AssertionError('Unexpected interface: {0}'.format(
                    interface.name))

    def test_normative_type_by_short_name(self):
        #test template with a short name Compute
        template = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "data/test_tosca_normative_type_by_shortname.yaml")

        tosca_tpl = ToscaTemplate(template)
        expected_type = "tosca.nodes.Compute"
        for tpl in tosca_tpl.nodetemplates:
            self.assertEqual(tpl.type, expected_type)
        for tpl in tosca_tpl.nodetemplates:
            compute_type = NodeType(tpl.type)
            self.assertEqual(
                sorted([
                    'tosca.capabilities.Container',
                    'tosca.capabilities.OperatingSystem',
                    'tosca.capabilities.network.Bindable',
                    'tosca.capabilities.Scalable'
                ]),
                sorted(
                    [c.type for c in compute_type.get_capabilities_objects()]))

    def test_template_with_no_inputs(self):
        tosca_tpl = self._load_template('test_no_inputs_in_template.yaml')
        self.assertEqual(0, len(tosca_tpl.inputs))

    def test_template_with_no_outputs(self):
        tosca_tpl = self._load_template('test_no_outputs_in_template.yaml')
        self.assertEqual(0, len(tosca_tpl.outputs))

    def test_relationship_interface(self):
        template = ToscaTemplate(self.tosca_elk_tpl)
        for node_tpl in template.nodetemplates:
            if node_tpl.name == 'nodejs':
                config_interface = 'tosca.interfaces.relationship.Configure'
                relation = node_tpl.relationships
                for key in relation.keys():
                    rel_tpl = relation.get(key).get_relationship_template()
                    interfaces = rel_tpl[0].interfaces
                    for interface in interfaces:
                        self.assertEqual(config_interface, interface.type)
                        self.assertEqual('pre_configure_source',
                                         interface.name)
                        self.assertEqual('nodejs/pre_configure_source.sh',
                                         interface.implementation)

    def test_template_macro(self):
        template = ToscaTemplate(self.tosca_elk_tpl)
        for node_tpl in template.nodetemplates:
            if node_tpl.name == 'mongo_server':
                self.assertEqual(['disk_size', 'mem_size', 'num_cpus'],
                                 sorted(node_tpl.get_properties().keys()))

    def test_template_requirements(self):
        """Test different formats of requirements

        The requirements can be defined in few different ways,
        1. Requirement expressed as a capability with an implicit relationship.
        2. Requirement expressed with explicit relationship.
        3. Requirement expressed with a relationship template.
        4. Requirement expressed via TOSCA types to provision a node
           with explicit relationship.
        5. Requirement expressed via TOSCA types with a filter.
        """
        tosca_tpl = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 "data/test_requirements.yaml")
        tosca = ToscaTemplate(tosca_tpl)
        for node_tpl in tosca.nodetemplates:
            if node_tpl.name == 'my_app':
                expected_relationship = [
                    ('tosca.relationships.ConnectsTo', 'mysql_database'),
                    ('tosca.relationships.HostedOn', 'my_webserver')
                ]
                actual_relationship = sorted([
                    (relation.type, node.name)
                    for relation, node in node_tpl.relationships.items()
                ])
                self.assertEqual(expected_relationship, actual_relationship)
            if node_tpl.name == 'mysql_database':
                self.assertEqual(
                    [('tosca.relationships.HostedOn', 'my_dbms')],
                    [(relation.type, node.name)
                     for relation, node in node_tpl.relationships.items()])
            if node_tpl.name == 'my_server':
                self.assertEqual(
                    [('tosca.relationships.AttachesTo', 'my_storage')],
                    [(relation.type, node.name)
                     for relation, node in node_tpl.relationships.items()])

    def test_template_requirements_not_implemented(self):
        #TODO(spzala) replace this test with new one once TOSCA types look up
        #support is implemented.
        """Requirements that yet need to be implemented

        The following requirement formats are not yet implemented,
        due to look up dependency:
        1. Requirement expressed via TOSCA types to provision a node
           with explicit relationship.
        2. Requirement expressed via TOSCA types with a filter.
        """
        tpl_snippet_1 = '''
        node_templates:
          mysql_database:
            type: tosca.nodes.Database
            description: Requires a particular node type and relationship.
                        To be full-filled via lookup into node repository.
            requirements:
              - req1:
                  node: tosca.nodes.DBMS
                  relationship: tosca.relationships.HostedOn
        '''

        tpl_snippet_2 = '''
        node_templates:
          my_webserver:
            type: tosca.nodes.WebServer
            description: Requires a particular node type with a filter.
                         To be full-filled via lookup into node repository.
            requirements:
              - req1:
                  node: tosca.nodes.Compute
                  target_filter:
                    properties:
                      num_cpus: { in_range: [ 1, 4 ] }
                      mem_size: { greater_or_equal: 2 }
                    capabilities:
                      - tosca.capabilities.OS:
                          properties:
                            architecture: x86_64
                            type: linux
        '''

        tpl_snippet_3 = '''
        node_templates:
          my_webserver2:
            type: tosca.nodes.WebServer
            description: Requires a node type with a particular capability.
                         To be full-filled via lookup into node repository.
            requirements:
              - req1:
                  node: tosca.nodes.Compute
                  relationship: tosca.relationships.HostedOn
                  capability: tosca.capabilities.Container
        '''
        self._requirements_not_implemented(tpl_snippet_1, 'mysql_database')
        self._requirements_not_implemented(tpl_snippet_2, 'my_webserver')
        self._requirements_not_implemented(tpl_snippet_3, 'my_webserver2')

    def _requirements_not_implemented(self, tpl_snippet, tpl_name):
        nodetemplates = (translator.toscalib.utils.yamlparser.simple_parse(
            tpl_snippet))['node_templates']
        self.assertRaises(
            NotImplementedError,
            lambda: NodeTemplate(tpl_name, nodetemplates).relationships)

    def test_custom_capability_type_definition(self):
        tpl_snippet = '''
        node_templates:
          test_app:
            type: tosca.nodes.WebApplication.TestApp
            capabilities:
              test_cap:
                properties:
                  test: 1
        '''
        #custom definition with capability type definition
        custom_def = '''
        tosca.nodes.WebApplication.TestApp:
          derived_from: tosca.nodes.WebApplication
          capabilities:
            test_cap:
               type: tosca.capabilities.TestCapability
        tosca.capabilities.TestCapability:
          derived_from: tosca.capabilities.Root
          properties:
            test:
              type: integer
              required: no
        '''
        expected_capabilities = ['test_cap']
        nodetemplates = (translator.toscalib.utils.yamlparser.simple_parse(
            tpl_snippet))['node_templates']
        custom_def = (
            translator.toscalib.utils.yamlparser.simple_parse(custom_def))
        name = list(nodetemplates.keys())[0]
        tpl = NodeTemplate(name, nodetemplates, custom_def)
        self.assertEqual(expected_capabilities,
                         sorted(tpl.get_capabilities().keys()))

        #custom definition without capability type definition
        custom_def = '''
        tosca.nodes.WebApplication.TestApp:
          derived_from: tosca.nodes.WebApplication
          capabilities:
            test_cap:
               type: tosca.capabilities.TestCapability
        '''
        custom_def = (
            translator.toscalib.utils.yamlparser.simple_parse(custom_def))
        tpl = NodeTemplate(name, nodetemplates, custom_def)
        err = self.assertRaises(
            exception.InvalidTypeError, lambda: NodeTemplate(
                name, nodetemplates, custom_def).get_capabilities_objects())
        self.assertEqual(
            'Type "tosca.capabilities.TestCapability" is not '
            'a valid type.', six.text_type(err))
示例#18
0
class IntrinsicFunctionsTest(TestCase):

    tosca_tpl = os.path.join(
        os.path.dirname(os.path.abspath(__file__)),
        "data/tosca_single_instance_wordpress.yaml")
    tosca = ToscaTemplate(tosca_tpl)

    def _get_node(self, node_name):
        return [
            node for node in self.tosca.nodetemplates
            if node.name == node_name][0]

    def _get_operation(self, interfaces, operation):
        return [
            interface for interface in interfaces
            if interface.name == operation][0]

    def _get_property(self, node_template, property_name):
        return [prop.value for prop in node_template.get_properties_objects()
                if prop.name == property_name][0]

    def test_get_property(self):
        mysql_dbms = self._get_node('mysql_dbms')
        operation = self._get_operation(mysql_dbms.interfaces, 'configure')
        db_root_password = operation.inputs['db_root_password']
        self.assertTrue(isinstance(db_root_password, functions.GetProperty))
        result = db_root_password.result()
        self.assertTrue(isinstance(result, functions.GetInput))

    def test_get_requirement_property(self):
        wordpress = self._get_node('wordpress')
        operation = self._get_operation(wordpress.interfaces, 'configure')
        wp_db_port = operation.inputs['wp_db_port']
        self.assertTrue(isinstance(wp_db_port, functions.GetProperty))
        result = wp_db_port.result()
        self.assertTrue(isinstance(result, functions.GetInput))
        self.assertEqual('db_port', result.input_name)

    def test_get_capability_property(self):
        mysql_database = self._get_node('mysql_database')
        operation = self._get_operation(mysql_database.interfaces, 'configure')
        db_port = operation.inputs['db_port']
        self.assertTrue(isinstance(db_port, functions.GetProperty))
        result = db_port.result()
        self.assertTrue(isinstance(result, functions.GetInput))
        self.assertEqual('db_port', result.input_name)

    def test_unknown_capability_property(self):
        err = self.assertRaises(
            KeyError,
            self._load_template,
            'functions/test_unknown_capability_property.yaml')
        self.assertIn("'unknown'", six.text_type(err))
        self.assertIn("'database_endpoint'", six.text_type(err))
        self.assertIn("'database'", six.text_type(err))

    def test_get_input_in_properties(self):
        mysql_dbms = self._get_node('mysql_dbms')
        expected_inputs = ['db_root_pwd', 'db_port']
        props = mysql_dbms.get_properties()
        for key in props.keys():
            prop = props[key]
            self.assertTrue(isinstance(prop.value, functions.GetInput))
            expected_inputs.remove(prop.value.input_name)
        self.assertListEqual(expected_inputs, [])

    def test_get_input_in_interface(self):
        mysql_dbms = self._get_node('mysql_dbms')
        operation = self._get_operation(mysql_dbms.interfaces, 'configure')
        db_user = operation.inputs['db_user']
        self.assertTrue(isinstance(db_user, functions.GetInput))

    def test_get_input_validation(self):
        self.assertRaises(exception.UnknownInputError,
                          self._load_template,
                          'functions/test_unknown_input_in_property.yaml')
        self.assertRaises(exception.UnknownInputError,
                          self._load_template,
                          'functions/test_unknown_input_in_interface.yaml')

    def test_get_input_default_value_result(self):
        mysql_dbms = self._get_node('mysql_dbms')
        dbms_port = self._get_property(mysql_dbms, 'dbms_port')
        self.assertEqual(3306, dbms_port.result())
        dbms_root_password = self._get_property(mysql_dbms,
                                                'dbms_root_password')
        self.assertIsNone(dbms_root_password.result())
示例#19
0
 def test_template_macro(self):
     template = ToscaTemplate(self.tosca_elk_tpl)
     for node_tpl in template.nodetemplates:
         if node_tpl.name == 'mongo_server':
             self.assertEqual(['disk_size', 'mem_size', 'num_cpus'],
                              sorted(node_tpl.get_properties().keys()))
示例#20
0
 def test_well_defined_template(self):
     tpl_path = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "data/tosca_single_instance_wordpress.yaml")
     self.assertIsNotNone(ToscaTemplate(tpl_path))
示例#21
0
class ToscaMongoNodejsTest(TestCase):
    parsed_params = {
        'storage_snapshot_id': 'test_id',
        'storage_location': '/test',
        'cpus': '1',
        'storage_size': '1'
    }
    '''TOSCA template with nodejs, app and mongodb on 2 servers.'''
    tosca_tpl = os.path.join(
        os.path.dirname(os.path.abspath(__file__)),
        "../toscalib/tests/data/tosca_nodejs_mongodb_two_instances.yaml")
    tosca = ToscaTemplate(tosca_tpl)

    def test_relationship_def(self):
        expected_relationship = ['tosca.relationships.HostedOn']
        expected_capabilities_names = ['host']
        for tpl in self.tosca.nodetemplates:
            if tpl.name == 'nodejs':
                def_keys = tpl.type_definition.relationship.keys()
                self.assertEqual(expected_relationship,
                                 sorted([x.type for x in def_keys]))
                self.assertEqual(expected_capabilities_names,
                                 sorted([x.capability_name for x in def_keys]))

    def test_relationships(self):
        expected_relationship = ['tosca.relationships.HostedOn']
        expected_relatednodes = ['app_server']
        for tpl in self.tosca.nodetemplates:
            rels = tpl.relationships
            if rels:
                if tpl.name == 'nodejs':
                    self.assertEqual(
                        expected_relationship,
                        sorted([x.type for x in tpl.relationships.keys()]))
                    self.assertEqual(
                        expected_relatednodes,
                        sorted([y.name for y in tpl.relationships.values()]))

    def test_related_nodes(self):
        expected_nodejs = ['app_server']
        actual_nodejs = []
        for tpl in self.tosca.nodetemplates:
            if tpl.name == 'nodejs':
                for node in tpl.related_nodes:
                    actual_nodejs.append(node.name)
        self.assertEqual(sorted(actual_nodejs), expected_nodejs)

    def test_translate_nodejs_mongodb(self):
        translate = TOSCATranslator(self.tosca, self.parsed_params)
        output = translate.translate()

        expected_resource = {
            'mongo_dbms_create_config': {
                'properties': {
                    'config': {
                        'get_file': 'mongodb/create.sh'
                    },
                    'group': 'script'
                },
                'type': 'OS::Heat::SoftwareConfig'
            },
            'mongo_dbms_configure_config': {
                'properties': {
                    'config': {
                        'get_file': 'mongodb/config.sh'
                    },
                    'group': 'script'
                },
                'type': 'OS::Heat::SoftwareConfig'
            },
            'mongo_dbms_start_config': {
                'properties': {
                    'config': {
                        'get_file': 'mongodb/start.sh'
                    },
                    'group': 'script'
                },
                'type': 'OS::Heat::SoftwareConfig'
            },
            'nodejs_create_config': {
                'properties': {
                    'config': {
                        'get_file': 'nodejs/create.sh'
                    },
                    'group': 'script'
                },
                'type': 'OS::Heat::SoftwareConfig'
            },
            'nodejs_configure_config': {
                'properties': {
                    'config': {
                        'get_file': 'nodejs/config.sh'
                    },
                    'group': 'script'
                },
                'type': 'OS::Heat::SoftwareConfig'
            },
            'nodejs_start_config': {
                'properties': {
                    'config': {
                        'get_file': 'nodejs/start.sh'
                    },
                    'group': 'script'
                },
                'type': 'OS::Heat::SoftwareConfig'
            },
            'mongo_dbms_create_deploy': {
                'properties': {
                    'config': {
                        'get_resource': 'mongo_dbms_create_config'
                    },
                    'server': {
                        'get_resource': 'mongo_server'
                    }
                },
                'type': 'OS::Heat::SoftwareDeployment'
            },
            'mongo_dbms_configure_deploy': {
                'type': 'OS::Heat::SoftwareDeployment',
                'depends_on': ['mongo_dbms_create_deploy'],
                'properties': {
                    'config': {
                        'get_resource': 'mongo_dbms_configure_config'
                    },
                    'input_values': {
                        'mongodb_ip': {
                            'get_attr':
                            ['mongo_server', 'networks', 'private', 0]
                        }
                    },
                    'server': {
                        'get_resource': 'mongo_server'
                    }
                }
            },
            'mongo_dbms_start_deploy': {
                'type': 'OS::Heat::SoftwareDeployment',
                'depends_on': ['mongo_dbms_configure_deploy'],
                'properties': {
                    'config': {
                        'get_resource': 'mongo_dbms_start_config'
                    },
                    'server': {
                        'get_resource': 'mongo_server'
                    }
                }
            },
            'nodejs_create_deploy': {
                'properties': {
                    'config': {
                        'get_resource': 'nodejs_create_config'
                    },
                    'server': {
                        'get_resource': 'app_server'
                    }
                },
                'type': 'OS::Heat::SoftwareDeployment'
            },
            'nodejs_configure_deploy': {
                'depends_on': ['nodejs_create_deploy'],
                'properties': {
                    'config': {
                        'get_resource': 'nodejs_configure_config'
                    },
                    'input_values': {
                        'github_url': 'https://github.com/sample.git',
                        'mongodb_ip': {
                            'get_attr':
                            ['mongo_server', 'networks', 'private', 0]
                        }
                    },
                    'server': {
                        'get_resource': 'app_server'
                    }
                },
                'type': 'OS::Heat::SoftwareDeployment'
            },
            'nodejs_start_deploy': {
                'depends_on': ['nodejs_configure_deploy'],
                'properties': {
                    'config': {
                        'get_resource': 'nodejs_start_config'
                    },
                    'server': {
                        'get_resource': 'app_server'
                    }
                },
                'type': 'OS::Heat::SoftwareDeployment'
            },
            'app_server': {
                'properties': {
                    'flavor': 'm1.medium',
                    'image': 'ubuntu-software-config-os-init',
                    'key_name': 'userkey',
                    'user_data_format': 'SOFTWARE_CONFIG'
                },
                'type': 'OS::Nova::Server'
            },
            'mongo_server': {
                'properties': {
                    'flavor': 'm1.medium',
                    'image': 'ubuntu-software-config-os-init',
                    'key_name': 'userkey',
                    'user_data_format': 'SOFTWARE_CONFIG'
                },
                'type': 'OS::Nova::Server'
            }
        }

        output_dict = translator.toscalib.utils.yamlparser.simple_parse(output)

        resources = output_dict.get('resources')
        for resource_name in resources:
            translated_value = resources.get(resource_name)
            expected_value = expected_resource.get(resource_name)
            self.assertEqual(translated_value, expected_value)
示例#22
0
 def test_datatype_in_template_positive(self):
     tpl_path = os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         "data/datatypes/test_custom_datatypes_positive.yaml")
     self.assertIsNotNone(ToscaTemplate(tpl_path))
示例#23
0
 def _load_template(self, filename):
     return ToscaTemplate(os.path.join(
         os.path.dirname(os.path.abspath(__file__)),
         'data',
         filename))