Merge "Support retrospective mapping of project type to modules"
This commit is contained in:
		@@ -57,27 +57,49 @@ def record_filter(ignore=None, use_default=True):
 | 
			
		||||
        ignore = []
 | 
			
		||||
 | 
			
		||||
    def decorator(f):
 | 
			
		||||
        def _filter_records_by_modules(memory_storage_inst, modules, releases):
 | 
			
		||||
            selected = set([])
 | 
			
		||||
            for m, r in vault.resolve_modules(modules, releases):
 | 
			
		||||
                y = memory_storage_inst.get_record_ids_by_modules([m])
 | 
			
		||||
                if r:
 | 
			
		||||
                    x = memory_storage_inst.get_record_ids_by_releases([r])
 | 
			
		||||
                    selected |= x & y
 | 
			
		||||
                else:
 | 
			
		||||
                    selected |= y
 | 
			
		||||
            return selected
 | 
			
		||||
 | 
			
		||||
        @functools.wraps(f)
 | 
			
		||||
        def record_filter_decorated_function(*args, **kwargs):
 | 
			
		||||
 | 
			
		||||
            memory_storage_inst = vault.get_memory_storage()
 | 
			
		||||
            record_ids = set(memory_storage_inst.get_record_ids())  # a copy
 | 
			
		||||
 | 
			
		||||
            if 'module' not in ignore:
 | 
			
		||||
                param = parameters.get_parameter(kwargs, 'module', 'modules',
 | 
			
		||||
                                                 use_default)
 | 
			
		||||
                if param:
 | 
			
		||||
            releases = []
 | 
			
		||||
            if 'release' not in ignore:
 | 
			
		||||
                releases = parameters.get_parameter(kwargs, 'release',
 | 
			
		||||
                                                    'releases', use_default)
 | 
			
		||||
                if releases:
 | 
			
		||||
                    if 'all' not in releases:
 | 
			
		||||
                        record_ids &= (
 | 
			
		||||
                        memory_storage_inst.get_record_ids_by_modules(
 | 
			
		||||
                            vault.resolve_modules(param)))
 | 
			
		||||
                            memory_storage_inst.get_record_ids_by_releases(
 | 
			
		||||
                                c.lower() for c in releases))
 | 
			
		||||
 | 
			
		||||
            modules = parameters.get_parameter(kwargs, 'module', 'modules',
 | 
			
		||||
                                               use_default)
 | 
			
		||||
 | 
			
		||||
            if 'project_type' not in ignore:
 | 
			
		||||
                param = parameters.get_parameter(kwargs, 'project_type',
 | 
			
		||||
                                                 'project_types', use_default)
 | 
			
		||||
                if param:
 | 
			
		||||
                    record_ids &= (
 | 
			
		||||
                        memory_storage_inst.get_record_ids_by_modules(
 | 
			
		||||
                            vault.resolve_project_types(param)))
 | 
			
		||||
                    record_ids &= _filter_records_by_modules(
 | 
			
		||||
                        memory_storage_inst,
 | 
			
		||||
                        vault.resolve_project_types(param),
 | 
			
		||||
                        releases)
 | 
			
		||||
 | 
			
		||||
            if 'module' not in ignore:
 | 
			
		||||
                if modules:
 | 
			
		||||
                    record_ids &= _filter_records_by_modules(
 | 
			
		||||
                        memory_storage_inst, modules, releases)
 | 
			
		||||
 | 
			
		||||
            if 'user_id' not in ignore:
 | 
			
		||||
                param = parameters.get_parameter(kwargs, 'user_id', 'user_ids')
 | 
			
		||||
@@ -94,15 +116,6 @@ def record_filter(ignore=None, use_default=True):
 | 
			
		||||
                    record_ids &= (
 | 
			
		||||
                        memory_storage_inst.get_record_ids_by_companies(param))
 | 
			
		||||
 | 
			
		||||
            if 'release' not in ignore:
 | 
			
		||||
                param = parameters.get_parameter(kwargs, 'release', 'releases',
 | 
			
		||||
                                                 use_default)
 | 
			
		||||
                if param:
 | 
			
		||||
                    if 'all' not in param:
 | 
			
		||||
                        record_ids &= (
 | 
			
		||||
                            memory_storage_inst.get_record_ids_by_releases(
 | 
			
		||||
                                c.lower() for c in param))
 | 
			
		||||
 | 
			
		||||
            if 'metric' not in ignore:
 | 
			
		||||
                metrics = parameters.get_parameter(kwargs, 'metric')
 | 
			
		||||
                if 'all' not in metrics:
 | 
			
		||||
 
 | 
			
		||||
@@ -13,11 +13,11 @@
 | 
			
		||||
# See the License for the specific language governing permissions and
 | 
			
		||||
# limitations under the License.
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
import flask
 | 
			
		||||
from oslo.config import cfg
 | 
			
		||||
import six
 | 
			
		||||
 | 
			
		||||
from dashboard import memory_storage
 | 
			
		||||
from stackalytics.openstack.common import log as logging
 | 
			
		||||
@@ -84,40 +84,11 @@ def _init_releases(vault):
 | 
			
		||||
    vault['releases'] = releases_map
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _make_module(module_id, text, modules, tag):
 | 
			
		||||
    return {'id': module_id, 'text': text,
 | 
			
		||||
            'modules': set(modules), 'tag': tag}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _init_module_groups(vault):
 | 
			
		||||
    runtime_storage_inst = vault['runtime_storage']
 | 
			
		||||
    memory_storage_inst = vault['memory_storage']
 | 
			
		||||
 | 
			
		||||
    module_group_index = collections.defaultdict(set)
 | 
			
		||||
    module_id_index = {}
 | 
			
		||||
    module_groups = runtime_storage_inst.get_by_key('module_groups') or {}
 | 
			
		||||
 | 
			
		||||
    for module_group in module_groups.values():
 | 
			
		||||
        module_group_name = module_group['module_group_name']
 | 
			
		||||
        module_group_id = module_group.get('id') or module_group_name.lower()
 | 
			
		||||
 | 
			
		||||
        module_id_index[module_group_id] = _make_module(
 | 
			
		||||
            module_group_id, module_group_name, module_group['modules'],
 | 
			
		||||
            module_group.get('tag') or 'group')
 | 
			
		||||
 | 
			
		||||
        for module in module_group['modules']:
 | 
			
		||||
            module_group_index[module].add(module_group_id)
 | 
			
		||||
 | 
			
		||||
    for module in memory_storage_inst.get_modules():
 | 
			
		||||
        module_id_index[module] = _make_module(module.lower(), module,
 | 
			
		||||
                                               [module.lower()], 'module')
 | 
			
		||||
 | 
			
		||||
    module_id_index['all'] = _make_module('all', 'All',
 | 
			
		||||
                                          memory_storage_inst.get_modules(),
 | 
			
		||||
                                          'project_type')
 | 
			
		||||
 | 
			
		||||
    vault['module_group_index'] = module_group_index
 | 
			
		||||
    vault['module_id_index'] = module_id_index
 | 
			
		||||
    vault['module_id_index'] = module_groups
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _init_project_types(vault):
 | 
			
		||||
