From ea49d4e127fdfbff5d44d397e310eec73b5bed37 Mon Sep 17 00:00:00 2001 From: Jacob Callahan Date: Wed, 13 Sep 2023 14:00:53 -0400 Subject: [PATCH] Introduce docstring standards for Ruff Most rules are used, but a few are ignored for style. --- nailgun/client.py | 16 +- nailgun/config.py | 1 + nailgun/entities.py | 408 +++++++++++++++++++----------------- nailgun/entity_fields.py | 22 +- nailgun/entity_mixins.py | 37 ++-- pyproject.toml | 2 +- tests/test_client.py | 3 +- tests/test_config.py | 3 +- tests/test_entities.py | 229 ++++++++------------ tests/test_entity_mixins.py | 48 ++--- 10 files changed, 379 insertions(+), 390 deletions(-) diff --git a/nailgun/client.py b/nailgun/client.py index 3ae64d00..13165db7 100644 --- a/nailgun/client.py +++ b/nailgun/client.py @@ -85,7 +85,7 @@ def _set_content_type(kwargs): def _truncate_data(data, max_len=500): - """Truncate data to a max length""" + """Truncate data to a max length.""" if isinstance(data, str | bytes): if len(data) > max_len: return f"{data[:max_len - 3]}..." @@ -133,7 +133,7 @@ def _log_response(response): def request(method, url, **kwargs): - """A wrapper for ``requests.request``.""" + """Wrap ``requests.request``.""" _set_content_type(kwargs) if _content_type_is_json(kwargs) and kwargs.get('data') is not None: kwargs['data'] = dumps(kwargs['data']) @@ -144,7 +144,7 @@ def request(method, url, **kwargs): def head(url, **kwargs): - """A wrapper for ``requests.head``.""" + """Wrap ``requests.head``.""" _set_content_type(kwargs) if _content_type_is_json(kwargs) and kwargs.get('data') is not None: kwargs['data'] = dumps(kwargs['data']) @@ -155,7 +155,7 @@ def head(url, **kwargs): def get(url, params=None, **kwargs): - """A wrapper for ``requests.get``.""" + """Wrap ``requests.get``.""" _set_content_type(kwargs) if _content_type_is_json(kwargs) and kwargs.get('data') is not None: kwargs['data'] = dumps(kwargs['data']) @@ -166,7 +166,7 @@ def get(url, params=None, **kwargs): def post(url, data=None, json=None, **kwargs): - """A wrapper for ``requests.post``.""" + """Wrap ``requests.post``.""" _set_content_type(kwargs) if _content_type_is_json(kwargs) and data is not None: data = dumps(data) @@ -177,7 +177,7 @@ def post(url, data=None, json=None, **kwargs): def put(url, data=None, **kwargs): - """A wrapper for ``requests.put``. Sends a PUT request.""" + """Wrap ``requests.put``. Sends a PUT request.""" _set_content_type(kwargs) if _content_type_is_json(kwargs) and data is not None: data = dumps(data) @@ -188,7 +188,7 @@ def put(url, data=None, **kwargs): def patch(url, data=None, **kwargs): - """A wrapper for ``requests.patch``. Sends a PATCH request.""" + """Wrap ``requests.patch``. Sends a PATCH request.""" _set_content_type(kwargs) if _content_type_is_json(kwargs) and data is not None: data = dumps(data) @@ -199,7 +199,7 @@ def patch(url, data=None, **kwargs): def delete(url, **kwargs): - """A wrapper for ``requests.delete``. Sends a DELETE request.""" + """Wrap ``requests.delete``. Sends a DELETE request.""" _set_content_type(kwargs) if _content_type_is_json(kwargs) and kwargs.get('data') is not None: kwargs['data'] = dumps(kwargs['data']) diff --git a/nailgun/config.py b/nailgun/config.py index ad261d30..4155ebdd 100644 --- a/nailgun/config.py +++ b/nailgun/config.py @@ -110,6 +110,7 @@ def __init__(self, url, auth=None, version=None): self.version = parse(version) def __repr__(self): + """Return a string representation of the object.""" attrs = vars(self).copy() if "version" in attrs: attrs["version"] = str(attrs.pop("version")) diff --git a/nailgun/entities.py b/nailgun/entities.py index 843610c6..82b53479 100644 --- a/nailgun/entities.py +++ b/nailgun/entities.py @@ -1,4 +1,4 @@ -"""This module defines all entities which Foreman exposes. +"""All entities which Foreman exposes. Each class in this module allows you to work with a certain set of logically related API paths exposed by the server. For example, @@ -196,7 +196,7 @@ def _get_version(server_config): @lru_cache def _feature_list(server_config, smart_proxy_id=1): - """Get list of features enabled on capsule""" + """Get list of features enabled on capsule.""" smart_proxy = SmartProxy(server_config, id=smart_proxy_id).read_json() return [feature['name'] for feature in smart_proxy['features']] @@ -275,14 +275,14 @@ def path(self, which=None): return super().path(which) def update_payload(self, fields=None): - """Always include organization_id.""" + """Include organization_id in all payloads.""" payload = super().update_payload(fields) # organization is required for the AK update call payload['organization_id'] = self.organization.id return payload def add_host_collection(self, synchronous=True, timeout=None, **kwargs): - """Helper for associating host collection with activation key. + """Associate host collection with activation key. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -301,7 +301,7 @@ def add_host_collection(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def add_subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Helper for adding subscriptions to activation key. + """Add subscriptions to activation key. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -341,7 +341,7 @@ def copy(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def remove_subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Helper for removing subscriptions from an activation key. + """Remove subscriptions from an activation key. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -360,7 +360,7 @@ def remove_subscriptions(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Helper for retrieving subscriptions on an activation key. + """Retrieve subscriptions on an activation key. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -398,7 +398,7 @@ def content_override(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def product_content(self, synchronous=True, timeout=None, **kwargs): - """Helper for showing content available for activation key. + """Show content available for activation key. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -417,7 +417,7 @@ def product_content(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def remove_host_collection(self, synchronous=True, timeout=None, **kwargs): - """Helper for disassociating host collection from the activation key. + """Disassociate host collection from the activation key. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -481,7 +481,7 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def read(self, entity=None, attrs=None, ignore=None, params=None): - """Handle read values dependencies""" + """Handle read values dependencies.""" if attrs is None: attrs = self.read_json() if ignore is None: @@ -540,7 +540,7 @@ def path(self, which=None): return super().path(which) def refresh(self, synchronous=True, timeout=None, **kwargs): - """Helper to refresh an ACS. + """Refresh an ACS. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -559,7 +559,7 @@ def refresh(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_refresh(self, synchronous=True, timeout=None, **kwargs): - """Refresh the set of ACSes + """Refresh the set of ACSes. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -577,7 +577,7 @@ def bulk_refresh(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_destroy(self, synchronous=True, timeout=None, **kwargs): - """Destroy the set of ACSes + """Destroy the set of ACSes. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -663,6 +663,7 @@ def __init__(self, server_config=None, **kwargs): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: download_html @@ -676,7 +677,7 @@ def path(self, which=None): return super().path(which) def download_html(self, synchronous=True, timeout=None, **kwargs): - """Download ARF report in HTML + """Download ARF report in HTML. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -847,7 +848,7 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def content_add_lifecycle_environment(self, synchronous=True, timeout=None, **kwargs): - """Helper to associate lifecycle environment with capsule + """Associate lifecycle environment with capsule. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -865,7 +866,7 @@ def content_add_lifecycle_environment(self, synchronous=True, timeout=None, **kw return _handle_response(response, self._server_config, synchronous, timeout) def content_delete_lifecycle_environment(self, synchronous=True, timeout=None, **kwargs): - """Helper to disassociate lifecycle environment from capsule + """Disassociate lifecycle environment from capsule. Here is an example of how to use this method:: capsule.content_delete_lifecycle_environment(data={'environment_id': lce.id}) @@ -893,8 +894,7 @@ def content_delete_lifecycle_environment(self, synchronous=True, timeout=None, * return _handle_response(response, self._server_config, synchronous, timeout) def content_lifecycle_environments(self, synchronous=True, timeout=None, **kwargs): - """Helper to get all the lifecycle environments, associated with - capsule + """Get all lifecycle environments associated with a capsule. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -912,7 +912,7 @@ def content_lifecycle_environments(self, synchronous=True, timeout=None, **kwarg return _handle_response(response, self._server_config, synchronous, timeout) def content_sync(self, synchronous=True, timeout=None, **kwargs): - """Helper to sync content on a capsule + """Sync content on a capsule. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -930,7 +930,7 @@ def content_sync(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def content_get_sync(self, synchronous=True, timeout=None, **kwargs): - """Helper to get content sync status on capsule + """Get content sync status on capsule. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1092,6 +1092,7 @@ def __init__(self, server_config=None, **kwargs): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: available_images @@ -1145,7 +1146,7 @@ def update(self, fields=None): return self.read() def available_images(self, synchronous=True, timeout=None, **kwargs): - """Get images available to be added to the compute resource + """Get images available to be added to the compute resource. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1164,7 +1165,7 @@ def available_images(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def available_zones(self, synchronous=True, timeout=None, **kwargs): - """Get images available to be added to the compute resource + """Get images available to be added to the compute resource. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1183,7 +1184,7 @@ def available_zones(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def available_flavors(self, synchronous=True, timeout=None, **kwargs): - """Get flavors available to be added to the compute resource + """Get flavors available to be added to the compute resource. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1202,7 +1203,7 @@ def available_flavors(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def available_networks(self, synchronous=True, timeout=None, **kwargs): - """Get networks available to be selected for host provisioning + """Get networks available to be selected for host provisioning. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1221,7 +1222,7 @@ def available_networks(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def images(self, synchronous=True, timeout=None, **kwargs): - """Get images created in a compute resource + """Get images created in a compute resource. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1240,7 +1241,7 @@ def images(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def associate(self, synchronous=True, timeout=None, **kwargs): - """Associate the host + """Associate the host. :param kwargs: Arguments to pass to requests. :returns: The server's response, with all JSON decoded. @@ -1323,7 +1324,7 @@ def update_payload(self, fields=None): return {'discovered_host': super().update_payload(fields)} def facts(self, synchronous=True, timeout=None, **kwargs): - """Helper to update facts for discovered host, and create the host. + """Update facts for discovered host, and create the host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1342,7 +1343,7 @@ def facts(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def refresh_facts(self, synchronous=True, timeout=None, **kwargs): - """Helper to refresh facts for discovered host + """Refresh facts for discovered host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1361,7 +1362,7 @@ def refresh_facts(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def read(self, entity=None, attrs=None, ignore=None, params=None): - """Make sure, everything except `id` and `name` are in the ignore list for read""" + """Make sure, everything except `id` and `name` are in the ignore list for read.""" if ignore is None: ignore = set() ignore.add('ip') @@ -1374,7 +1375,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): return super().read(entity, attrs, ignore, params) def reboot(self, synchronous=True, timeout=None, **kwargs): - """Helper to reboot the discovered host + """Reboot the discovered host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1393,7 +1394,7 @@ def reboot(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def reboot_all(self, synchronous=True, timeout=None, **kwargs): - """Helper for rebooting all discovered hosts + """Reboot all discovered hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1411,7 +1412,7 @@ def reboot_all(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def auto_provision(self, synchronous=True, timeout=None, **kwargs): - """Helper for auto-provisioning of the discovered host + """Auto-provision the discovered host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1429,7 +1430,7 @@ def auto_provision(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def auto_provision_all(self, synchronous=True, timeout=None, **kwargs): - """Helper for auto-provisioning of all discovered hosts + """Auto-provision of all discovered hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1587,7 +1588,7 @@ def __init__(self, server_config=None, **kwargs): } def read(self, entity=None, attrs=None, ignore=None, params=None): - """Ignore usergroup from read and alter auth_source_ldap with auth_source""" + """Ignore usergroup from read and alter auth_source_ldap with auth_source.""" entity = entity or self.entity_with_parent() if ignore is None: ignore = set() @@ -1664,7 +1665,7 @@ def __init__(self, server_config=None, **kwargs): class OVirtComputeResource(AbstractComputeResource): - """A representation for compute resources with Ovirt provider""" + """A representation for compute resources with Ovirt provider.""" def __init__(self, server_config=None, **kwargs): self._fields = { @@ -1680,7 +1681,7 @@ def __init__(self, server_config=None, **kwargs): self._fields['provider_friendly_name'].default = 'OVirt' def read(self, entity=None, attrs=None, ignore=None, params=None): - """Make sure, ``password`` is in the ignore list for read""" + """Make sure, ``password`` is in the ignore list for read.""" if ignore is None: ignore = set() ignore.add('password') @@ -1688,7 +1689,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): class VMWareComputeResource(AbstractComputeResource): - """A representation for compute resources with Vmware provider""" + """A representation for compute resources with Vmware provider.""" def __init__(self, server_config=None, **kwargs): self._fields = { @@ -1703,7 +1704,7 @@ def __init__(self, server_config=None, **kwargs): self._fields['provider_friendly_name'].default = 'VMware' def read(self, entity=None, attrs=None, ignore=None, params=None): - """Make sure, ``password`` is in the ignore list for read""" + """Make sure, ``password`` is in the ignore list for read.""" if ignore is None: ignore = set() ignore.add('password') @@ -1724,7 +1725,7 @@ def __init__(self, server_config=None, **kwargs): self._fields['provider_friendly_name'].default = 'GCE' def read(self, entity=None, attrs=None, ignore=None, params=None): - """Make sure, ``key_path`` is in the ignore list for read""" + """Make sure, ``key_path`` is in the ignore list for read.""" if ignore is None: ignore = set() ignore.add('key_path') @@ -1732,7 +1733,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): class AzureRMComputeResource(AbstractComputeResource): - """A representation for compute resources with AzureRM provider""" + """A representation for compute resources with AzureRM provider.""" def __init__(self, server_config=None, **kwargs): self._fields = { @@ -1750,7 +1751,7 @@ def __init__(self, server_config=None, **kwargs): self._fields['provider_friendly_name'].default = 'Azure Resource Manager' def read(self, entity=None, attrs=None, ignore=None, params=None): - """Make sure, ``secret_key`` is in the ignore list for read""" + """Make sure, ``secret_key`` is in the ignore list for read.""" if ignore is None: ignore = set() ignore.add('secret_key') @@ -1811,9 +1812,7 @@ def __init__(self, server_config=None, **kwargs): } def read(self, entity=None, attrs=None, ignore=None, params=None): - """Create a JobTemplate object before calling read() - ignore 'advanced' - """ + """Create a JobTemplate object before calling read, ignore 'advanced'.""" entity = entity or self.entity_with_parent() if ignore is None: ignore = set() @@ -1845,7 +1844,7 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def run(self, synchronous=True, **kwargs): - """Helper to run existing job template + """Run an existing job template. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -1918,7 +1917,6 @@ def __init__(self, server_config=None, **kwargs): def create_payload(self): """Wrap submitted data within an extra dict.""" - payload = super().create_payload() effective_user = payload.pop('effective_user', None) if effective_user: @@ -1936,8 +1934,10 @@ def update_payload(self, fields=None): def read(self, entity=None, attrs=None, ignore=None, params=None): """Ignore the template inputs when initially reading the job template. + Look up each TemplateInput entity separately - and afterwords add them to the JobTemplate entity.""" + and afterwords add them to the JobTemplate entity. + """ if attrs is None: attrs = self.read_json(params=params) if ignore is None: @@ -2055,7 +2055,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): return super().read(entity, attrs, ignore, params) def build_pxe_default(self, synchronous=True, timeout=None, **kwargs): - """Helper to build pxe default template. + """Build pxe default template. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2073,7 +2073,7 @@ def build_pxe_default(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def clone(self, synchronous=True, timeout=None, **kwargs): - """Helper to clone an existing provision template + """Clone an existing provision template. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2156,7 +2156,7 @@ def path(self, which=None): return super().path(which) def clone(self, synchronous=True, timeout=None, **kwargs): - """Helper to clone an existing report template + """Clone an existing report template. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2174,7 +2174,7 @@ def clone(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def generate(self, synchronous=True, timeout=None, **kwargs): - """Helper to generate an existing report template + """Generate an existing report template. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2192,7 +2192,7 @@ def generate(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def schedule_report(self, synchronous=True, timeout=None, **kwargs): - """Helper to schedule an existing report template + """Schedule an existing report template. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2210,7 +2210,7 @@ def schedule_report(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def report_data(self, synchronous=True, timeout=None, **kwargs): - """Helper to call report_data on an existing scheduled report + """Call report_data on an existing scheduled report. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2437,7 +2437,7 @@ def path(self, which=None): return super().path(which) def incremental_update(self, synchronous=True, timeout=None, **kwargs): - """Helper for incrementally updating a content view version. + """Incrementally update a content view version. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2456,7 +2456,7 @@ def incremental_update(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def promote(self, synchronous=True, timeout=None, **kwargs): - """Helper for promoting an existing published content view. + """Promote an existing published content view. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2767,7 +2767,7 @@ def path(self, which=None): return super().path(which) def publish(self, synchronous=True, timeout=None, **kwargs): - """Helper for publishing an existing content view. + """Publish an existing content view. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -2851,10 +2851,9 @@ def __init__(self, server_config=None, **kwargs): } def read(self, entity=None, attrs=None, ignore=None, params=None): - """ - Add composite_content_view to the response if needed, as - :meth:`nailgun.entity_mixins.EntityReadMixin.read` can't initialize - composite_content_view. + """Add composite_content_view to the response if needed. + + :meth:`nailgun.entity_mixins.EntityReadMixin.read` can't initialize composite_content_view. """ if attrs is None: attrs = self.read_json() @@ -2867,6 +2866,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: add @@ -2905,7 +2905,7 @@ def add(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def remove(self, synchronous=True, timeout=None, **kwargs): - """remove provided Content View Component. + """Remove provided Content View Component. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3064,6 +3064,7 @@ def update_payload(self, fields=None): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: smart_class_parameters @@ -3077,7 +3078,7 @@ def path(self, which=None): return super().path(which) def list_scparams(self, synchronous=True, timeout=None, **kwargs): - """List all smart class parameters + """List all smart class parameters. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3127,7 +3128,7 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def compare(self, synchronous=True, timeout=None, **kwargs): - """Compare errata from different content view versions + """Compare errata from different content view versions. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3161,9 +3162,12 @@ def path(self, which=None): return super().path(which) def read(self, entity=None, attrs=None, ignore=None, params=None): - """Following fields are only accessible for filtering search results - and are never returned by the server: ``content_view_version_id``, - ``environment_id``, ``repository_id``. + """Read errata from the server. + + Following fields are only accessible for filtering search results + and are never returned by the server: + + ``content_view_version_id``, ``environment_id``, ``repository_id``. """ if ignore is None: ignore = set() @@ -3221,7 +3225,7 @@ def create_payload(self): return {'filter': super().create_payload()} def read(self, entity=None, attrs=None, ignore=None, params=None): - """Deal with different named data returned from the server""" + """Deal with different named data returned from the server.""" if attrs is None: attrs = self.read_json() attrs['override'] = attrs.pop('override?') @@ -3324,7 +3328,7 @@ def poll(self, poll_rate=None, timeout=None, must_succeed=True): return _poll_task(self.id, self._server_config, poll_rate, timeout, must_succeed) def summary(self, synchronous=True, timeout=None, **kwargs): - """Helper to view a summary of tasks. + """View a summary of tasks. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3343,7 +3347,7 @@ def summary(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_cancel(self, synchronous=True, timeout=None, **kwargs): - """Cancels the task(s). + """Cancel the task(s). :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3609,6 +3613,7 @@ def update_payload(self, fields=None): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: clone @@ -3639,7 +3644,7 @@ def path(self, which=None): return super().path(which) def add_puppetclass(self, synchronous=True, timeout=None, **kwargs): - """Add a Puppet class to host group + """Add a Puppet class to host group. Here is an example of how to use this method:: hostgroup.add_puppetclass(data={'puppetclass_id': puppet.id}) @@ -3661,7 +3666,7 @@ def add_puppetclass(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def delete_puppetclass(self, synchronous=True, timeout=None, **kwargs): - """Remove a Puppet class from host group + """Remove a Puppet class from host group. Here is an example of how to use this method:: hostgroup.delete_puppetclass(data={'puppetclass_id': puppet.id}) @@ -3688,7 +3693,7 @@ def delete_puppetclass(self, synchronous=True, timeout=None, **kwargs): ) def list_scparams(self, synchronous=True, timeout=None, **kwargs): - """List all smart class parameters + """List all smart class parameters. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3707,7 +3712,7 @@ def list_scparams(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def clone(self, synchronous=True, timeout=None, **kwargs): - """Helper to clone an existing host group + """Clone an existing host group. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3725,7 +3730,7 @@ def clone(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def rebuild_config(self, synchronous=True, timeout=None, **kwargs): - """Helper to 'Rebuild orchestration config' of an existing host group + """Rebuild orchestration config of an existing host group. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3743,7 +3748,7 @@ def rebuild_config(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def assign_ansible_roles(self, synchronous=True, timeout=None, **kwargs): - """Add an Ansible Role to a hostgroup + """Add an Ansible Role to a hostgroup. Here is an example of how to use this method:: hostgroup.assign_ansible_roles(data={'ansible_role_ids': @@ -3766,7 +3771,7 @@ def assign_ansible_roles(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def list_ansible_roles(self, synchronous=True, timeout=None, **kwargs): - """List all Ansible Roles assigned to a hostgroup + """List all Ansible Roles assigned to a hostgroup. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3785,7 +3790,7 @@ def list_ansible_roles(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def add_ansible_role(self, synchronous=True, timeout=None, **kwargs): - """Add single Ansible Role to a hostgroup + """Add single Ansible Role to a hostgroup. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3805,7 +3810,7 @@ def add_ansible_role(self, synchronous=True, timeout=None, **kwargs): ) def remove_ansible_role(self, synchronous=True, timeout=None, **kwargs): - """Remove single Ansible Role assigned to a hostgroup + """Remove single Ansible Role assigned to a hostgroup. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3875,7 +3880,7 @@ def path(self, which=None): return super().path(which) def subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Helper for getting subscriptions from host + """Get subscriptions from host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3894,7 +3899,7 @@ def subscriptions(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def add_subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Helper for adding subscriptions to host + """Add subscriptions to host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -3913,7 +3918,7 @@ def add_subscriptions(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def remove_subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Helper for removing subscriptions from host + """Remove subscriptions from host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4196,7 +4201,7 @@ def create(self, create_missing=None): ).read() def enc(self, synchronous=True, timeout=None, **kwargs): - """Return external node classifier (ENC) information + """Return external node classifier (ENC) information. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4214,7 +4219,7 @@ def enc(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def errata(self, synchronous=True, timeout=None, **kwargs): - """List errata available for the host + """List errata available for the host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4233,7 +4238,7 @@ def errata(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def traces(self, synchronous=True, timeout=None, **kwargs): - """List services that need restarting for the host + """List services that need restarting for the host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4251,7 +4256,7 @@ def traces(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_traces(self, synchronous=True, timeout=None, **kwargs): - """List services that need restarting for the specified set of hosts + """List services that need restarting for the specified set of hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4269,7 +4274,7 @@ def bulk_traces(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def resolve_traces(self, synchronous=True, timeout=None, **kwargs): - """Resolve traces for the host + """Resolve traces for the host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4287,7 +4292,7 @@ def resolve_traces(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_resolve_traces(self, synchronous=True, timeout=None, **kwargs): - """Resolve traces for the specified set of hosts + """Resolve traces for the specified set of hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4305,7 +4310,7 @@ def bulk_resolve_traces(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_destroy(self, synchronous=True, timeout=None, **kwargs): - """Destroy the set of hosts + """Destroy the set of hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4323,7 +4328,7 @@ def bulk_destroy(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def packages(self, synchronous=True, timeout=None, **kwargs): - """List packages installed on the host + """List packages installed on the host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4341,7 +4346,7 @@ def packages(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def module_streams(self, synchronous=True, timeout=None, **kwargs): - """List module_streams available for the host + """List module_streams available for the host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4360,7 +4365,7 @@ def module_streams(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def errata_applicability(self, synchronous=True, timeout=None, **kwargs): - """Force regenerate errata applicability + """Force regenerate errata applicability. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4379,7 +4384,7 @@ def errata_applicability(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def errata_apply(self, synchronous=True, timeout=None, **kwargs): - """Schedule errata for installation + """Schedule errata for installation. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4398,7 +4403,7 @@ def errata_apply(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def install_content(self, synchronous=True, timeout=None, **kwargs): - """Install content on one or more hosts + """Install content on one or more hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4417,7 +4422,7 @@ def install_content(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_add_subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Add subscriptions to one or more hosts + """Add subscriptions to one or more hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4436,7 +4441,7 @@ def bulk_add_subscriptions(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_remove_subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Remove subscriptions from one or more hosts + """Remove subscriptions from one or more hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4455,7 +4460,7 @@ def bulk_remove_subscriptions(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def bulk_available_incremental_updates(self, synchronous=True, timeout=None, **kwargs): - """Get available_incremental_updates for one or more hosts + """Get available_incremental_updates for one or more hosts. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4474,7 +4479,7 @@ def bulk_available_incremental_updates(self, synchronous=True, timeout=None, **k return _handle_response(response, self._server_config, synchronous, timeout) def get_facts(self, synchronous=True, timeout=None, **kwargs): - """List all fact values of a given host + """List all fact values of a given host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4493,7 +4498,7 @@ def get_facts(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def upload_facts(self, synchronous=True, timeout=None, **kwargs): - """Upload facts for a host, creating the host if required + """Upload facts for a host, creating the host if required. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4609,6 +4614,7 @@ def update_payload(self, fields=None): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: bulk/install_content @@ -4672,7 +4678,7 @@ def path(self, which=None): return super().path(which) def add_puppetclass(self, synchronous=True, timeout=None, **kwargs): - """Add a Puppet class to host + """Add a Puppet class to host. Here is an example of how to use this method:: host.add_puppetclass(data={'puppetclass_id': puppet.id}) @@ -4694,7 +4700,7 @@ def add_puppetclass(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def delete_puppetclass(self, synchronous=True, timeout=None, **kwargs): - """Remove a Puppet class from host + """Remove a Puppet class from host. Here is an example of how to use this method:: host.delete_puppetclass(data={'puppetclass_id': puppet.id}) @@ -4721,7 +4727,7 @@ def delete_puppetclass(self, synchronous=True, timeout=None, **kwargs): ) def read_template(self, synchronous=True, timeout=None, **kwargs): - """Fetches and reads the provisioning template for given host + """Fetch and read the provisioning template for given host. Here is an example of how to use this method:: host.read_template(data={'template_kind': 'iPXE'}) @@ -4748,7 +4754,7 @@ def read_template(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def list_scparams(self, synchronous=True, timeout=None, **kwargs): - """List all smart class parameters + """List all smart class parameters. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4767,7 +4773,7 @@ def list_scparams(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def power(self, synchronous=True, timeout=None, **kwargs): - """Power the host off or on + """Power the host off or on. :param kwargs: Arguments to pass to requests. :returns: The server's response, with all JSON decoded. @@ -4814,7 +4820,7 @@ def search(self, fields=None, query=None, filters=None): return entities def disassociate(self, synchronous=True, timeout=None, **kwargs): - """Disassociate the host + """Disassociate the host. :param kwargs: Arguments to pass to requests. :returns: The server's response, with all JSON decoded. @@ -4828,7 +4834,7 @@ def disassociate(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def assign_ansible_roles(self, synchronous=True, timeout=None, **kwargs): - """Add an Ansible Role to a host + """Add an Ansible Role to a host. Here is an example of how to use this method:: host.assign_ansible_roles(data={'ansible_role_ids': @@ -4851,7 +4857,7 @@ def assign_ansible_roles(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def list_ansible_roles(self, synchronous=True, timeout=None, **kwargs): - """List all Ansible Roles assigned to a Host + """List all Ansible Roles assigned to a Host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4870,7 +4876,7 @@ def list_ansible_roles(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def add_ansible_role(self, synchronous=True, timeout=None, **kwargs): - """Add single Ansible Role to a host + """Add single Ansible Role to a host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4890,7 +4896,7 @@ def add_ansible_role(self, synchronous=True, timeout=None, **kwargs): ) def remove_ansible_role(self, synchronous=True, timeout=None, **kwargs): - """Remove single Ansible Role assigned to a host + """Remove single Ansible Role assigned to a host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4910,7 +4916,7 @@ def remove_ansible_role(self, synchronous=True, timeout=None, **kwargs): ) def play_ansible_roles(self, synchronous=True, timeout=None, **kwargs): - """Play all assigned ansible roles on a Host + """Play all assigned ansible roles on a Host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -4929,7 +4935,7 @@ def play_ansible_roles(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout)['task_id'] def list_provisioning_templates(self, synchronous=True, timeout=None, **kwargs): - """List all Provisioning templates assigned to a Host + """List all Provisioning templates assigned to a Host. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -5116,9 +5122,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): return super().read(entity, attrs, ignore, params) def search_normalize(self, results): - """Append host id to search results to be able to initialize found - :class:`Interface` successfully - """ + """Append host id to search results to initialize found :class:`Interface` successfully.""" for interface in results: interface['host_id'] = self.host.id return super().search_normalize(results) @@ -5218,6 +5222,7 @@ def update_payload(self, fields=None): def create_payload(self): """Wrap submitted data within an extra dict. + For more information, see `Bugzilla #1151220 `_. """ @@ -5225,6 +5230,7 @@ def create_payload(self): def read(self, entity=None, attrs=None, ignore=None, params=None): """Make sure, password, organization and location is in the ignore list for read. + For more information, see `Bugzilla #1779642 `_. """ @@ -5708,7 +5714,7 @@ def sca_enable(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def repo_discover(self, synchronous=True, timeout=None, **kwargs): - """repo discovery. + """Repo discovery. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -5762,7 +5768,7 @@ def sca_eligible(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def subscriptions(self, synchronous=True, timeout=None, **kwargs): - """Helper for getting subscriptions from organization. + """Get subscriptions from organization. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -5797,7 +5803,7 @@ def rh_cloud_download_report(self, destination, **kwargs): tarfile.write(response.content) def rh_cloud_generate_report(self, synchronous=True, timeout=None, **kwargs): - """Start RHCloud Inventory report generation process + """Start RHCloud Inventory report generation process. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -5816,7 +5822,7 @@ def rh_cloud_generate_report(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def rh_cloud_inventory_sync(self, synchronous=True, timeout=None, **kwargs): - """Start inventory synchronization + """Start inventory synchronization. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -5861,6 +5867,7 @@ def __init__(self, server_config=None, **kwargs): def read(self, entity=None, attrs=None, ignore=None, params=None): """Fetch as many attributes as possible for this entity. + Since operatingsystem is needed to instanciate, prepare the entity accordingly. """ @@ -5871,8 +5878,9 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): return super().read(entity, attrs, ignore, params) def update_payload(self, fields=None): - """Wrap payload in ``os_default_template`` - relates to `Redmine #21169`_. + """Wrap payload in ``os_default_template``. + + Relates to `Redmine #21169`_. .. _Redmine #21169: http://projects.theforeman.org/issues/21169 """ @@ -5906,7 +5914,7 @@ def __init__(self, server_config=None, **kwargs): } def create_payload(self): - """Remove ``smart_class_parameter_id``""" + """Remove ``smart_class_parameter_id``.""" payload = super().create_payload() if hasattr(self, 'smart_class_parameter'): del payload['smart_class_parameter_id'] @@ -5975,7 +5983,9 @@ def __init__(self, server_config=None, **kwargs): } def read(self, entity=None, attrs=None, ignore=None, params=None): - """Ignore path related fields as they're never returned by the server + """Read parameter from server. + + Ignore path related fields as they're never returned by the server and are only added to entity to be able to use proper path. """ entity = entity or self.entity_with_parent(**{self._parent_type: self._parent_id}) @@ -6085,7 +6095,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): return result def search(self, fields=None, query=None, filters=None): - """Search for entities with missing attribute + """Search for entities with missing attribute. :param fields: A set naming which fields should be used when generating a search query. If ``None``, all values on the entity are used. If @@ -6172,7 +6182,7 @@ def path(self, which=None): return super().path(which) def destroy(self, synchronous=True, timeout=None, **kwargs): - """Helper to destroy one or more products. + """Destroy one or more products. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6191,7 +6201,7 @@ def destroy(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def sync(self, synchronous=True, timeout=None, **kwargs): - """Helper to sync one or more products. + """Sync one or more products. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6210,7 +6220,7 @@ def sync(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def http_proxy(self, synchronous=True, timeout=None, **kwargs): - """Helper to update the http proxy configuration on the repositories of one or more products. + """Update the http proxy configuration on the repositories of one or more products. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6229,7 +6239,7 @@ def http_proxy(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def sync_plan(self, synchronous=True, timeout=None, **kwargs): - """Helper to sync one or more products. + """Sync one or more products. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6306,7 +6316,8 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def search_normalize(self, results): - """Flattens results. + """Flatten results. + :meth:`nailgun.entity_mixins.EntitySearchMixin.search_normalize` expects structure like list(dict_1(name: class_1), dict_2(name: class_2)), @@ -6318,6 +6329,7 @@ def search_normalize(self, results): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: smart_class_parameters @@ -6331,7 +6343,7 @@ def path(self, which=None): return super().path(which) def list_scparams(self, synchronous=True, timeout=None, **kwargs): - """List of smart class parameters for a specific Puppet class + """List of smart class parameters for a specific Puppet class. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6508,7 +6520,7 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def cancel(self, synchronous=True, timeout=None, **kwargs): - """Helper for canceling a recurring logic + """Cancel a recurring logic. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6528,6 +6540,7 @@ def cancel(self, synchronous=True, timeout=None, **kwargs): def path(self, which=None): """Extend ``nailgun.entity_mixins.RecurringLogic.path``. + The format of the returned path depends on the value of ``which``: cancel @@ -6572,8 +6585,9 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def create_payload(self): - """Wrap submitted data within an extra dict. In addition, - rename the ``activation_keys_ids`` field to ``activation_keys``. + """Wrap submitted data within an extra dict. + + In addition, rename the ``activation_keys_ids`` field to ``activation_keys``. """ payload = super().create_payload() @@ -6582,8 +6596,10 @@ def create_payload(self): return payload def read(self, entity=None, attrs=None, ignore=None, params=None): - """Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore - all the fields and returns 'registration_command' output in dict + """Read registration command from server. + + Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore + all the fields and returns 'registration_command' output in dict. """ if attrs is None: attrs = self.read_json() @@ -6712,7 +6728,9 @@ def path(self, which=None): return super().path(which) def read(self, entity=None, attrs=None, ignore=None, params=None): - """Ignore ``organization`` field as it's never returned by the server + """Read repository from server. + + Ignore ``organization`` field as it's never returned by the server and is only added to entity to be able to use organization path dependent helpers and also upstream_password as it is not returned for security reasons. @@ -6755,7 +6773,7 @@ def errata(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def sync(self, synchronous=True, timeout=None, **kwargs): - """Helper for syncing an existing repository. + """Sync an existing repository. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6825,7 +6843,7 @@ def import_uploads( timeout=None, **kwargs, ): - """Import uploads into a repository + """Import uploads into a repository. It expects either a list of uploads or upload_ids (but not both). @@ -6855,7 +6873,7 @@ def import_uploads( return json def remove_content(self, synchronous=True, timeout=None, **kwargs): - """Remove content from a repository + """Remove content from a repository. It expects content/packages/docker manifests ids sent as data. Here is an example of how to use this method:: @@ -6879,7 +6897,7 @@ def remove_content(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def packages(self, synchronous=True, timeout=None, **kwargs): - """List packages associated with repository + """List packages associated with repository. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6898,7 +6916,7 @@ def packages(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def module_streams(self, synchronous=True, timeout=None, **kwargs): - """List module_streams associated with repository + """List module_streams associated with repository. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6917,7 +6935,7 @@ def module_streams(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def files(self, synchronous=True, timeout=None, **kwargs): - """List files associated with repository + """List files associated with repository. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -6937,7 +6955,7 @@ def files(self, synchronous=True, timeout=None, **kwargs): class RepositorySet(Entity, EntityReadMixin, EntitySearchMixin): - """A representation of a Repository Set entity""" + """A representation of a Repository Set entity.""" def __init__(self, server_config=None, **kwargs): self._fields = { @@ -6966,13 +6984,12 @@ def __init__(self, server_config=None, **kwargs): } def available_repositories(self, **kwargs): - """Lists available repositories for the repository set + """List available repositories for the repository set. :param kwargs: Arguments to pass to requests. :returns: The server's response, with all JSON decoded. :raises: ``requests.exceptions.HTTPError`` If the server responds with an HTTP 4XX or 5XX message. - """ if 'data' not in kwargs: kwargs['data'] = {} @@ -6983,9 +7000,9 @@ def available_repositories(self, **kwargs): return _handle_response(response, self._server_config) def enable(self, synchronous=True, timeout=None, **kwargs): - """Enables the RedHat Repository + """Enable a RedHat Repository. - RedHat Repos needs to be enabled first, so that we can sync it. + RedHat repos needs to be enabled first, so that we can sync it. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -7007,7 +7024,7 @@ def enable(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def disable(self, synchronous=True, timeout=None, **kwargs): - """Disables the RedHat Repository + """Disables a RedHat Repository. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -7180,7 +7197,7 @@ def path(self, which=None): return super().path(which) def enable_connector(self, synchronous=True, timeout=None, **kwargs): - """Function to enable RH Cloud connector""" + """Enable RH Cloud connector.""" kwargs = kwargs.copy() kwargs.update(self._server_config.get_client_kwargs()) kwargs['data'] = {} @@ -7247,6 +7264,7 @@ def update_payload(self, fields=None): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: clone @@ -7260,7 +7278,7 @@ def path(self, which=None): return super().path(which) def clone(self, synchronous=True, timeout=None, **kwargs): - """Helper to clone an existing Role + """Clone an existing Role. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -7297,8 +7315,10 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def read(self, entity=None, attrs=None, ignore=None, params=None): - """Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore - the ``created_at and updated_at`` + """Read setting from server. + + Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore + the ``created_at and updated_at``. """ if ignore is None: ignore = set() @@ -7341,6 +7361,7 @@ def __init__(self, server_config=None, **kwargs): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: refresh @@ -7354,7 +7375,7 @@ def path(self, which=None): return super().path(which) def refresh(self, synchronous=True, timeout=None, **kwargs): - """Refresh Capsule features + """Refresh Capsule features. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -7403,8 +7424,7 @@ def import_puppetclasses(self, synchronous=True, timeout=None, **kwargs): ) def read(self, entity=None, attrs=None, ignore=None, params=None): - """Ignore ``download_policy`` field as it's never returned by the - server. + """Ignore ``download_policy`` field as it's never returned by the server. For more information, see `Bugzilla #1486609 `_. @@ -7476,6 +7496,7 @@ class Snapshot( EntityUpdateMixin, ): """A representation of a Snapshot entity. + Foreman_snapshot as mentioned in the plugin: https://github.com/ATIX-AG/foreman_snapshot_management # Read Snapshot @@ -7489,7 +7510,7 @@ class Snapshot( # Revert Snapshot Snapshot(host=, id=).revert() # Delete Snapshot - Snapshot(host=, id=).delete() + Snapshot(host=, id=).delete(). """ def __init__(self, server_config=None, **kwargs): @@ -7506,8 +7527,9 @@ def __init__(self, server_config=None, **kwargs): def path(self, which=None): """Extend nailgun.entity_mixins.Entity.path. + revert - /api/v2/hosts//snapshots//revert + /api/v2/hosts//snapshots//revert. """ if which == "revert": return f'{super().path(which="self")}/{which}' @@ -7538,20 +7560,16 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): return super().read(entity, attrs, ignore, params) def search_normalize(self, results): - """Append host id to search results to be able to initialize found - :class:`Snapshot` successfully - """ - + """Append host id to search results to initialize found :class:`Snapshot` successfully.""" for snapshot in results: snapshot['host_id'] = self.host.id return super().search_normalize(results) def revert(self, **kwargs): - """Rollbacks the Snapshot + """Rollback the Snapshot. Makes HTTP PUT call to revert the snapshot. """ - kwargs.update(self._server_config.get_client_kwargs()) response = client.put(self.path('revert'), **kwargs) return _handle_response(response, self._server_config) @@ -7602,9 +7620,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): return super().read(entity, attrs, ignore, params) def search_normalize(self, results): - """Append user id to search results to be able to initialize found - :class:`User` successfully - """ + """Append user id to search results to initialize found :class:`User` successfully.""" for sshkey in results: sshkey['user_id'] = self.user.id return super().search_normalize(results) @@ -7763,7 +7779,7 @@ def path(self, which=None): return super().path(which) def _org_path(self, which, payload): - """A helper method for generating paths with organization IDs in them. + """Generate paths with organization IDs in them. :param which: A path such as "manifest_history" that has an organization ID in it. @@ -7820,7 +7836,9 @@ def manifest_history(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def read(self, entity=None, attrs=None, ignore=None, params=None): - """Ignore ``organization`` field as it's never returned by the server + """Read subscription from server. + + Ignore ``organization`` field as it's never returned by the server and is only added to entity to be able to use organization path dependent helpers. """ @@ -8114,7 +8132,7 @@ def path(self, which=None): return super().path(which) def imports(self, synchronous=True, timeout=None, **kwargs): - """Helper to import templates + """Import templates. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -8132,7 +8150,7 @@ def imports(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def exports(self, synchronous=True, timeout=None, **kwargs): - """Helper to export templates + """Export templates. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -8417,19 +8435,15 @@ def path(self, which=None): return super().path(which) def create_payload(self): - """ - Wraps config in extra dict - """ + """Wrap config in extra dict.""" return {'foreman_virt_who_configure_config': super().create_payload()} def update_payload(self, fields=None): - """ - Wraps config in extra dict - """ + """Wrap config in extra dict.""" return {'foreman_virt_who_configure_config': super().update_payload(fields)} def deploy_script(self, synchronous=True, timeout=None, **kwargs): - """Helper for Config's deploy_script method. + """Deploy script for a VirtWho Config. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -8448,9 +8462,10 @@ def deploy_script(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def read(self, entity=None, attrs=None, ignore=None, params=None): - """ + """Read subscription from server. + Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore - the ``hypervisor_password`` + the ``hypervisor_password``. """ if not ignore: ignore = set() @@ -8459,7 +8474,8 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): return super().read(entity, attrs, ignore, params) def get_organization_configs(self, synchronous=True, timeout=None, **kwargs): - """ + """Get all virt-who configurations per organization. + Unusually, the ``/foreman_virt_who_configure/api/v2/organizations/ :organization_id/configs`` path is totally unsupported. Support to List of virt-who configurations per organization. @@ -8520,8 +8536,10 @@ def create(self, create_missing=None): ).read() def read(self, entity=None, attrs=None, ignore=None, params=None): - """Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore - the ``scap_file`` + """Read subscription from server. + + Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore + the ``scap_file``. """ if ignore is None: ignore = set() @@ -8530,6 +8548,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: xml @@ -8548,7 +8567,7 @@ def update(self, fields=None): return self.read() def xml(self, synchronous=True, timeout=None, **kwargs): - """Download an SCAP content as XML + """Download an SCAP content as XML. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -8622,7 +8641,8 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def create(self, create_missing=None): - """Overrides creation of Webhooks + """Override creation of Webhooks. + Before creating the Webhook, we want to call get_events to get a valid list of events to pass into our POST call. @@ -8635,8 +8655,10 @@ def create(self, create_missing=None): ).read() def read(self, entity=None, attrs=None, ignore=None, params=None): - """Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore - the ``webhook_template_id``, ``password``, and ``proxy_authorization`` + """Read subscription from server. + + Override :meth:`nailgun.entity_mixins.EntityReadMixin.read` to ignore + the ``webhook_template_id``, ``password``, and ``proxy_authorization``. """ if ignore is None: ignore = set() @@ -8647,6 +8669,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: events @@ -8660,7 +8683,9 @@ def path(self, which=None): return super().path(which) def get_events(self, synchronous=True, timeout=None, **kwargs): - """GET api/webhooks/events returns the list of all valid events + """Get all valid events for a Webhook. + + GET api/webhooks/events returns the list of all valid events we can use to create a Webhook. Calling this list before our create allows us to test all possible events. @@ -8691,6 +8716,7 @@ def __init__(self, server_config=None, **kwargs): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: fetch @@ -8706,7 +8732,7 @@ def path(self, which=None): return super().path(which) def fetch(self, synchronous=True, timeout=None, **kwargs): - """Helper for fetching all ansible playbooks. + """Fetch all ansible playbooks. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -8725,7 +8751,7 @@ def fetch(self, synchronous=True, timeout=None, **kwargs): return _handle_response(response, self._server_config, synchronous, timeout) def sync(self, synchronous=True, timeout=None, **kwargs): - """Helper to sync ansible playbooks. + """Sync ansible playbooks. :param synchronous: What should happen if the server returns an HTTP 202 (accepted) status code? Wait for the task to complete if @@ -8762,6 +8788,7 @@ def __init__(self, server_config=None, **kwargs): def path(self, which=None): """Extend ``nailgun.entity_mixins.Entity.path``. + The format of the returned path depends on the value of ``which``: sync @@ -8775,7 +8802,7 @@ def path(self, which=None): return super().path(which) def sync(self, synchronous=True, timeout=None, **kwargs): - """Helper to sync ansible roles from a proxy. + """Sync ansible roles from a proxy. AnsibleRoles.sync(data={'proxy_id': "target_sat.ip", 'role_names': ["role_name"]}) @@ -8830,7 +8857,9 @@ def __init__(self, server_config=None, **kwargs): super().__init__(server_config, **kwargs) def read(self, entity=None, attrs=None, ignore=None, params=None): - """Ignore path related fields as they're never returned by the server + """Read table preferences from server. + + Ignore path related fields as they're never returned by the server and are only added to entity to be able to use proper path. """ entity = entity or self.entity_with_parent(user=self.user) @@ -8841,6 +8870,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): def search(self, fields=None, query=None, filters=None): """List/search for TablePreferences. + Field 'user' is only used for path and is not returned. """ return super().search( diff --git a/nailgun/entity_fields.py b/nailgun/entity_fields.py index a30ae568..b4c03e15 100644 --- a/nailgun/entity_fields.py +++ b/nailgun/entity_fields.py @@ -51,7 +51,7 @@ class Field: - """Base class to implement other fields + """Base class to implement other fields. Record this field's attributes. @@ -76,7 +76,7 @@ def __init__(self, required=False, choices=None, default=_SENTINEL, unique=False class BooleanField(Field): - """Field that represents a boolean""" + """Field that represents a boolean.""" def gen_value(self): """Return a value suitable for a :class:`BooleanField`.""" @@ -85,7 +85,7 @@ def gen_value(self): class EmailField(Field): - """Field that represents an email""" + """Field that represents an email.""" def gen_value(self): """Return a value suitable for a :class:`EmailField`.""" @@ -94,7 +94,7 @@ def gen_value(self): class FloatField(Field): - """Field that represents a float""" + """Field that represents a float.""" def gen_value(self): """Return a value suitable for a :class:`FloatField`.""" @@ -159,7 +159,7 @@ def gen_value(self): class DateField(Field): - """Field that represents a date""" + """Field that represents a date.""" def __init__(self, min_date=None, max_date=None, *args, **kwargs): # If ``None`` is passed then ``FauxFactory`` will deal with it. @@ -173,7 +173,7 @@ def gen_value(self): class DateTimeField(Field): - """Field that represents a datetime""" + """Field that represents a datetime.""" def __init__(self, min_date=None, max_date=None, *args, **kwargs): # If ``None`` is passed then ``FauxFactory`` will deal with it. @@ -196,7 +196,7 @@ def gen_value(self): class IPAddressField(StringField): - """Field that represents an IP address""" + """Field that represents an IP address.""" def gen_value(self): """Return a value suitable for a :class:`IPAddressField`.""" @@ -204,7 +204,7 @@ def gen_value(self): class NetmaskField(StringField): - """Field that represents an netmask""" + """Field that represents an netmask.""" def gen_value(self): """Return a value suitable for a :class:`NetmaskField`.""" @@ -212,11 +212,11 @@ def gen_value(self): class ListField(Field): - """Field that represents a list of strings""" + """Field that represents a list of strings.""" class MACAddressField(StringField): - """Field that represents a MAC address""" + """Field that represents a MAC address.""" def gen_value(self): """Return a value suitable for a :class:`MACAddressField`.""" @@ -260,7 +260,7 @@ def gen_value(self): class URLField(StringField): - """Field that represents an URL + """Field that represents an URL. :param str scheme: The URL scheme can be one of ['http', 'https', 'ftp'] """ diff --git a/nailgun/entity_mixins.py b/nailgun/entity_mixins.py index d7a56c26..b025ccfb 100644 --- a/nailgun/entity_mixins.py +++ b/nailgun/entity_mixins.py @@ -43,7 +43,7 @@ def call_entity_method_with_timeout(entity_callable, timeout=300, **kwargs): - """Call Entity callable with a custom timeout + """Call Entity callable with a custom timeout. :param entity_callable, the entity method object to call :param timeout: the time to wait for the method call to finish @@ -211,7 +211,7 @@ def _payload(fields, values): elif isinstance(field, ListField): def parse(obj): - """parse obj payload if it is an Entity""" + """Parse obj payload if it is an Entity.""" if isinstance(obj, Entity): return _payload(obj.get_fields(), obj.get_values()) return obj @@ -530,6 +530,7 @@ def get_values(self): return attrs def __repr__(self): + """Return a string representation of the current object.""" kv_pairs = ", ".join( f"{key}={value!r}" for key, value in self.get_values().items() @@ -538,7 +539,9 @@ def __repr__(self): return f'{self.__module__}.{type(self).__name__}({kv_pairs})' def to_json(self): - r"""Create a JSON encoded string with Entity properties. Ex: + r"""Create a JSON encoded string with Entity properties. + + Ex: >>> from nailgun import entities, config >>> kwargs = { @@ -555,6 +558,7 @@ def to_json(self): def to_json_dict(self, filter_fcn=None): """Create a dict with Entity properties for json encoding. + It can be overridden by subclasses for each standard serialization doesn't work. By default it call _to_json_dict on OneToOne fields and build a list calling the same method on each OneToMany object's @@ -591,8 +595,9 @@ def to_json_dict(self, filter_fcn=None): return json_dct def __eq__(self, other): - """Compare two entities based on their properties. Even nested - objects are considered for equality + """Compare two entities based on their properties. + + Even nested objects are considered for equality. :param other: entity to compare self to :return: boolean indicating if entities are equal or not @@ -602,7 +607,8 @@ def __eq__(self, other): return self.to_json_dict() == other.to_json_dict() def compare(self, other, filter_fcn=None): - """Returns True if properties can be compared in terms of eq. + """Return True if properties can be compared in terms of eq. + Entity's Fields can be filtered accordingly to 'filter_fcn'. This callable receives field's name as first parameter and field itself as second parameter. @@ -610,7 +616,7 @@ def compare(self, other, filter_fcn=None): comparison and False otherwise. If not provided field's marked as unique will not be compared by default. 'id' and 'name' are examples of unique fields commonly ignored. Check Entities fields for fields marked - with 'unique=True' + with 'unique=True'. :param other: entity to compare @@ -622,7 +628,7 @@ def compare(self, other, filter_fcn=None): if filter_fcn is None: def filter_unique(_, field): - """Filter function for unique fields""" + """Filter function for unique fields.""" return not field.unique filter_fcn = filter_unique @@ -630,7 +636,7 @@ def filter_unique(_, field): return self.to_json_dict(filter_fcn) == other.to_json_dict(filter_fcn) def entity_with_parent(self, **parent): - """Returns modified entity by adding parent entity + """Return modified entity by adding parent entity. :parent dict: optional, The key/value pair of base entity else fetch from the fields """ @@ -651,7 +657,7 @@ def entity_with_parent(self, **parent): class EntityDeleteMixin: - """This mixin provides the ability to delete an entity. + """Provide the ability to delete an entity. The methods provided by this class work together. The call tree looks like this:: @@ -698,7 +704,6 @@ def delete(self, synchronous=True, timeout=None): out. """ - response = self.delete_raw() response.raise_for_status() @@ -717,7 +722,7 @@ def delete(self, synchronous=True, timeout=None): class EntityReadMixin: - """This mixin provides the ability to read an entity. + """Provide the ability to read an entity. The methods provided by this class work together. The call tree looks like this:: @@ -849,7 +854,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None): class EntityCreateMixin: - """This mixin provides the ability to create an entity. + """Provide the ability to create an entity. The methods provided by this class work together. The call tree looks like this:: @@ -985,7 +990,7 @@ def create(self, create_missing=None): class EntityUpdateMixin: - """This mixin provides the ability to update an entity. + """Provide the ability to update an entity. The methods provided by this class work together. The call tree looks like this:: @@ -1084,7 +1089,7 @@ def update(self, fields=None): class EntitySearchMixin: - """This mixin provides the ability to search for entities. + """Provide the ability to search for entities. The methods provided by this class work together. The call tree looks like this:: @@ -1444,7 +1449,7 @@ def search_filter(entities, filters): def to_json_serializable(obj): - """Transforms obj into a json serializable object. + """Transform obj into a json serializable object. :param obj: entity or any json serializable object diff --git a/pyproject.toml b/pyproject.toml index 6326758f..708a464e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ select = [ "C", # complexity "C4", # flake8-comprehensions "COM818", # Trailing comma on bare tuple prohibited - # "D", # docstrings + "D", # docstrings "E", # pycodestyle "F", # pyflakes/autoflake "G", # flake8-logging-format diff --git a/tests/test_client.py b/tests/test_client.py index 0de36914..cd5bb2b7 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -30,7 +30,7 @@ def test_false(self): self.assertFalse(client._content_type_is_json(kwargs)) def test_false_with_no_headers(self): - """If no headers passed should return None""" + """If no headers passed should return None.""" self.assertFalse(client._content_type_is_json({})) @@ -63,6 +63,7 @@ class ClientTestCase(TestCase): """Tests for functions in :mod:`nailgun.client`.""" def setUp(self): + """Set up some common variables.""" self.bogus_url = gen_alpha() self.mock_response = mock.Mock(status_code=200) diff --git a/tests/test_config.py b/tests/test_config.py index 5ed49783..4b871b28 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -69,6 +69,7 @@ def test_init(self): def test_init_invalid(self): """Test instantiating :class: `nailgun.config.BaseServerConfig`. + Assert that configs with invalid versions do not load. """ with self.assertRaises(InvalidVersion): @@ -171,7 +172,7 @@ def test_init(self): ) def test_raise_config_file_error(self): - """Should raise error if path not found""" + """Should raise error if path not found.""" with self.assertRaises(ConfigFileError): _get_config_file_path('foo', 'bar') diff --git a/tests/test_entities.py b/tests/test_entities.py index f4a6bab3..d5b15679 100644 --- a/tests/test_entities.py +++ b/tests/test_entities.py @@ -38,7 +38,7 @@ def make_entity(cls, **kwargs): - """Helper function to create entity with dummy ServerConfig""" + """Create entity with dummy ServerConfig.""" cfg = config.ServerConfig(url='https://foo.bar', verify=False, auth=('foo', 'bar')) return cls(cfg, **kwargs) @@ -82,7 +82,6 @@ def test_init_succeeds(self): Assert that the returned object is an instance of the class that produced it. - """ entities_ = [ (entity, {}) @@ -225,7 +224,6 @@ def test_required_params(self): Assert that ``TypeError`` is raised if the required extra parameters are not provided. - """ for entity in ( entities.ContentViewComponent, @@ -397,7 +395,6 @@ def test_no_such_path_error(self): """Trigger :class:`nailgun.entity_mixins.NoSuchPathError` exceptions. Do this by calling ``entity().path(which=…)``. - """ for entity, which in ( (entities.ActivationKey, 'releases'), @@ -431,9 +428,10 @@ def test_no_such_path_error(self): def test_arfreport(self): """Test :meth:`nailgun.entities.ArfReport.path`. + Assert that the following return appropriate paths: * ``ArfReport(id=…).path()`` - * ``ArfReport(id=…).path('download_html')`` + * ``ArfReport(id=…).path('download_html')``. """ self.assertIn('compliance/arf_reports/1', entities.ArfReport(self.cfg, id=1).path()) for which in ['download_html']: @@ -445,7 +443,7 @@ def test_arfreport(self): self.assertRegex(path, fr'{which}$') def test_os_default_template(self): - """Test ``nailgun.entities.OSDefaultTemplate.path`` + """Test ``nailgun.entities.OSDefaultTemplate.path``. Assert that the following return appropriate paths: @@ -463,7 +461,6 @@ def test_externalusergroup(self): * ``ExternalUserGroup(id=…,usergroup=…).path()`` * ``ExternalUserGroup(id=…,usergroup=…).path('refresh')`` - """ self.assertIn( 'usergroups/1/external_usergroups/2', @@ -487,7 +484,6 @@ def test_repository_set(self): * ``RepositorySet(id=…).path('available_repositories')`` * ``RepositorySet(id=…).path('disable')`` * ``RepositorySet(id=…).path('enable')`` - """ self.assertIn( '/repository_sets/2', entities.RepositorySet(self.cfg, id=2, product=1).path() @@ -508,7 +504,6 @@ def test_snapshot(self): * ``Snapshot(id=…).path()`` * ``Snapshot(id=…).path('revert')`` - """ self.assertIn( 'hosts/1/snapshots/snapshot-2', @@ -531,7 +526,6 @@ def test_sync_plan(self): * ``SyncPlan(id=…).path()`` * ``SyncPlan(id=…).path('add_products')`` * ``SyncPlan(id=…).path('remove_products')`` - """ self.assertIn( 'organizations/1/sync_plans/2', @@ -555,7 +549,6 @@ def test_subscription(self): * ``Subscription(organization=…).path('manifest_history')`` * ``Subscription(organization=…).path('refresh_manifest')`` * ``Subscription(organization=…).path('upload')`` - """ sub = entities.Subscription(self.cfg, organization=gen_integer(1, 100)) for which in ('delete_manifest', 'manifest_history', 'refresh_manifest', 'upload'): @@ -571,7 +564,6 @@ def test_capsule(self): * ``Capsule().path('content_lifecycle_environments')`` * ``Capsule().path('content_sync')`` - """ capsule = entities.Capsule(self.cfg, id=gen_integer(1, 100)) for which in ('content_lifecycle_environments', 'content_sync'): @@ -588,7 +580,6 @@ def test_hostsubscription(self): * ``HostSubscription(host=…).path('add_subscriptions')`` * ``HostSubscription(host=…).path('remove_subscriptions')`` - """ sub = entities.HostSubscription(self.cfg, host=gen_integer(1, 100)) for which in ('add_subscriptions', 'remove_subscriptions'): @@ -852,7 +843,7 @@ def setUpClass(cls): ) def test_auth_source_ldap_v1(self): - """Test ``AuthSourceLDAP(onthefly_register=False).create_missing()``""" + """Test ``AuthSourceLDAP(onthefly_register=False).create_missing()``.""" entity = entities.AuthSourceLDAP(self.cfg, onthefly_register=False) with mock.patch.object(EntityCreateMixin, 'create_missing'): entity.create_missing() @@ -866,7 +857,7 @@ def test_auth_source_ldap_v2(self): self.assertTrue(set(self.AS_LDAP_FIELDS).issubset(entity.get_values())) def test_auth_source_ldap_v3(self): - """Does ``AuthSourceLDAP.create_missing`` overwrite fields?""" + """Check if ``AuthSourceLDAP.create_missing`` overwrite fields.""" attrs = {field: i for i, field in enumerate(self.AS_LDAP_FIELDS)} attrs.update({'onthefly_register': True}) entity = entities.AuthSourceLDAP(self.cfg, **attrs) @@ -970,7 +961,7 @@ def test_domain_v2(self): self.assertTrue(entity.name.islower()) def test_external_usergroup(self): - """Test ``ExternalUserGroup()``""" + """Test ``ExternalUserGroup()``.""" entity = entities.ExternalUserGroup(self.cfg, usergroup=1) with mock.patch.object(EntityCreateMixin, 'create_missing'): entity.create_missing() @@ -1001,7 +992,7 @@ def test_host_v1(self): ) def test_host_v2(self): - """Test ``Host()`` with providing all the optional entities unlinked""" + """Test ``Host()`` with providing all the optional entities unlinked.""" org = entities.Organization(self.cfg, id=1) loc = entities.Location(self.cfg, id=1) domain = entities.Domain( @@ -1062,6 +1053,7 @@ def test_host_v2(self): def test_host_v3(self): """Test ``Host()`` providing optional entities with id only. + Check that additional read was called for that entities. """ optional = { @@ -1109,7 +1101,7 @@ def test_lifecycle_environment_v2(self): self.assertEqual(entity.prior, search.return_value[0]) def test_lifecycle_environment_v3(self): - """What happens when the "Library" lifecycle env cannot be found?""" + """Check happens when the "Library" lifecycle env cannot be found.""" entity = entities.LifecycleEnvironment( self.cfg, name='not Library', @@ -1152,7 +1144,6 @@ def test_entity_arg(self): for the ``entity`` argument. Assert that these entities pass their server configuration objects to the child entities that they create and pass in to the ``entity`` argument. - """ for entity in ( entities.ContentViewFilterRule( @@ -1191,7 +1182,6 @@ def test_attrs_arg_v1(self): This test is only appropriate for entities that override the ``read`` method in order to fiddle with the ``attrs`` argument. - """ for entity in ( # entities.DiscoveryRule, # see test_discovery_rule @@ -1218,7 +1208,6 @@ def test_attrs_arg_v2(self): This test is only appropriate for entities that override the ``read`` method in order to fiddle with the ``attrs`` argument. - """ # test_data is a single-use variable. We use it anyway for formatting # purposes. @@ -1240,7 +1229,6 @@ def test_entity_ids(self): Assert that the returned attributes are renamed to be more regular before calling ``read()``. - """ # test_data is a single-use variable. We use it anyway for formatting # purposes. @@ -1272,7 +1260,6 @@ def test_ignore_arg_v1(self): """Call ``read`` on a variety of entities.``. Assert that the ``ignore`` argument is correctly passed on. - """ for entity, ignored_attrs in ( (entities.AzureRMComputeResource, {'secret_key'}), @@ -1313,7 +1300,6 @@ def test_ignore_arg_v3(self): """Call :meth:`nailgun.entities.AuthSourceLDAP.read`. Assert that the entity ignores the 'account_password' field. - """ with mock.patch.object(EntityUpdateMixin, 'update_json') as u_json: with mock.patch.object(EntityReadMixin, 'read') as read: @@ -1327,7 +1313,6 @@ def test_ignore_arg_v4(self): Assert that entity`s predefined values of ``ignore`` are always correctly passed on. - """ for input_ignore, actual_ignore in ( (None, {'password'}), @@ -1477,7 +1462,6 @@ def test_discovery_rule(self): """Call :meth:`nailgun.entities.DiscoveryRule.read`. Ensure that the ``max_count`` attribute is fetched. - """ with mock.patch.object(EntityUpdateMixin, 'update_json') as u_json: u_json.return_value = {'max_count': 'max_count'} @@ -1490,11 +1474,9 @@ def test_discovery_rule(self): self.assertEqual(u_json.call_args, mock.call([])) def test_product_with_sync_plan(self): - """Call :meth:`nailgun.entities.Product.read` for a product with sync - plan assigned. + """Call :meth:`nailgun.entities.Product.read` for a product with sync plan assigned. Ensure that the sync plan entity was correctly fetched. - """ sync_plan = entities.SyncPlan(self.cfg, id=1, organization=1) product = entities.Product(self.cfg, id=1, organization=1) @@ -1513,7 +1495,6 @@ def test_hostgroup_ignore_root_pass(self): """Call :meth:`nailgun.entities.HostGroup.read`. Assert that the entity ignores the ``root_pass`` field. - """ with mock.patch.object(EntityReadMixin, 'read') as read: with mock.patch.object(EntityReadMixin, 'read_json'): @@ -1523,6 +1504,7 @@ def test_hostgroup_ignore_root_pass(self): def test_http_proxy_ignore_arg(self): """Call :meth:`nailgun.entities.HTTPProxy.read`. + Assert that the entity ignores the ``password, organization and location`` field. """ with mock.patch.object(EntityReadMixin, 'read') as read: @@ -1534,11 +1516,9 @@ def test_http_proxy_ignore_arg(self): self.assertIn('location', read.call_args[0][2]) def test_usergroup_with_external_usergroup(self): - """Call :meth:`nailgun.entities.ExternalUserGroup.read` for a usergroup with external - usergroup assigned. + """Call :meth:`nailgun.entities.ExternalUserGroup.read` with external usergroup assigned. Ensure that the external usergroup entity was correctly fetched. - """ with mock.patch.object(EntityReadMixin, 'read') as read: with mock.patch.object(EntityReadMixin, 'read_json'): @@ -1551,7 +1531,6 @@ def test_subnet(self): """Call :meth:`nailgun.entities.Subnet.read`. Ensure that the ``from_`` attribute is successfully set. - """ with mock.patch.object(EntityReadMixin, 'read_json') as read_json: read_json.return_value = {'from': 'foo'} @@ -1563,9 +1542,7 @@ def test_subnet(self): class SearchTestCase(TestCase): - """Tests for - :meth:`nailgun.entity_mixins.EntitySearchMixin.search`. - """ + """Tests for :meth:`nailgun.entity_mixins.EntitySearchMixin.search`.""" @classmethod def setUpClass(cls): @@ -1573,11 +1550,9 @@ def setUpClass(cls): cls.cfg = config.ServerConfig('http://example.com') def test_product_with_sync_plan(self): - """Call :meth:`nailgun.entities.Product.search` for a product with sync - plan assigned. + """Call :meth:`nailgun.entities.Product.search` for a product with sync plan assigned. Ensure that the sync plan entity was correctly fetched. - """ with mock.patch.object(EntitySearchMixin, 'search_json') as search_json: # Synplan set @@ -1621,11 +1596,9 @@ def test_product_with_sync_plan(self): self.assertIsNone(result[0].sync_plan) def test_host_with_image(self): - """Call :meth:`nailgun.entities.Host.search` for a host with image - assigned. + """Call :meth:`nailgun.entities.Host.search` for a host with image assigned. Ensure that the image entity was correctly fetched. - """ with mock.patch.object(EntitySearchMixin, 'search_json') as search_json: # Image is set @@ -1664,9 +1637,7 @@ def test_host_with_image(self): class SearchNormalizeTestCase(TestCase): - """Tests for - :meth:`nailgun.entity_mixins.EntitySearchMixin.search_normalize`. - """ + """Tests for :meth:`nailgun.entity_mixins.EntitySearchMixin.search_normalize`.""" @classmethod def setUpClass(cls): @@ -1731,8 +1702,7 @@ def test_interface(self): self.assertEqual(args['host_id'], 3) def test_host_with_image(self): - """Call :meth:`nailgun.entities.Host.read` for a host with image - assigned. + """Call :meth:`nailgun.entities.Host.read` for a host with image assigned. Ensure that the image entity was correctly fetched. """ @@ -1839,9 +1809,7 @@ def test_generic(self): self.assertIsInstance(entity(self.cfg, **params).search_payload(), dict) def test_content_view_filter_rule(self): - """errata_id field should be Errata ID when sent to the server, - not DB ID. - """ + """errata_id field should be Errata ID when sent to the server, not DB ID.""" errata_kwargs = { "id": 1, "uuid": "1a321570-cd30-4622-abff-2290b47ef814", @@ -1993,7 +1961,6 @@ def test_discovery_rule_search(self): The field should be renamed from ``search_`` to ``search`` when ``update_payload`` is called. - """ payload = entities.DiscoveryRule( self.cfg, @@ -2007,7 +1974,6 @@ def test_image(self): The field should be renamed from ``path_`` to ``path`` when ``update_payload`` is called. - """ payload = entities.Image( self.cfg, @@ -2020,13 +1986,13 @@ def test_media_path(self): The field should be renamed from ``path_`` to ``path`` when ``update_payload`` is called. - """ payload = entities.Media(self.cfg, path_='foo').update_payload() self.assertNotIn('path_', payload['medium']) self.assertIn('path', payload['medium']) def test_hostcollection_updatable_fields(self): + """Check whether ``HostCollection`` updates its ``updatable_fields`` field.""" org1 = entities.Organization(self.cfg, name='org1') org2 = entities.Organization(self.cfg, name='org2') host_collection = entities.HostCollection(self.cfg, name='oldname', organization=org1) @@ -2063,7 +2029,9 @@ def test_organization_rh_repo_url(self): self.assertIn('redhat_repository_url', payload) def test_os_default_template(self): - """Check, that ``os_default_template`` serves ``template_kind_id`` and + """Test ``update_payload`` for ``OSDefaultTemplate``. + + Check, that ``os_default_template`` serves ``template_kind_id`` and ``provisioning_template_id`` only wrapped in sub dict See: `Redmine #21169`_. @@ -2085,7 +2053,6 @@ def test_subnet_from(self): The field should be renamed from ``from_`` to ``from`` when ``update_payload`` is called. - """ payload = entities.Subnet( self.cfg, @@ -2113,7 +2080,6 @@ def setUpClass(cls): entity_obj3.method1, 'get', entity_obj3.method2, 'put', ) - """ cfg = config.ServerConfig('http://example.com') generic = {'server_config': cfg, 'id': 1} @@ -2233,7 +2199,6 @@ def test_generic(self): * Each method passes the right arguments to `client.*`. * Each method calls `entities._handle_response` once. * The result of `_handle_response(…)` is the return value. - """ for method, request in self.methods_requests: with self.subTest((method, request)): @@ -2257,7 +2222,6 @@ def test_intelligent(self): * Each method passes the right arguments to `client.*`. * Each method calls `entities._handle_response` once. * The result of `_handle_response(…)` is the return value. - """ for method, request, data in self.intelligent_methods_requests: with self.subTest((method, request)): @@ -2296,10 +2260,10 @@ def test_read(self): class FileTestCase(TestCase): - """Class with entity File tests""" + """Class with entity File tests.""" def test_to_json(self): - """Check json serialisation on nested entities""" + """Check json serialisation on nested entities.""" file_kwargs = { 'id': 1, 'name': 'test_file.txt', @@ -2391,7 +2355,6 @@ def test_content_upload_create(self): Make the (mock) server return a "success" status. Make the same assertions as for :meth:`tests.test_entities.GenericTestCase.test_generic`. - """ with mock.patch.object(client, 'post') as post: self.content_upload.create() @@ -2404,7 +2367,6 @@ def test_content_upload_delete(self): Make the (mock) server return a "success" status. Make the same assertions as for :meth:`tests.test_entities.GenericTestCase.test_generic`. - """ with mock.patch.object(client, 'delete') as delete: with mock.patch.object(client, 'post') as post: @@ -2421,7 +2383,6 @@ def test_content_upload_update(self): Make the (mock) server return a "success" status. Make the same assertions as for :meth:`tests.test_entities.GenericTestCase.test_generic`. - """ with mock.patch.object(client, 'post') as post: with mock.patch.object(client, 'put') as put: @@ -2440,7 +2401,6 @@ def test_content_upload_upload(self): Make the (mock) server return a "success" status. Make the same assertions as for :meth:`tests.test_entities.GenericTestCase.test_generic`. - """ filename = gen_string('alpha') filepath = os.path.join(gen_string('alpha'), filename) @@ -2465,7 +2425,6 @@ def test_content_upload_no_filename(self): Make the (mock) server return a "success" status. Make the same assertions as for :meth:`tests.test_entities.GenericTestCase.test_generic`. - """ filename = gen_string('alpha') filepath = os.path.join(gen_string('alpha'), filename) @@ -2489,6 +2448,7 @@ class ContentViewTestCase(TestCase): """Tests for :class:`nailgun.entities.ContentView`.""" def setUp(self): + """Set common attributes for all tests.""" self.server_config = config.ServerConfig('http://example.com') self.cv = entities.ContentView( self.server_config, @@ -2583,7 +2543,6 @@ class ContentViewComponentTestCase(TestCase): def setUp(self): """Set a server configuration at ``self.cfg``.""" - self.server_config = config.ServerConfig('http://example.com') self.ccv = entities.ContentView( self.server_config, @@ -2637,6 +2596,7 @@ def setUp(self): self.read_json_pacther = mock.patch.object(self.cvc, 'read_json') def test_path(self): + """Check that path is correctly constructed.""" for which in ['add', 'remove']: path = self.cvc.path(which=which) self.assertIn( @@ -2653,7 +2613,6 @@ def test_add(self): * Method calls `client.*` once. * Method calls `entities._handle_response` once. - """ self.assertEqual(inspect.getfullargspec(self.cvc.add), EXPECTED_ARGSPEC) return_dict = {'results': [self.common_return_value]} @@ -2673,7 +2632,6 @@ def test_remove(self): * Method calls `client.*` once. * Method calls `entities._handle_response` once. - """ self.assertEqual(inspect.getfullargspec(self.cvc.remove), EXPECTED_ARGSPEC) return_dict = {'results': self.common_return_value} @@ -2689,8 +2647,9 @@ class ActivationKeyTestCase(TestCase): """Tests for :class:`nailgun.entities.ActivationKey`.""" def test_creation_and_update(self): - """Check template combinations as json or entity is set on correct - attribute template_combinations_attributes ( check #333) + """Check template combinations as json or entity is set on correct attribute. + + template_combinations_attributes ( check #333). """ cfg = config.ServerConfig(url='foo') activation_key = entities.ActivationKey(cfg, name='test_ak', organization=42) @@ -2709,8 +2668,9 @@ class ReportTemplateTestCase(TestCase): """Tests for :class:`nailgun.entities.ReportTemplate`.""" def test_creation_and_update(self): - """Check template combinations as json or entity is set on correct - attribute template_combinations_attributes ( check #333) + """Check template combinations as json or entity is set on correct attribute. + + template_combinations_attributes ( check #333). """ cfg = config.ServerConfig(url='foo') report_template = entities.ReportTemplate(cfg, name='cfg', default=False, template='cat') @@ -2728,7 +2688,7 @@ def test_creation_and_update(self): self.assertEqual(expected_dct, report_template.update_payload()) def test_generate(self): - """Generate template""" + """Generate template.""" cfg = config.ServerConfig(url='foo') report_template = entities.ReportTemplate(cfg, id=42) with mock.patch.object(client, 'post') as post: @@ -2741,7 +2701,7 @@ def test_generate(self): self.assertEqual(post.call_args[1], {'data': {'input_values': {'hosts': 'whatever'}}}) def test_schedule(self): - """Schedule template""" + """Schedule template.""" cfg = config.ServerConfig(url='foo') report_template = entities.ReportTemplate(cfg, id=43) with mock.patch.object(client, 'post') as post: @@ -2754,7 +2714,7 @@ def test_schedule(self): self.assertEqual(post.call_args[1], {'data': {'input_values': {'hosts': 'whatever'}}}) def test_report_data(self): - """Schedule template""" + """Schedule template.""" cfg = config.ServerConfig(url='foo') report_template = entities.ReportTemplate(cfg, id=44) with mock.patch.object(client, 'get') as get_response: @@ -2773,8 +2733,9 @@ class ProvisioningTemplateTestCase(TestCase): """Tests for :class:`nailgun.entities.ProvisioningTemplate`.""" def test_creation_and_update(self): - """Check template combinations as json or entity is set on correct - attribute template_combinations_attributes ( check #333) + """Check template combinations as json or entity is set on correct attribute. + + template_combinations_attributes ( check #333). """ cfg = config.ServerConfig(url='foo') env = entities.Environment(cfg, id=2, name='env') @@ -2815,6 +2776,7 @@ class TemplateInputTestCase(TestCase): """Tests for :class:`nailgun.entities.TemplateInput`.""" def setUp(self): + """Set common attributes for all tests.""" self.cfg = config.ServerConfig('some url') self.job_template = entities.JobTemplate(self.cfg, id=2) self.entity = entities.TemplateInput(self.cfg, id=1, template=self.job_template) @@ -2837,9 +2799,11 @@ def setUp(self): del self.data['template_id'] def tearDown(self): + """Stop patching ``self.entity.read_json``.""" self.read_json_patcher.stop() def test_read(self): + """Check that ``read`` is sane.""" entity = self.entity.read() self.read_json.assert_called_once() self.assertEqual(self.data, {key: getattr(entity, key) for key in self.data}) @@ -2851,6 +2815,7 @@ class JobTemplateTestCase(TestCase): """Tests for :class:`nailgun.entities.JobTemplate`.""" def setUp(self): + """Set common attributes for all tests.""" self.cfg = config.ServerConfig('some url') self.entity = entities.JobTemplate(self.cfg, id=1) self.read_json_patcher = mock.patch.object(EntityReadMixin, 'read_json') @@ -2875,9 +2840,11 @@ def setUp(self): del self.data['template_inputs'] def tearDown(self): + """Stop patching ``self.entity.read_json``.""" self.read_json_patcher.stop() def test_read(self): + """Check that ``read`` is sane.""" entity = self.entity.read() self.read_json.assert_called_once() self.assertEqual(self.data, {key: getattr(entity, key) for key in self.data}) @@ -2893,9 +2860,11 @@ class TablePreferencesTestCase(TestCase): """Tests for :class:`nailgun.entities.TablePreferences`.""" def setUp(self): + """Set a common ServerConfig.""" self.sc = config.ServerConfig('some url') def test_read(self): + """Test ``nailgun.entities.TablePreferences.read``.""" user_id = gen_integer(min_value=1) user = entities.User(self.sc, id=user_id) entity = entities.TablePreferences(self.sc, user=user) @@ -2919,6 +2888,7 @@ def test_read(self): self.assertEqual(res.columns, ['testcol']) def test_search(self): + """Test ``nailgun.entities.TablePreferences.search``.""" user_id = gen_integer(min_value=1) user = entities.User(self.sc, id=user_id) ret = { @@ -2939,6 +2909,7 @@ class HostGroupTestCase(TestCase): """Tests for :class:`nailgun.entities.HostGroup`.""" def setUp(self): + """Set common attributes for all tests.""" self.entity = entities.HostGroup(config.ServerConfig('some url')) self.read_json_pacther = mock.patch.object(self.entity, 'read_json') self.read_pacther = mock.patch.object(EntityReadMixin, 'read') @@ -3034,8 +3005,9 @@ def test_delete_func_with_id(self): self.assertEqual(handlr.return_value, response) def test_clone_hostgroup(self): - """Test for :meth:`nailgun.entities.HostGroup.clone` - Assert that the method is called one with correct argumets + """Test for :meth:`nailgun.entities.HostGroup.clone`. + + Assert that the method is called one with correct argumets. """ entity = self.entity entity.id = 1 @@ -3051,8 +3023,9 @@ def test_clone_hostgroup(self): self.assertEqual(handler.return_value, response) def test_rebuild_config(self): - """Test for :meth:`nailgun.entities.HostGroup.rebuild_config` - Assert that the method is called one with correct arguments + """Test for :meth:`nailgun.entities.HostGroup.rebuild_config`. + + Assert that the method is called one with correct arguments. """ entity = self.entity entity.id = 1 @@ -3076,8 +3049,7 @@ def setUp(self): self.cfg = config.ServerConfig('http://example.com') def test_init_with_owner_type(self): - """Assert ``owner`` attribute is an entity of correct type, according - to ``owner_type`` field value""" + """Assert ``owner`` attribute is type correct, according to ``owner_type`` field value.""" for owner_type, entity in (('User', entities.User), ('Usergroup', entities.UserGroup)): host = entities.Host( self.cfg, @@ -3088,9 +3060,7 @@ def test_init_with_owner_type(self): self.assertTrue(isinstance(host.owner, entity)) def test_update_owner_type(self): - """Ensure that in case ``owner_type`` value changes, ``owner`` changes - it's type accordingly. - """ + """Ensure that when ``owner_type`` value changes, ``owner`` correctly changes its type.""" host = entities.Host( self.cfg, id=gen_integer(min_value=1), @@ -3123,9 +3093,7 @@ def test_owner_type_property(self): self.assertFalse('_owner_type' in result) def test_init_with_owner(self): - """Assert that both ``id`` or ``entity`` can be passed as a value for - ``owner`` attribute. - """ + """Assert both ``id`` or ``entity`` can be passed as a value for ``owner`` attribute.""" owner_id = gen_integer(min_value=1) owner_entity = entities.UserGroup( self.cfg, @@ -3142,9 +3110,7 @@ def test_init_with_owner(self): self.assertEqual(owner_id, host.owner.id) def test_no_facet_attributes(self): - """Assert that ``content_facet_attributes`` attribute is ignored when - ``content_facet_attributes`` attribute is not returned for host - """ + """Assert that ``content_facet_attributes`` is ignored when not returned for host.""" with mock.patch.object(EntityReadMixin, 'read') as read: with mock.patch.object(entities, '_feature_list', return_value={'Puppet'}): entities.Host(self.cfg).read( @@ -3215,7 +3181,7 @@ def test_delete_func_with_id(self): self.assertEqual(handlr.return_value, response) def test_disassociate(self): - """Disassociate host""" + """Disassociate host.""" cfg = config.ServerConfig(url='foo') host = entities.Host(cfg, id=42) with mock.patch.object(client, 'put') as put: @@ -3227,7 +3193,7 @@ def test_disassociate(self): self.assertEqual(put.call_args[0][0], 'foo/api/v2/hosts/42/disassociate') def test_play_ansible_roles(self): - """Play Ansible roles""" + """Play Ansible roles.""" cfg = config.ServerConfig(url='foo') host = entities.Host(cfg, id=42) exp_ret = mock.MagicMock() @@ -3255,6 +3221,7 @@ def setUp(self): def test_search_normalize(self): """Call :meth:`nailgun.entities.PuppetClass.search_normalize`. + Assert that returned value is a list and contains all subdictionaries. """ with mock.patch.object(EntitySearchMixin, 'search_normalize') as s_n: @@ -3285,7 +3252,6 @@ def test_upload_content_v1(self): Make the (mock) server return a "success" status. Make the same assertions as for :meth:`tests.test_entities.GenericTestCase.test_generic`. - """ kwargs = {'kwarg': gen_integer()} with mock.patch.object(client, 'post') as post, mock.patch.object( @@ -3305,7 +3271,6 @@ def test_upload_content_v2(self): Assert that :class:`nailgun.entities.APIResponseError` is raised when the (mock) server fails to return a "success" status. - """ kwargs = {'kwarg': gen_integer()} with mock.patch.object(client, 'post') as post, mock.patch.object( @@ -3320,13 +3285,11 @@ def test_upload_content_v2(self): self.assertEqual(handler.call_count, 1) def test_import_uploads_uploads(self): - """Call :meth:`nailgun.entities.Repository.import_uploads` with - the `uploads` parameter. + """Call :meth:`nailgun.entities.Repository.import_uploads` with the `uploads` parameter. Make the (mock) server return a "success" status. Make the same assertions as for :meth:`tests.test_entities.GenericTestCase.test_generic`. - """ kwargs = {'kwarg': gen_integer()} uploads = [ @@ -3350,13 +3313,11 @@ def test_import_uploads_uploads(self): self.assertEqual(handler.return_value, response) def test_import_uploads_upload_ids(self): - """Call :meth:`nailgun.entities.Repository.import_uploads` with - the `upload_ids` parameter. + """Call :meth:`nailgun.entities.Repository.import_uploads` with the `upload_ids` parameter. Make the (mock) server return a "success" status. Make the same assertions as for :meth:`tests.test_entities.GenericTestCase.test_generic`. - """ kwargs = {'kwarg': gen_integer()} upload_ids = [gen_string('numeric')] @@ -3373,8 +3334,9 @@ def test_import_uploads_upload_ids(self): self.assertEqual(handler.return_value, response) def test_files(self): - """Test for :meth:`nailgun.entities.Repository.files` - Assert that the method is called one with correct arguments + """Test for :meth:`nailgun.entities.Repository.files`. + + Assert that the method is called one with correct arguments. """ self.assertEqual(inspect.getfullargspec(self.repo.files), EXPECTED_ARGSPEC) kwargs = {'kwarg': gen_integer(), 'data': {'name': gen_string('utf8', 5)}} @@ -3415,9 +3377,10 @@ def setUp(self): def test_import_puppetclasses(self): """Call :meth:`nailgun.entities.SmartProxy.import_puppetclasses`. + Assert that * ``environment`` parameter is not sent to requests, - * proper path is built + * proper path is built. """ params = [{}, {'environment': 2}, {'environment': self.env}] for param in params: @@ -3466,7 +3429,6 @@ def test_methods(self): It would be ideal if these method could be refactored such that this unit test could be dropped. - """ cfg = config.ServerConfig('http://example.com') generic = {'server_config': cfg, 'id': 1} @@ -3526,7 +3488,7 @@ def test_api_response_error(self): self.assertEqual(search.call_count, 1) def test_to_json(self): - """json serialization""" + """Json serialization.""" kwargs = { 'id': 1, 'description': 'some description', @@ -3539,10 +3501,10 @@ def test_to_json(self): class PackageTestCase(TestCase): - """Class with entity Package tests""" + """Class with entity Package tests.""" def test_to_json(self): - """Check json serialisation on nested entities""" + """Check json serialisation on nested entities.""" package_kwargs = { 'nvrea': 'sclo-git25-1.0-2.el7.x86_64', 'checksum': ('751e639a0b8add0adc0c5cf0bf77693b3197b17533037ce2e7b9daa618898b99'), @@ -3566,10 +3528,10 @@ def test_to_json(self): class SrpmsTestCase(TestCase): - """Class with entity Srpms tests""" + """Class with entity Srpms tests.""" def test_to_json(self): - """Check json serialisation on nested entities""" + """Check json serialisation on nested entities.""" package_kwargs = { "arch": "src", "checksum": "bc69f30e1a33cff127e44c6caeabc7eb9c2f92ea21a2e6590edcf3e0ebfc87e3", @@ -3592,10 +3554,10 @@ def test_to_json(self): class PackageGroupTestCase(TestCase): - """Class with entity Package Group tests""" + """Class with entity Package Group tests.""" def test_to_json(self): - """Check json serialisation on nested entities""" + """Check json serialisation on nested entities.""" pkg_group_kwargs = { 'description': None, 'id': 3, @@ -3609,10 +3571,10 @@ def test_to_json(self): class ModuleStreamTestCase(TestCase): - """Class with entity Module Stream tests""" + """Class with entity Module Stream tests.""" def test_to_json(self): - """Check json serialisation on nested entities""" + """Check json serialisation on nested entities.""" module_stream_kwargs = { "id": 3, "name": "walrus", @@ -3648,7 +3610,7 @@ def test_default(self): ) def test_json_content(self): - """Give the response JSON content type""" + """Give the response JSON content type.""" response = mock.Mock() response.headers = {'content-type': 'application/json; charset=utf-8'} self.assertEqual( @@ -3690,7 +3652,6 @@ def test_accepted_v1(self): * Do not pass the ``synchronous`` argument. * Pass ``synchronous=False``. - """ response = mock.Mock() response.status_code = ACCEPTED @@ -3710,7 +3671,6 @@ def test_accepted_v2(self): """Give the response an HTTP "ACCEPTED" status code. Pass ``synchronous=True`` as an argument. - """ response = mock.Mock() response.status_code = ACCEPTED @@ -3741,7 +3701,6 @@ def test_missing_org_id(self): Assert that ``read_json``, ``_get_org`` and ``read`` are all called once, and that the second is called with the correct arguments. - """ for entity in (entities.ContentView, entities.Product): with self.subTest(entity): @@ -3758,15 +3717,15 @@ def test_missing_org_id(self): class JsonSerializableTestCase(TestCase): - """Test regarding Json serializable on different object""" + """Test regarding Json serializable on different object.""" def test_regular_objects(self): - """Checking regular objects transformation""" + """Checking regular objects transformation.""" lst = [[1, 0.3], {'name': 'foo'}] self.assertEqual(lst, entities.to_json_serializable(lst)) def test_entities(self): - """Testing nested entities serialization""" + """Testing nested entities serialization.""" package_kwargs = { 'nvrea': 'sclo-git25-1.0-2.el7.x86_64', 'checksum': ('751e639a0b8add0adc0c5cf0bf77693b3197b17533037ce2e7b9daa618898b99'), @@ -3801,7 +3760,7 @@ def test_entities(self): self.assertListEqual(expected, entities.to_json_serializable(to_be_transformed)) def test_nested_entities(self): - """Check nested entities serialization""" + """Check nested entities serialization.""" env_kwargs = {'id': 1, 'name': 'env'} env = make_entity(entities.Environment, **env_kwargs) @@ -3832,13 +3791,12 @@ def test_nested_entities(self): self.assertDictEqual(cfg_kwargs, entities.to_json_serializable(cfg_template)) def test_date_field(self): - """Check date field serialization""" - + """Check date field serialization.""" errata = make_entity(entities.Errata, issued=date(2016, 9, 20)) self.assertDictEqual({'issued': '2016-09-20'}, entities.to_json_serializable(errata)) def test_boolean_datetime_float(self): - """Check serialization for boolean, datetime and float fields""" + """Check serialization for boolean, datetime and float fields.""" kwargs = {'pending': True, 'progress': 0.25, 'started_at': datetime(2016, 11, 20, 1, 2, 3)} task = make_entity(entities.ForemanTask, **kwargs) kwargs['started_at'] = '2016-11-20 01:02:03' @@ -3846,16 +3804,16 @@ def test_boolean_datetime_float(self): class VirtWhoConfigTestCase(TestCase): - """ - Tests for :class:`nailgun.entities.VirtWhoConfig` - """ + """Tests for :class:`nailgun.entities.VirtWhoConfig`.""" @classmethod def setUpClass(cls): + """Set ``self.server`` and ``self.cfg``.""" cls.server = 'sat.example.com' cls.cfg = config.ServerConfig(f'http://{cls.server}/') def test_create(self): + """Test create payload.""" org = entities.Organization(self.cfg, name='vhorg', id=2) vh = entities.VirtWhoConfig( server_config=self.cfg, @@ -3892,6 +3850,7 @@ def test_create(self): self.assertDictEqual(expected_dict, vh.create_payload()) def test_update(self): + """Test update payload.""" org = entities.Organization(self.cfg, name='vhorg', id=2) vh = entities.VirtWhoConfig( server_config=self.cfg, @@ -3928,7 +3887,6 @@ def test_methods(self): slightly different set of mocks. Test the following: * :meth:`nailgun.entities.VirtWhoConfig.get_organization_configs` - """ cfg = config.ServerConfig('http://example.com') generic = {'server_config': cfg, 'id': 1} @@ -3952,10 +3910,11 @@ class JobInvocationTestCase(TestCase): @classmethod def setUpClass(cls): + """Set a common ServerConfig.""" cls.cfg = config.ServerConfig('http://example.com') def test_required_param(self): - """Check required parameters""" + """Check required parameters.""" data_list = [ {'inputs': 'ls', 'search_query': 'foo'}, {'feature': 'foo', 'inputs': 'ls'}, @@ -3968,9 +3927,7 @@ def test_required_param(self): entities.JobInvocation(self.cfg).run(data=data) def test_non_sync_run(self): - """Run job asynchronously with valid parameters and check that correct - post request is sent - """ + """Run job asynchronously with valid parameters and check that correct request is sent.""" with mock.patch.object(client, 'post') as post: entities.JobInvocation(self.cfg).run( synchronous=False, @@ -3985,7 +3942,7 @@ def test_non_sync_run(self): self.assertEqual(len(post.call_args[0]), 1) def test_sync_run(self): - """Check that sync run will result in ForemanTask poll""" + """Check that sync run will result in ForemanTask poll.""" with mock.patch.object(entities, '_poll_task') as poll_task: with mock.patch.object(client, 'post'): entities.JobInvocation(self.cfg).run( diff --git a/tests/test_entity_mixins.py b/tests/test_entity_mixins.py index c2538b93..8a0cc020 100644 --- a/tests/test_entity_mixins.py +++ b/tests/test_entity_mixins.py @@ -37,7 +37,7 @@ class SampleEntity(entity_mixins.Entity): - """Sample entity to be used in the tests""" + """Sample entity to be used in the tests.""" def __init__(self, server_config=None, **kwargs): self._fields = { @@ -208,7 +208,7 @@ def setUp(self): self.cfg = config.ServerConfig('bogus url') def test__poll_task_failure(self): - """What happens when a foreman task completes but does not succeed? + """Check what happens when a foreman task completes but does not succeed. Assert that a :class:`nailgun.entity_mixins.TaskFailedError` exception is raised. @@ -222,7 +222,7 @@ def test__poll_task_failure(self): entity_mixins._poll_task(gen_integer(), self.cfg) def test__poll_task_success(self): - """What happens when a foreman task completes and does succeed? + """Check what happens when a foreman task completes and does succeed. Assert that the server's response is returned. @@ -237,9 +237,7 @@ def test__poll_task_success(self): ) def test__poll_task_timeout(self): - """What happens when a foreman task timesout? - Assert that the task is still running. - """ + """Assert that the task is still running after timeout.""" with self.assertRaises(entity_mixins.TaskTimedOutError): with mock.patch.object(client, 'get') as get: get.return_value.json.return_value = {'state': 'running', 'result': 'pending'} @@ -305,8 +303,9 @@ def test_entity_get_values(self): ) def test_entity_get_values_v2(self): - """Test :meth:`nailgun.entity_mixins.Entity.get_values`, ensure - ``_path_fields`` are never returned. + """Test :meth:`nailgun.entity_mixins.Entity.get_values`. + + ensure ``_path_fields`` are never returned. """ for values in ( {}, @@ -357,7 +356,7 @@ def test_bad_value_error(self): SampleEntityTwo(self.cfg, one_to_many=1) def test_eq_none(self): - """Test method ``nailgun.entity_mixins.Entity.__eq__`` against None + """Test method ``nailgun.entity_mixins.Entity.__eq__`` against None. Assert that ``__eq__`` returns False when compared to None. @@ -421,12 +420,12 @@ def test_eq(self): self.assertEqual(mary, mary_clone) def test_compare_to_null(self): - """Assert entity comparison to None""" + """Assert entity comparison to None.""" alice = SampleEntity(self.cfg, id=1, name='Alice', unique='a') self.assertFalse(alice.compare(None)) def test_compare(self): - """Assert compare take only not unique fields into account""" + """Assert compare take only not unique fields into account.""" alice = SampleEntity(self.cfg, id=1, name='Alice', unique='a') alice_2 = SampleEntity(self.cfg, id=2, name='Alice', unique='b') self.assertTrue( @@ -439,12 +438,12 @@ def test_compare(self): ) def test_compare_with_filter(self): - """Assert compare can filter fields based on callable""" + """Assert compare can filter fields based on callable.""" alice = SampleEntity(self.cfg, id=1, name='Alice', unique='a') alice_2 = SampleEntity(self.cfg, id=2, name='Alice', unique='a') def filter_example(fields_name, _): - """Filter function to avoid comparison only on id""" + """Filter function to avoid comparison only on id.""" return fields_name != 'id' self.assertTrue( @@ -575,7 +574,7 @@ def __init__(self, server_config=None, **kwargs): self.assertEqual(entity.int_default, 5) def test_create_raw_v1(self): - """What happens if the ``create_missing`` arg is not specified? + """Check what happens if the ``create_missing`` arg is not specified. :meth:`nailgun.entity_mixins.EntityCreateMixin.create_raw` should default to :data:`nailgun.entity_mixins.CREATE_MISSING`. We do not set @@ -592,7 +591,7 @@ def test_create_raw_v1(self): self.assertEqual(post.call_count, 1) def test_create_raw_v2(self): - """What happens if the ``create_missing`` arg is ``True``?""" + """Check what happens if the ``create_missing`` arg is ``True``.""" with mock.patch.object(self.entity, 'create_missing') as c_missing: with mock.patch.object(self.entity, 'create_payload') as c_payload: with mock.patch.object(client, 'post') as post: @@ -602,7 +601,7 @@ def test_create_raw_v2(self): self.assertEqual(post.call_count, 1) def test_create_raw_v3(self): - """What happens if the ``create_missing`` arg is ``False``?""" + """Check what happens if the ``create_missing`` arg is ``False``.""" with mock.patch.object(self.entity, 'create_missing') as c_missing: with mock.patch.object(self.entity, 'create_payload') as c_payload: with mock.patch.object(client, 'post') as post: @@ -958,7 +957,7 @@ def test_delete_raw(self): ) def test_delete_v1(self): - """What happens if the server returns an error HTTP status code?""" + """Check what happens if the server returns an error HTTP status code.""" response = mock.Mock() response.raise_for_status.side_effect = HTTPError('oh no!') with mock.patch.object( @@ -969,7 +968,7 @@ def test_delete_v1(self): self.entity.delete() def test_delete_v2(self): - """What happens if the server returns an HTTP ACCEPTED status code?""" + """Check what happens if the server returns an HTTP ACCEPTED status code.""" response = mock.Mock() response.status_code = http_client.ACCEPTED response.json.return_value = {'id': gen_integer()} @@ -987,7 +986,7 @@ def test_delete_v2(self): ) def test_delete_v3(self): - """What happens if the server returns an HTTP NO_CONTENT status?""" + """Check what happens if the server returns an HTTP NO_CONTENT status.""" response = mock.Mock() response.status_code = http_client.NO_CONTENT with mock.patch.object( @@ -999,7 +998,7 @@ def test_delete_v3(self): self.assertEqual(poll_task.call_count, 0) def test_delete_v4(self): - """What happens if the server returns some other stuccess status?""" + """Check what happens if the server returns some other stuccess status.""" response = mock.Mock() response.json.return_value = gen_integer() with mock.patch.object( @@ -1010,9 +1009,7 @@ def test_delete_v4(self): self.assertEqual(self.entity.delete(), response.json.return_value) def test_delete_v5(self): - """ - What happens if the server returns an HTTP OK status and empty content? - """ + """Check what happens if the server returns an HTTP OK status and empty content.""" response = mock.Mock() response.status_code = http_client.OK response.content = '' @@ -1025,10 +1022,7 @@ def test_delete_v5(self): self.assertEqual(poll_task.call_count, 0) def test_delete_v6(self): - """ - What happens if the server returns an HTTP OK status and blank only - content? - """ + """Assert delete works when receiving an OK response with no content.""" response = mock.Mock() response.status_code = http_client.OK response.content = ' '