Esempio n. 1
0
def add_template(template, **kwargs):
    """
        Add template and a type and typeattrs.
    """
    tmpl = Template()
    tmpl.name = template.name
    tmpl.created_by = kwargs.get('user_id')
    if template.parent_id:
        tmpl.parent_id = template.parent_id
    if template.description:
        tmpl.description = template.description
    if template.layout:
        tmpl.layout = get_json_as_string(template.layout)
    if template.project_id:
        tmpl.project_id = template.project_id

    db.DBSession.add(tmpl)

    if template.templatetypes is not None:
        types = template.templatetypes
        for templatetype in types:
            ttype = _update_templatetype(templatetype, **kwargs)
            tmpl.templatetypes.append(ttype)

    db.DBSession.flush()

    log.info("[Added template]\n{}".format(template))

    return tmpl
Esempio n. 2
0
def add_child_template(parent_id, name, description=None, **kwargs):
    """
        Add template and a type and typeattrs.
    """
    parent_template = db.DBSession.query(Template).filter(
        Template.id == parent_id).one()

    tmpl = Template()
    tmpl.name = name
    if description is not None:
        tmpl.description = description
    else:
        tmpl.description = parent_template.description
    tmpl.layout = parent_template.layout
    tmpl.parent_id = parent_id

    #now add a default network type, but only if the parent has one defined
    parent_type = _get_network_type(parent_id)

    if parent_type is not None:

        network_type = TemplateType()

        network_type.name = "{}-network".format(tmpl.name)
        network_type.resource_type = 'NETWORK'
        network_type.parent_id = parent_type.id
        network_type.status = 'A'

        tmpl.templatetypes.append(network_type)
    else:
        log.warn(
            "Unable to set a network type on this template as its "
            "parent %s does not contain one, so cannot create a "
            "parent-child relationship.", parent_id)

    db.DBSession.add(tmpl)

    db.DBSession.flush()

    return tmpl
