Beispiel #1
0
    def configure(count, name, policy):
        """Configure application monitor"""

        restapi = context.GLOBAL.cell_api()
        url = _REST_PATH + name

        options = {}
        if count is not None:
            options['count'] = count
        if policy is not None:
            options['policy'] = policy

        # reconfigure if any of the parameters is specified
        if options:
            existing = None
            try:
                existing = restclient.get(restapi, url).json()
            except restclient.NotFoundError:
                _LOGGER.debug('App monitor not found: %s', name)

            if existing is None:
                _check_configure_usage(count)

                _LOGGER.debug('Creating app monitor: %s', name)
                restclient.post(restapi, url, payload=options)

            else:
                existing.update(options)
                _LOGGER.debug('Updating app monitor: %s', name)
                restclient.put(restapi, url, payload=existing)

        _LOGGER.debug('Retrieving app monitor: %s', name)
        monitor_entry = restclient.get(restapi, url)
        cli.out(formatter(monitor_entry.json()))
Beispiel #2
0
    def configure(tenant, systems, name, env):
        """Configure allocation tenant."""
        restapi = context.GLOBAL.admin_api(ctx.get('api'))
        tenant_url = '/tenant/%s' % tenant

        if systems:
            try:
                existing = restclient.get(restapi, tenant_url).json()
                all_systems = set(existing['systems'])
                all_systems.update(map(int, systems))
                restclient.put(restapi,
                               tenant_url,
                               payload={'systems': list(all_systems)})
            except restclient.NotFoundError:
                restclient.post(restapi,
                                tenant_url,
                                payload={'systems': map(int, systems)})

        if env:
            if name is None:
                name = env

            alloc_url = '/allocation/%s/%s' % (tenant, name)
            try:
                restclient.post(restapi,
                                alloc_url,
                                payload={'environment': env})
            except restclient.AlreadyExistsError:
                pass

        _display_tenant(restapi, tenant)
Beispiel #3
0
    def configure(name, cell, pattern, endpoints, alias, scope):
        """Create, modify or get Treadmill App DNS entry"""
        restapi = context.GLOBAL.admin_api()
        url = _REST_PATH + name
        data = {}

        if cell:
            data['cells'] = cell
        if pattern is not None:
            data['pattern'] = pattern
        if endpoints is not None:
            data['endpoints'] = endpoints
        if alias is not None:
            data['alias'] = alias
        if scope is not None:
            data['scope'] = scope

        if data:
            try:
                _LOGGER.debug('Trying to create app-dns entry %s', name)
                restclient.post(restapi, url, data)
            except restclient.AlreadyExistsError:
                _LOGGER.debug('Updating app-dns entry %s', name)
                restclient.put(restapi, url, data)

        _LOGGER.debug('Retrieving App DNS entry %s', name)
        app_dns_entry = restclient.get(restapi, url).json()

        cli.out(formatter(app_dns_entry))
Beispiel #4
0
    def configure(job_id, event, resource, expression, count):
        """Create or modify an existing app start schedule"""
        restapi = context.GLOBAL.cell_api(ctx['api'])
        url = _REST_PATH + job_id

        data = {}

        if event:
            data['event'] = event
        if resource:
            data['resource'] = resource
        if expression:
            data['expression'] = expression
        if count is not None:
            data['count'] = count

        if data:
            try:
                _LOGGER.debug('Creating cron job: %s', job_id)
                restclient.post(restapi, url, payload=data)
            except restclient.AlreadyExistsError:
                _LOGGER.debug('Updating cron job: %s', job_id)
                restclient.put(restapi, url, payload=data)

        _LOGGER.debug('Retrieving cron job: %s', job_id)
        job = restclient.get(restapi, url).json()
        _LOGGER.debug('job: %r', job)

        cli.out(_FORMATTER(job))
