def _get_expected_rules(self, networks, firewall_policy): """Builds a FirewallRules object with the rules that should be defined. Args: networks (list): A list of networks on the project that the policy applies to. firewall_policy (list): A list of firewall rules that should be configured on the project networks. Returns: fe.FirewallRules: A new FirewallRules object with the expected policy. Raises: EnforcementError: Raised if one or more firewall rules in the policy are invalid. """ expected_rules = fe.FirewallRules(self.project_id) try: for network_name in networks: expected_rules.add_rules( firewall_policy, network_name=network_name) except fe.InvalidFirewallRuleError as e: raise EnforcementError(STATUS_ERROR, 'error adding the expected ' 'firewall rules from the policy: %s' % e) return expected_rules
def _initialize_firewall_enforcer(self): """Gets current and expected rules, returns a FirewallEnforcer object. Returns: A new FirewallEnforcer object configured with the expected policy for the project. Raises: EnforcementError: Raised if there are any errors fetching the current firewall rules or building the expected rules from the policy. """ if not self.project_networks: raise EnforcementError(STATUS_ERROR, 'no networks found for project') self.rules_before_enforcement = self._get_current_fw_rules() self.expected_rules = fe.FirewallRules(self.project_id) try: for network_name in self.project_networks: self.expected_rules.add_rules(self.firewall_policy, network_name=network_name) except fe.InvalidFirewallRuleError as e: raise EnforcementError( STATUS_ERROR, 'error adding the expected ' 'firewall rules from the policy: %s' % e) enforcer = fe.FirewallEnforcer(self.project_id, self.firewall_api, self.expected_rules, self.rules_before_enforcement, project_sema=self._project_sema, operation_sema=self._operation_sema) return enforcer
def _get_current_fw_rules(self, add_rule_callback=None): """Create a new FirewallRules object with the current rules. Args: add_rule_callback (Callable): A callback function that checks whether a firewall rule should be applied. If the callback returns False, that rule will not be modified. Returns: fe.FirewallRules: A new FirewallRules object with the current rules added to it. Raises: ProjectDeletedError: Raised if the project has been deleted. ComputeApiDisabledError: Raised if the Compute API is not enabled on the project. EnforcementError: Raised if there are any exceptions raised while adding the firewall rules. """ current_rules = fe.FirewallRules(self.project_id, add_rule_callback=add_rule_callback) try: current_rules.add_rules_from_api(self.firewall_api) except errors.HttpError as e: # Handle race condition where a project is deleted after it is # enqueued. error_msg = str( e) # HttpError Class decodes json encoded error into str if ((e.resp.status in (400, 404) and ('Invalid value for project' in error_msg or 'Failed to find project' in error_msg)) or # Error string changed (e.resp.status == 403 and 'scheduled for deletion' in error_msg)): raise ProjectDeletedError(error_msg) elif (e.resp.status == 403 and 'Compute Engine API has not been used' in error_msg): raise ComputeApiDisabledError(error_msg) else: raise EnforcementError(STATUS_ERROR, 'error getting current firewall ' 'rules from API: %s' % e) except fe.InvalidFirewallRuleError as e: raise EnforcementError(STATUS_ERROR, 'error getting current firewall ' 'rules from API: %s' % e) return current_rules
def _get_current_fw_rules(self): """Create a new FirewallRules object with the current rules. Returns: A new FirewallRules object with the current rules added to it. Raises: EnforcementError: Raised if there are any exceptions raised while adding the firewall rules. """ current_rules = fe.FirewallRules(self.project_id) try: current_rules.add_rules_from_api(self.firewall_api) except errors.HttpError as e: # Handle race condition where a project is deleted after it is # enqueued. error_msg = str( e) # HttpError Class decodes json encoded error into str if ((e.resp.status in (400, 404) and ('Invalid value for project' in error_msg or 'Failed to find project' in error_msg)) or # Error string changed (e.resp.status == 403 and 'scheduled for deletion' in error_msg)): raise ProjectDeletedError(error_msg) elif (e.resp.status == 403 and 'Compute Engine API has not been used' in error_msg): raise ComputeApiDisabledError(error_msg) else: raise EnforcementError( STATUS_ERROR, 'error getting current firewall ' 'rules from API: %s' % e) except fe.InvalidFirewallRuleError as e: raise EnforcementError( STATUS_ERROR, 'error getting current firewall ' 'rules from API: %s' % e) return current_rules