'All sections except \'targets\' describe some feature of
the Nova hypervisor driver implementation.'

def _get_features(self, cfg, targets):

    features = []
    for section in cfg.sections():
        if (section == 'targets'):
            continue
        if section.startswith('target.'):
            continue
        if (not cfg.has_option(section, 'title')):
            raise Exception(("'title'    field    missing    in    '[%s]'    section" % section))
        title = cfg.get(section, 'title')
        maturity = MatrixFeature.MATURITY_INCOMPLETE
        if cfg.has_option(section, 'maturity'):
            maturity = cfg.get(section, 'maturity').lower()
            if (maturity not in MatrixFeature.MATURITY_ALL):
                raise Exception(("'maturity'    field    value    '%s'    in    ['%s']section    must    be    %s" % (maturity, section, ','.join(MatrixFeature.MATURITY_ALL))))
        notes = None
        if cfg.has_option(section, 'notes'):
            notes = cfg.get(section, 'notes')
        cli = []
        if cfg.has_option(section, 'cli'):
            cli = cfg.get(section, 'cli')
        api_doc_link = None
        if cfg.has_option(section, 'api_doc_link'):
            api_doc_link = cfg.get(section, 'api_doc_link')
        admin_doc_link = None
        if cfg.has_option(section, 'admin_doc_link'):
            admin_doc_link = cfg.get(section, 'admin_doc_link')
        tempest_test_uuids = []
        if cfg.has_option(section, 'tempest_test_uuids'):
            tempest_test_uuids = cfg.get(section, 'tempest_test_uuids')
        feature = MatrixFeature(section, title, notes, cli, maturity, api_doc_link, admin_doc_link, tempest_test_uuids)
        for item in cfg.options(section):
            key = item.replace('driver-impl-', '')
            if (key not in targets):
                if item.startswith('driver-impl-'):
                    raise Exception(("Driver    impl    '%s'    in    '[%s]'    not    declared" % (item, section)))
                continue
            impl_status_and_release = cfg.get(section, item)
            impl_status_and_release = impl_status_and_release.split(':')
            impl_status = impl_status_and_release[0]
            release = None
            if (len(impl_status_and_release) == 2):
                release = impl_status_and_release[1]
            if (impl_status not in MatrixImplementation.STATUS_ALL):
                raise Exception(("'%s'    value    '%s'    in    '[%s]'    section    must    be    %s" % (item, impl_status, section, ','.join(MatrixImplementation.STATUS_ALL))))
            noteskey = ('driver-notes-' + item[12:])
            notes = None
            if cfg.has_option(section, noteskey):
                notes = cfg.get(section, noteskey)
            target = targets[key]
            impl = MatrixImplementation(impl_status, notes, release)
            feature.implementations[target.key] = impl
        for key in targets:
            if (key not in feature.implementations):
                raise Exception(("'%s'    missing    in    '[%s]'    section" % (key, section)))
        features.append(feature)
    return features