@@ -184,20 +155,37 @@ def get_user_from_runtime_storage(user_id):
 | 
			
		||||
    return user_index[user_id]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def resolve_modules(module_ids):
 | 
			
		||||
def resolve_modules(module_ids, releases):
 | 
			
		||||
    module_id_index = get_vault().get('module_id_index') or {}
 | 
			
		||||
    modules = set()
 | 
			
		||||
 | 
			
		||||
    for module_id in module_ids:
 | 
			
		||||
        if module_id in module_id_index:
 | 
			
		||||
            modules |= set(module_id_index[module_id]['modules'])
 | 
			
		||||
    return modules
 | 
			
		||||
            module_group = module_id_index[module_id]
 | 
			
		||||
 | 
			
		||||
            if not releases or 'all' in releases:
 | 
			
		||||
                if 'releases' in module_group:
 | 
			
		||||
                    for release, modules in six.iteritems(
 | 
			
		||||
                            module_group['releases']):
 | 
			
		||||
                        for module in modules:
 | 
			
		||||
                            yield module, release
 | 
			
		||||
                if 'modules' in module_group:
 | 
			
		||||
                    for module in module_group['modules']:
 | 
			
		||||
                        yield module, None
 | 
			
		||||
            else:
 | 
			
		||||
                for release in releases:
 | 
			
		||||
                    if 'releases' in module_group:
 | 
			
		||||
                        for module in module_group['releases'][release]:
 | 
			
		||||
                            yield module, release
 | 
			
		||||
                    if 'modules' in module_group:
 | 
			
		||||
                        for module in module_group['modules']:
 | 
			
		||||
                            yield module, release
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def resolve_project_types(project_types):
 | 
			
		||||
    modules = set()
 | 
			
		||||
    project_types_index = get_vault()['project_types_index']
 | 
			
		||||
    for pt in project_types:
 | 
			
		||||
        pt = pt.lower()
 | 
			
		||||
        if is_project_type_valid(pt):
 | 
			
		||||
            modules |= resolve_modules(
 | 
			
		||||
                get_vault()['project_types_index'][pt]['modules'])
 | 
			
		||||
        if pt in project_types_index:
 | 
			
		||||
            modules |= set(project_types_index[pt]['modules'])
 | 
			
		||||
    return modules
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,6 @@ import time
 | 
			
		||||
 | 
			
		||||
import flask
 | 
			
		||||
from flask.ext import gravatar as gravatar_ext
 | 
			
		||||
import itertools
 | 
			
		||||
from oslo.config import cfg
 | 
			
		||||
import six
 | 
			
		||||
 | 
			
		||||
@@ -136,7 +135,7 @@ def get_core_engineer_branch(user, modules):
 | 
			
		||||
def get_engineers(records, metric_filter, finalize_handler):
 | 
			
		||||
 | 
			
		||||
    modules_names = parameters.get_parameter({}, 'module', 'modules')
 | 
			
		||||
    modules = vault.resolve_modules(modules_names)
 | 
			
		||||
    modules = set([m for m, r in vault.resolve_modules(modules_names, [''])])
 | 
			
		||||
 | 
			
		||||
    def postprocessing(record):
 | 
			
		||||
        if finalize_handler:
 | 
			
		||||
@@ -157,7 +156,7 @@ def get_engineers(records, metric_filter, finalize_handler):
 | 
			
		||||
@decorators.record_filter(ignore='metric')
 | 
			
		||||
def get_engineers_extended(records):
 | 
			
		||||
    modules_names = parameters.get_parameter({}, 'module', 'modules')
 | 
			
		||||
    modules = vault.resolve_modules(modules_names)
 | 
			
		||||
    modules = set([m for m, r in vault.resolve_modules(modules_names, [''])])
 | 
			
		||||
 | 
			
		||||
    def postprocessing(record):
 | 
			
		||||
        record = decorators.mark_finalize(record)
 | 
			
		||||
@@ -257,26 +256,24 @@ def get_companies_json(records):
 | 
			
		||||
@decorators.exception_handler()
 | 
			
		||||
@decorators.record_filter(ignore='module')
 | 
			
		||||
