<commit_before>#!/usr/bin/env python
#
# Copyright 2012, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from opencenter import backends
import opencenter.webapp.ast
import opencenter.db.api


class NodeBackend(backends.Backend):
    def __init__(self):
        super(NodeBackend, self).__init__(__file__)

    def additional_constraints(self, api, node_id, action, ns):
        if action == 'set_fact':
            addl_constraints = []

            if not 'key' in ns:
                raise ValueError('no key in ns')
            key = ns['key']

            # see what backend this key is in...
            for name, obj in backends.backend_objects.iteritems():
                if key in obj.facts:
                    # we can only solve for settable facts.  If the
                    # fact is not settable, then there is likely (HAS TO BE!)
                    # a primitive to set this somewhere else.  Probably in
                    # the same backend.
                    fact_info = obj.facts[key]
                    if fact_info['settable'] is not True:
                        return None

                    addl_constraints.append('"%s" in facts.backends' % name)
                    # if fact_info['converge']:
                    #     addl_constraints.append('facts.converged = true')
                    return addl_constraints
            return None

        if action == 'unapply_fact':
            if not 'key' in ns:
                raise ValueError('no key in ns')

            key = ns['key']

            addl_constraints = []

            for name, obj in backends.backend_objects.iteritems():
                if key in obj.facts:
                    # we can only solve for settable facts.  If the
                    # fact is not settable, then there is likely (HAS TO BE!)
                    # a primitive to set this somewhere else.  Probably in
                    # the same backend.
                    addl_constraints.append('"%s" in facts.backends' % name)
                    fact_info = obj.facts[key]
                    if fact_info['converge'] is True:
                        addl_constraints.append('facts.converged = true')

                    return addl_constraints
            return None

        if action == 'apply_fact':
            if not 'key' in ns:
                raise ValueError('no key in ns')
            key = ns['key']

            addl_constraints = []
            # see what backend this key is in...
            for name, obj in backends.backend_objects.iteritems():
                if key in obj.facts:
                    # we can only solve for settable facts.  If the
                    # fact is not settable, then there is likely (HAS TO BE!)
                    # a primitive to set this somewhere else.  Probably in
                    # the same backend.
                    addl_constraints.append('"%s" in facts.backends' % name)
                    fact_info = obj.facts[key]
                    if fact_info['converge'] is True:
                        addl_constraints.append('facts.converged = true')

                    return addl_constraints
            return None

        if action == 'add_backend':
            if ns['backend'] == 'node':
                return []

            if opencenter.backends.primitive_by_name(
                    '%s.add_backend' % ns['backend']) is None:
                return []
            else:
                return None

        if action == 'set_parent':
            new_constraints = []

            if not 'parent' in ns:
                raise ValueError('no parent set')
            parent = api._model_get_by_id('nodes', ns['parent'])
            if 'container' in parent['facts'].get('backends', {}):
                # should already be the case, but...
                new_constraints.append('"node" in facts.backends')

                existing_node = api._model_get_by_id('nodes', node_id)

                ephemeral_api = opencenter.db.api.ephemeral_api_from_api(api)
                opencenter.webapp.ast.apply_expression(existing_node,
                                                       'facts.parent_id :='
                                                       '"%s"' %
                                                       parent['id'],
                                                       ephemeral_api)

                proposed_node = ephemeral_api._model_get_by_id('nodes',
                                                               node_id)

                self.logger.debug('Setting parent would change %s to %s' %
                                  (existing_node, proposed_node))

                # this should be much smarter.  losing vs gaining,
                # and add/remove facts as appropriate.
                all_keys = set(existing_node['facts'].keys() +<commit_msg>Do not allow set_parent on locked nodes<commit_after>#!/usr/bin/env python
#
# Copyright 2012, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from opencenter import backends
import opencenter.webapp.ast
import opencenter.db.api


class NodeBackend(backends.Backend):
    def __init__(self):
        super(NodeBackend, self).__init__(__file__)

    def additional_constraints(self, api, node_id, action, ns):
        if action == 'set_fact':
            addl_constraints = []

            if not 'key' in ns:
                raise ValueError('no key in ns')
            key = ns['key']

            # see what backend this key is in...
            for name, obj in backends.backend_objects.iteritems():
                if key in obj.facts:
                    # we can only solve for settable facts.  If the
                    # fact is not settable, then there is likely (HAS TO BE!)
                    # a primitive to set this somewhere else.  Probably in
                    # the same backend.
                    fact_info = obj.facts[key]
                    if fact_info['settable'] is not True:
                        return None

                    addl_constraints.append('"%s" in facts.backends' % name)
                    # if fact_info['converge']:
                    #     addl_constraints.append('facts.converged = true')
                    return addl_constraints
            return None

        if action == 'unapply_fact':
            if not 'key' in ns:
                raise ValueError('no key in ns')

            key = ns['key']

            addl_constraints = []

            for name, obj in backends.backend_objects.iteritems():
                if key in obj.facts:
                    # we can only solve for settable facts.  If the
                    # fact is not settable, then there is likely (HAS TO BE!)
                    # a primitive to set this somewhere else.  Probably in
                    # the same backend.
                    addl_constraints.append('"%s" in facts.backends' % name)
                    fact_info = obj.facts[key]
                    if fact_info['converge'] is True:
                        addl_constraints.append('facts.converged = true')

                    return addl_constraints
            return None

        if action == 'apply_fact':
            if not 'key' in ns:
                raise ValueError('no key in ns')
            key = ns['key']

            addl_constraints = []
            # see what backend this key is in...
            for name, obj in backends.backend_objects.iteritems():
                if key in obj.facts:
                    # we can only solve for settable facts.  If the
                    # fact is not settable, then there is likely (HAS TO BE!)
                    # a primitive to set this somewhere else.  Probably in
                    # the same backend.
                    addl_constraints.append('"%s" in facts.backends' % name)
                    fact_info = obj.facts[key]
                    if fact_info['converge'] is True:
                        addl_constraints.append('facts.converged = true')

                    return addl_constraints
            return None

        if action == 'add_backend':
            if ns['backend'] == 'node':
                return []

            if opencenter.backends.primitive_by_name(
                    '%s.add_backend' % ns['backend']) is None:
                return []
            else:
                return None

        if action == 'set_parent':
            new_constraints = []

            if not 'parent' in ns:
                raise ValueError('no parent set')
            parent = api._model_get_by_id('nodes', ns['parent'])
            if 'container' in parent['facts'].get('backends', {}):
                # should already be the case, but...
                new_constraints.append('"node" in facts.backends')

                existing_node = api._model_get_by_id('nodes', node_id)
                if existing_node.get('attrs', {}).get('locked', False) == True:
                    # Node is locked, set_parent not allowed.
                    return None
                ephemeral_api = opencenter.db.api.ephemeral_api_from_api(api)
                opencenter.webapp.ast.apply_expression(existing_node,
                                                       'facts.parent_id :='
                                                       '"%s"' %
                                                       parent['id'],
                                                       ephemeral_api)

                proposed_node = ephemeral_api._model_get_by_id('nodes',
                                                               node_id)

                self.logger.debug('Setting parent would change %s to %s' %
                                  (existing_node, proposed_node))

                # this should be much smarter.  losing vs gaining,
                # and add/remove facts as appropriate.
                all_keys = set(existing_node['facts'].keys() +
{'fraction_non_alphanumeric': 0.0825629290617849, 'fraction_numerical': 0.0014645308924485126, 'mean_word_length': 1.4215425531914894, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3087870', 'n_tokens_mistral': 2790, 'n_tokens_neox': 2607, 'n_words': 871}