コード例 #1
0
 def get_and_replace_parent_variables(self):
     """
     Checks the particles desired state definition and checks to see if there are values that
     dependent on one of its parents.
     The format should look like $flavor:pcf_name$key_in_parent_current_state_definition.
     If there are values then this function looks for the corresponding parents and adds those
     values to this particles desired_state_definition.
     """
     var_lookup_list = pcf_util.find_nested_vars(
         self.desired_state_definition, var_list=[])
     for (nested_key, id_var) in var_lookup_list:
         if id_var[0] == "inherit":
             pcf_id = id_var[1]
             parent_var = id_var[2]
             try:
                 parent = next(p for p in self.parents
                               if p.pcf_id == pcf_id)
             except StopIteration:
                 raise pcf_exceptions.InvalidValueReplaceException(
                     "{} parent was not found".format(pcf_id))
             else:
                 var = pcf_util.find_nested_dict_value(
                     curr_dict=parent.current_state_definition,
                     list_nested_keys=parent_var.split('.'))
                 if not var:
                     raise pcf_exceptions.InvalidValueReplaceException(
                         "{} var was not found in {}".format(
                             parent_var, pcf_id))
             pcf_util.replace_value_nested_dict(
                 curr_dict=self.desired_state_definition,
                 list_nested_keys=nested_key.split('.'),
                 new_value=var)
コード例 #2
0
    def _fuse_particles(self):
        """
        This functions adds all particles to a pcf object (pcf_field). If a particle contains a multiplier field that number of particles
        are created with indexes appended to the particle's unique identifier. If the quasiparticle has a parent, that parent is added to all
        particles in the quasiparticle. Finally link_particles is called on the pcf_field.
        """
        for particle in self.member_particles:
            if not particle.get("pcf_name"):
                particle["pcf_name"] = self.name
            multiplier = particle.get("multiplier", False)
            base_particle_config = particle.get("base_particle_config", False)

            if base_particle_config:
                particle = self.update_particle_definition(
                    particle,
                    self.pcf_field.get_particle_from_pcf_id(
                        particle["flavor"] + ":" + base_particle_config))

            # when there is no multiplier add quasiparticle parents to particle and add particle to pcf field
            if not multiplier:
                if self.particle_definition.get("parents"):
                    particle = self.add_parents_to_particle(particle)

                self.pcf_field.load_particle_definition(particle)

            # when there is a multiplier get the unique identifers, index them, add quasiparticle parents, and then add all particles to the pcf field
            else:
                particle_name = particle["pcf_name"]
                unique_identifier_list = pcf_util.get_particle_unique_identifiers(
                    particle['flavor'])
                unqiue_value_dict = dict([
                    (x,
                     pcf_util.find_nested_dict_value(particle, x.split('.')))
                    for x in unique_identifier_list
                ])
                for i in range(multiplier):
                    particle_multiple = deepcopy(particle)

                    particle_multiple["pcf_name"] = particle_name + "-" + str(
                        i)
                    # appends the correct index to each item in particle definition that is unique
                    particle_multiple = functools.reduce(
                        (lambda d, l: pcf_util.replace_value_nested_dict(
                            d, l.split('.'),
                            unqiue_value_dict.get(l) + '-' + str(i))),
                        unique_identifier_list, particle_multiple)
                    if self.particle_definition.get("parents"):
                        particle_multiple = self.add_parents_to_particle(
                            particle_multiple)

                    self.pcf_field.load_particle_definition(particle_multiple)

        self.pcf_field.link_particles(self.pcf_field.particles)