def get_modules_json(records):
 | 
			
		||||
    module_group_index = vault.get_vault()['module_group_index']
 | 
			
		||||
    module_id_index = vault.get_vault()['module_id_index']
 | 
			
		||||
 | 
			
		||||
    tags = parameters.get_parameter({}, 'tag', 'tags')
 | 
			
		||||
 | 
			
		||||
    # all modules mentioned in records
 | 
			
		||||
    module_ids = set(record['module'] for record in records)
 | 
			
		||||
    # plus all module groups that hold these modules
 | 
			
		||||
    module_ids |= set(itertools.chain.from_iterable(
 | 
			
		||||
        module_group_index.get(module, []) for module in module_ids))
 | 
			
		||||
    module_ids = set(record['module'] for record in records
 | 
			
		||||
                     if record['module'] in module_id_index)
 | 
			
		||||
 | 
			
		||||
    add_modules = set([])
 | 
			
		||||
    for module in six.itervalues(module_id_index):
 | 
			
		||||
        if set(module['modules']) <= module_ids:
 | 
			
		||||
            add_modules.add(module['id'])
 | 
			
		||||
    module_ids |= add_modules
 | 
			
		||||
 | 
			
		||||
    # keep only modules with specified tags
 | 
			
		||||
    if tags:
 | 
			
		||||
        module_ids = set(module_id for module_id in module_ids
 | 
			
		||||
                         if module_id_index[module_id].get('tag') in tags)
 | 
			
		||||
    # keep only modules that are in project type completely
 | 
			
		||||
    pts = parameters.get_parameter({}, 'project_type', 'project_types')
 | 
			
		||||
    if pts:
 | 
			
		||||
        m = set(vault.resolve_project_types(pts))
 | 
			
		||||
        module_ids = set(module_id for module_id in module_ids
 | 
			
		||||
                         if module_id_index[module_id]['modules'] <= m)
 | 
			
		||||
 | 
			
		||||
    query = (flask.request.args.get('query') or '').lower()
 | 
			
		||||
    matched = []
 | 
			
		||||
@@ -286,6 +283,8 @@ def get_modules_json(records):
 | 
			
		||||
            module = dict([(k, v) for k, v in
 | 
			
		||||
                           six.iteritems(module_id_index[module_id])
 | 
			
		||||
                           if k not in ['modules']])
 | 
			
		||||
            module['text'] = module['module_group_name']
 | 
			
		||||
            del module['module_group_name']
 | 
			
		||||
            matched.append(module)
 | 
			
		||||
 | 
			
		||||
    return sorted(matched, key=operator.itemgetter('text'))
 | 
			
		||||
@@ -312,7 +311,7 @@ def get_module(module):
 | 
			
		||||
    module = module.lower()
 | 
			
		||||
    if module in module_id_index:
 | 
			
		||||
        return {'id': module_id_index[module]['id'],
 | 
			
		||||
                'text': module_id_index[module]['text'],
 | 
			
		||||
                'text': module_id_index[module]['module_group_name'],
 | 
			
		||||
                'tag': module_id_index[module]['tag']}
 | 
			
		||||
    flask.abort(404)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										326
									
								
								etc/copy_of_programs.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								etc/copy_of_programs.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,326 @@
 | 
			
		||||
Compute:
 | 
			
		||||
  codename: Nova
 | 
			
		||||
  ptl: Michael Still (mikal)
 | 
			
		||||
  mission:
 | 
			
		||||
    To implement services and associated libraries to provide massively scalable,
 | 
			
		||||
    on demand, self service access to compute resources, including bare metal,
 | 
			
		||||
    virtual machines, and containers.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Nova
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/nova
 | 
			
		||||
      integrated-since: austin
 | 
			
		||||
    - repo: openstack/python-novaclient
 | 
			
		||||
    - repo: openstack/nova-specs
 | 
			
		||||
 | 
			
		||||
Object Storage:
 | 
			
		||||
  codename: Swift
 | 
			
		||||
  ptl: John Dickinson (notmyname)
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Swift
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/swift
 | 
			
		||||
      integrated-since: austin
 | 
			
		||||
    - repo: openstack/python-swiftclient
 | 
			
		||||
    - repo: openstack/swift-bench
 | 
			
		||||
 | 
			
		||||
Image Service:
 | 
			
		||||
  codename: Glance
 | 
			
		||||
  ptl: Mark Washenberger (markwash)
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Glance
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/glance
 | 
			
		||||
      integrated-since: bexar
 | 
			
		||||
    - repo: openstack/python-glanceclient
 | 
			
		||||
 | 
			
		||||
Identity:
 | 
			
		||||
  codename: Keystone
 | 
			
		||||
  ptl: Dolph Mathews (dolphm)
 | 
			
		||||
  mission:
 | 
			
		||||
    To facilitate API client authentication, service discovery, and distributed
 | 
			
		||||
    multi-tenant authorization.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Keystone
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/keystone
 | 
			
		||||
      integrated-since: essex
 | 
			
		||||
    - repo: openstack/python-keystoneclient
 | 
			
		||||
 | 
			
		||||
Dashboard:
 | 
			
		||||
  codename: Horizon
 | 
			
		||||
  ptl: David Lyle (david-lyle)
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Horizon
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/horizon
 | 
			
		||||
      integrated-since: essex
 | 
			
		||||
    - repo: openstack/django_openstack_auth
 | 
			
		||||
    - repo: openstack/tuskar-ui
 | 
			
		||||
 | 
			
		||||
Networking:
 | 
			
		||||
  codename: Neutron
 | 
			
		||||
  ptl: Kyle Mestery (mestery)
 | 
			
		||||
  mission:
 | 
			
		||||
    To implement services and associated libraries to provide on-demand,
 | 
			
		||||
    scalable, and technology-agnostic network abstraction.
 | 
			
		||||
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Neutron
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/neutron
 | 
			
		||||
      integrated-since: folsom
 | 
			
		||||
    - repo: openstack/python-neutronclient
 | 
			
		||||
    - repo: openstack/neutron-specs
 | 
			
		||||
 | 
			
		||||
Block Storage:
 | 
			
		||||
  codename: Cinder
 | 
			
		||||
  ptl: John Griffith (jgriffith)
 | 
			
		||||
  mission:
 | 
			
		||||
    To implement services and libraries to provide on-demand,
 | 
			
		||||
    self-service access to Block Storage resources via abstraction
 | 
			
		||||
    and automation on top of other block storage devices.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Cinder
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/cinder
 | 
			
		||||
      integrated-since: folsom
 | 
			
		||||
    - repo: openstack/python-cinderclient
 | 
			
		||||
 | 
			
		||||
Telemetry:
 | 
			
		||||
  codename: Ceilometer
 | 
			
		||||
  ptl : Eoghan Glynn (eglynn)
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Ceilometer
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/ceilometer
 | 
			
		||||
      incubated-since: grizzly
 | 
			
		||||
      integrated-since: havana
 | 
			
		||||
    - repo: openstack/python-ceilometerclient
 | 
			
		||||
 | 
			
		||||
