def test_builders(self): x = pretty_print_xml # This is a more declarative way to create rules. # First the long way. rules = RoutingRules() condition = Condition(http_error_code=404) redirect = Redirect(hostname='example.com', replace_key_prefix='report-404/') rules.add_rule(RoutingRule(condition, redirect)) xml = rules.to_xml() # Then the more concise way. rules2 = RoutingRules().add_rule( RoutingRule.when(http_error_code=404).then_redirect( hostname='example.com', replace_key_prefix='report-404/')) xml2 = rules2.to_xml() self.assertEqual(x(xml), x(xml2))
def test_builders(self): x = pretty_print_xml # This is a more declarative way to create rules. # First the long way. rules = RoutingRules() condition = Condition(http_error_code=404) redirect = Redirect(hostname='example.com', replace_key_prefix='report-404/') rules.add_rule(RoutingRule(condition, redirect)) xml = rules.to_xml() # Then the more concise way. rules2 = RoutingRules().add_rule( RoutingRule.when(http_error_code=404).then_redirect( hostname='example.com', replace_key_prefix='report-404/')) xml2 = rules2.to_xml() self.assertEqual(x(xml), x(xml2))
def parse_routing_rules(routing_config, hostname): """ Parse routing rule description. The configuration is a dictionary. The top-level keys are common prefixes for the rules in them. Each top-level key maps to a dictionary that maps the rest of a prefix to the redirection target. A redirection target is a dictionary of keyword arguments to ``boto.s3.website.Redirect``. If no hostname is provided in the redirection target, then the passed hostname is used, and the common prefix is prepended to the redirection target. :param routing_config: ``dict`` containing the routing configuration. :param bytes hostname: The hostname the bucket is hosted at. :return: Parsed routing rules. :rtype: ``boto.s3.website.RoutingRules`` """ rules = [] for prefix, relative_redirects in routing_config.items(): for postfix, destination in relative_redirects.items(): destination.setdefault('http_redirect_code', '302') destination['protocol'] = 'https' if 'hostname' not in destination.keys(): destination['hostname'] = hostname for key in ('replace_key', 'replace_key_prefix'): if key in destination: destination[key] = prefix + destination[key] rules.append(RoutingRule.when( key_prefix=prefix+postfix, ).then_redirect(**destination)) # Sort the rules in reverse order of prefix to match, so that # long-match wins. return RoutingRules( sorted(rules, key=lambda rule: rule.condition.key_prefix, reverse=True) )
except S3ResponseError, e: module.fail_json(msg=e.message) # Check bucket is configured as website try: website_config = bucket.get_website_configuration_obj() except S3ResponseError, e: module.fail_json(msg=e.message) current_redirect_rules = website_config.routing_rules # Create routing rules object routing_rules_obj = RoutingRules() # Create redirect rule rule = RoutingRule.when(key_prefix=key_prefix, http_error_code=http_error_code).then_redirect(hostname, protocol, replace_key_with, replace_key_prefix_with, http_redirect_code) appended = False for existing_rule in current_redirect_rules: # Match based on http_error_code and prefix if rule.condition.http_error_code == existing_rule.condition.http_error_code and rule.condition.key_prefix == existing_rule.condition.key_prefix: if rule.to_xml() == existing_rule.to_xml(): # append the already existing rule (no change) routing_rules_obj.add_rule(rule) appended = True else: # replace the existing rule routing_rules_obj.add_rule(rule) appended = True changed = True else: