Exemple #1
0
 def get_update_model(self):
     update_model = super(SecurityListHelperCustom, self).get_update_model()
     existing_security_list = self.get_resource().data
     existing_ingress_security_rules = existing_security_list.ingress_security_rules
     existing_ingress_security_rules_dict = to_dict(
         existing_ingress_security_rules)
     existing_egress_security_rules = existing_security_list.egress_security_rules
     existing_egress_security_rules_dict = to_dict(
         existing_egress_security_rules)
     if self.module.params.get("purge_security_rules") is False:
         if existing_ingress_security_rules:
             update_model.ingress_security_rules = (
                 update_model.ingress_security_rules or [])
             update_model.ingress_security_rules = (
                 existing_ingress_security_rules + [
                     security_rule for security_rule in update_model.
                     ingress_security_rules if not oci_common_utils.
                     is_in_list(existing_ingress_security_rules_dict,
                                to_dict(security_rule))
                 ])
         if existing_egress_security_rules:
             update_model.egress_security_rules = (
                 update_model.egress_security_rules or [])
             update_model.egress_security_rules = existing_egress_security_rules + [
                 security_rule
                 for security_rule in update_model.egress_security_rules
                 if not oci_common_utils.is_in_list(
                     existing_egress_security_rules_dict,
                     to_dict(security_rule))
             ]
     elif self.module.params.get("delete_security_rules") is True:
         if update_model.ingress_security_rules is None:
             update_model.ingress_security_rules = existing_ingress_security_rules
         else:
             existing_ingress_security_rules = existing_ingress_security_rules or []
             update_model.ingress_security_rules = [
                 existing_security_rule for existing_security_rule in
                 existing_ingress_security_rules if not any([
                     oci_common_utils.compare_dicts(
                         to_dict(security_rule),
                         to_dict(existing_security_rule)) for security_rule
                     in update_model.ingress_security_rules
                 ])
             ]
         if update_model.egress_security_rules is None:
             update_model.egress_security_rules = existing_egress_security_rules
         else:
             existing_egress_security_rules = existing_egress_security_rules or []
             update_model.egress_security_rules = [
                 existing_security_rule for existing_security_rule in
                 existing_egress_security_rules if not any([
                     oci_common_utils.compare_dicts(
                         to_dict(security_rule),
                         to_dict(existing_security_rule))
                     for security_rule in update_model.egress_security_rules
                 ])
             ]
     return update_model
 def get_update_model(self):
     update_model = super(RouteTableHelperCustom, self).get_update_model()
     existing_route_table = self.get_resource().data
     existing_route_rules = getattr(existing_route_table, "route_rules",
                                    []) or []
     existing_route_rules_dict = to_dict(existing_route_rules)
     if self.module.params.get("purge_route_rules") is False:
         if existing_route_rules:
             update_model.route_rules = (getattr(update_model,
                                                 "route_rules", []) or [])
             update_model.route_rules = existing_route_rules + [
                 route_rule for route_rule in update_model.route_rules
                 if not oci_common_utils.is_in_list(
                     existing_route_rules_dict, to_dict(route_rule))
             ]
     elif self.module.params.get("delete_route_rules") is True:
         update_model.route_rules = getattr(update_model, "route_rules",
                                            []) or []
         if not update_model.route_rules:
             update_model.route_rules = existing_route_rules
         else:
             existing_route_rules = existing_route_rules or []
             update_model.route_rules = [
                 existing_route_rule
                 for existing_route_rule in existing_route_rules
                 if not any([
                     oci_common_utils.compare_dicts(
                         to_dict(route_rule), to_dict(existing_route_rule))
                     for route_rule in update_model.route_rules
                 ])
             ]
     return update_model
Exemple #3
0
    def is_action_necessary(self, action, resource=None):

        # Handling idempotency for `scale` operation when both `capacity_type` & `capacity_value` are same as
        # existing capacity metadata.

        if ((action.lower() == self.ACTION_SCALE_ANALYTICS_INSTANCE)
                and self.module.params.get("capacity") and
            (resource.capacity.capacity_type
             == self.module.params.get("capacity").get("capacity_type")
             and resource.capacity.capacity_value
             == self.module.params.get("capacity").get("capacity_value"))):
            return False

        elif (action.lower() ==
              self.ACTION_CHANGE_ANALYTICS_INSTANCE_NETWORK_ENDPOINT_DETAILS):

            action_details = oci_common_utils.convert_input_data_to_model_class(
                self.module.params,
                ChangeAnalyticsInstanceNetworkEndpointDetails)
            return not oci_common_utils.compare_dicts(
                to_dict(action_details.network_endpoint_details),
                to_dict(resource.network_endpoint_details),
            )

        return super(AnalyticsInstanceActionsHelperCustom,
                     self).is_action_necessary(action, resource)
Exemple #4
0
 def is_action_necessary(self, action, resource=None):
     if (action.upper() ==
             self.CHANGE_INTEGRATION_INSTANCE_NETWORK_ENDPOINT_ACTION_KEY):
         # Let the API throw the validation error
         if not self.module.params.get("network_endpoint_details"):
             return True
         resource = resource or self.get_resource()
         return not oci_common_utils.compare_dicts(
             self.module.params.get("network_endpoint_details"),
             to_dict(getattr(resource, "network_endpoint_details", None)),
         )
     return super(IntegrationInstanceActionsHelperCustom,
                  self).is_action_necessary(action, resource)
Exemple #5
0
 def is_action_necessary(self, action, resource=None):
     resource = resource or self.get_resource().data
     if action == self.UPDATE_CLUSTER_ENDPOINT_CONFIG_KEY:
         action_details = oci_common_utils.convert_input_data_to_model_class(
             self.module.params, UpdateClusterEndpointConfigDetails
         )
         return not oci_common_utils.compare_dicts(
             to_dict(action_details),
             to_dict(getattr(resource, "endpoint_config", None)),
         )
     return super(ClusterActionsHelperCustom, self).is_action_necessary(
         action, resource
     )
 def evaluate_response_for_load_balancer_detachment(response):
     if not response.data.load_balancers:
         return True
     user_load_balancer_detachment_details = to_dict(
         oci_common_utils.convert_input_data_to_model_class(
             self.module.params, DetachLoadBalancerDetails))
     for existing_load_balancer_attachment in response.data.load_balancers:
         if (oci_common_utils.compare_dicts(
                 user_load_balancer_detachment_details,
                 to_dict(existing_load_balancer_attachment),
         ) and existing_load_balancer_attachment.lifecycle_state
                 == self.LIFECYCLE_STATE_DETACHED):
             return True
     return False
Exemple #7
0
    def is_patch_necessary(self, existing_resource_dict):

        patch_model = self.get_patch_model()
        patch_model_dict = self.get_patch_model_dict_for_idempotence_check(
            patch_model)
        patch_is_necessary = not oci_common_utils.compare_dicts(
            patch_model_dict, existing_resource_dict)

        _debug("is patch necessary for {resource_type}: {patch_is_necessary}".
               format(
                   resource_type=self.resource_type,
                   patch_is_necessary=patch_is_necessary,
               ))

        return patch_is_necessary
Exemple #8
0
    def is_update_necessary(self, existing_resource_dict):
        update_model = self.get_update_model()
        update_model_dict = self.get_update_model_dict_for_idempotence_check(
            update_model)
        update_is_necessary = not oci_common_utils.compare_dicts(
            update_model_dict, existing_resource_dict["capabilities"])

        _debug(
            "is update necessary for {resource_type}: {update_is_necessary}".
            format(
                resource_type=self.resource_type,
                update_is_necessary=update_is_necessary,
            ))

        return update_is_necessary
 def is_detach_load_balancer_necessary(self, instance_pool):
     if not instance_pool.load_balancers:
         return False
     user_load_balancer_detachment_details = to_dict(
         oci_common_utils.convert_input_data_to_model_class(
             self.module.params, DetachLoadBalancerDetails))
     for existing_load_balancer_attachment in instance_pool.load_balancers:
         if (existing_load_balancer_attachment.lifecycle_state
                 in oci_common_utils.DEAD_STATES):
             continue
         if oci_common_utils.compare_dicts(
                 user_load_balancer_detachment_details,
                 to_dict(existing_load_balancer_attachment),
         ):
             return True
     return False
    def is_update_necessary(self):
        current_resource_dict = to_dict(self.get_resource().data)
        update_model = self.get_update_model()
        update_model_dict = self.get_update_model_dict_for_idempotence_check(
            update_model)
        update_is_necessary = not oci_common_utils.compare_dicts(
            update_model_dict, current_resource_dict)

        _debug(
            "is update necessary for {resource_type}: {update_is_necessary}".
            format(
                resource_type=self.resource_type,
                update_is_necessary=update_is_necessary,
            ))

        return update_is_necessary