Orchestration:
 | 
			
		||||
  codename: Heat
 | 
			
		||||
  ptl: Zane Bitter (zaneb)
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Heat
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/heat
 | 
			
		||||
      incubated-since: grizzly
 | 
			
		||||
      integrated-since: havana
 | 
			
		||||
    - repo: openstack/python-heatclient
 | 
			
		||||
    - repo: openstack/heat-cfntools
 | 
			
		||||
    - repo: openstack/heat-templates
 | 
			
		||||
    - repo: openstack-dev/heat-cfnclient
 | 
			
		||||
 | 
			
		||||
Database Service:
 | 
			
		||||
  codename: Trove
 | 
			
		||||
  ptl: Nikhil Manchanda (SlickNik)
 | 
			
		||||
  mission:
 | 
			
		||||
    To provide scalable and reliable Cloud Database as a Service
 | 
			
		||||
    functionality for both relational and non-relational database
 | 
			
		||||
    engines, and to continue to improve its fully-featured and
 | 
			
		||||
    extensible open source framework.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Trove
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/trove
 | 
			
		||||
      incubated-since: havana
 | 
			
		||||
      integrated-since: icehouse
 | 
			
		||||
    - repo: openstack/python-troveclient
 | 
			
		||||
    - repo: openstack/trove-integration
 | 
			
		||||
 | 
			
		||||
Bare metal:
 | 
			
		||||
  codename: Ironic
 | 
			
		||||
  ptl: Devananda van der Veen (devananda)
 | 
			
		||||
  mission:
 | 
			
		||||
    To produce an OpenStack service and associated python libraries capable
 | 
			
		||||
    of managing and provisioning physical machines, and to do this in a
 | 
			
		||||
    security-aware and fault-tolerant manner.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Ironic
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/ironic
 | 
			
		||||
      incubated-since: havana
 | 
			
		||||
    - repo: openstack/python-ironicclient
 | 
			
		||||
    - repo: openstack/ironic-python-agent
 | 
			
		||||
 | 
			
		||||
Common Libraries:
 | 
			
		||||
  codename: Oslo
 | 
			
		||||
  ptl: Doug Hellmann (dhellmann)
 | 
			
		||||
  mission:
 | 
			
		||||
    To produce a set of python libraries containing code shared by OpenStack
 | 
			
		||||
    projects. The APIs provided by these libraries should be high quality,
 | 
			
		||||
    stable, consistent, documented and generally applicable.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Oslo
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/cliff
 | 
			
		||||
    - repo: openstack/oslo.config
 | 
			
		||||
    - repo: openstack/oslo-incubator
 | 
			
		||||
    - repo: openstack/oslo.messaging
 | 
			
		||||
    - repo: openstack/oslo.rootwrap
 | 
			
		||||
    - repo: openstack/oslosphinx
 | 
			
		||||
    - repo: openstack/oslo.test
 | 
			
		||||
    - repo: openstack/oslo.version
 | 
			
		||||
    - repo: openstack/oslo.vmware
 | 
			
		||||
    - repo: openstack/pycadf
 | 
			
		||||
    - repo: openstack/stevedore
 | 
			
		||||
    - repo: openstack/taskflow
 | 
			
		||||
    - repo: openstack-dev/cookiecutter
 | 
			
		||||
    - repo: openstack-dev/oslo-cookiecutter
 | 
			
		||||
    - repo: openstack-dev/hacking
 | 
			
		||||
    - repo: openstack-dev/pbr
 | 
			
		||||
 | 
			
		||||
Infrastructure:
 | 
			
		||||
  ptl: James E. Blair (jeblair)
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Infrastructure
 | 
			
		||||
  mission:
 | 
			
		||||
    Develop and maintain the tooling and infrastructure needed to
 | 
			
		||||
    support the development process and general operation of the
 | 
			
		||||
    OpenStack project.
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack-dev/openstack-nose
 | 
			
		||||
    - repo: openstack-infra/activity-board
 | 
			
		||||
    - repo: openstack-infra/askbot-theme
 | 
			
		||||
    - repo: openstack-infra/config
 | 
			
		||||
    - repo: openstack-infra/devstack-gate
 | 
			
		||||
    - repo: openstack-infra/elastic-recheck
 | 
			
		||||
    - repo: openstack-infra/gear
 | 
			
		||||
    - repo: openstack-infra/gearman-plugin
 | 
			
		||||
    - repo: openstack-infra/gerrit
 | 
			
		||||
    - repo: openstack-infra/gerritbot
 | 
			
		||||
    - repo: openstack-infra/gerritlib
 | 
			
		||||
    - repo: openstack-infra/git-review
 | 
			
		||||
    - repo: openstack-infra/gitdm
 | 
			
		||||
    - repo: openstack-infra/groups
 | 
			
		||||
    - repo: openstack-infra/jeepyb
 | 
			
		||||
    - repo: openstack-infra/jenkins-job-builder
 | 
			
		||||
    - repo: openstack-infra/lodgeit
 | 
			
		||||
    - repo: openstack-infra/meetbot
 | 
			
		||||
    - repo: openstack-infra/nodepool
 | 
			
		||||
    - repo: openstack-infra/nose-html-output
 | 
			
		||||
    - repo: openstack-infra/odsreg
 | 
			
		||||
    - repo: openstack-infra/openstackid
 | 
			
		||||
    - repo: openstack-infra/os-loganalyze
 | 
			
		||||
    - repo: openstack-infra/publications
 | 
			
		||||
    - repo: openstack-infra/puppet-apparmor
 | 
			
		||||
    - repo: openstack-infra/puppet-dashboard
 | 
			
		||||
    - repo: openstack-infra/puppet-vcsrepo
 | 
			
		||||
    - repo: openstack-infra/pypi-mirror
 | 
			
		||||
    - repo: openstack-infra/releasestatus
 | 
			
		||||
    - repo: openstack-infra/reviewday
 | 
			
		||||
    - repo: openstack-infra/reviewstats
 | 
			
		||||
    - repo: openstack-infra/statusbot
 | 
			
		||||
    - repo: openstack-infra/storyboard
 | 
			
		||||
    - repo: openstack-infra/storyboard-webclient
 | 
			
		||||
    - repo: openstack-infra/tripleo-ci
 | 
			
		||||
    - repo: openstack-infra/zmq-event-publisher
 | 
			
		||||
    - repo: openstack-infra/zuul
 | 
			
		||||
    - repo: openstack-infra/zuul-packaging
 | 
			
		||||
    - repo: openstack/openstack-planet
 | 
			
		||||
 | 
			
		||||
Documentation:
 | 
			
		||||
  ptl: Anne Gentle (annegentle)
 | 
			
		||||
  mission:
 | 
			
		||||
    Provide documentation for core OpenStack projects to promote OpenStack.
 | 
			
		||||
    Develop and maintain tools and processes to ensure quality, accurate
 | 
			
		||||
    documentation. Treat documentation like OpenStack code.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Documentation
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/api-site
 | 
			
		||||
    - repo: openstack/compute-api
 | 
			
		||||
    - repo: openstack/database-api
 | 
			
		||||
    - repo: openstack/identity-api
 | 
			
		||||
    - repo: openstack/image-api
 | 
			
		||||
    - repo: openstack/netconn-api
 | 
			
		||||
    - repo: openstack/object-api
 | 
			
		||||
    - repo: openstack/openstack-doc-tools
 | 
			
		||||
    - repo: openstack/openstack-manuals
 | 
			
		||||
    - repo: openstack/operations-guide
 | 
			
		||||
    - repo: openstack/volume-api
 | 
			
		||||
 | 
			
		||||
Quality Assurance:
 | 
			
		||||
  codename: QA
 | 
			
		||||
  ptl: Matthew Treinish (mtreinish)
 | 
			
		||||
  mission:
 | 
			
		||||
    Develop, maintain, and initiate tools and plans to ensure the upstream
 | 
			
		||||
    stability and quality of OpenStack, and its release readiness at any
 | 
			
		||||
    point during the release cycle.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/QA
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/tempest
 | 
			
		||||
    - repo: openstack-dev/grenade
 | 
			
		||||
    - repo: openstack/qa-specs
 | 
			
		||||
 | 
			
		||||
Deployment:
 | 
			
		||||
  codename: TripleO
 | 
			
		||||
  ptl: Robert Collins (lifeless)
 | 
			
		||||
  mission:
 | 
			
		||||
    Develop and maintain tooling and infrastructure able to deploy OpenStack
 | 
			
		||||
    in production, using OpenStack itself wherever possible.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/TripleO
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/diskimage-builder
 | 
			
		||||
    - repo: openstack/os-apply-config
 | 
			
		||||
    - repo: openstack/os-cloud-config
 | 
			
		||||
    - repo: openstack/os-collect-config
 | 
			
		||||
    - repo: openstack/os-refresh-config
 | 
			
		||||
    - repo: openstack/tripleo-heat-templates
 | 
			
		||||
    - repo: openstack/tripleo-image-elements
 | 
			
		||||
    - repo: openstack/tripleo-incubator
 | 
			
		||||
    - repo: openstack/tuskar
 | 
			
		||||
    - repo: openstack/python-tuskarclient
 | 
			
		||||
 | 
			
		||||
Devstack:
 | 
			
		||||
  ptl: Dean Troyer (dtroyer)
 | 
			
		||||
  mission:
 | 
			
		||||
    To provide an installation of OpenStack from git repository master, or
 | 
			
		||||
    specific branches, suitable for development and operational testing.
 | 
			
		||||
    It also attempts to document the process and provide examples of command
 | 
			
		||||
    line usage.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/DevStack
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack-dev/devstack
 | 
			
		||||
 | 
			
		||||
Release cycle management:
 | 
			
		||||
  ptl: Thierry Carrez (ttx)
 | 
			
		||||
  mission:
 | 
			
		||||
    To organize the release cycle and the work necessary to produce
 | 
			
		||||
    coordinated releases of the integrated components of OpenStack.
 | 
			
		||||
    To collect bugfix backports and produce stable point releases for the
 | 
			
		||||
    previously-released branch. To coordinate the publication of security
 | 
			
		||||
    patches and advisories (OSSA) for security-supported branches.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Release_Cycle_Management
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/requirements
 | 
			
		||||
    - repo: openstack-infra/release-tools
 | 
			
		||||
 | 
			
		||||
Queue service:
 | 
			
		||||
  codename: Marconi
 | 
			
		||||
  ptl: Kurt Griffiths (kgriffs)
 | 
			
		||||
  mission:
 | 
			
		||||
    To produce an OpenStack message queueing API and service that affords
 | 
			
		||||
    a variety of distributed application messaging patterns in an efficient,
 | 
			
		||||
    scalable and highly-available manner, and to create and maintain
 | 
			
		||||
    associated Python libraries and documentation.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Marconi
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/marconi
 | 
			
		||||
      incubated-since: icehouse
 | 
			
		||||
    - repo: openstack/python-marconiclient
 | 
			
		||||
 | 
			
		||||
Data processing service:
 | 
			
		||||
  codename: Sahara
 | 
			
		||||
  ptl: Sergey Lukjanov (SergeyLukjanov)
 | 
			
		||||
  mission:
 | 
			
		||||
    To provide a scalable data processing stack and associated management
 | 
			
		||||
    interfaces.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Sahara
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: openstack/sahara
 | 
			
		||||
      incubated-since: icehouse
 | 
			
		||||
      integrated-since: juno
 | 
			
		||||
    - repo: openstack/python-saharaclient
 | 
			
		||||
    - repo: openstack/sahara-dashboard
 | 
			
		||||
    - repo: openstack/sahara-extra
 | 
			
		||||
    - repo: openstack/sahara-image-elements
 | 
			
		||||
 | 
			
		||||
Key management service:
 | 
			
		||||
  codename: Barbican
 | 
			
		||||
  ptl: Jarret Raim (jraim)
 | 
			
		||||
  mission:
 | 
			
		||||
    To produce a secret storage and generation system capable of providing key
 | 
			
		||||
    management for services wishing to enable encryption features.
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Barbican
 | 
			
		||||
  projects:
 | 
			
		||||
    - repo: stackforge/barbican
 | 
			
		||||
      incubated-since: juno
 | 
			
		||||
    - repo: stackforge/python-barbicanclient
 | 
			
		||||