Esempio n. 3
0
def import_template_dict(template_dict, allow_update=True, **kwargs):

    user_id = kwargs.get('user_id')

    template_file_j = template_dict

    file_attributes = template_file_j.get('attributes')
    file_datasets = template_file_j.get('datasets', {})
    template_j = JSONObject(template_file_j.get('template', {}))

    #default datasets are optional, so don't force them to exist in the structure
    default_datasets_j = {}
    for k, v in file_datasets.items():
        default_datasets_j[int(k)] = Dataset(v)

    if file_attributes is None or len(template_j) == 0:
        raise HydraError("Invalid template. The template must have the following structure: " + \
                            "{'attributes':\\{...\\}, 'datasets':\\{...\\}, 'template':\\{...\\}}")

    #Normalise attribute IDs so they're always ints (in case they're specified as strings)
    attributes_j = {}
    for k, v in file_attributes.items():
        attributes_j[int(k)] = JSONObject(v)

    template_name = template_j.name
    template_description = template_j.description

    template_layout = None
    if template_j.layout is not None:
        if isinstance(template_j.layout, dict):
            template_layout = json.dumps(template_j.layout)
        else:
            template_layout = template_j.layout

    try:
        template_i = db.DBSession.query(Template).filter(
            Template.name == template_name).options(
                joinedload('templatetypes').joinedload('typeattrs').joinedload(
                    'attr')).one()
        if allow_update == False:
            raise HydraError("Existing Template Found with name %s" %
                             (template_name, ))
        else:
            template_i.layout = template_layout
            template_i.description = template_description
    except NoResultFound:
        log.debug("Template not found. Creating new one. name=%s",
                  template_name)
        template_i = Template(name=template_name,
                              description=template_description,
                              layout=template_layout)
        db.DBSession.add(template_i)

    types_j = template_j.templatetypes
    type_id_map = {r.id: r for r in template_i.templatetypes}
    #Delete any types which are in the DB but no longer in the JSON file
    type_name_map = {r.name: r.id for r in template_i.templatetypes}
    attr_name_map = {}
    for type_i in template_i.templatetypes:
        for typeattr in type_i.typeattrs:
            attr_name_map[typeattr.attr.name] = (typeattr.attr_id,
                                                 typeattr.type_id)

    existing_types = set([r.name for r in template_i.templatetypes])
    log.debug(
        ["%s : %s" % (tt.name, tt.id) for tt in template_i.templatetypes])
    log.debug("Existing types: %s", existing_types)

    new_types = set([t.name for t in types_j])
    log.debug("New Types: %s", new_types)

    types_to_delete = existing_types - new_types
    log.debug("Types to delete: %s", types_to_delete)
    log.debug(type_name_map)
    for type_to_delete in types_to_delete:
        type_id = type_name_map[type_to_delete]
        try:
            for i, tt in enumerate(template_i.templatetypes):
                if tt.id == type_id:
                    type_i = template_i.templatetypes[i]

                    #first remove all the type attributes associated to the type
                    for ta_i in type_i.typeattrs:
                        db.DBSession.delete(ta_i)

                    del (template_i.templatetypes[i])
                    log.debug("Deleting type %s (%s)", type_i.name, type_i.id)
                    del (type_name_map[type_to_delete])
                    db.DBSession.delete(type_i)
        except NoResultFound:
            pass

    #Add or update types.
    for type_j in types_j:
        type_name = type_j.name

        #check if the type is already in the DB. If not, create a new one.
        type_is_new = False
        if type_name in existing_types:
            type_id = type_name_map[type_name]
            type_i = type_id_map[type_id]
        else:
            log.debug("Type %s not found, creating new one.", type_name)
            type_i = TemplateType()
            type_i.name = type_name
            template_i.templatetypes.append(type_i)
            type_i.status = 'A'  ## defaults to active
            type_is_new = True

        if type_j.description is not None:
            type_i.description = type_j.description

        if type_j.alias is not None:
            type_i.alias = type_j.alias

        #Allow 'type' or 'resource_type' to be accepted
        if type_j.type is not None:
            type_i.resource_type = type_j.type
        elif type_j.resource_type is not None:
            type_i.resource_type = type_j.resource_type

        if type_j.resource_type is None:
            raise HydraError("No resource type specified."
                             " 'NODE', 'LINK', 'GROUP' or 'NETWORK'")

        if type_j.layout is not None:
            if isinstance(type_j, dict):
                type_i.layout = json.dumps(type_j.layout)
            else:
                type_i.layout = type_j.layout

        #delete any TypeAttrs which are in the DB but not in the JSON file
        existing_attrs = []
        if not type_is_new:
            for r in template_i.templatetypes:
                if r.name == type_name:
                    for typeattr in r.typeattrs:
                        existing_attrs.append(typeattr.attr.name)

        existing_attrs = set(existing_attrs)

        type_attrs = []
        for typeattr_j in type_j.typeattrs:
            if typeattr_j.attr_id is not None:
                attr_j = attributes_j[typeattr_j.attr_id].name
            elif typeattr_j.attr is not None:
                attr_j = typeattr_j.attr.name
            type_attrs.append(attr_j)

        type_attrs = set(type_attrs)

        attrs_to_delete = existing_attrs - type_attrs
        for attr_to_delete in attrs_to_delete:
            attr_id, type_id = attr_name_map[attr_to_delete]
            try:
                attr_i = db.DBSession.query(TypeAttr).filter(
                    TypeAttr.attr_id == attr_id,
                    TypeAttr.type_id == type_id).options(
                        joinedload('attr')).one()
                db.DBSession.delete(attr_i)
                log.debug("Attr %s in type %s deleted", attr_i.attr.name,
                          attr_i.templatetype.name)
            except NoResultFound:
                log.debug("Attr %s not found in type %s" % (attr_id, type_id))
                continue

        #Add or update type typeattrs
        #Support an external attribute dict or embedded attributes.
        for typeattr_j in type_j.typeattrs:
            if typeattr_j.attr_id is not None:
                attr_j = attributes_j[typeattr_j.attr_id]
            elif typeattr_j.attr is not None:
                attr_j = typeattr_j.attr

            default_dataset_j = None
            if typeattr_j.default_dataset is not None:
                default_dataset_j = typeattr_j.default_dataset
            elif typeattr_j.default is not None:  # for backward compatibility
                default_dataset_j = typeattr_j.default
            elif typeattr_j.default_dataset_id is not None:
                default_dataset_j = default_datasets_j[int(
                    typeattr_j.default_dataset_id)]

            parse_json_typeattr(type_i,
                                typeattr_j,
                                attr_j,
                                default_dataset_j,
                                user_id=user_id)

    db.DBSession.flush()

    return template_i
