def test_app_to_entry_docker(self): """Tests convertion of app dictionary to ldap entry.""" app = { '_id': 'xxx', 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': [], 'features': [], 'endpoints': [], 'environ': [], 'services': [ { 'name': 'foo', 'image': 'testimage', 'useshell': True, 'command': 'echo', 'restart': { 'limit': 3, 'interval': 30, }, }, ] } ldap_entry = { 'app': ['xxx'], 'cpu': ['100%'], 'memory': ['1G'], 'disk': ['1G'], 'service-name;tm-service-0': ['foo'], 'service-command;tm-service-0': ['echo'], 'service-useshell;tm-service-0': [True], 'service-image;tm-service-0': ['testimage'], 'service-restart-limit;tm-service-0': ['3'], 'service-restart-interval;tm-service-0': ['30'], } self.assertEqual(ldap_entry, admin.Application(None).to_entry(app)) app['affinity_limits'] = {} app['args'] = [] app['passthrough'] = [] app['ephemeral_ports'] = {} self.assertEqual(app, admin.Application(None).from_entry(ldap_entry))
def configure_apps(ctx, apps): """Configure cell API.""" admin_app = admin.Application(context.GLOBAL.ldap.conn) # For apps that need write access to LDAP. The context LDAP must have # write access because this is what we use to write manifests here. write_uri = admin_app.admin.write_uri ctx.obj.admin_ldap_url = ','.join(write_uri) if write_uri else None if not apps: apps = _CELL_APPS # Configure apps identity groups identity_groups = _ident_groups(ctx) for groupname, count in six.iteritems(identity_groups): masterapi.update_identity_group( context.GLOBAL.zk.conn, groupname, count ) # Configure apps for appname in apps: fullname, app = _render_app(appname, ctx) print(fullname) print(yaml.dump(app)) try: admin_app.create(fullname, app) except ldap_exceptions.LDAPEntryAlreadyExistsResult: admin_app.replace(fullname, app)
def test_create_docker(self): """Dummy test for treadmill.api.cell.create() for docker""" app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '20G', 'image': 'docker://microsoft/windowsservercore', 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, { 'name': 'y', 'port': 2, 'type': 'infra' }, ] } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload)
def delete(app): """Delete applicaiton.""" admin_app = admin.Application(context.GLOBAL.ldap.conn) try: admin_app.delete(app) except ldap3.LDAPNoSuchObjectResult: click.echo('App does not exist: %s' % app, err=True)
def create(rsrc_id, rsrc, count=1): """Create (configure) instance.""" _LOGGER.info('create: count = %s, %s %r', count, rsrc_id, rsrc) if not rsrc: admin_app = admin.Application(context.GLOBAL.ldap.conn) configured = admin_app.get(rsrc_id) else: configured = rsrc app.verify_feature(rsrc.get('features', [])) if '_id' in configured: del configured['_id'] _validate(configured) if instance_plugin: configured = instance_plugin.add_attributes( rsrc_id, configured) if 'proid' not in configured: raise Exception('Missing required attribute: proid') if 'environment' not in configured: raise Exception('Missing required attribute: environment') if 'identity_group' not in configured: configured['identity_group'] = None scheduled = master.create_apps(context.GLOBAL.zk.conn, rsrc_id, configured, count) return scheduled
def test_create_valid_affinity(self): """Test valid affinity name for treadmill.api.cell.create(). """ app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'features': [], 'affinity': 'foo.bar', 'services': [ { 'name': 'a', 'command': '/a', }, ], 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload)
def test_create(self): """Dummy test for treadmill.api.cell.create()""" app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': [u'a@realm1', u'b@realm2'], 'features': [], 'services': [ { 'name': 'a', 'command': '/a', 'restart': { 'limit': 3, 'interval': 60, }, }, { 'name': 'b', 'command': '/b', }, ], 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra'}, {'name': 'y', 'port': 2, 'type': 'infra'}, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload)
def create(rsrc_id, rsrc, count=1, created_by=None): """Create (configure) instance.""" _LOGGER.info('create: count = %s, %s %r, created_by = %s', count, rsrc_id, rsrc, created_by) admin_app = admin.Application(context.GLOBAL.ldap.conn) if not rsrc: configured = admin_app.get(rsrc_id) else: # Make sure defaults are present configured = admin_app.from_entry(admin_app.to_entry(rsrc)) app.verify_feature(rsrc.get('features', [])) if 'services' in configured and not configured['services']: del configured['services'] if '_id' in configured: del configured['_id'] _LOGGER.info('Configured: %s %r', rsrc_id, configured) _validate(configured) self.plugins = _api_plugins(self.plugins) for plugin in self.plugins: configured = plugin.add_attributes(rsrc_id, configured) _check_required_attributes(configured) _set_defaults(configured, rsrc_id) scheduled = masterapi.create_apps(context.GLOBAL.zk.conn, rsrc_id, configured, count, created_by) return scheduled
def _test_replication(self, ldap_suffix, url, other_url): """Check ldap replication {url} -> {other_url}.""" print('Checking %s' % url) time.sleep(2) other_conn = admin.Admin(other_url, ldap_suffix) other_conn.connect() other_admin_app = admin.Application(other_conn) other_admin_app.get(self.name)
def configure(app, manifest): """Get or modify app configuration.""" admin_app = admin.Application(context.GLOBAL.ldap.conn) if manifest: data = yaml.load(manifest.read()) try: admin_app.create(app, data) except ldap3.LDAPEntryAlreadyExistsResult: admin_app.replace(app, data) try: cli.out(formatter(admin_app.get(app))) except ldap3.LDAPNoSuchObjectResult: click.echo('App does not exist: %s' % app, err=True)
def test_create_docker(self): """Dummy test for treadmill.api.cell.create() for docker""" app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '20G', 'image': 'docker://microsoft/windowsservercore', 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, { 'name': 'y', 'port': 2, 'type': 'infra' }, ], 'services': [ { 'name': 'foo', 'image': 'testimage', 'useshell': True, 'command': 'echo', 'restart': { 'limit': 3, 'interval': 30, }, }, { 'name': 'bar', 'image': 'testimage', 'useshell': False, 'command': 'echo', 'restart': { 'limit': 3, 'interval': 30, }, }, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload)
def configure(app, manifest): """Create, get or modify an app configuration""" admin_app = admin.Application(context.GLOBAL.ldap.conn) if manifest: with io.open(manifest, 'rb') as fd: data = yaml.load(stream=fd) try: admin_app.create(app, data) except ldap_exceptions.LDAPEntryAlreadyExistsResult: admin_app.replace(app, data) try: cli.out(formatter(admin_app.get(app))) except ldap_exceptions.LDAPNoSuchObjectResult: click.echo('App does not exist: %s' % app, err=True)
def start(job_id=None, app_name=None, count=1): """Start an application in the given cell""" _LOGGER.debug('app_name: %s', app_name) _LOGGER.debug('job_id: %s', job_id) _LOGGER.debug('count: %s', count) zkclient = context.GLOBAL.zk.conn scheduler = cron.get_scheduler(zkclient) job = scheduler.get_job(job_id) if not app_name: _LOGGER.error('No app name provided, cannot continue') return admin_app = admin.Application(context.GLOBAL.ldap.conn) configured = admin_app.get(app_name) if not configured: _LOGGER.info('App %s is not configured, pausing job %s', app_name, job.id) job.pause() return instance_plugin = None try: instance_plugin = importlib.import_module( 'treadmill.plugins.api.instance') except ImportError as err: _LOGGER.info('Unable to load auth plugin: %s', err) if instance_plugin: configured = instance_plugin.add_attributes(app_name, configured) if 'identity_group' not in configured: configured['identity_group'] = None if 'affinity' not in configured: configured['affinity'] = '{0}.{1}'.format(*app_name.split('.')) if '_id' in configured: del configured['_id'] _LOGGER.info('Configured: %s %r', app_name, configured) scheduled = master.create_apps(zkclient, app_name, configured, count) _LOGGER.debug('scheduled: %r', scheduled)
def create(rsrc_id, rsrc, count=1, created_by=None): """Create (configure) instance.""" _LOGGER.info('create: count = %s, %s %r, created_by = %s', count, rsrc_id, rsrc, created_by) # Check scheduled quota. zkclient = context.GLOBAL.zk.conn scheduled_stats = masterapi.get_scheduled_stats(zkclient) total_apps = sum(scheduled_stats.values()) if total_apps + count > _TOTAL_SCHEDULED_QUOTA: raise exc.QuotaExceededError( 'Total scheduled apps quota exceeded.') proid_apps = scheduled_stats.get(rsrc_id[:rsrc_id.find('.')], 0) if proid_apps + count > _PROID_SCHEDULED_QUOTA: raise exc.QuotaExceededError( 'Proid scheduled apps quota exceeded.') admin_app = admin.Application(context.GLOBAL.ldap.conn) if not rsrc: configured = admin_app.get(rsrc_id) else: # Make sure defaults are present configured = admin_app.from_entry(admin_app.to_entry(rsrc)) app.verify_feature(rsrc.get('features', [])) if 'services' in configured and not configured['services']: del configured['services'] if '_id' in configured: del configured['_id'] _LOGGER.info('Configured: %s %r', rsrc_id, configured) _validate(configured) self.plugins = _api_plugins(self.plugins) for plugin in self.plugins: configured = plugin.add_attributes(rsrc_id, configured) _check_required_attributes(configured) _set_defaults(configured, rsrc_id) scheduled = masterapi.create_apps(zkclient, rsrc_id, configured, count, created_by) return scheduled
def setUp(self): self.name = '%s.chk.%s.%s' % (sysproid, sysinfo.hostname(), time.time()) manifest = { 'memory': '1G', 'cpu': '10%', 'disk': '1G', 'services': [{ 'name': 'test', 'command': 'test' }] } conn = admin.Admin(url, ldap_suffix) conn.connect() self.admin_app = admin.Application(conn) self.admin_app.create(self.name, manifest)
def configure_apps(apps, cors_origin, krb_realm, dry_run): """Configure system apps.""" ctx = cell_admin.CellCtx(cors=cors_origin, krb_realm=krb_realm) cell_apps = cell_admin.get_apps(ctx) if not apps: apps = list(cell_apps) admin_app = admin.Application(context.GLOBAL.ldap.conn) # For apps that need write access to LDAP. The context LDAP must have # write access because this is what we use to write manifests here. write_uri = context.GLOBAL.ldap.write_url ctx.admin_ldap_url = ','.join(write_uri) if write_uri else None # Configure apps identity groups identity_groups = cell_admin.get_identity_groups(ctx) for groupname, count in identity_groups.items(): cli.echo_green('Configuring identity group %s: %d', groupname, count) if not dry_run: masterapi.update_identity_group(context.GLOBAL.zk.conn, groupname, count) # Configure apps for appname in apps: fullname = cell_apps[appname]['fullname'] app = cell_admin.render_template(appname, ctx) cli.echo_green('Configuring app %s:', fullname) cli.out(yaml.dump(app, explicit_start=True)) if not dry_run: try: admin_app.create(fullname, app) except admin_exceptions.AlreadyExistsResult: admin_app.replace(fullname, app)
def create(rsrc_id, rsrc, count=1): """Create (configure) instance.""" _LOGGER.info('create: count = %s, %s %r', count, rsrc_id, rsrc) admin_app = admin.Application(context.GLOBAL.ldap.conn) if not rsrc: configured = admin_app.get(rsrc_id) _LOGGER.info('Configured: %s %r', rsrc_id, configured) else: # Make sure defaults are present configured = admin_app.from_entry(admin_app.to_entry(rsrc)) app.verify_feature(rsrc.get('features', [])) if '_id' in configured: del configured['_id'] _validate(configured) if instance_plugin: configured = instance_plugin.add_attributes( rsrc_id, configured) if 'proid' not in configured: raise exc.TreadmillError('Missing required attribute: proid') if 'environment' not in configured: raise exc.TreadmillError( 'Missing required attribute: environment') if 'identity_group' not in configured: configured['identity_group'] = None if 'affinity' not in configured: configured['affinity'] = '{0}.{1}'.format(*rsrc_id.split('.')) scheduled = master.create_apps(context.GLOBAL.zk.conn, rsrc_id, configured, count) return scheduled
def test_app_to_entry(self): """Tests convertion of app dictionary to ldap entry.""" app = { '_id': 'xxx', 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': ['a', 'b'], 'features': [], 'services': [ { 'name': 'a', 'restart_count': 1, 'command': '/a' }, { 'name': 'b', 'restart_count': 2, 'command': '/b' }, ], 'endpoints': [ { 'name': 'x', 'port': 1 }, { 'name': 'y', 'port': 2 }, ], } md5_a = hashlib.md5('a').hexdigest() md5_b = hashlib.md5('b').hexdigest() md5_x = hashlib.md5('x').hexdigest() md5_y = hashlib.md5('y').hexdigest() ldap_entry = { 'app': ['xxx'], 'cpu': ['100%'], 'memory': ['1G'], 'disk': ['1G'], 'ticket': ['a', 'b'], 'service-name;tm-service-' + md5_a: ['a'], 'service-name;tm-service-' + md5_b: ['b'], 'service-restart-count;tm-service-' + md5_a: ['1'], 'service-restart-count;tm-service-' + md5_b: ['2'], 'service-command;tm-service-' + md5_a: ['/a'], 'service-command;tm-service-' + md5_b: ['/b'], 'endpoint-name;tm-endpoint-' + md5_x: ['x'], 'endpoint-name;tm-endpoint-' + md5_y: ['y'], 'endpoint-port;tm-endpoint-' + md5_x: ['1'], 'endpoint-port;tm-endpoint-' + md5_y: ['2'], } self.assertEquals(ldap_entry, admin.Application(None).to_entry(app)) self.assertEquals(app, admin.Application(None).from_entry(ldap_entry))
def test_app_to_entry_and_back(self): """Test converting app to/from entry populating default values.""" app = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'services': [{'command': '/a', 'name': 'a', 'restart': {'interval': 30, 'limit': 3}}], 'endpoints': [{'name': 'y', 'port': 2}], } expected = { 'tickets': [], 'features': [], 'endpoints': [{'name': 'y', 'port': 2}], 'environ': [], 'memory': '1G', 'services': [{'command': '/a', 'name': 'a', 'restart': {'interval': 30, 'limit': 3}}], 'disk': '1G', 'affinity_limits': {}, 'cpu': '100%', 'passthrough': [], 'ephemeral_ports': {}, 'args': [] } admin_app = admin.Application(None) self.assertEqual( expected, admin_app.from_entry(admin_app.to_entry(app)) ) app['services'][0]['root'] = True expected['services'][0]['root'] = True self.assertEqual( expected, admin_app.from_entry(admin_app.to_entry(app)) ) app['vring'] = { 'cells': ['a', 'b'], 'rules': [{ 'pattern': 'x.y*', 'endpoints': ['http', 'tcp'], }] } expected['vring'] = { 'cells': ['a', 'b'], 'rules': [{ 'pattern': 'x.y*', 'endpoints': ['http', 'tcp'], }] } self.assertEqual( expected, admin_app.from_entry(admin_app.to_entry(app)) ) app['passthrough'] = ['xxx.x.com', 'yyy.x.com'] expected['passthrough'] = ['xxx.x.com', 'yyy.x.com'] self.assertEqual( expected, admin_app.from_entry(admin_app.to_entry(app)) ) app['ephemeral_ports'] = { 'tcp': 10, } expected['ephemeral_ports'] = { 'tcp': 10, 'udp': 0, } app['schedule_once'] = True expected['schedule_once'] = True self.assertEqual( expected, admin_app.from_entry(admin_app.to_entry(app)) ) app['data_retention_timeout'] = '30m' expected['data_retention_timeout'] = '30m' self.assertEqual( expected, admin_app.from_entry(admin_app.to_entry(app)) )
def test_app_to_entry(self): """Tests convertion of app dictionary to ldap entry.""" app = { '_id': 'xxx', 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': ['a', None, 'b'], 'features': [], 'args': [], 'environ': [{'name': 'a', 'value': 'b'}], 'services': [ { 'name': 'a', 'command': '/a', 'restart': { 'limit': 3, 'interval': 30, }, }, { 'name': 'b', 'command': '/b', }, { 'name': 'c', 'command': '/c', 'restart': { 'limit': 0, }, }, ], 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra', 'proto': 'udp'}, {'name': 'y', 'port': 2, 'type': 'infra'}, ], 'affinity_limits': {'server': 1, 'rack': 2}, 'passthrough': [], 'ephemeral_ports': { 'tcp': 5, 'udp': 10, }, 'shared_ip': True, 'shared_network': True } md5_a = hashlib.md5(b'a').hexdigest() md5_b = hashlib.md5(b'b').hexdigest() md5_c = hashlib.md5(b'c').hexdigest() md5_x = hashlib.md5(b'x').hexdigest() md5_y = hashlib.md5(b'y').hexdigest() md5_srv = hashlib.md5(b'server').hexdigest() md5_rack = hashlib.md5(b'rack').hexdigest() ldap_entry = { 'app': ['xxx'], 'cpu': ['100%'], 'memory': ['1G'], 'disk': ['1G'], 'ticket': ['a', 'b'], 'service-name;tm-service-' + md5_a: ['a'], 'service-name;tm-service-' + md5_b: ['b'], 'service-name;tm-service-' + md5_c: ['c'], 'service-restart-limit;tm-service-' + md5_a: ['3'], 'service-restart-limit;tm-service-' + md5_b: ['5'], 'service-restart-limit;tm-service-' + md5_c: ['0'], 'service-restart-interval;tm-service-' + md5_a: ['30'], 'service-restart-interval;tm-service-' + md5_b: ['60'], 'service-restart-interval;tm-service-' + md5_c: ['60'], 'service-command;tm-service-' + md5_a: ['/a'], 'service-command;tm-service-' + md5_b: ['/b'], 'service-command;tm-service-' + md5_c: ['/c'], 'endpoint-name;tm-endpoint-' + md5_x: ['x'], 'endpoint-name;tm-endpoint-' + md5_y: ['y'], 'endpoint-port;tm-endpoint-' + md5_x: ['1'], 'endpoint-port;tm-endpoint-' + md5_y: ['2'], 'endpoint-type;tm-endpoint-' + md5_x: ['infra'], 'endpoint-type;tm-endpoint-' + md5_y: ['infra'], 'endpoint-proto;tm-endpoint-' + md5_x: ['udp'], 'envvar-name;tm-envvar-' + md5_a: ['a'], 'envvar-value;tm-envvar-' + md5_a: ['b'], 'affinity-level;tm-affinity-' + md5_srv: ['server'], 'affinity-limit;tm-affinity-' + md5_srv: ['1'], 'affinity-level;tm-affinity-' + md5_rack: ['rack'], 'affinity-limit;tm-affinity-' + md5_rack: ['2'], 'ephemeral-ports-tcp': ['5'], 'ephemeral-ports-udp': ['10'], 'shared-ip': ['TRUE'], 'shared-network': ['TRUE'] } self.assertEqual(ldap_entry, admin.Application(None).to_entry(app)) # When converting to entry, None are skipped, and unicode is converted # to str. # # Adjuest app['tickets'] accordingly. app['tickets'] = ['a', 'b'] # Account for default restart values app['services'][1]['restart'] = {'limit': 5, 'interval': 60} app['services'][2]['restart']['interval'] = 60 self.assertEqual(app, admin.Application(None).from_entry(ldap_entry))
def test_app_to_entry(self): """Tests convertion of app dictionary to ldap entry.""" app = { '_id': 'xxx', 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': ['a', None, 'b'], 'features': [], 'args': [], 'environ': [ { 'name': 'BAR', 'value': '34567' }, { 'name': 'FOO', 'value': '12345' }, ], 'services': [ { 'name': 'a', 'command': '/a', 'restart': { 'limit': 3, 'interval': 30, }, }, { 'name': 'b', 'command': '/b', }, { 'name': 'c', 'command': '/c', 'restart': { 'limit': 0, }, }, ], 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra', 'proto': 'udp' }, { 'name': 'y', 'port': 2, 'type': 'infra' }, ], 'affinity_limits': { 'server': 1, 'rack': 2 }, 'passthrough': [], 'ephemeral_ports': { 'tcp': 5, 'udp': 10, }, 'shared_ip': True, 'shared_network': True } ldap_entry = { 'app': ['xxx'], 'cpu': ['100%'], 'memory': ['1G'], 'disk': ['1G'], 'ticket': ['a', 'b'], 'service-name;tm-service-0': ['a'], 'service-name;tm-service-1': ['b'], 'service-name;tm-service-2': ['c'], 'service-restart-limit;tm-service-0': ['3'], 'service-restart-limit;tm-service-1': ['5'], 'service-restart-limit;tm-service-2': ['0'], 'service-restart-interval;tm-service-0': ['30'], 'service-restart-interval;tm-service-1': ['60'], 'service-restart-interval;tm-service-2': ['60'], 'service-command;tm-service-0': ['/a'], 'service-command;tm-service-1': ['/b'], 'service-command;tm-service-2': ['/c'], 'endpoint-name;tm-endpoint-0': ['x'], 'endpoint-name;tm-endpoint-1': ['y'], 'endpoint-port;tm-endpoint-0': ['1'], 'endpoint-port;tm-endpoint-1': ['2'], 'endpoint-type;tm-endpoint-0': ['infra'], 'endpoint-type;tm-endpoint-1': ['infra'], 'endpoint-proto;tm-endpoint-0': ['udp'], 'envvar-name;tm-envvar-0': ['BAR'], 'envvar-value;tm-envvar-0': ['34567'], 'envvar-name;tm-envvar-1': ['FOO'], 'envvar-value;tm-envvar-1': ['12345'], 'affinity-level;tm-affinity-0': ['rack'], 'affinity-limit;tm-affinity-0': ['2'], 'affinity-level;tm-affinity-1': ['server'], 'affinity-limit;tm-affinity-1': ['1'], 'ephemeral-ports-tcp': ['5'], 'ephemeral-ports-udp': ['10'], 'shared-ip': [True], 'shared-network': [True] } # TODO this logs "Expected [<class 'str'>], got ['a', None, 'b']" # see treadmill.admin:_dict_2_entry self.assertEqual(ldap_entry, admin.Application(None).to_entry(app)) # When converting to entry, None are skipped, and unicode is converted # to str. # # Adjust app['tickets'] accordingly. app['tickets'] = ['a', 'b'] # Account for default restart values app['services'][1]['restart'] = {'limit': 5, 'interval': 60} app['services'][2]['restart']['interval'] = 60 self.assertEqual(app, admin.Application(None).from_entry(ldap_entry))
def test_get(self): """Dummy test for treadmill.api.cell.get()""" app_admin = admin.Application(None) self.app.get('proid.name') app_admin.get.assert_called_with('proid.name')
def _list(): """List configured applicaitons.""" admin_app = admin.Application(context.GLOBAL.ldap.conn) cli.out(formatter(admin_app.list({})))
def _admin_app(): """Lazily return admin object.""" return admin.Application(context.GLOBAL.ldap.conn)
def create(rsrc_id, rsrc, count=1, created_by=None, debug=False, debug_services=None): """Create (configure) instance.""" _LOGGER.info('create: count = %s, %s %r, created_by = %s', count, rsrc_id, rsrc, created_by) # Check scheduled quota. zkclient = context.GLOBAL.zk.conn scheduled_stats = masterapi.get_scheduled_stats(zkclient) if not scheduled_stats: scheduled_stats = {} total_apps = sum(scheduled_stats.values()) if total_apps + count > _TOTAL_SCHEDULED_QUOTA: raise exc.QuotaExceededError( 'Total scheduled apps quota exceeded.') proid_apps = scheduled_stats.get(rsrc_id[:rsrc_id.find('.')], 0) if proid_apps + count > _PROID_SCHEDULED_QUOTA: raise exc.QuotaExceededError( 'Proid scheduled apps quota exceeded.') admin_app = admin.Application(context.GLOBAL.ldap.conn) if not rsrc: configured = admin_app.get(rsrc_id) else: # Make sure defaults are present configured = admin_app.from_entry(admin_app.to_entry(rsrc)) app.verify_feature(rsrc.get('features', [])) if 'services' in configured and not configured['services']: del configured['services'] if '_id' in configured: del configured['_id'] _LOGGER.info('Configured: %s %r', rsrc_id, configured) _validate(configured) for plugin in self._plugins: configured = plugin.add_attributes(rsrc_id, configured) _check_required_attributes(configured) _set_defaults(configured, rsrc_id) services = { service['name']: service for service in configured.get('services', []) } if not debug_services: debug_services = list(services) if debug else [] for service in debug_services: if service in services: services[service]['downed'] = True _LOGGER.info('Configuring service %s as down', service) else: raise exc.InvalidInputError(__name__, 'Invalid service %s' % service) scheduled = masterapi.create_apps(zkclient, rsrc_id, configured, count, created_by) return scheduled
def test_list(self): """Dummy test for treadmill.api.cell._list()""" app_admin = admin.Application(None) self.app.list('*') self.assertTrue(app_admin.list.called)