Beispiel #5
0
    def reserve(allocation, env, cell, partition, rank, rank_adjustment,
                max_utilization, empty, memory, cpu, disk, traits):
        """Reserve capacity on the cell for given environment."""
        _check_reserve_usage(empty, memory, cpu, disk)

        restapi = context.GLOBAL.admin_api(ctx.get('api'))

        _check_tenant_exists(restapi, allocation)
        _make_allocation(restapi, allocation, env)

        data = {}
        if empty:
            data['memory'] = '0M'
            data['disk'] = '0M'
            data['cpu'] = '0%'

        if memory:
            data['memory'] = memory
        if cpu:
            data['cpu'] = cpu
        if disk:
            data['disk'] = disk

        if rank is not None:
            data['rank'] = rank
        if rank_adjustment is not None:
            data['rank_adjustment'] = rank_adjustment
        if max_utilization is not None:
            data['max_utilization'] = max_utilization
        if partition:
            data['partition'] = partition
        if traits:
            data['traits'] = cli.combine(traits)

        if data:
            reservation_url = '/allocation/{}/{}/reservation/{}'.format(
                allocation, env, cell)

            try:
                existing = restclient.get(restapi, reservation_url).json()
                # TODO: need cleaner way of deleting attributes that are not
                #       valid for update. It is a hack.
                for attr in list(existing):
                    if (attr not in ['memory', 'cpu', 'disk', 'partition']):
                        del existing[attr]

                existing.update(data)
                restclient.put(restapi, reservation_url, payload=existing)

            except restclient.NotFoundError:
                # some attributes need default values when creating
                if not partition:
                    data['partition'] = admin.DEFAULT_PARTITION

                restclient.post(restapi, reservation_url, payload=data)

        _display_tenant(restapi, allocation)
Beispiel #6
0
 def test_default_timeout_put(self, resp_mock):
     """Tests that default timeout for put request is set correctly."""
     resp_mock.return_value.status_code = http.client.OK
     resp_mock.return_value.text = 'foo'
     restclient.put('http://foo.com', '/', '')
     resp_mock.assert_called_with(
         'http://foo.com/', stream=None, auth=mock.ANY,
         headers=None, json='', timeout=(0.5, None), proxies=None
     )
Beispiel #7
0
    def reserve(allocation, env, cell, partition, rank, rank_adjustment,
                max_utilization, empty, memory, cpu, disk, traits):
        """Reserve capacity on the cell for given environment."""
        _check_reserve_usage(empty, memory, cpu, disk)

        restapi = context.GLOBAL.admin_api(ctx.get('api'))

        _check_tenant_exists(restapi, allocation)
        _make_allocation(restapi, allocation, env)

        data = {}
        if empty:
            data['memory'] = '0M'
            data['disk'] = '0M'
            data['cpu'] = '0%'

        if memory:
            data['memory'] = memory
        if cpu:
            data['cpu'] = cpu
        if disk:
            data['disk'] = disk
        if partition:
            data['partition'] = partition

        reservation_url = '/allocation/{}/{}/reservation/{}'.format(
            allocation, env, cell)

        try:
            existing = restclient.get(restapi, reservation_url).json()
            if data:
                # To meet the json schema required in create
                if 'memory' not in data:
                    data['memory'] = existing['memory']
                if 'cpu' not in data:
                    data['cpu'] = existing['cpu']
                if 'disk' not in data:
                    data['disk'] = existing['disk']
                if 'partition' not in data:
                    data['partition'] = existing['partition']
                restclient.put(restapi, reservation_url, payload=data)
        except restclient.NotFoundError:
            if rank is not None:
                data['rank'] = rank
            if rank_adjustment is not None:
                data['rank_adjustment'] = rank_adjustment
            if max_utilization is not None:
                data['max_utilization'] = max_utilization
            if traits:
                data['traits'] = cli.combine(traits)

            restclient.post(restapi, reservation_url, payload=data)

        _display_tenant(restapi, allocation)
