Ejemplo n.º 1
0
def test_json_simple_property():
    """ Test simple dict """

    dataIn = {'a': 1, 'b': 2, 'c': 3}
    dataOut1 = {'a': 1, 'b': 2, 'c': 3}
    dataOut2 = {'c': 3, 'b': 2, 'a': 1}
    dataOut3 = {'a': 1, 'b': 2}
    dataOut4 = {'b': 2}
    dataOut5 = {}

    patch_strIn = '[{"path": "/a", "op": "remove"}]'
    patch_strOutPropExists = '[{"path": "/a", "op": "remove"}]'
    patch_strOutPropNotExists = '[]'

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut1, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut2, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut3, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropNotExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut4, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropNotExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut5, patch)
    assert patch == expected_patch
Ejemplo n.º 2
0
    def merge(self, desired_data):
        u"""Merge in properties from controller instead of replacing"""
        # 1. stop processing if no merging is needed
        prev_updates = self._retrieve_whitelist_updates()
        if desired_data == {} and prev_updates is None:
            # nothing needs to be done (cccl has not and will not make changes
            # to this resource)
            return False

        prev_data = copy.deepcopy(self._data)

        # 2. remove old CCCL updates
        pospatch.convert_to_positional_patch(self._data, prev_updates)

        try:
            # This actually backs out the previous updates
            # to get back to the original F5 resource state.
            if prev_updates:
                self._data = prev_updates.apply(self._data)
        except Exception as e:  # pylint: disable=broad-except
            LOGGER.warning("Failed removing updates to resource %s: %s",
                           self.name, e)

        # 3. perform new merge with latest CCCL specific config
        original_resource = copy.deepcopy(self)
        self._data = merge(self._data, desired_data)
        self.post_merge_adjustments()

        # 4. compute the new updates so we can back out next go-around
        cur_updates = jsonpatch.make_patch(self._data, original_resource.data)

        # 5. remove move / adjust indexes per resource specific
        pospatch.convert_from_positional_patch(self._data, cur_updates)

        changed = self._data != prev_data

        # 6. update metadata with new CCCL updates
        self._save_whitelist_updates(cur_updates)

        # 7. determine if there was a needed change
        return changed
Ejemplo n.º 3
0
    def merge(self, desired_data):
        u"""Merge in properties from controller instead of replacing"""
        # 1. stop processing if no merging is needed
        prev_updates = self._retrieve_whitelist_updates()
        if desired_data == {} and prev_updates is None:
            # nothing needs to be done (cccl has not and will not make changes
            # to this resource)
            return False

        prev_data = copy.deepcopy(self._data)

        # 2. remove old CCCL updates
        pospatch.convert_to_positional_patch(self._data, prev_updates)

        try:
            # This actually backs out the previous updates
            # to get back to the original F5 resource state.
            if prev_updates:
                self._data = prev_updates.apply(self._data)
        except Exception as e:  # pylint: disable=broad-except
            LOGGER.warning("Failed removing updates to resource %s: %s",
                           self.name, e)

        # 3. perform new merge with latest CCCL specific config
        original_resource = copy.deepcopy(self)
        self._data = merge(self._data, desired_data)
        self.post_merge_adjustments()

        # 4. compute the new updates so we can back out next go-around
        cur_updates = jsonpatch.make_patch(self._data, original_resource.data)

        # 5. remove move / adjust indexes per resource specific
        pospatch.convert_from_positional_patch(self._data, cur_updates)

        changed = self._data != prev_data

        # 6. update metadata with new CCCL updates
        self._save_whitelist_updates(cur_updates)

        # 7. determine if there was a needed change
        return changed
Ejemplo n.º 4
0
def test_json_simple_array():
    """ Test simple arrays """

    dataIn = {
        'rules': [
            'A',
            'B',
        ],
    }
    dataOut1 = {
        'rules': [
            'A',
            'B',
        ],
    }
    dataOut2 = {
        'rules': [
            'B',
            'A',
        ],
    }
    dataOut3 = {
        'rules': [
            'A',
        ],
    }
    dataOut4 = {
        'rules': [
            'B',
        ],
    }

    patch_strIn = '[{"path": "/rules/1", "op": "remove"}]'
    patch_strOut1 = '[{"path": "/rules/1", "op": "remove"}]'
    patch_strOut2 = '[{"path": "/rules/0", "op": "remove"}]'
    patch_strOut3 = '[]'
    patch_strOut4 = '[{"path": "/rules/0", "op": "remove"}]'

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut1)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut1, patch)
    assert patch == expected_patch

    # Test that if the order is switched (user rearranges the
    # order on the Big-IP), the patching still works correctly
    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut2)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut2, patch)
    assert patch == expected_patch

    # Test if the patched entry is deleted (e.g. user deleted a
    # rule/policy on the Big-IP)
    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut3)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut3, patch)
    assert patch == expected_patch

    # Test if another entry is deleted (e.g. user deleted a
    # rule/policy on the Big-IP)
    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut4)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut4, patch)
    assert patch == expected_patch
Ejemplo n.º 5
0
def test_json_simple_property():
    """ Test simple dict """

    dataIn = {
        'a': 1,
        'b': 2,
        'c': 3
    }
    dataOut1 = {
        'a': 1,
        'b': 2,
        'c': 3
    }
    dataOut2 = {
        'c': 3,
        'b': 2,
        'a': 1
    }
    dataOut3 = {
        'a': 1,
        'b': 2
    }
    dataOut4 = {
        'b': 2
    }
    dataOut5 = {
    }

    patch_strIn = '[{"path": "/a", "op": "remove"}]'
    patch_strOutPropExists = '[{"path": "/a", "op": "remove"}]'
    patch_strOutPropNotExists = '[]'

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut1, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut2, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut3, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropNotExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut4, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOutPropNotExists)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut5, patch)
    assert patch == expected_patch
