diff --git a/marmoset/pxe/client_config.py b/marmoset/pxe/client_config.py index 60d5275..285d425 100644 --- a/marmoset/pxe/client_config.py +++ b/marmoset/pxe/client_config.py @@ -1,4 +1,4 @@ -"""file for dealing with PXE client configs""" +"""file for dealing with PXE client configs.""" import base64 import crypt import os @@ -11,7 +11,7 @@ class ClientConfig: - """Class to handle PXE configs for clients""" + """Class to handle PXE configs for clients.""" CFG_DIR = '/srv/tftp/pxelinux.cfg/' @@ -53,7 +53,7 @@ def __init__(self, ip_address, password=None, script=None, uuid=None, ipv6_address=None, ipv6_gateway=None, ipv6_prefix=None, persistent=False): """ - Initialize a PXE config object with provided data + Initialize a PXE config object with provided data. We do a lot of data validation here. Besides that we do a lot of assumptions her. Example: IPv6 is a all-or-nothing setup. All IPv6 diff --git a/marmoset/pxe/exceptions.py b/marmoset/pxe/exceptions.py index 6536a9d..9f3e5ed 100644 --- a/marmoset/pxe/exceptions.py +++ b/marmoset/pxe/exceptions.py @@ -1,15 +1,15 @@ -"""Module to deal with exceptions in the PXE part""" +"""Module to deal with exceptions in the PXE part.""" class Error(Exception): - """Class to deal with it""" + """Class to deal with it.""" def __init__(self, message): - """Initialize the message attribute""" + """Initialize the message attribute.""" self.message = message class InputError(Error): - """Dummy class""" + """Dummy class.""" pass diff --git a/marmoset/pxe/label.py b/marmoset/pxe/label.py index db61695..3adaccb 100644 --- a/marmoset/pxe/label.py +++ b/marmoset/pxe/label.py @@ -1,10 +1,10 @@ -"""File for dealing with PXE lables""" +"""File for dealing with PXE lables.""" from .client_config import ClientConfig from .exceptions import InputError class Label: - """class to handle PXE lables""" + """class to handle PXE lables.""" instances = [] @@ -23,7 +23,7 @@ def names(cls): def __init__(self, name, callback=None): """ - Initialize attributes with defaults + Initialize attributes with defaults. This also checks if a configured callback method (from our config file) for a PXE label actually exists as a mehod. diff --git a/marmoset/validation.py b/marmoset/validation.py index 7fa5dda..c4b5e11 100644 --- a/marmoset/validation.py +++ b/marmoset/validation.py @@ -1,4 +1,4 @@ -"""helper fill with several validation functions""" +"""helper fill with several validation functions.""" import ipaddress import re from uuid import UUID @@ -7,12 +7,12 @@ def is_mac(mac): - """Returns True if param is a valid MAC""" + """Return True if param is a valid MAC.""" return True if re.match("^%s$" % MAC_REGEX, mac) else False def is_ipv4(ipaddr): - """Returns True if param is a valid IPv4 address""" + """Return True if param is a valid IPv4 address.""" try: ipaddress.IPv4Address(ipaddr) except ipaddress.AddressValueError: @@ -21,7 +21,7 @@ def is_ipv4(ipaddr): def is_ipv6(ipaddr): - """Returns True if param is a valid IPv6 address""" + """Return True if param is a valid IPv6 address.""" try: ipaddress.IPv6Address(ipaddr) except ipaddress.AddressValueError: @@ -30,7 +30,7 @@ def is_ipv6(ipaddr): def is_cidr(cidr): - """Returns True if param is a valid IPv4 CIDR""" + """Return True if param is a valid IPv4 CIDR.""" try: if "/" not in cidr: return False @@ -42,7 +42,7 @@ def is_cidr(cidr): def is_uuid(uuid): - """Returns True if param is a valid UUID""" + """Return True if param is a valid UUID.""" try: UUID(uuid) except Exception: @@ -51,7 +51,7 @@ def is_uuid(uuid): def get_cidr(cidr): - """Returns a hash with parsed CIDR, containing IP, Netmask, Gateway""" + """Return a hash with parsed CIDR, containing IP, Netmask, Gateway.""" interface = ipaddress.IPv4Interface(cidr) gateway = list(interface.network.hosts())[0] return {'ip': str(interface.ip), @@ -60,18 +60,18 @@ def get_cidr(cidr): def get_ip_from_cidr(cidr): - """Returns the IP from a CIDR""" + """Return the IP from a CIDR.""" data = get_cidr(cidr) return data['ip'] def get_nm_from_cidr(cidr): - """Returns the netmask from a CIDR""" + """Return the netmask from a CIDR.""" data = get_cidr(cidr) return data['nm'] def get_gw_from_cidr(cidr): - """Returns the gateway from a CIDR""" + """Return the gateway from a CIDR.""" data = get_cidr(cidr) return data['gw'] diff --git a/marmoset/webserver/__init__.py b/marmoset/webserver/__init__.py index 6df2c1f..4f42530 100644 --- a/marmoset/webserver/__init__.py +++ b/marmoset/webserver/__init__.py @@ -1,4 +1,4 @@ -"""initial file for providing a Flask based API""" +"""initial file for providing a Flask based API.""" from flask import Flask, jsonify # https://flask-restful.readthedocs.io/en/latest/quickstart.html from flask_restful import Api @@ -11,14 +11,14 @@ def jsonify_nl(*args, **kwargs): - """Encode data to json""" + """Encode data to json.""" resp = jsonify(*args, **kwargs) resp.set_data(resp.get_data() + b'\n') return resp def app(config): - """Setup the initial flask app""" + """Setup the initial flask app.""" auth.Username = config['Webserver'].get('Username') auth.Password = config['Webserver'].get('Password') @@ -83,7 +83,7 @@ def app(config): @app.errorhandler(404) def not_found(ex): - """Function to generate 404 handler""" + """Function to generate 404 handler.""" # pylint: disable-msg=unused-argument # pylint: disable-msg=unused-variable resp = jsonify_nl(message="Route not found.", status=404) @@ -92,7 +92,7 @@ def not_found(ex): @app.errorhandler(401) def unauthorized(ex): - """Function to generate 401 handler""" + """Function to generate 401 handler.""" # pylint: disable-msg=unused-argument # pylint: disable-msg=unused-variable resp = jsonify_nl(message="Unauthorized", status=401) @@ -103,7 +103,7 @@ def unauthorized(ex): def run(args): - """Function to run the app""" + """Function to run the app.""" # pylint: disable-msg=unused-argument webserver = app(config) print(webserver.url_map) diff --git a/marmoset/webserver/dhcp.py b/marmoset/webserver/dhcp.py index 871b79c..f02dc2c 100644 --- a/marmoset/webserver/dhcp.py +++ b/marmoset/webserver/dhcp.py @@ -1,4 +1,4 @@ -"""File to handle all web interaction with DHCP records""" +"""File to handle all web interaction with DHCP records.""" from flask import request from flask.ext.restful import Resource from flask.ext.restful import abort @@ -25,14 +25,14 @@ class DhcpCollection(Resource): - """Collection class to dal with all DHCP records""" + """Collection class to dal with all DHCP records.""" def get(self): - """Returns all DHCP records""" + """Return all DHCP records.""" return [vars(c) for c in dhcp.DhcpConfig.all()] def post(self): - """Creates a new PXE record""" + """Create a new PXE record.""" args = parser.parse_args() if ((args.gateway is None and config['DHCPConfig'].getboolean( @@ -78,10 +78,10 @@ def post(self): class DhcpIpv4Object(Resource): - """Class to handle a single DHCP record based on IPv4 address""" + """Class to handle a single DHCP record based on IPv4 address.""" def get(self, ipv4): - """Returns a single DHCP record based on the provided ipv4""" + """Return a single DHCP record based on the provided ipv4.""" if not validation.is_ipv4(ipv4): return {'message': 'please provide a valid ipv4 address'}, 406 @@ -93,7 +93,7 @@ def get(self, ipv4): return vars(dhcp_config) def put(self, ipv4): - """Updates a DHCP recordd""" + """Update a DHCP recordd.""" args = parser.parse_args(request) if not validation.is_ipv4(ipv4): @@ -142,10 +142,10 @@ def delete(self, ipv4): class DhcpMacObject(Resource): - """Class to handle a single DHCP record based on a MAC address""" + """Class to handle a single DHCP record based on a MAC address.""" def get(self, mac): - """Returns a single DHCP record based on the provided MAC""" + """Return a single DHCP record based on the provided MAC.""" if not validation.is_mac(mac): return {'message': 'please provide a valid mac address'}, 406 @@ -157,7 +157,7 @@ def get(self, mac): return vars(dhcp_config) def put(self, mac): - """Updates a DHCP record""" + """Update a DHCP record.""" args = parser.parse_args(request) if not validation.is_mac(mac): @@ -189,7 +189,7 @@ def put(self, mac): return vars(dhcp_config), 201, {'Location': location} def delete(self, mac): - """Deletes a DHCP record""" + """Delete a DHCP record.""" if not validation.is_mac(mac): return {'message': 'please provide a valid mac address'}, 406 diff --git a/marmoset/webserver/flask/__init__.py b/marmoset/webserver/flask/__init__.py index 543884d..df0f3d0 100644 --- a/marmoset/webserver/flask/__init__.py +++ b/marmoset/webserver/flask/__init__.py @@ -1 +1 @@ -"""flask initial file""" +"""flask initial file.""" diff --git a/marmoset/webserver/flask/auth.py b/marmoset/webserver/flask/auth.py index 042126e..a584acd 100644 --- a/marmoset/webserver/flask/auth.py +++ b/marmoset/webserver/flask/auth.py @@ -22,11 +22,12 @@ def for_all_routes(app): return app -# we've to disable pep8 here because it detects uppercase chars in the method name +# we've to disable pep8 here because +# it detects uppercase chars in the method name # pep8 compliance requires lowercase only function names, but thats the case def __check_auth(username, password): # nopep8 """ - Check username/password combination + Check username/password combination. This function is called to check if a username / password combination is valid. @@ -34,10 +35,11 @@ def __check_auth(username, password): # nopep8 return username == Username and password == Password -# we've to disable pep8 here because it detects uppercase chars in the method name +# we've to disable pep8 here because +# it detects uppercase chars in the method name # pep8 compliance requires lowercase only function names, but thats the case def __is_whitelist_endpoint(endpoint): # nopep8 - """Check if a given endpoint is whitelisted in our configuration file""" + """Check if a given endpoint is whitelisted in our configuration file.""" whitelist_conf = current_app.config['AUTH_WHITELIST_ENDPOINT'] if whitelist_conf is not None: whitelist = whitelist_conf.split(',') @@ -46,7 +48,8 @@ def __is_whitelist_endpoint(endpoint): # nopep8 return False -# we've to disable pep8 here because it detects uppercase chars in the method name +# we've to disable pep8 here because +# it detects uppercase chars in the method name # pep8 compliance requires lowercase only function names, but thats the case def __authenticate(): # nopep8 auth = request.authorization diff --git a/marmoset/webserver/flask/json.py b/marmoset/webserver/flask/json.py index 61e1af4..441c142 100644 --- a/marmoset/webserver/flask/json.py +++ b/marmoset/webserver/flask/json.py @@ -1,11 +1,11 @@ -"""Flask extension module which holds a few helper functions""" +"""Flask extension module which holds a few helper functions.""" from flask import Flask, jsonify from werkzeug.exceptions import default_exceptions, HTTPException # pylint: disable-msg=keyword-arg-before-vararg def response(code=200, headers={}, *args, **kwargs): - """Creates a json encoded response""" + """Create a json encoded response.""" # pylint: disable-msg=dangerous-default-value # pylint: disable-msg=redefined-outer-name response = jsonify(*args, **kwargs) @@ -16,7 +16,7 @@ def response(code=200, headers={}, *args, **kwargs): def error(ex=None, code=500, headers={}): - """Creates a proper HTTP error""" + """Create a proper HTTP error.""" # pylint: disable-msg=dangerous-default-value code = ex.code if isinstance(ex, HTTPException) else code return response(code, headers, message=str(ex)) @@ -24,7 +24,7 @@ def error(ex=None, code=500, headers={}): def app(import_name, **kwargs): """ - Creates a JSON-oriented Flask app. + Create a JSON-oriented Flask app. All error responses that you don't specifically manage yourself will have application/json content diff --git a/marmoset/webserver/imagecatalog.py b/marmoset/webserver/imagecatalog.py index 5a6cc4b..5c80578 100644 --- a/marmoset/webserver/imagecatalog.py +++ b/marmoset/webserver/imagecatalog.py @@ -1,19 +1,23 @@ +"""Class for handling image metadata.""" from flask.ext.restful import Resource, abort from ..imagecatalog.catalog import ImageCatalog class ImageMetadataCollection(Resource): + """Collection class to deal with metadata for images.""" def get(self): - """List all images' metadata""" + """List all images' metadata.""" catalog = ImageCatalog() metadata_list = catalog.list_all_metadata() return metadata_list class ImageMetadata(Resource): + """Class to get metadata for a single image.""" + def get(self, image_file): - """Get image's metadata""" + """Get image's metadata.""" catalog = ImageCatalog() image = catalog.get_image(image_file) if image is not None: @@ -22,7 +26,10 @@ def get(self, image_file): class ImageSignature(Resource): + """Class to get signatures for a single image.""" + def get(self, image_file): + """Return the signature as JSON, if available.""" catalog = ImageCatalog() image = catalog.get_image(image_file) if image is not None: diff --git a/marmoset/webserver/installimage.py b/marmoset/webserver/installimage.py index 661375b..497ed9a 100644 --- a/marmoset/webserver/installimage.py +++ b/marmoset/webserver/installimage.py @@ -1,4 +1,4 @@ -"""File to handle all web interaction with installimage configurations""" +"""File to handle all web interaction with installimage configurations.""" from flask import request, make_response from flask.ext.restful import Resource, url_for, abort @@ -9,18 +9,18 @@ class InstallimageCollection(Resource): - """Collection Class to deal with all installimage configurations""" + """Collection Class to deal with all installimage configurations.""" def get(self): - """Returns all current configurations""" + """Return all current configurations.""" return [vars(c) for c in InstallimageConfig.all()] class InstallimageObject(Resource): - """Class to handle a single installimage configuration""" + """Class to handle a single installimage configuration.""" def get(self, mac): - """Returns a specific config based on the provided MAC""" + """Return a specific config based on the provided MAC.""" installimage_config = InstallimageConfig(mac) if installimage_config.exists(): @@ -28,7 +28,7 @@ def get(self, mac): abort(404) def post(self, mac): - """Creates or updates a config based on the provided MAC""" + """Create or updates a config based on the provided MAC.""" args = parser.parse_args(request) installimage_config = InstallimageConfig(mac) @@ -47,7 +47,7 @@ def post(self, mac): return vars(installimage_config), 201, {'Location': location} def delete(self, mac): - """Deletes a specific config based on the provided MAC""" + """Delete a specific config based on the provided MAC.""" installimage_config = InstallimageConfig(mac) if installimage_config.exists(): @@ -57,10 +57,10 @@ def delete(self, mac): class InstallimageConfigCommand(Resource): - """Class to do something?""" + """Class for handling installimage configs""" def get(self, mac): - """Returns the configuration in a format suitable for the installimage""" + """Return the configuration as installimage format.""" installimage_config = InstallimageConfig(mac) response = make_response(installimage_config.get_content()) diff --git a/marmoset/webserver/installstatus.py b/marmoset/webserver/installstatus.py index 55480da..72129d3 100644 --- a/marmoset/webserver/installstatus.py +++ b/marmoset/webserver/installstatus.py @@ -1,4 +1,4 @@ -"""File to handle all web interaction with status updates from our installimage""" +"""handle all web interaction with status updates from our installimage.""" from flask.ext.restful import reqparse, Resource, abort from flask import request from marmoset.installstatus import InstallStatus @@ -6,10 +6,10 @@ class InstallStatusLatest(Resource): - """latest status update for uuid""" + """latest status update for uuid.""" def get(self, uuid): - """Returns the latest status based on provided UUID""" + """Return the latest status based on provided UUID.""" install_status = InstallStatus(uuid) latest_status = install_status.get_latest_status() if latest_status is None: @@ -18,10 +18,10 @@ def get(self, uuid): class InstallStatusHistory(Resource): - """status update history for uuid""" + """status update history for uuid.""" def get(self, uuid): - """Returns the history for a provided UUID""" + """Return the history for a provided UUID.""" install_status = InstallStatus(uuid) history = install_status.get_history() if not history: @@ -30,10 +30,10 @@ def get(self, uuid): class InstallStatusReport(Resource): - """post new status update for uuid""" + """post new status update for uuid.""" def post(self, uuid): - """Creates a new statusupdate for a UUID""" + """Create a new statusupdate for a UUID.""" if not validation.is_uuid(uuid): return abort(404) @@ -51,10 +51,10 @@ def post(self, uuid): class InstallStatusStats(Resource): - """stats related to the installimage job""" + """stats related to the installimage job.""" def get(self, uuid): - """Return statistics for the performend installation based on provided UUID""" + """Return statistics for the performend installation based on provided UUID.""" install_status = InstallStatus(uuid) stats = install_status.get_stats() if stats['start_date'] is None: diff --git a/marmoset/webserver/pxe.py b/marmoset/webserver/pxe.py index 783156c..3c13b2f 100644 --- a/marmoset/webserver/pxe.py +++ b/marmoset/webserver/pxe.py @@ -1,4 +1,4 @@ -"""File to handle all web interaction with PXE records""" +"""File to handle all web interaction with PXE records.""" from flask.ext.restful import reqparse, Resource, url_for, abort from .. import pxe @@ -30,7 +30,7 @@ class PXECollection(Resource): - """Collection class to deal with PXE records""" + """Collection class to deal with PXE records.""" def get(self): """List all PXE entries.""" @@ -38,7 +38,7 @@ def get(self): def post(self): """ - Accepts a new PXE entry + Accept a new PXE entry. Add a PXE entry for the given ip_address. Password, uuid, script and IPv6 parameteres are optional parameters. The IPv6 parameters are used @@ -74,7 +74,7 @@ def post(self): class PXEObject(Resource): - """Class to handle a single PXE record""" + """Class to handle a single PXE record.""" def get(self, ip_address): """Lookup a PXE entry for the given ip_address.""" diff --git a/marmoset/webserver/vm.py b/marmoset/webserver/vm.py index f17a0be..1d29676 100644 --- a/marmoset/webserver/vm.py +++ b/marmoset/webserver/vm.py @@ -1,11 +1,11 @@ -"""File to handle all web interaction with virtual machines""" +"""File to handle all web interaction with virtual machines.""" from flask.ext.restful import reqparse, Resource, abort from .. import virt def find_domain(uuid): - """Searches for a given domain based on the provided UUID""" + """Search for a given domain based on the provided UUID.""" domain = virt.Domain.find_by('uuid', uuid) if domain is None: abort(404) @@ -14,15 +14,15 @@ def find_domain(uuid): class VMCollection(Resource): - """Collection class to deal with all virtual machines""" + """Collection class to deal with all virtual machines.""" def get(self): - """Returns all domains""" + """Return all domains.""" domains = virt.Domain.all() return [d.attributes() for d in domains] def post(self): - """Creates a new virtual machine""" + """Create a new virtual machine.""" parser = reqparse.RequestParser() parser.add_argument('user', type=str, required=True) parser.add_argument('name', type=str, required=True) @@ -40,15 +40,15 @@ def post(self): class VMObject(Resource): - """Class to handle a single virtual machine""" + """Class to handle a single virtual machine.""" def get(self, uuid): - """Returns a single domain based on the UUID""" + """Return a single domain based on the UUID.""" domain = find_domain(uuid) return domain.attributes() def put(self, uuid): - """Updates a domain based on the provided UUID""" + """Update a domain based on the provided UUID.""" domain = find_domain(uuid) parser = reqparse.RequestParser() parser.add_argument('memory', type=str, store_missing=False) @@ -62,7 +62,7 @@ def put(self, uuid): abort(422, message=str(exception)) def delete(self, uuid): - """Deletes a domain based on the provided UUID""" + """Delete a domain based on the provided UUID.""" try: virt.remove(dict(uuid=uuid)) return '', 204 @@ -71,10 +71,10 @@ def delete(self, uuid): class VMCommand(Resource): - """Class to send libvirt commands to a domain""" + """Class to send libvirt commands to a domain.""" def put(self, uuid): - """Sends the provided command to a given UUID""" + """Send the provided command to a given UUID.""" parser = reqparse.RequestParser() parser.add_argument('command', type=str, required=True, choices=['start', 'stop', 'shutdown', 'reset']) diff --git a/setup.py b/setup.py index 99844dc..2b37d7e 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Basic setup.py that describes the project""" +"""Basic setup.py that describes the project.""" import os try: @@ -9,7 +9,7 @@ def read(fname): - """Read a file with absolute path, based on provided filename""" + """Read a file with absolute path, based on provided filename.""" return open(os.path.join(os.path.dirname(__file__), fname)).read()