Beispiel #8
0
    def assign(allocation, env, cell, pattern, priority, delete):
        """Assign application pattern:priority to the allocation.

        Application pattern must start with <PROID>. and is a glob expression.

        Environments of the proid and one specified in command line using
        --env option must match.

        Once scheduled, Treadmill scheduler will match application against all
        available patterns and assign application to a reserved capacity.

        All application assigned to a capacity are ordered by priority from
        high to low.
        """
        restapi = context.GLOBAL.admin_api(ctx.get('api'))

        _check_tenant_exists(restapi, allocation)
        _make_allocation(restapi, allocation, env)

        reservation_url = '/allocation/{}/{}/reservation/{}'.format(
            allocation, env, cell)

        try:
            restclient.get(restapi, reservation_url)
        except restclient.NotFoundError:
            # TODO: default partition should be resolved in API, not in CLI.
            restclient.post(restapi,
                            reservation_url,
                            payload={
                                'memory': '0M',
                                'disk': '0M',
                                'cpu': '0%',
                                'partition': admin.DEFAULT_PARTITION
                            })

        url = '/allocation/{}/{}/assignment/{}/{}'.format(
            allocation, env, cell, pattern)

        if delete:
            restclient.delete(restapi, url)
        else:
            default_prio = None
            existing = restclient.get(restapi, url).json()
            for assignment in existing:
                if assignment['pattern'] == pattern:
                    default_prio = assignment['priority']
            if default_prio is None:
                default_prio = _DEFAULT_PRIORITY

            data = {'priority': priority if priority else default_prio}
            restclient.put(restapi, url, payload=data)

        _display_tenant(restapi, allocation)
 def test_raw_payload_put(self, resp_mock):
     """Tests that put can send payload not in json."""
     resp_mock.return_value.status_code = http_client.OK
     resp_mock.return_value.text = 'foo'
     restclient.put('http://foo.com', '/', 'payload', payload_to_json=False)
     resp_mock.assert_called_with('http://foo.com/',
                                  stream=None,
                                  auth=mock.ANY,
                                  headers=None,
                                  timeout=(0.5, None),
                                  proxies=None,
                                  data='payload',
                                  verify=True)
Beispiel #10
0
    def assign(allocation, cell, pattern, priority, delete):
        """Assign application pattern:priority to the allocation."""
        restapi = context.GLOBAL.admin_api(ctx.get('api'))
        url = '/allocation/%s/assignment/%s/%s' % (allocation, cell, pattern)
        if delete:
            restclient.delete(restapi, url)
        else:
            try:
                restclient.post(restapi, url, payload={'priority': priority})
            except restclient.AlreadyExistsError:
                restclient.put(restapi, url, payload={'priority': priority})

        _display_alloc(restapi, allocation)
def _configure_monitor(name, count):
    """Configure target count for the current cell."""
    _LOGGER.info('configuring monitor: %s, count: %s', name, count)
    url = '/app-monitor/%s' % name

    restapi = context.GLOBAL.cell_api()
    data = {'count': count}
    try:
        _LOGGER.debug('Creating app monitor: %s', name)
        restclient.post(restapi, url, payload=data)
    except restclient.AlreadyExistsError:
        _LOGGER.debug('Updating app monitor: %s', name)
        restclient.put(restapi, url, payload=data)
 def test_verify_put(self, resp_mock):
     """Tests that 'verify' for put request is set correctly."""
     resp_mock.return_value.status_code = http_client.OK
     resp_mock.return_value.text = 'foo'
     restclient.put('http://foo.com', '/', '', verify='/path/to/ca/certs')
     resp_mock.assert_called_with('http://foo.com/',
                                  stream=None,
                                  auth=mock.ANY,
                                  headers=None,
                                  json='',
                                  timeout=(0.5, None),
                                  proxies=None,
                                  verify='/path/to/ca/certs')