Exemple #11
0
 def get_resource(self):
     vanity_url_list = self.list_resources()
     for resource in vanity_url_list:
         resource_dict = to_dict(resource)
         vanity_url_key = self.module.params.get("vanity_url_key")
         if vanity_url_key and vanity_url_key == resource_dict.get("key"):
             return oci_common_utils.get_default_response_from_resource(
                 resource)
         elif oci_common_utils.compare_dicts(
                 source_dict=self.module.params,
                 target_dict=resource_dict,
                 ignore_attr_if_not_in_target=True,
         ):
             return oci_common_utils.get_default_response_from_resource(
                 resource)
     return oci_common_utils.raise_does_not_exist_service_error()
    def get_update_model(self):
        # right now this happens to be the same as exclude attributes
        # if the service eventually supports updating username / password
        # we should empty this list and leave exlude attributes, thus I am
        # keeping them as separate
        # this is a unique case for this API because it has fields on the Update model
        # that are not possible to update
        update_attributes_not_present_on_get_model_which_dont_support_update = [
            "admin_password",
            "admin_username",
        ]
        existing_resource_dict = self.get_existing_resource_dict_for_update()
        params_to_pass_in_update_call = {}

        # MySQL UpdateDbSystem will throw an error if you specify any fields in the update request that the service
        # does not allow updating (which is most of the fields)
        # Thus, we only want to pass through values that are updated relative to the existing value on the resource
        # For example, if we pass subnet_id, even if it is set to the same value as resource.subnet_id the service will
        # throw an error, so we have custom logic to exclude it
        for key, input_value in six.iteritems(self.module.params):
            if (key in
                    update_attributes_not_present_on_get_model_which_dont_support_update
                ):
                continue

            if input_value is not None and key in existing_resource_dict:
                existing_value = existing_resource_dict[key]
                values_are_equal = input_value == existing_value
                dicts_are_equivalent = (isinstance(input_value, dict)
                                        and isinstance(existing_value, dict)
                                        and oci_common_utils.compare_dicts(
                                            input_value, existing_value))
                if values_are_equal or dicts_are_equivalent:
                    _debug(
                        "skipping updating field {field_name} because it already matches the value on the resource."
                        .format(field_name=key))
                    continue

            params_to_pass_in_update_call[key] = input_value

        return oci_common_utils.convert_input_data_to_model_class(
            params_to_pass_in_update_call, self.get_update_model_class())
Exemple #13
0
    def get_resource(self):
        private_access_channels = self.list_resources()
        if private_access_channels:
            for channel in private_access_channels:
                resource_dict = to_dict(channel)
                private_access_channel_key = self.module.params.get(
                    "private_access_channel_key")
                if (private_access_channel_key
                        and private_access_channel_key == channel.key):
                    return oci_common_utils.get_default_response_from_resource(
                        resource=channel)
                elif oci_common_utils.compare_dicts(
                        source_dict=self.module.params,
                        target_dict=resource_dict,
                        ignore_attr_if_not_in_target=True,
                ):
                    return oci_common_utils.get_default_response_from_resource(
                        resource=channel)

        return oci_common_utils.raise_does_not_exist_service_error()
