tower_cli/models/base.py
def write(self, pk=None, create_on_missing=False, fail_on_found=False, force_on_exists=True, **kwargs):
        """
        =====API DOCS=====
        Modify the given object using the Ansible Tower API.

        :param pk: Primary key of the resource to be read. Tower CLI will only attempt to read that object
                   if ``pk`` is provided (not ``None``).
        :type pk: int
        :param create_on_missing: Flag that if set, a new object is created if ``pk`` is not set and objects
                                  matching the appropriate unique criteria is not found.
        :type create_on_missing: bool
        :param fail_on_found: Flag that if set, the operation fails if an object matching the unique criteria
                              already exists.
        :type fail_on_found: bool
        :param force_on_exists: Flag that if set, then if an object is modified based on matching via unique
                                fields (as opposed to the primary key), other fields are updated based on data
                                sent; If unset, then the non-unique values are only written in a creation case.
        :type force_on_exists: bool
        :param `**kwargs`: Keyword arguments which, all together, will be used as POST/PATCH body to create/modify
                           the resource object. if ``pk`` is not set, key-value pairs of ``**kwargs`` which are
                           also in resource's identity will be used to lookup existing reosource.
        :returns: A dictionary combining the JSON output of the resource, as well as two extra fields: "changed",
                  a flag indicating if the resource is created or successfully updated; "id", an integer which
                  is the primary key of the specified object.
        :rtype: dict
        :raises tower_cli.exceptions.BadRequest: When required fields are missing in ``**kwargs`` when creating
                                                 a new resource object.

        =====API DOCS=====
        """
        existing_data = {}

        # Remove default values (anything where the value is None).
        self._pop_none(kwargs)

        # Determine which record we are writing, if we weren't given a primary key.
        if not pk:
            debug.log('Checking for an existing record.', header='details')
            existing_data = self._lookup(
                fail_on_found=fail_on_found, fail_on_missing=not create_on_missing, include_debug_header=False,
                **kwargs
            )
            if existing_data:
                pk = existing_data['id']
        else:
            # We already know the primary key, but get the existing data.
            # This allows us to know whether the write made any changes.
            debug.log('Getting existing record.', header='details')
            existing_data = self.get(pk)

        # Sanity check: Are we missing required values?
        # If we don't have a primary key, then all required values must be set, and if they're not, it's an error.
        missing_fields = []
        for i in self.fields:
            if i.key not in kwargs and i.name not in kwargs and i.required:
                missing_fields.append(i.key or i.name)
        if missing_fields and not pk:
            raise exc.BadRequest('Missing required fields: %s' % ', '.join(missing_fields).replace('_', '-'))

        # Sanity check: Do we need to do a write at all?
        # If `force_on_exists` is False and the record was, in fact, found, then no action is required.
        if pk and not force_on_exists:
            debug.log('Record already exists, and --force-on-exists is off; do nothing.', header='decision', nl=2)
            answer = OrderedDict((('changed', False), ('id', pk)))
            answer.update(existing_data)
            return answer

        # Similarly, if all existing data matches our write parameters, there's no need to do anything.
        if all([kwargs[k] == existing_data.get(k, None) for k in kwargs.keys()]):
            debug.log('All provided fields match existing data; do nothing.', header='decision', nl=2)
            answer = OrderedDict((('changed', False), ('id', pk)))
            answer.update(existing_data)
            return answer

        # Reinsert None for special case of null association
        for key in kwargs:
            if kwargs[key] == 'null':
                kwargs[key] = None

        # Get the URL and method to use for the write.
        url = self.endpoint
        method = 'POST'
        if pk:
            url = self._get_patch_url(url, pk)
            method = 'PATCH'

        # If debugging is on, print the URL and data being sent.
        debug.log('Writing the record.', header='details')

        # Actually perform the write.
        r = getattr(client, method.lower())(url, data=kwargs)

        # At this point, we know the write succeeded, and we know that data was changed in the process.
        answer = OrderedDict((('changed', True), ('id', r.json()['id'])))
        answer.update(r.json())
        return answer
