Пример #1
0
    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))
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
 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)
Пример #5
0
        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
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
        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
Пример #9
0
            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)
Пример #10
0
    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)
Пример #11
0
    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)
Пример #12
0
    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)
Пример #13
0
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)
Пример #14
0
        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
Пример #15
0
        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)
Пример #16
0
    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)
Пример #17
0
        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
Пример #18
0
    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))
Пример #19
0
    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))
        )
Пример #20
0
    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))
Пример #21
0
    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))
Пример #22
0
 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')
Пример #23
0
 def _list():
     """List configured applicaitons."""
     admin_app = admin.Application(context.GLOBAL.ldap.conn)
     cli.out(formatter(admin_app.list({})))
Пример #24
0
 def _admin_app():
     """Lazily return admin object."""
     return admin.Application(context.GLOBAL.ldap.conn)
Пример #25
0
        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
Пример #26
0
 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)