Example #1
0
    def get_profile_data(self, profile):
        """get_profile_data

        Get data for a profile out of etcd. This should be used on profiles
        returned from functions like ``get_profiles``.

        :param profile: A ``Profile`` class.
        :return: A ``Profile`` class with tags and rules data present.
        """
        LOG.debug("Getting profile %s", profile.id)
        etcd_profile_id = with_openstack_sg_prefix(profile.id)

        tags_result = self.client.read(
            datamodel_v1.key_for_profile_tags(etcd_profile_id),
            timeout=ETCD_TIMEOUT)
        rules_result = self.client.read(
            datamodel_v1.key_for_profile_rules(etcd_profile_id),
            timeout=ETCD_TIMEOUT)

        return Profile(
            id=profile.id,
            tags_modified_index=tags_result.modifiedIndex,
            rules_modified_index=rules_result.modifiedIndex,
            tags_data=tags_result.value,
            rules_data=rules_result.value,
        )
Example #2
0
    def get_profile_data(self, profile):
        """get_profile_data

        Get data for a profile out of etcd. This should be used on profiles
        returned from functions like ``get_profiles``.

        :param profile: A ``Profile`` class.
        :return: A ``Profile`` class with tags and rules data present.
        """
        LOG.debug("Getting profile %s", profile.id)
        etcd_profile_id = with_openstack_sg_prefix(profile.id)

        tags_result = self.client.read(
            datamodel_v1.key_for_profile_tags(etcd_profile_id),
            timeout=ETCD_TIMEOUT
        )
        rules_result = self.client.read(
            datamodel_v1.key_for_profile_rules(etcd_profile_id),
            timeout=ETCD_TIMEOUT
        )

        return Profile(
            id=profile.id,
            tags_modified_index=tags_result.modifiedIndex,
            rules_modified_index=rules_result.modifiedIndex,
            tags_data=tags_result.value,
            rules_data=rules_result.value,
        )
Example #3
0
    def write_profile_to_etcd(self,
                              profile,
                              prev_rules_index=None,
                              prev_tags_index=None):
        """Write a single security profile into etcd."""
        LOG.debug("Writing profile %s", profile)
        etcd_profile_id = with_openstack_sg_prefix(profile.id)

        # python-etcd is stupid about the prevIndex keyword argument, so we
        # need to explicitly filter out None-y values ourselves.
        rules_kwargs = {}
        if prev_rules_index is not None:
            rules_kwargs['prevIndex'] = prev_rules_index

        tags_kwargs = {}
        if prev_tags_index is not None:
            tags_kwargs['prevIndex'] = prev_tags_index

        self.client.write(
            datamodel_v1.key_for_profile_rules(etcd_profile_id),
            json.dumps(profile_rules(profile)),
            **rules_kwargs
        )

        self.client.write(
            datamodel_v1.key_for_profile_tags(etcd_profile_id),
            json.dumps(profile_tags(profile)),
            **tags_kwargs
        )
Example #4
0
    def atomic_delete_profile(self, profile):
        """atomic_delete_profile

        Atomically delete a profile. This occurs in two stages: first the tag,
        then the rules. Abort if the first stage fails, as we can assume that
        someone else is trying to replace the profile.

        Tolerates attempting to delete keys that are already deleted.

        This will also attempt to clean up the directory, but isn't overly
        bothered if that fails.
        """
        LOG.info(
            "Deleting profile %s, tags modified %s, rules modified %s",
            profile.id,
            profile.tags_modified_index,
            profile.rules_modified_index
        )
        etcd_profile_id = with_openstack_sg_prefix(profile.id)

        # Try to delete tags and rules. We don't care if we can't, but we
        # should log in case it's symptomatic of a wider problem.
        try:
            self.client.delete(
                datamodel_v1.key_for_profile_tags(etcd_profile_id),
                prevIndex=profile.tags_modified_index,
                timeout=ETCD_TIMEOUT
            )
        except etcd.EtcdKeyNotFound:
            LOG.info(
                "Profile %s tags already deleted, nothing to do.", profile.id
            )

        try:
            self.client.delete(
                datamodel_v1.key_for_profile_rules(etcd_profile_id),
                prevIndex=profile.rules_modified_index,
                timeout=ETCD_TIMEOUT
            )
        except etcd.EtcdKeyNotFound:
            LOG.info(
                "Profile %s rules already deleted, nothing to do.", profile.id
            )

        # Strip the rules/tags specific part of the key.
        profile_key = datamodel_v1.key_for_profile(etcd_profile_id)

        try:
            self.client.delete(profile_key, dir=True, timeout=ETCD_TIMEOUT)
        except etcd.EtcdException as e:
            LOG.debug("Failed to delete %s (%r), giving up.", profile_key, e)