def write(self, pk=None, create_on_missing=False, fail_on_found=False, force_on_exists=True, **kwargs):
        """
        =====API DOCS=====
        Modify the given object using the Ansible Tower API.

        :param pk: Primary key of the resource to be read. Tower CLI will only attempt to read that object
                   if ``pk`` is provided (not ``None``).
        :type pk: int
        :param create_on_missing: Flag that if set, a new object is created if ``pk`` is not set and objects
                                  matching the appropriate unique criteria is not found.
        :type create_on_missing: bool
        :param fail_on_found: Flag that if set, the operation fails if an object matching the unique criteria
                              already exists.
        :type fail_on_found: bool
        :param force_on_exists: Flag that if set, then if an object is modified based on matching via unique
                                fields (as opposed to the primary key), other fields are updated based on data
                                sent; If unset, then the non-unique values are only written in a creation case.
        :type force_on_exists: bool
        :param `**kwargs`: Keyword arguments which, all together, will be used as POST/PATCH body to create/modify
                           the resource object. if ``pk`` is not set, key-value pairs of ``**kwargs`` which are
                           also in resource's identity will be used to lookup existing reosource.
        :returns: A dictionary combining the JSON output of the resource, as well as two extra fields: "changed",
                  a flag indicating if the resource is created or successfully updated; "id", an integer which
                  is the primary key of the specified object.
        :rtype: dict
        :raises tower_cli.exceptions.BadRequest: When required fields are missing in ``**kwargs`` when creating
                                                 a new resource object.

        =====API DOCS=====
        """
        existing_data = {}

        # Remove default values (anything where the value is None).
        self._pop_none(kwargs)

        # Determine which record we are writing, if we weren't given a primary key.
        if not pk:
            debug.log('Checking for an existing record.', header='details')
            existing_data = self._lookup(
                fail_on_found=fail_on_found, fail_on_missing=not create_on_missing, include_debug_header=False,
                **kwargs
            )
            if existing_data:
                pk = existing_data['id']
        else:
            # We already know the primary key, but get the existing data.
            # This allows us to know whether the write made any changes.
            debug.log('Getting existing record.', header='details')
            existing_data = self.get(pk)

        # Sanity check: Are we missing required values?
        # If we don't have a primary key, then all required values must be set, and if they're not, it's an error.
        missing_fields = []
        for i in self.fields:
            if i.key not in kwargs and i.name not in kwargs and i.required:
                missing_fields.append(i.key or i.name)
        if missing_fields and not pk:
            raise exc.BadRequest('Missing required fields: %s' % ', '.join(missing_fields).replace('_', '-'))

        # Sanity check: Do we need to do a write at all?
        # If `force_on_exists` is False and the record was, in fact, found, then no action is required.
        if pk and not force_on_exists:
            debug.log('Record already exists, and --force-on-exists is off; do nothing.', header='decision', nl=2)
            answer = OrderedDict((('changed', False), ('id', pk)))
            answer.update(existing_data)
            return answer

        # Similarly, if all existing data matches our write parameters, there's no need to do anything.
        if all([kwargs[k] == existing_data.get(k, None) for k in kwargs.keys()]):
            debug.log('All provided fields match existing data; do nothing.', header='decision', nl=2)
            answer = OrderedDict((('changed', False), ('id', pk)))
            answer.update(existing_data)
            return answer

        # Reinsert None for special case of null association
        for key in kwargs:
            if kwargs[key] == 'null':
                kwargs[key] = None

        # Get the URL and method to use for the write.
        url = self.endpoint
        method = 'POST'
        if pk:
            url = self._get_patch_url(url, pk)
            method = 'PATCH'

        # If debugging is on, print the URL and data being sent.
        debug.log('Writing the record.', header='details')

        # Actually perform the write.
        r = getattr(client, method.lower())(url, data=kwargs)

        # At this point, we know the write succeeded, and we know that data was changed in the process.
        answer = OrderedDict((('changed', True), ('id', r.json()['id'])))
        answer.update(r.json())
        return answer