Beispiel #13
0
    def reserve(allocation, cell, partition, rank, memory, cpu, disk):
        """Reserve capacity on the cell."""
        restapi = context.GLOBAL.admin_api(ctx.get('api'))

        if (cell is None
                and any([memory, cpu, disk, rank is not None, partition])):
            raise click.UsageError(
                'Must specify cell with modifying reservation.')

        if cell:
            # Create reservation for the given cell.
            reservation_url = '/allocation/%s/reservation/%s' % (allocation,
                                                                 cell)
            try:
                existing = restclient.get(restapi, reservation_url).json()
                # TODO: need cleaner way of deleting attributes that are not
                #       valid for update. It is a hack.
                for attr in existing.keys():
                    if (attr not in [
                            'memory', 'cpu', 'disk', 'rank', 'partition'
                    ]):
                        del existing[attr]

                if memory:
                    existing['memory'] = memory
                if cpu:
                    existing['cpu'] = cpu
                if disk:
                    existing['disk'] = disk
                if rank is not None:
                    existing['rank'] = rank
                if partition:
                    existing['partition'] = partition
                restclient.put(restapi, reservation_url, payload=existing)
            except restclient.NotFoundError:
                payload = {
                    'memory': memory,
                    'disk': disk,
                    'cpu': cpu,
                    'rank': rank if rank is not None else 100
                }

                if partition:
                    payload['partition'] = partition
                else:
                    payload['partition'] = admin.DEFAULT_PARTITION

                restclient.post(restapi, reservation_url, payload=payload)

        _display_alloc(restapi, allocation)
Beispiel #14
0
    def assign(allocation, cell, pattern, priority, delete):
        """Assign application pattern:priority to the allocation."""
        restapi = context.GLOBAL.admin_api(ctx.get('api'))
        url = '/allocation/%s/assignment/%s/%s' % (allocation, cell, pattern)

        if not delete and priority is None:
            raise click.UsageError(
                'Must specify priority when creating/modifying assignments.')

        if delete:
            restclient.delete(restapi, url)
        else:
            restclient.put(restapi, url, payload={'priority': priority})

        _display_alloc(restapi, allocation)
Beispiel #15
0
    def put(path, payload):
        """REST PUT request."""
        request = yaml.load(payload.read())
        response = restclient.put(ctx['api'], path, payload=request)

        formatter = cli.make_formatter(None)
        cli.out(formatter(response.json()))
    def assign(allocation, env, cell, pattern, priority, delete):
        """Assign application pattern:priority to the allocation.

        Application pattern must start with <PROID>. and is a glob expression.

        Environments of the proid and one specified in command line using
        --env option must match.

        Once scheduled, Treadmill scheduler will match application against all
        available patterns and assign application to a reserved capacity.

        All application assigned to a capacity are ordered by priority from
        high to low.
        """
        restapi = context.GLOBAL.admin_api()

        _check_tenant_exists(restapi, allocation)
        _make_allocation(restapi, allocation, env)

        reservation_url = '/allocation/{}/{}/reservation/{}'.format(
            allocation, env, cell)

        try:
            restclient.get(restapi, reservation_url)
        except restclient.NotFoundError:
            restclient.post(restapi,
                            reservation_url,
                            payload={
                                'memory': '0M',
                                'disk': '0M',
                                'cpu': '0%'
                            })

        url = '/allocation/{}/{}/assignment/{}/{}'.format(
            allocation, env, cell, pattern)

        if delete:
            restclient.delete(restapi, url)
        else:
            data = {}
            if priority:
                data['priority'] = priority
            # assign is always put
            # because assign and reserve belong to the same ldap obj
            restclient.put(restapi, url, payload=data)

            _display_tenant(restapi, allocation)
Beispiel #17
0
    def pause(job_id):
        """Pause a cron job"""
        restapi = context.GLOBAL.cell_api()
        url = _REST_PATH + job_id + '?pause=true'
        job = restclient.put(restapi, url, {}).json()
        _LOGGER.debug('job: %r', job)

        cli.out(_FORMATTER(job))
Beispiel #18
0
    def resume(job_id):
        """Resume a cron job"""
        restapi = context.GLOBAL.cell_api(ctx['api'])
        url = _REST_PATH + job_id + '?resume=true'
        job = restclient.put(restapi, url, {}).json()
        _LOGGER.debug('job: %r', job)

        cli.out(_FORMATTER(job))