Exemple #14
0
    def get_matching_resource(self):

        create_model = self.get_create_model()
        attributes_to_consider = (
            [
                parameter for parameter in self.NAME_PARAMETERS
                if self.module.params.get(parameter)
            ] if self._use_name_as_identifier() else
            self.get_attributes_to_consider_for_create_idempotency_check(
                create_model))
        create_model_dict = self.get_create_model_dict_for_idempotence_check(
            create_model)

        # There are cases where method - `list_resources()` returns `Summary` model instead of `Get` model. In most of
        # the cases `Summary` model doesn't have all the parameters available in `Get` model. It is possible to get and
        # return `Get` model for all the resources obtained by calling `list_resources()` however doing that we would
        # have to deal with performance overhead of multiple REST calls. To avoid that first we would filter out
        # potential matches and then return 'Get' model for each match.
        prospective_matches = []
        for resource in self.list_resources():

            if not self._is_resource_active(resource):
                continue

            resource_dict = self.get_existing_resource_dict_for_idempotence_check(
                resource)

            # set `ignore_attr_if_not_in_target` to `True` to avoid false negatives.
            if oci_common_utils.compare_dicts(
                    source_dict=create_model_dict,
                    target_dict=resource_dict,
                    attrs=attributes_to_consider,
                    ignore_attr_if_not_in_target=True,
            ):
                prospective_matches.append(resource)

        for resource in prospective_matches:

            # some resources return a summary model instead of a full model in the list call. Returning the summary
            # model makes the return values inconsistent between the first and subsequent runs. So get and return
            # the get model (if exists).
            if self.is_summary_model(resource):
                resource = self.get_get_model_from_summary_model(resource)

            resource_dict = self.get_existing_resource_dict_for_idempotence_check(
                resource)

            _debug(
                "Comparing create model dict values {0} against an existing resource's "
                "values {1}".format(
                    pretty_print_json(create_model_dict),
                    pretty_print_json(resource_dict),
                ))

            if oci_common_utils.compare_dicts(
                    source_dict=create_model_dict,
                    target_dict=resource_dict,
                    attrs=attributes_to_consider,
            ):
                _debug("Resource with same attributes found: {0}.".format(
                    pretty_print_json(resource_dict)))

                return resource

        _debug(
            "No matching resource found. Attempting to create a new resource.")
        return None
 def is_action_necessary(self, action, resource=None):
     existing_route_rules = to_dict(resource or self.get_resource().data)
     logger.debug("Existing rules: {0}".format(existing_route_rules))
     if action == self.ADD_KEY:
         if not self.module.params.get("route_rules"):
             return False
         logger.debug("Original route rules to add: {0}".format(
             self.module.params.get("route_rules")))
         action_details = oci_common_utils.convert_input_data_to_model_class(
             self.module.params, AddDrgRouteRulesDetails)
         route_rules = to_dict(
             getattr(action_details, "route_rules", []) or [])
         route_rules_to_add = []
         for route_rule in route_rules:
             if not oci_common_utils.is_in_list(existing_route_rules,
                                                route_rule):
                 route_rules_to_add.append(route_rule)
         logger.debug("Route rules to add: {0}".format(route_rules_to_add))
         if route_rules_to_add:
             self.module.params["route_rules"] = route_rules_to_add
             return True
         return False
     elif action == self.UPDATE_KEY:
         if not self.module.params.get("route_rules"):
             return False
         logger.debug("Original route rules to update: {0}".format(
             self.module.params.get("route_rules")))
         action_details = oci_common_utils.convert_input_data_to_model_class(
             self.module.params, UpdateDrgRouteRulesDetails)
         route_rules = to_dict(
             getattr(action_details, "route_rules", []) or [])
         route_rules_to_update = []
         for route_rule in route_rules:
             existing_route_rule = None
             for existing_rule in existing_route_rules:
                 if existing_rule.get("id") == route_rule.get("id"):
                     existing_route_rule = existing_rule
             if not existing_route_rule:
                 self.module.fail_json(
                     msg="Could not find an existing rule with id: {0}".
                     format(route_rule.get("id")))
             if not oci_common_utils.compare_dicts(route_rule,
                                                   existing_route_rule):
                 route_rules_to_update.append(route_rule)
         logger.debug(
             "Route rules to update: {0}".format(route_rules_to_update))
         if route_rules_to_update:
             self.module.params["route_rules"] = route_rules_to_update
             return True
         return False
     elif action == self.REMOVE_KEY:
         route_rule_ids = self.module.params.get("route_rule_ids")
         if not route_rule_ids:
             return False
         existing_route_rule_ids = [
             existing_route_rule.get("id")
             for existing_route_rule in existing_route_rules
         ]
         logger.debug("Original route_rule_ids to remove: {0}".format(
             route_rule_ids))
         route_rule_ids_to_remove = []
         for route_rule_id in route_rule_ids:
             if route_rule_id in existing_route_rule_ids:
                 route_rule_ids_to_remove.append(route_rule_id)
         logger.debug("route_rule_ids to remove: {0}".format(
             route_rule_ids_to_remove))
         if route_rule_ids_to_remove:
             self.module.params["route_rule_ids"] = route_rule_ids_to_remove
             return True
         return False
     return super(DrgRouteRulesActionsHelperCustom,
                  self).is_action_necessary(action, resource)
 def is_action_necessary(self, action, resource=None):
     existing_statements = to_dict(resource or self.get_resource().data)
     logger.debug("Existing statements: {0}".format(existing_statements))
     if action == self.ADD_DRG_ROUTE_DISTRIBUTION_STATEMENTS_KEY:
         if not self.module.params.get("statements"):
             return False
         logger.debug("Original statements to add: {0}".format(
             self.module.params.get("statements")))
         action_details = oci_common_utils.convert_input_data_to_model_class(
             self.module.params, AddDrgRouteDistributionStatementsDetails)
         statements = to_dict(
             getattr(action_details, "statements", []) or [])
         statements_to_add = []
         for statement in statements:
             if not oci_common_utils.is_in_list(existing_statements,
                                                statement):
                 statements_to_add.append(statement)
         logger.debug("Statements to add: {0}".format(statements_to_add))
         if statements_to_add:
             self.module.params["statements"] = statements_to_add
             return True
         return False
     elif action == self.UPDATE_DRG_ROUTE_DISTRIBUTION_STATEMENTS_KEY:
         if not self.module.params.get("statements"):
             return False
         logger.debug("Original statements to update: {0}".format(
             self.module.params.get("statements")))
         action_details = oci_common_utils.convert_input_data_to_model_class(
             self.module.params,
             UpdateDrgRouteDistributionStatementsDetails)
         statements = to_dict(
             getattr(action_details, "statements", []) or [])
         statements_to_update = []
         for statement in statements:
             existing_statement = None
             for existing_stmt in existing_statements:
                 if existing_stmt.get("id") == statement.get("id"):
                     existing_statement = existing_stmt
             if not existing_statement:
                 self.module.fail_json(
                     msg="Could not find an existing statement with id: {0}"
                     .format(statement.get("id")))
             if not oci_common_utils.compare_dicts(statement,
                                                   existing_statement):
                 statements_to_update.append(statement)
         logger.debug(
             "Statements to update: {0}".format(statements_to_update))
         if statements_to_update:
             self.module.params["statements"] = statements_to_update
             return True
         return False
     elif action == self.REMOVE_DRG_ROUTE_DISTRIBUTION_STATEMENTS_KEY:
         statement_ids = self.module.params.get("statement_ids")
         if not statement_ids:
             return False
         existing_statement_ids = [
             existing_statement.get("id")
             for existing_statement in existing_statements
         ]
         logger.debug(
             "Original statement_ids to remove: {0}".format(statement_ids))
         statement_ids_to_remove = []
         for statement_id in statement_ids:
             if statement_id in existing_statement_ids:
                 statement_ids_to_remove.append(statement_id)
         logger.debug(
             "statement_ids to remove: {0}".format(statement_ids_to_remove))
         if statement_ids_to_remove:
             self.module.params["statement_ids"] = statement_ids_to_remove
             return True
         return False
     return super(DrgRouteDistributionStatementsActionsHelperCustom,
                  self).is_action_necessary(action, resource)