def write ( self , pk = None , create_on_missing = False , fail_on_found = False , force_on_exists = True , * * kwargs ) : existing_data = { } # Remove default values (anything where the value is None). self . _pop_none ( kwargs ) # Determine which record we are writing, if we weren't given a primary key. if not pk : debug . log ( 'Checking for an existing record.' , header = 'details' ) existing_data = self . _lookup ( fail_on_found = fail_on_found , fail_on_missing = not create_on_missing , include_debug_header = False , * * kwargs ) if existing_data : pk = existing_data [ 'id' ] else : # We already know the primary key, but get the existing data. # This allows us to know whether the write made any changes. debug . log ( 'Getting existing record.' , header = 'details' ) existing_data = self . get ( pk ) # Sanity check: Are we missing required values? # If we don't have a primary key, then all required values must be set, and if they're not, it's an error. missing_fields = [ ] for i in self . fields : if i . key not in kwargs and i . name not in kwargs and i . required : missing_fields . append ( i . key or i . name ) if missing_fields and not pk : raise exc . BadRequest ( 'Missing required fields: %s' % ', ' . join ( missing_fields ) . replace ( '_' , '-' ) ) # Sanity check: Do we need to do a write at all? # If `force_on_exists` is False and the record was, in fact, found, then no action is required. if pk and not force_on_exists : debug . log ( 'Record already exists, and --force-on-exists is off; do nothing.' , header = 'decision' , nl = 2 ) answer = OrderedDict ( ( ( 'changed' , False ) , ( 'id' , pk ) ) ) answer . update ( existing_data ) return answer # Similarly, if all existing data matches our write parameters, there's no need to do anything. if all ( [ kwargs [ k ] == existing_data . get ( k , None ) for k in kwargs . keys ( ) ] ) : debug . log ( 'All provided fields match existing data; do nothing.' , header = 'decision' , nl = 2 ) answer = OrderedDict ( ( ( 'changed' , False ) , ( 'id' , pk ) ) ) answer . update ( existing_data ) return answer # Reinsert None for special case of null association for key in kwargs : if kwargs [ key ] == 'null' : kwargs [ key ] = None # Get the URL and method to use for the write. url = self . endpoint method = 'POST' if pk : url = self . _get_patch_url ( url , pk ) method = 'PATCH' # If debugging is on, print the URL and data being sent. debug . log ( 'Writing the record.' , header = 'details' ) # Actually perform the write. r = getattr ( client , method . lower ( ) ) ( url , data = kwargs ) # At this point, we know the write succeeded, and we know that data was changed in the process. answer = OrderedDict ( ( ( 'changed' , True ) , ( 'id' , r . json ( ) [ 'id' ] ) ) ) answer . update ( r . json ( ) ) return answer
=====API DOCS=====
        Modify the given object using the Ansible Tower API.

        :param pk: Primary key of the resource to be read. Tower CLI will only attempt to read that object
                   if ``pk`` is provided (not ``None``).
        :type pk: int
        :param create_on_missing: Flag that if set, a new object is created if ``pk`` is not set and objects
                                  matching the appropriate unique criteria is not found.
        :type create_on_missing: bool
        :param fail_on_found: Flag that if set, the operation fails if an object matching the unique criteria
                              already exists.
        :type fail_on_found: bool
        :param force_on_exists: Flag that if set, then if an object is modified based on matching via unique
                                fields (as opposed to the primary key), other fields are updated based on data
                                sent; If unset, then the non-unique values are only written in a creation case.
        :type force_on_exists: bool
        :param `**kwargs`: Keyword arguments which, all together, will be used as POST/PATCH body to create/modify
                           the resource object. if ``pk`` is not set, key-value pairs of ``**kwargs`` which are
                           also in resource's identity will be used to lookup existing reosource.
        :returns: A dictionary combining the JSON output of the resource, as well as two extra fields: "changed",
                  a flag indicating if the resource is created or successfully updated; "id", an integer which
                  is the primary key of the specified object.
        :rtype: dict
        :raises tower_cli.exceptions.BadRequest: When required fields are missing in ``**kwargs`` when creating
                                                 a new resource object.

        =====API DOCS=====
===== API DOCS ===== Modify the given object using the Ansible Tower API .