# Path: stacker_blueprints/util.py
# def merge_tags(left, right, factory=Tags):
#     """
#     Merge two sets of tags into a new troposphere object
# 
#     Args:
#         left (Union[dict, troposphere.Tags]): dictionary or Tags object to be
#             merged with lower priority
#         right (Union[dict, troposphere.Tags]): dictionary or Tags object to be
#             merged with higher priority
#         factory (type): Type of object to create. Defaults to the troposphere
#             Tags class.
#     """
# 
#     if isinstance(left, Mapping):
#         tags = dict(left)
#     elif hasattr(left, 'tags'):
#         tags = _tags_to_dict(left.tags)
#     else:
#         tags = _tags_to_dict(left)
# 
#     if isinstance(right, Mapping):
#         tags.update(right)
#     elif hasattr(left, 'tags'):
#         tags.update(_tags_to_dict(right.tags))
#     else:
#         tags.update(_tags_to_dict(right))
# 
#     return factory(**tags)


from troposphere import ec2, efs
from troposphere import Join, Output, Ref, Tags
from stacker.blueprints.base import Blueprint
from stacker.blueprints.variables.types import TroposphereType
from stacker.exceptions import ValidatorError
from stacker_blueprints.util import merge_tags

    def validate_efs_subnets(self):
        validator = '{}.{}'.format(type(self).__name__, 'validate_efs_subnets')
        v = self.get_variables()

        subnet_count = len(v['Subnets'])
        if not subnet_count:
            raise ValidatorError(
                'Subnets', validator, v['Subnets'],
                'At least one Subnet must be provided')

        ip_count = len(v['IpAddresses'])
        if ip_count and ip_count != subnet_count:
            raise ValidatorError(
                'IpAddresses', validator, v['IpAddresses'],
                'The number of IpAddresses must match the number of Subnets')

    def resolve_variables(self, provided_variables):
        super(ElasticFileSystem, self).resolve_variables(provided_variables)

        self.validate_efs_security_groups()
        self.validate_efs_subnets()

    def prepare_efs_security_groups(self):
        t = self.template
        v = self.get_variables()

        created_groups = []
        for sg in v['SecurityGroups']:
            sg.VpcId = v['VpcId']

# Path: stacker_blueprints/util.py
# def merge_tags(left, right, factory=Tags):
#     """
#     Merge two sets of tags into a new troposphere object
# 
#     Args:
#         left (Union[dict, troposphere.Tags]): dictionary or Tags object to be
#             merged with lower priority
#         right (Union[dict, troposphere.Tags]): dictionary or Tags object to be
#             merged with higher priority
#         factory (type): Type of object to create. Defaults to the troposphere
#             Tags class.
#     """
# 
#     if isinstance(left, Mapping):
#         tags = dict(left)
#     elif hasattr(left, 'tags'):
#         tags = _tags_to_dict(left.tags)
#     else:
#         tags = _tags_to_dict(left)
# 
#     if isinstance(right, Mapping):
#         tags.update(right)
#     elif hasattr(left, 'tags'):
#         tags.update(_tags_to_dict(right.tags))
#     else:
#         tags.update(_tags_to_dict(right))
# 
#     return factory(**tags)


# Path: stacker_blueprints/efs.py
from troposphere import ec2, efs
from troposphere import Join, Output, Ref, Tags
from stacker.blueprints.base import Blueprint
from stacker.blueprints.variables.types import TroposphereType
from stacker.exceptions import ValidatorError
from stacker_blueprints.util import merge_tags


    def validate_efs_subnets(self):
        validator = '{}.{}'.format(type(self).__name__, 'validate_efs_subnets')
        v = self.get_variables()

        subnet_count = len(v['Subnets'])
        if not subnet_count:
            raise ValidatorError(
                'Subnets', validator, v['Subnets'],
                'At least one Subnet must be provided')

        ip_count = len(v['IpAddresses'])
        if ip_count and ip_count != subnet_count:
            raise ValidatorError(
                'IpAddresses', validator, v['IpAddresses'],
                'The number of IpAddresses must match the number of Subnets')

    def resolve_variables(self, provided_variables):
        super(ElasticFileSystem, self).resolve_variables(provided_variables)

        self.validate_efs_security_groups()
        self.validate_efs_subnets()

    def prepare_efs_security_groups(self):
        t = self.template
        v = self.get_variables()

        created_groups = []
        for sg in v['SecurityGroups']:
            sg.VpcId = v['VpcId']

            sg.Tags = merge_tags(v['Tags'], getattr(sg, 'Tags', {}))