@@ -7448,11 +7448,23 @@
 | 
			
		||||
    "releases": [
 | 
			
		||||
        {
 | 
			
		||||
            "release_name": "prehistory",
 | 
			
		||||
            "end_date": "2011-Apr-21"
 | 
			
		||||
            "end_date": "2010-Jan-01"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "release_name": "Austin",
 | 
			
		||||
            "end_date": "2010-Oct-21"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "release_name": "Bexar",
 | 
			
		||||
            "end_date": "2011-Feb-03"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "release_name": "Cactus",
 | 
			
		||||
            "end_date": "2011-Apr-15"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "release_name": "Diablo",
 | 
			
		||||
            "end_date": "2011-Sep-08"
 | 
			
		||||
            "end_date": "2011-Sep-22"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "release_name": "Essex",
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ Image Service:
 | 
			
		||||
  ptl: Mark Washenberger (markwash)
 | 
			
		||||
  url: https://wiki.openstack.org/wiki/Glance
 | 
			
		||||
  projects:
 | 
			
		||||
    integrated:
 | 
			
		||||
    - openstack/glance
 | 
			
		||||
    other:
 | 
			
		||||
    - openstack/python-glanceclient
 | 
			
		||||
    - repo: openstack/glance
 | 
			
		||||
      integrated-since: havana
 | 
			
		||||
      incubated-since: grizzly
 | 
			
		||||
    - repo: openstack/python-glanceclient
 | 
			
		||||
 
 | 
			
		||||
@@ -138,7 +138,8 @@ def _store_companies(runtime_storage_inst, companies):
 | 
			
		||||
def _store_module_groups(runtime_storage_inst, module_groups):
 | 
			
		||||
    stored_mg = runtime_storage_inst.get_by_key('module_groups') or {}
 | 
			
		||||
    for mg in module_groups:
 | 
			
		||||
        stored_mg[mg['module_group_name']] = mg
 | 
			
		||||
        mg['id'] = mg['module_group_name']
 | 
			
		||||
        stored_mg[mg['id']] = mg
 | 
			
		||||
    runtime_storage_inst.set_by_key('module_groups', stored_mg)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -194,42 +194,86 @@ def _make_module_group(group_id, name, modules, tag=None):
 | 
			
		||||
    return module_group
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _read_module_groups(program_list_uri):
 | 
			
		||||
def _read_official_programs_yaml(program_list_uri, release_names):
 | 
			
		||||
    LOG.debug('Process list of programs from uri: %s', program_list_uri)
 | 
			
		||||
    content = yaml.safe_load(utils.read_uri(program_list_uri))
 | 
			
		||||
    module_groups = []
 | 
			
		||||
    modules_by_types = collections.defaultdict(list)
 | 
			
		||||
    module_groups = collections.defaultdict(
 | 
			
		||||
        lambda: {'modules': [], 'releases': collections.defaultdict(list)})
 | 
			
		||||
 | 
			
		||||
    official_integrated = module_groups['official-integrated']
 | 
			
		||||
    official_integrated['tag'] = 'project_type'
 | 
			
		||||
    official_integrated['module_group_name'] = 'official-integrated'
 | 
			
		||||
    official_incubated = module_groups['official-incubated']
 | 
			
		||||
    official_incubated['tag'] = 'project_type'
 | 
			
		||||
    official_incubated['module_group_name'] = 'official-incubated'
 | 
			
		||||
    official_other = module_groups['official-other']
 | 
			
		||||
    official_other['tag'] = 'project_type'
 | 
			
		||||
    official_other['module_group_name'] = 'official-other'
 | 
			
		||||
 | 
			
		||||
    for name, info in six.iteritems(content):
 | 
			
		||||
        # for one program
 | 
			
		||||
        group_id = name.lower()
 | 
			
		||||
        if 'codename' in info:
 | 
			
		||||
            name = '%s (%s)' % (info['codename'], name)
 | 
			
		||||
            group_id = '%s-group' % info['codename'].lower()
 | 
			
		||||
 | 
			
		||||
        all_modules = []
 | 
			
		||||
        for project_type, project_list in six.iteritems(info['projects']):
 | 
			
		||||
            module_list = [s.split('/')[1] for s in project_list]
 | 
			
		||||
            modules_by_types[project_type] += module_list
 | 
			
		||||
            all_modules += module_list
 | 
			
		||||
        module_groups[group_id]['module_group_name'] = name
 | 
			
		||||
        module_groups[group_id]['tag'] = 'program'
 | 
			
		||||
 | 
			
		||||
        module_groups.append(_make_module_group(
 | 
			
		||||
            group_id, name, all_modules, 'program'))
 | 
			
		||||
        for module in info['projects']:
 | 
			
		||||
            module_name = module['repo'].split('/')[1]
 | 
			
		||||
 | 
			
		||||
            module_groups[group_id]['modules'].append(module_name)
 | 
			
		||||
 | 
			
		||||
            if ('integrated-since' in module) or ('incubated-since' in module):
 | 
			
		||||
                project_type = 'official-other'
 | 
			
		||||
                for release_name in release_names:
 | 
			
		||||
                    if release_name == module.get('incubated-since'):
 | 
			
		||||
                        project_type = 'official-incubated'
 | 
			
		||||
                    elif release_name == module.get('integrated-since'):
 | 
			
		||||
                        project_type = 'official-integrated'
 | 
			
		||||
 | 
			
		||||
                    module_groups[project_type]['releases'][
 | 
			
		||||
                        release_name].append(module_name)
 | 
			
		||||
            else:
 | 
			
		||||
                module_groups['official-other']['modules'].append(module_name)
 | 
			
		||||
 | 
			
		||||
    # set ids for module groups
 | 
			
		||||
    for group_id, group in six.iteritems(module_groups):
 | 
			
		||||
        group['id'] = group_id
 | 
			
		||||
 | 
			
		||||
    all_modules = []
 | 
			
		||||
    for project_type, modules_list in six.iteritems(modules_by_types):
 | 
			
		||||
        all_modules += modules_list
 | 
			
		||||
        module_groups.append(
 | 
			
		||||
            _make_module_group(
 | 
			
		||||
                'official-%s' % project_type, project_type.capitalize(),
 | 
			
		||||
                modules_list, 'project_type'))
 | 
			
		||||
    module_groups.append(_make_module_group(
 | 
			
		||||
        'official-all', 'OpenStack', all_modules, 'project_type'))
 | 
			
		||||
    return module_groups
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def process_program_list(runtime_storage_inst, program_list_uri):
 | 
			
		||||
    module_groups = runtime_storage_inst.get_by_key('module_groups') or {}
 | 
			
		||||
    for mg in _read_module_groups(program_list_uri):
 | 
			
		||||
        module_groups[mg['module_group_name']] = mg
 | 
			
		||||
    release_names = [r['release_name'].lower()
 | 
			
		||||
                     for r in runtime_storage_inst.get_by_key('releases')[1:]]
 | 
			
		||||
 | 
			
		||||
    official_module_groups = _read_official_programs_yaml(
 | 
			
		||||
        program_list_uri, release_names)
 | 
			
		||||
    LOG.debug('Update module groups with official: %s', official_module_groups)
 | 
			
		||||
    module_groups.update(official_module_groups)
 | 
			
		||||
 | 
			
		||||
    # register modules as module groups
 | 
			
		||||
    repos = runtime_storage_inst.get_by_key('repos') or []
 | 
			
		||||
    for repo in repos:
 | 
			
		||||
        module = repo['module']
 | 
			
		||||
        module_groups[module] = {
 | 
			
		||||
            'id': module,
 | 
			
		||||
            'module_group_name': module,
 | 
			
		||||
            'modules': [module],
 | 
			
		||||
            'tag': 'module'
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    # register module 'unknown' - used for emails not mapped to any module
 | 
			
		||||
    module_groups['unknown'] = {
 | 
			
		||||
        'id': 'unknown',
 | 
			
		||||
        'module_group_name': 'unknown',
 | 
			
		||||
        'modules': ['unknown'],
 | 
			
		||||
        'tag': 'module'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    runtime_storage_inst.set_by_key('module_groups', module_groups)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,13 @@ def make_records(**kwargs):
 | 
			
		||||
    return generate_records
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_module(module_name):
 | 
			
		||||
    return {'id': module_name,
 | 
			
		||||
            'module_group_name': module_name,
 | 
			
		||||
            'modules': [module_name],
 | 
			
		||||
            'tag': 'module'}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestStorage(runtime_storage.RuntimeStorage):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, data):
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,11 @@ class TestAPICompanies(test_api.TestAPI):
 | 
			
		||||
                    ],
 | 
			
		||||
                    'module_groups': {
 | 
			
		||||
                        'openstack': {'module_group_name': 'openstack',
 | 
			
		||||
                                      'modules': ['nova', 'glance']}
 | 
			
		||||
                                      'modules': ['nova', 'glance']},
 | 
			
		||||
                        'nova': {'module_group_name': 'nova',
 | 
			
		||||
                                 'modules': ['nova']},
 | 
			
		||||
                        'glance': {'module_group_name': 'glance',
 | 
			
		||||
                                   'modules': ['glance']},
 | 
			
		||||
                    }},
 | 
			
		||||
                test_api.make_records(record_type=['commit'],
 | 
			
		||||
                                      loc=[10, 20, 30],
 | 
			
		||||
 
 | 
			
		||||
@@ -26,9 +26,15 @@ class TestAPIModules(test_api.TestAPI):
 | 
			
		||||
                            'uri': 'git://github.com/openstack/nova.git'},
 | 
			
		||||
                           {'module': 'glance', 'organization': 'openstack',
 | 
			
		||||
                            'uri': 'git://github.com/openstack/glance.git'}],
 | 
			
		||||
                 'module_groups': {'nova-group': {
 | 
			
		||||
                 'module_groups': {
 | 
			
		||||
                     'nova-group': {'id': 'nova-group',
 | 
			
		||||
                                    'module_group_name': 'nova-group',
 | 
			
		||||
                     'modules': ['nova', 'nova-cli']}},
 | 
			
		||||
                                    'modules': ['nova', 'nova-cli'],
 | 
			
		||||
                                    'tag': 'group'},
 | 
			
		||||
                     'nova': test_api.make_module('nova'),
 | 
			
		||||
                     'nova-cli': test_api.make_module('nova-cli'),
 | 
			
		||||
                     'glance': test_api.make_module('glance'),
 | 
			
		||||
                 },
 | 
			
		||||
                 'project_types': [
 | 
			
		||||
                     {'id': 'all', 'title': 'All',
 | 
			
		||||
                      'modules': ['nova', 'glance', 'nova-cli']},
 | 
			
		||||
@@ -73,9 +79,14 @@ class TestAPIModules(test_api.TestAPI):
 | 
			
		||||
        with test_api.make_runtime_storage(
 | 
			
		||||
                {'repos': [{'module': 'nova', 'organization': 'openstack',
 | 
			
		||||
                            'uri': 'git://github.com/openstack/nova.git'}],
 | 
			
		||||
                 'module_groups': {'nova-group': {
 | 
			
		||||
                 'module_groups': {
 | 
			
		||||
                     'nova-group': {'id': 'nova-group',
 | 
			
		||||
                                    'module_group_name': 'nova-group',
 | 
			
		||||
                     'modules': ['nova', 'python-novaclient']}}},
 | 
			
		||||
                                    'modules': ['nova', 'nova-cli'],
 | 
			
		||||
                                    'tag': 'group'},
 | 
			
		||||
                     'nova': test_api.make_module('nova'),
 | 
			
		||||
                     'nova-cli': test_api.make_module('nova-cli'),
 | 
			
		||||
                 }},
 | 
			
		||||
                test_api.make_records(record_type=['commit'])):
 | 
			
		||||
 | 
			
		||||
            response = self.app.get('/api/1.0/modules/nova')
 | 
			
		||||
 
 | 
			
		||||