Beispiel #19
0
    def cells(add, remove, name):
        """Add or remove cells from the app-dns."""
        url = _REST_PATH + name
        restapi = context.GLOBAL.admin_api()
        existing = restclient.get(restapi, url).json()

        cells = set(existing['cells'])

        if add:
            cells.update(add)
        if remove:
            cells = cells - set(remove)

        if '_id' in existing:
            del existing['_id']
        existing['cells'] = list(cells)
        restclient.put(restapi, url, existing)
Beispiel #20
0
    def configure(count, name):
        """Configure application monitor"""
        restapi = context.GLOBAL.cell_api()
        url = _REST_PATH + name

        if count is not None:
            data = {'count': count}
            try:
                _LOGGER.debug('Creating app monitor: %s', name)
                restclient.post(restapi, url, payload=data)
            except restclient.AlreadyExistsError:
                _LOGGER.debug('Updating app monitor: %s', name)
                restclient.put(restapi, url, payload=data)

        _LOGGER.debug('Retrieving app monitor: %s', name)
        monitor_entry = restclient.get(restapi, url)
        cli.out(formatter(monitor_entry.json()))
Beispiel #21
0
    def put(path, payload):
        """REST PUT request."""
        with io.open(payload, 'rb') as fd:
            request = yaml.load(stream=fd)
        response = restclient.put(ctx['api'], path, payload=request)

        formatter = cli.make_formatter(None)
        cli.out(formatter(response.json()))
Beispiel #22
0
    def configure(allocation, systems, set_):
        """Configure allocation.

        Allocation name is global, and is associated with list of systems.
        """
        restapi = context.GLOBAL.admin_api()
        url = '/tenant/{}'.format(allocation)

        if systems:

            # If tenant exists, update or replace it with new systems.
            # If update fails with resource does not exist error, try creating
            # tenants from parent to child, those that do not exist will be
            # created with provided systems.
            try:
                existing = restclient.get(restapi, url).json()
                all_systems = set(six.moves.map(int, systems))
                # if the system ids have to be extended instead of replaced
                if not set_:
                    all_systems.update(existing['systems'])
                restclient.put(restapi,
                               url,
                               payload={'systems': list(all_systems)})
            except restclient.NotFoundError:
                # Create parent tenants recursively.
                #
                # If parent does not exist, it will be created with the systems
                # specified.
                parts = allocation.split(':')
                for idx in range(1, len(parts) + 1):
                    url = '/tenant/{}'.format(':'.join(parts[:idx]))

                    try:
                        existing = restclient.get(restapi, url).json()
                    except restclient.NotFoundError:
                        restclient.post(restapi,
                                        url,
                                        payload={
                                            'systems':
                                            list(six.moves.map(int, systems))
                                        })

        _display_tenant(restapi, allocation)
Beispiel #23
0
def _configure(apis, manifest, appname):
    """Configure a Treadmill app"""
    try:
        existing = restclient.get(apis, _APP_REST_PATH + appname).json()

    except restclient.NotFoundError:
        if not manifest:
            raise
        else:
            existing = None

    if manifest:
        app = yaml.load(manifest.read())
        if existing:
            restclient.put(apis, _APP_REST_PATH + appname, payload=app)
        else:
            restclient.post(apis, _APP_REST_PATH + appname, payload=app)

        # Get new value after update.
        existing = restclient.get(apis, _APP_REST_PATH + appname).json()

    cli.out(_FORMATTER(existing))
Beispiel #24
0
def _configure(apis, manifest, appname):
    """Configure a Treadmill app"""
    try:
        existing = restclient.get(apis, _APP_REST_PATH + appname).json()
    except restclient.NotFoundError:
        if not manifest:
            raise
        existing = None

    if manifest:
        app = yaml.load(stream=manifest)

        if existing:
            response = restclient.put(apis,
                                      _APP_REST_PATH + appname,
                                      payload=app)
        else:
            response = restclient.post(apis,
                                       _APP_REST_PATH + appname,
                                       payload=app)
        existing = response.json()

    cli.out(_FORMATTER(existing))