Esempio n. 4
0
def import_template_xml(template_xml, allow_update=True, **kwargs):
    """
        Add the template, type and typeattrs described
        in an XML file.

        Delete type, typeattr entries in the DB that are not in the XML file
        The assumption is that they have been deleted and are no longer required.
    """
    user_id = kwargs.get('user_id')

    template_xsd_path = config.get('templates', 'template_xsd_path')
    xmlschema_doc = etree.parse(template_xsd_path)

    xmlschema = etree.XMLSchema(xmlschema_doc)

    xml_tree = etree.fromstring(template_xml)

    xmlschema.assertValid(xml_tree)

    template_name = xml_tree.find('template_name').text
    template_description = xml_tree.find('template_description')
    if template_description is not None:
        template_description = template_description.text

    template_layout = None
    if xml_tree.find('layout') is not None and \
               xml_tree.find('layout').text is not None:
        layout = xml_tree.find('layout')
        layout_string = get_etree_layout_as_dict(layout)
        template_layout = json.dumps(layout_string)

    try:
        tmpl_i = db.DBSession.query(Template).filter(Template.name == template_name)\
            .options(joinedload('templatetypes')
            .joinedload('typeattrs')
            .joinedload('attr')).one()

        if allow_update == False:
            raise HydraError("Existing Template Found with name %s" %
                             (template_name, ))
        else:
            log.debug("Existing template found. name=%s", template_name)
            tmpl_i.layout = template_layout
            tmpl_i.description = template_description
    except NoResultFound:
        log.debug("Template not found. Creating new one. name=%s",
                  template_name)
        tmpl_i = Template(name=template_name,
                          description=template_description,
                          layout=template_layout)
        db.DBSession.add(tmpl_i)

    types = xml_tree.find('resources')
    #Delete any types which are in the DB but no longer in the XML file
    type_name_map = {r.name: r.id for r in tmpl_i.templatetypes}
    attr_name_map = {}
    for type_i in tmpl_i.templatetypes:
        for typeattr in type_i.typeattrs:
            attr_name_map[typeattr.attr.name] = (typeattr.attr.id,
                                                 typeattr.type_id)

    existing_types = set([r.name for r in tmpl_i.templatetypes])

    new_types = set([r.find('name').text for r in types.findall('resource')])

    types_to_delete = existing_types - new_types

    for type_to_delete in types_to_delete:
        type_id = type_name_map[type_to_delete]
        try:
            type_i = db.DBSession.query(TemplateType).filter(
                TemplateType.id == type_id).one()
            log.debug("Deleting type %s", type_i.name)
            db.DBSession.delete(type_i)
        except NoResultFound:
            pass

    #Add or update types.
    for resource in types.findall('resource'):
        type_name = resource.find('name').text
        #check if the type is already in the DB. If not, create a new one.
        type_is_new = False
        if type_name in existing_types:
            type_id = type_name_map[type_name]
            type_i = db.DBSession.query(TemplateType).filter(
                TemplateType.id == type_id).options(
                    joinedload('typeattrs').joinedload('attr')).one()

        else:
            log.debug("Type %s not found, creating new one.", type_name)
            type_i = TemplateType()
            type_i.name = type_name
            tmpl_i.templatetypes.append(type_i)
            type_is_new = True

        if resource.find('alias') is not None:
            type_i.alias = resource.find('alias').text

        if resource.find('description') is not None:
            type_i.description = resource.find('description').text

        if resource.find('type') is not None:
            type_i.resource_type = resource.find('type').text

        if resource.find('layout') is not None and \
            resource.find('layout').text is not None:
            layout = resource.find('layout')
            layout_string = get_etree_layout_as_dict(layout)
            type_i.layout = json.dumps(layout_string)

        #delete any TypeAttrs which are in the DB but not in the XML file
        existing_attrs = []
        if not type_is_new:
            for r in tmpl_i.templatetypes:
                if r.name == type_name:
                    for typeattr in r.typeattrs:
                        existing_attrs.append(typeattr.attr.name)

        existing_attrs = set(existing_attrs)

        template_attrs = set(
            [r.find('name').text for r in resource.findall('attribute')])

        attrs_to_delete = existing_attrs - template_attrs
        for attr_to_delete in attrs_to_delete:
            attr_id, type_id = attr_name_map[attr_to_delete]
            try:
                attr_i = db.DBSession.query(TypeAttr).filter(
                    TypeAttr.attr_id == attr_id,
                    TypeAttr.type_id == type_id).options(
                        joinedload('attr')).one()
                db.DBSession.delete(attr_i)
                log.debug("Attr %s in type %s deleted", attr_i.attr.name,
                          attr_i.templatetype.name)
            except NoResultFound:
                log.debug("Attr %s not found in type %s", attr_id, type_id)
                continue

        #Add or update type typeattrs
        for attribute in resource.findall('attribute'):
            new_typeattr = _parse_xml_typeattr(type_i,
                                               attribute,
                                               user_id=user_id)

    db.DBSession.flush()

    return tmpl_i