コード例 #3
0
    def is_state_definition_equivalent(self):
        """
        Determines if the current state definition and the desired state definition are equivalent.

        Returns:
            bool
        """
        filtered_curr_def = pcf_util.param_filter(
            self.current_state_definition, self.UPDATE_PARAM_FILTER)

        filtered_des_def = pcf_util.param_filter(self.desired_state_definition,
                                                 self.REMOVE_PARAM_FILTER,
                                                 True)

        def_diff = pcf_util.diff_dict(filtered_curr_def, filtered_des_def)

        curr_tags = self.client.describe_tags(ResourceArns=[self.arn])

        curr_tags = curr_tags.get('TagDescriptions')[0].get('Tags', None)
        des_tags = self.desired_state_definition.get('Tags', None)

        curr_availabilty_zones = pcf_util.find_nested_dict_value(
            self.current_state_definition, ['AvailabilityZones'])
        curr_subnets_list = pcf_util.transform_list_of_dicts_to_desired_list(
            curr_availabilty_zones, 'SubnetId')

        des_subnets_list = self.desired_state_definition.get('Subnets')

        curr_listeners = [
            pcf_util.param_filter(x, {'SslPolicy'}, True)
            for x in self.get_listener_status()
        ]
        des_listeners = self.custom_config['Listeners']

        for item in des_listeners:
            item.update({'Protocol': item.get('Protocol').upper()})

        for item in curr_listeners:
            if 'ListenerArn' in item:
                item.pop('ListenerArn')

        if def_diff or self._need_update(curr_tags, des_tags) or self._need_update(curr_listeners, des_listeners) \
            or not pcf_util.is_list_equal(curr_subnets_list, des_subnets_list):
            return False
        return True
コード例 #4
0
    def validate_unique_id(self):
        """
        Throws an error if particle flavor or any unique identifiers are missing
        """
        flavor_name = self.particle_definition.get("flavor")
        if not flavor_name:
            raise pcf_exceptions.FlavorMissingException
        try:
            # get list from UNIQUE_KEYS
            unique_identifier_list = pcf_util.get_particle_unique_identifiers(
                flavor_name)

            for uid in unique_identifier_list:
                if not pcf_util.find_nested_dict_value(
                        self.particle_definition, uid.split('.')):
                    raise pcf_exceptions.InvalidUniqueKeysException
        except AttributeError:
            # UNIQUE_KEYS list does not exist - disregard and move on (Only when UNIQUE_KEYS is not defined in a class)
            pass
コード例 #5
0
    def _update(self):
        """
        updates the alb particle to match the desired state

        """
        filtered_curr_def = pcf_util.param_filter(
            self.current_state_definition, self.UPDATE_PARAM_FILTER)

        filtered_des_def = pcf_util.param_filter(self.desired_state_definition,
                                                 self.REMOVE_PARAM_FILTER,
                                                 True)

        diff = pcf_util.diff_dict(filtered_curr_def, filtered_des_def)

        curr_tags = self.client.describe_tags(ResourceArns=[self.arn])
        curr_tags = curr_tags.get('TagDescriptions')[0].get('Tags')
        des_tags = self.desired_state_definition.get('Tags', [{}])

        curr_listeners = [x for x in self.get_listener_status()]
        # Format current listener to compare.
        filtered_curr_listeners = [x for x in self.get_listener_status()]
        for item in filtered_curr_listeners:
            if 'ListenerArn' in item:
                item.pop('ListenerArn')

        des_listeners = self.custom_config['Listeners']

        if diff.get('SecurityGroups', None):
            self.client.set_security_groups(
                LoadBalancerArn=self.arn,
                SecurityGroups=filtered_des_def.get('SecurityGroups'))

        curr_availabilty_zones = pcf_util.find_nested_dict_value(
            self.current_state_definition, ['AvailabilityZones'])
        curr_subnets_list = pcf_util.transform_list_of_dicts_to_desired_list(
            curr_availabilty_zones, 'SubnetId')
        des_subnets_list = self.desired_state_definition.get('Subnets')

        if not pcf_util.is_list_equal(curr_subnets_list, des_subnets_list):
            update = des_subnets_list
            if update:
                self.client.set_subnets(LoadBalancerArn=self.arn,
                                        Subnets=list(update))

        if self._need_update(curr_tags, des_tags):
            add = list(
                itertools.filterfalse(lambda x: x in curr_tags, des_tags))
            remove = list(
                itertools.filterfalse(lambda x: x in des_tags, curr_tags))
            if remove:
                self.client.remove_tags(ResourceArns=[self.arn],
                                        TagKeys=[x.get('Key') for x in remove])
            if add:
                self.client.add_tags(ResourceArns=[self.arn], Tags=add)

        if self._need_update(filtered_curr_listeners, des_listeners):
            #Format current listener and desired listener to compare.
            for item in des_listeners:
                item.update({'Protocol': item.get('Protocol').upper()})

            for item in curr_listeners:
                self.client.delete_listener(ListenerArn=item['ListenerArn'])

            for item in des_listeners:
                item['LoadBalancerArn'] = self.arn
                self.create_listener(item)