Ejemplo n.º 6
0
def test_json_compound_array():
    """ Test arrays of dictionaries """

    dataIn = {
        'profiles': [
            {
                'partition': 'Common',
                'name': 'http',
                'context': 'all'
            },
            {
                'partition': 'Common',
                'name': 'tcp',
                'context': 'all'
            }
        ],
    }
    dataOut1 = {
        'profiles': [
            {
                'partition': 'Common',
                'name': 'http',
                'context': 'all'
            },
            {
                'partition': 'Common',
                'name': 'tcp',
                'context': 'all'
            }
        ]
    }
    dataOut2 = {
        'profiles': [
            {
                'partition': 'Common',
                'name': 'tcp',
                'context': 'all'
            }
        ]
    }
    dataOut3 = {
        'profiles': [
            {
                'partition': 'Common',
                'name': 'http',
                'context': 'all'
            },
            {
                'partition': 'Common',
                'name': 'tcp',
            }
        ]
    }
    dataOut4 = {
        'profiles': [
            {
                'partition': 'Common',
                'name': 'http',
                'context': 'all'
            }
        ]
    }

    patch_strIn = \
        '[{"path": "/profiles/1/context", "value": "none", "op": "replace"}]'
    patch_strOut1 = \
        '[{"path": "/profiles/1/context", "value": "none", "op": "replace"}]'
    patch_strOut2 = \
        '[{"path": "/profiles/0/context", "value": "none", "op": "replace"}]'
    patch_strOut3 = \
        '[]'
    patch_strOut4 = '[]'

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut1)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut1, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut2)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut2, patch)
    assert patch == expected_patch

    # if an array entry is modified by user, we must treat it as a new
    # entry and will not attempt to patch it (fortunately, this does not
    # seem possible on the Big-IP).
    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut3)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut3, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut4)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut4, patch)
    assert patch == expected_patch
Ejemplo n.º 7
0
def test_json_simple_array():
    """ Test simple arrays """

    dataIn = {
        'rules': [
            'A',
            'B',
        ],
    }
    dataOut1 = {
        'rules': [
            'A',
            'B',
        ],
    }
    dataOut2 = {
        'rules': [
            'B',
            'A',
        ],
    }
    dataOut3 = {
        'rules': [
            'A',
        ],
    }
    dataOut4 = {
        'rules': [
            'B',
        ],
    }

    patch_strIn = '[{"path": "/rules/1", "op": "remove"}]'
    patch_strOut1 = '[{"path": "/rules/1", "op": "remove"}]'
    patch_strOut2 = '[{"path": "/rules/0", "op": "remove"}]'
    patch_strOut3 = '[]'
    patch_strOut4 = '[{"path": "/rules/0", "op": "remove"}]'

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut1)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut1, patch)
    assert patch == expected_patch

    # Test that if the order is switched (user rearranges the
    # order on the Big-IP), the patching still works correctly
    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut2)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut2, patch)
    assert patch == expected_patch

    # Test if the patched entry is deleted (e.g. user deleted a
    # rule/policy on the Big-IP)
    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut3)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut3, patch)
    assert patch == expected_patch

    # Test if another entry is deleted (e.g. user deleted a
    # rule/policy on the Big-IP)
    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut4)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut4, patch)
    assert patch == expected_patch
Ejemplo n.º 8
0
def test_json_compound_array():
    """ Test arrays of dictionaries """

    dataIn = {
        'profiles': [{
            'partition': 'Common',
            'name': 'http',
            'context': 'all'
        }, {
            'partition': 'Common',
            'name': 'tcp',
            'context': 'all'
        }],
    }
    dataOut1 = {
        'profiles': [{
            'partition': 'Common',
            'name': 'http',
            'context': 'all'
        }, {
            'partition': 'Common',
            'name': 'tcp',
            'context': 'all'
        }]
    }
    dataOut2 = {
        'profiles': [{
            'partition': 'Common',
            'name': 'tcp',
            'context': 'all'
        }]
    }
    dataOut3 = {
        'profiles': [{
            'partition': 'Common',
            'name': 'http',
            'context': 'all'
        }, {
            'partition': 'Common',
            'name': 'tcp',
        }]
    }
    dataOut4 = {
        'profiles': [{
            'partition': 'Common',
            'name': 'http',
            'context': 'all'
        }]
    }

    patch_strIn = \
        '[{"path": "/profiles/1/context", "value": "none", "op": "replace"}]'
    patch_strOut1 = \
        '[{"path": "/profiles/1/context", "value": "none", "op": "replace"}]'
    patch_strOut2 = \
        '[{"path": "/profiles/0/context", "value": "none", "op": "replace"}]'
    patch_strOut3 = \
        '[]'
    patch_strOut4 = '[]'

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut1)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut1, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut2)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut2, patch)
    assert patch == expected_patch

    # if an array entry is modified by user, we must treat it as a new
    # entry and will not attempt to patch it (fortunately, this does not
    # seem possible on the Big-IP).
    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut3)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut3, patch)
    assert patch == expected_patch

    patch = jsonpatch.JsonPatch.from_string(patch_strIn)
    expected_patch = jsonpatch.JsonPatch.from_string(patch_strOut4)
    pospatch.convert_from_positional_patch(dataIn, patch)
    pospatch.convert_to_positional_patch(dataOut4, patch)
    assert patch == expected_patch