Ejemplo n.º 1
0
    def _validate_rules(self, rules):
        """ _validate_rules is a helper method which recieves a list of raw
        rule definitions and ensures that all the mandatory fields of the rule
        are specified and that the protocol specified within them is supported
        by Azure security groups.
        """
        supported_protos = ["tcp", "udp", "*"]  # NOTE: '*' = both udp and tcp

        for ruleno, rule in enumerate(rules):
            # first; check that the field is there in the first place:
            if self._protocol_field_name not in rule:
                raise exceptions.SecurityGroupMissingFieldException(
                    "'%s': security group '%s''s rule number %d has no '%s'"
                    "field defined." % (
                        self, self._heat_resource_name,
                        ruleno + 1, self._protocol_field_name
                    )
                )

            # then, ensure the protocol is ok:
            proto = rule[self._protocol_field_name]
            if proto.lower() not in supported_protos:
                raise exceptions.SecurityGroupInvalidFieldException(
                    "'%s': security group '%s' rule number %d has an invalid '"
                    "%s' field: '%s'. Valid protocols are 'tcp', 'udp' and '*'"
                    % (
                        self, self._heat_resource_name, ruleno + 1,
                        self._protocol_field_name, proto
                    )
                )

            # lastly, check for all the other mandatory fields:
            for field in self._mandatory_rule_fields:
                if field not in rule:
                    raise exceptions.SecurityGroupMissingFieldException(
                        "'%s': security group '%s' rule number %d's '%s' field"
                        " is missing." % (
                            self, self._heat_resource_name, ruleno + 1, field
                        )
                    )
Ejemplo n.º 2
0
    def _get_target(self):
        """ _get_target returns the target security group of the rule.

        SecurityGroupIngress rules can specify the target group
        through the 'GroupId' field.
        """
        if 'GroupId' not in self._heat_resource.properties:
            raise exceptions.SecurityGroupMissingFieldException(
                "'%s': security group rule '%s' has no 'GroupId' field set." %
                (self, self._heat_resource_name))

        target_group = self._heat_resource.properties["GroupId"]
        if target_group not in self._context.heat_resource_stack:
            raise exceptions.SecurityGroupNotFoundException(
                "'%s': target security group '%s' for rule '%s' does not "
                "exist." % (self, target_group, self._heat_resource_name))

        return target_group
Ejemplo n.º 3
0
    def _validate_input_rule(self):
        """ _validate_input_rule is a helper method which checks the provided
        SecurityGroupRule resource's fields for all the mandatory ones.
        """
        mandatories = ["IpProtocol", "FromPort", "ToPort"]

        for field in mandatories:
            if field not in self._heat_resource.properties:
                raise exceptions.SecurityGroupMissingFieldException(
                    "'%s': security group rule resource '%s' has no '%s' "
                    "field." % (self, self._heat_resource_name, field))

        # validate the value of IpProtocol:
        allowed_protos = ["tcp", "udp", "*"]
        if (self._heat_resource.properties["IpProtocol"].lower()
                not in allowed_protos):
            raise exceptions.SecurityGroupInvalidFieldException(
                "'%s': Invalid value '%s' provided for 'IpProtocol'. "
                "only include 'tcp', 'udp' and '*'.", self,
                self._heat_resource.properties["IpProtocol"])
Ejemplo n.º 4
0
    def _get_target(self):
        """ _get_target returns the target SecurityGroup of the rule.

        SecurityGroupIngress rules can specify the target group through either
        a 'GroupId' or 'GroupName' field.
        """
        target_group = ""

        if 'GroupName' in self._heat_resource.properties:
            target_group = self._heat_resource.properties["GroupName"]
        elif 'GroupId' in self._heat_resource.properties:
            target_group = self._heat_resource.properties["GroupId"]

        # check that the target does indeed exist:
        if not target_group:
            raise exceptions.SecurityGroupMissingFieldException(
                "'%s': security group rule '%s' has neither a 'GroupName' or "
                "'GroupId' field set." % (self, self._heat_resource_name))
        if target_group not in self._context.heat_resource_stack:
            raise exceptions.SecurityGroupNotFoundException(
                "'%s': target security group '%s' for rule '%s' does not "
                "exist." % (self, target_group, self._heat_resource_name))

        return target_group
Ejemplo n.º 5
0
    def _get_cidr(self):
        """ _get_cidr is a helper method which returns the cidr
        representing the object of the SecurityGroupRule.

        This process is not as simple as simply looking for a 'CidrIp' field
        in the data of the rule, as it is optional and may be missing.
        """
        # first; check for the banal 'CidrIp' field:
        if "CidrIp" in self._heat_resource.properties:
            # if found; simply return it:
            return self._heat_resource.properties["CidrIp"]

        # else, we must try and fetch the 'CidrIp' from the target
        # security group's rules themselves:

        # first; check for the field:
        if (self._target_secgroup_field_name
                not in self._heat_resource.properties):
            raise exceptions.SecurityGroupMissingFieldException(
                "'%s': both the 'CidrIp' and '%s' fields are missing from "
                "security group rule '%s'." %
                (self, self._target_secgroup_field_name,
                 self._heat_resource_name))

        # now, check that the referenced security group actually exists:
        target_group_name = self._heat_resource.properties[
            self._target_secgroup_field_name]
        if target_group_name not in self._context.heat_resource_stack:
            raise exceptions.SecurityGroupNotFoundException(
                "'%s': referenced security group '%s' does not exist." %
                (self, target_group_name))

        # if here; log a warning saying inference was attempted:
        self._logger.warning(
            "'CidrIp' not set on '%s'. Attempting to infer it from "
            "the target SecurityGroup '%s'.", self._heat_resource_name,
            target_group_name)

        # then, fetch the target group and collect all of their Cidr fields:
        cidrs = []
        target_group = self._context.heat_resource_stack[target_group_name]
        if "SecurityGroupIngress" in target_group.properties:
            for rule in target_group.properties["SecurityGroupIngress"]:
                if "CidrIp" in rule:
                    cidrs.append(rule["CidrIp"])
        if "SecurityGroupEgress" in target_group.properties:
            for rule in target_group.properties["SecurityGroupEgress"]:
                if "CidrIp" in rule:
                    cidrs.append(rule["CidrIp"])

        # reduce to check if there is a single definitive Cidr to be used:
        cidrs = set(cidrs)
        if not len(cidrs) == 1:
            raise exceptions.SecurityGroupInvalidFieldException(
                "'%s': Unable to infer target Cidr of SecurityGroup '%s' for "
                "the security group rule '%s'." %
                (self, target_group_name, self._heat_resource_name))

        # else, log and return the single possible cidr deduced:
        self._logger.warning(
            "succesfully deduced that security group rule '%s' cidr is "
            " most likely '%s' based on the SecurityGroup it targets.",
            self._heat_resource_name,
            list(cidrs)[0])
        return list(cidrs)[0]