@@ -26,9 +26,14 @@ class TestAPIStats(test_api.TestAPI):
 | 
			
		||||
                            'uri': 'git://github.com/openstack/nova.git'},
 | 
			
		||||
                           {'module': 'glance', 'organization': 'openstack',
 | 
			
		||||
                            'uri': 'git://github.com/openstack/glance.git'}],
 | 
			
		||||
                 'module_groups': {'openstack': {
 | 
			
		||||
                 'module_groups': {
 | 
			
		||||
                     'openstack': {'id': 'openstack',
 | 
			
		||||
                                   'module_group_name': 'openstack',
 | 
			
		||||
                     'modules': ['nova', 'glance']}},
 | 
			
		||||
                                   'modules': ['nova', 'glance'],
 | 
			
		||||
                                   'tag': 'group'},
 | 
			
		||||
                     'nova': test_api.make_module('nova'),
 | 
			
		||||
                     'glance': test_api.make_module('glance'),
 | 
			
		||||
                 },
 | 
			
		||||
                 'project_types': [
 | 
			
		||||
                     {'id': 'all', 'title': 'All',
 | 
			
		||||
                      'modules': ['nova', 'glance']}]},
 | 
			
		||||
@@ -55,9 +60,14 @@ class TestAPIStats(test_api.TestAPI):
 | 
			
		||||
                           {'module': 'glance', 'project_type': 'openstack',
 | 
			
		||||
                            'organization': 'openstack',
 | 
			
		||||
                            'uri': 'git://github.com/openstack/glance.git'}],
 | 
			
		||||
                 'module_groups': {'openstack': {
 | 
			
		||||
                 'module_groups': {
 | 
			
		||||
                     'openstack': {'id': 'openstack',
 | 
			
		||||
                                   'module_group_name': 'openstack',
 | 
			
		||||
                     'modules': ['nova', 'glance']}},
 | 
			
		||||
                                   'modules': ['nova', 'glance'],
 | 
			
		||||
                                   'tag': 'group'},
 | 
			
		||||
                     'nova': test_api.make_module('nova'),
 | 
			
		||||
                     'glance': test_api.make_module('glance'),
 | 
			
		||||
                 },
 | 
			
		||||
                 'project_types': [
 | 
			
		||||
                     {'id': 'all', 'title': 'All',
 | 
			
		||||
                      'modules': ['nova', 'glance']}],
 | 
			
		||||