Example #5
0
    def atomic_delete_profile(self, profile):
        """atomic_delete_profile

        Atomically delete a profile. This occurs in two stages: first the tag,
        then the rules. Abort if the first stage fails, as we can assume that
        someone else is trying to replace the profile.

        Tolerates attempting to delete keys that are already deleted.

        This will also attempt to clean up the directory, but isn't overly
        bothered if that fails.
        """
        LOG.info("Deleting profile %s, tags modified %s, rules modified %s",
                 profile.id, profile.tags_modified_index,
                 profile.rules_modified_index)
        etcd_profile_id = with_openstack_sg_prefix(profile.id)

        # Try to delete tags and rules. We don't care if we can't, but we
        # should log in case it's symptomatic of a wider problem.
        try:
            self.client.delete(
                datamodel_v1.key_for_profile_tags(etcd_profile_id),
                prevIndex=profile.tags_modified_index,
                timeout=ETCD_TIMEOUT)
        except etcd.EtcdKeyNotFound:
            LOG.info("Profile %s tags already deleted, nothing to do.",
                     profile.id)

        try:
            self.client.delete(
                datamodel_v1.key_for_profile_rules(etcd_profile_id),
                prevIndex=profile.rules_modified_index,
                timeout=ETCD_TIMEOUT)
        except etcd.EtcdKeyNotFound:
            LOG.info("Profile %s rules already deleted, nothing to do.",
                     profile.id)

        # Strip the rules/tags specific part of the key.
        profile_key = datamodel_v1.key_for_profile(etcd_profile_id)

        try:
            self.client.delete(profile_key, dir=True, timeout=ETCD_TIMEOUT)
        except etcd.EtcdException as e:
            LOG.debug("Failed to delete %s (%r), giving up.", profile_key, e)
Example #6
0
    def write_profile_to_etcd(self,
                              profile,
                              prev_rules_index=None,
                              prev_tags_index=None):
        """Write a single security profile into etcd."""
        LOG.debug("Writing profile %s", profile)
        etcd_profile_id = with_openstack_sg_prefix(profile.id)

        # python-etcd is stupid about the prevIndex keyword argument, so we
        # need to explicitly filter out None-y values ourselves.
        rules_kwargs = {}
        if prev_rules_index is not None:
            rules_kwargs['prevIndex'] = prev_rules_index

        tags_kwargs = {}
        if prev_tags_index is not None:
            tags_kwargs['prevIndex'] = prev_tags_index

        self.client.write(datamodel_v1.key_for_profile_rules(etcd_profile_id),
                          json.dumps(profile_rules(profile)), **rules_kwargs)

        self.client.write(datamodel_v1.key_for_profile_tags(etcd_profile_id),
                          json.dumps(profile_tags(profile)), **tags_kwargs)
 def test_key_for_profile_tags(self):
     self.assertEqual(key_for_profile_tags("prof1"),
                      "/calico/v1/policy/profile/prof1/tags")
 def test_key_for_profile_tags(self):
     self.assertEqual(key_for_profile_tags("prof1"), "/calico/v1/policy/profile/prof1/tags")