@@ -98,9 +108,14 @@ class TestAPIStats(test_api.TestAPI):
 | 
			
		||||
                           {'module': 'glance', 'project_type': 'openstack',
 | 
			
		||||
                            'organization': 'openstack',
 | 
			
		||||
                            'uri': 'git://github.com/openstack/glance.git'}],
 | 
			
		||||
                 'module_groups': {'openstack': {
 | 
			
		||||
                 'module_groups': {
 | 
			
		||||
                     'openstack': {'id': 'openstack',
 | 
			
		||||
                                   'module_group_name': 'openstack',
 | 
			
		||||
                     'modules': ['nova', 'glance']}},
 | 
			
		||||
                                   'modules': ['nova', 'glance'],
 | 
			
		||||
                                   'tag': 'group'},
 | 
			
		||||
                     'nova': test_api.make_module('nova'),
 | 
			
		||||
                     'glance': test_api.make_module('glance'),
 | 
			
		||||
                 },
 | 
			
		||||
                 'project_types': [
 | 
			
		||||
                     {'id': 'all', 'title': 'All',
 | 
			
		||||
                      'modules': ['nova', 'glance']}],
 | 
			
		||||
 
 | 
			
		||||
@@ -20,18 +20,16 @@ from tests.api import test_api
 | 
			
		||||
 | 
			
		||||
class TestAPIUsers(test_api.TestAPI):
 | 
			
		||||
 | 
			
		||||
    def test_users_empty(self):
 | 
			
		||||
        with test_api.make_runtime_storage({}):
 | 
			
		||||
            response = self.app.get('/api/1.0/users')
 | 
			
		||||
            self.assertEqual(200, response.status_code)
 | 
			
		||||
 | 
			
		||||
    def test_users(self):
 | 
			
		||||
        with test_api.make_runtime_storage(
 | 
			
		||||
                {'repos': [{'module': 'nova', 'organization': 'openstack',
 | 
			
		||||
                            'uri': 'git://github.com/openstack/nova.git'}],
 | 
			
		||||
                 'project_types': [
 | 
			
		||||
                     {'id': 'openstack', 'title': 'openstack',
 | 
			
		||||
                      'modules': ['nova', 'glance']}]},
 | 
			
		||||
                      'modules': ['nova', 'glance']}],
 | 
			
		||||
                 'module_groups': {
 | 
			
		||||
                     'nova': test_api.make_module('nova'),
 | 
			
		||||
                     'glance': test_api.make_module('glance')}},
 | 
			
		||||
                test_api.make_records(record_type=['commit'], module=['nova'],
 | 
			
		||||
                                      user_id=['john_doe', 'bill_smith'])):
 | 
			
		||||
            response = self.app.get('/api/1.0/users?'
 | 
			
		||||
@@ -47,7 +45,10 @@ class TestAPIUsers(test_api.TestAPI):
 | 
			
		||||
                            'uri': 'git://github.com/openstack/nova.git'}],
 | 
			
		||||
                 'project_types': [
 | 
			
		||||
                     {'id': 'openstack', 'title': 'openstack',
 | 
			
		||||
                      'modules': ['nova', 'glance']}]},
 | 
			
		||||
                      'modules': ['nova', 'glance']}],
 | 
			
		||||
                 'module_groups': {
 | 
			
		||||
                     'nova': test_api.make_module('nova'),
 | 
			
		||||
                     'glance': test_api.make_module('glance')}},
 | 
			
		||||
                test_api.make_records(record_type=['commit'], module=['nova'],
 | 
			
		||||
                                      user_name=['John Doe', 'Bill Smith'])):
 | 
			
		||||
            response = self.app.get('/api/1.0/users?'
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user