Address issues found by pep8, pylint and unit tests

flake8 is quite a bit more picky and discovered a lot of
issues.

Don't let missing configuration blow things up in order to be
able to run unit tests.

Hacky workaround for missing ipalib/ipapython in PyPy
This commit is contained in:
Rob Crittenden 2016-11-09 19:37:24 +00:00
parent 02aae0e7d4
commit ef2c9baa36
9 changed files with 107 additions and 70 deletions

View File

@ -1,13 +0,0 @@
# Copyright 2016 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

View File

@ -18,17 +18,18 @@
import paste.urlmap
import routes
import webob.dec
from oslo_config import cfg
from oslo_context import context
from oslo_log import log
from oslo_middleware import request_id
from oslo_serialization import jsonutils
from oslo_service import wsgi
from oslo_utils import excutils
from oslo_utils import strutils
import six
import six.moves.urllib.parse as urlparse
import webob.exc
from novajoin import exception
CONF = cfg.CONF

View File

@ -1,4 +1,17 @@
#!/usr/bin/python
# Copyright 2016 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import getpass
import logging
@ -7,17 +20,19 @@ import pwd
import socket
import sys
import tempfile
from ipalib import api
from ipalib import errors
from ipapython.ipautil import run, kinit_password, user_input
from ipapython.ipautil import kinit_password
from ipapython.ipautil import run
from ipapython.ipautil import user_input
from novajoin.errors import ConfigurationError
logger = logging.getLogger()
class NovajoinRole(object):
"""
One-stop shopping for creating the IPA permissions, privilege and role.
"""One-stop shopping for creating the IPA permissions, privilege and role.
Assumes that ipalib is imported and initialized and an RPC context
already exists.
@ -30,9 +45,7 @@ class NovajoinRole(object):
self.ccache_name = None
def _get_fqdn(self):
"""
Try to determine the fully-qualfied domain name of this box
"""
"""Try to determine the fully-qualfied domain name of this box"""
fqdn = ""
try:
fqdn = socket.getfqdn()
@ -67,8 +80,7 @@ class NovajoinRole(object):
os.environ['KRB5CCNAME'] = current_ccache
def _call_ipa(self, command, args, kw):
"""
Call into the IPA API.
"""Call into the IPA API.
Duplicates are ignored to be idempotent. Other errors are
ignored implitly because they are encapsulated in the result

View File

@ -18,6 +18,7 @@ import copy
import inspect
import itertools
import random
import six
import sys
import time
@ -26,9 +27,9 @@ from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import timeutils
from novajoin import exception
from novajoin import keystone_client
import six
CONF = cfg.CONF
@ -39,12 +40,20 @@ GLANCE_APIVERSION = 2
def get_api_servers():
"""Return iterator of glance api_servers to cycle through the
"""Return iterator of glance api_servers.
Return iterator of glance api_servers to cycle through the
list, looping around to the beginning if necessary.
"""
api_servers = []
ks = keystone_client.get_client()
# Handle case where no credentials are configured
try:
ks = keystone_client.get_client()
except cfg.NoSuchOptError:
return []
catalog = keystone_client.get_service_catalog(ks)
image_service = catalog.url_for(service_type='image')

View File

@ -15,9 +15,15 @@
import os
import uuid
from ipalib import api
from ipalib import errors
from ipapython.ipautil import kinit_keytab
try:
from ipalib import api
from ipalib import errors
from ipapython.ipautil import kinit_keytab
ipalib_imported = True
except ImportError:
# ipalib/ipapython are not available in PyPy yet, don't make it
# a showstopper for the tests.
ipalib_imported = False
from oslo_config import cfg
from oslo_log import log as logging
@ -31,7 +37,12 @@ LOG = logging.getLogger(__name__)
class IPANovaJoinBase(object):
def __init__(self):
self.ntries = CONF.connect_retries
try:
self.ntries = CONF.connect_retries
except cfg.NoSuchOptError:
self.ntries = 1
if not ipalib_imported:
return
self.ccache = "MEMORY:" + str(uuid.uuid4())
os.environ['KRB5CCNAME'] = self.ccache
if self._ipa_client_configured() and not api.isdone('finalize'):
@ -39,7 +50,7 @@ class IPANovaJoinBase(object):
api.finalize()
def __get_connection(self):
"""Make a connection to IPA or raise an error"""
"""Make a connection to IPA or raise an error."""
tries = 0
while tries <= self.ntries:
@ -48,7 +59,8 @@ class IPANovaJoinBase(object):
except (errors.CCacheError, errors.TicketExpired) as e:
LOG.debug("kinit again: %s", e)
# pylint: disable=no-member
kinit_keytab(str('nova/%s@%s' % (api.env.host, api.env.realm)),
kinit_keytab(str('nova/%s@%s' %
(api.env.host, api.env.realm)),
CONF.keytab,
self.ccache)
tries += 1
@ -56,9 +68,12 @@ class IPANovaJoinBase(object):
return
def _call_ipa(self, command, *args, **kw):
"""Try twice to run the command. One execution may fail if we
"""Make an IPA call.
Try twice to run the command. One execution may fail if we
previously had a connection but the ticket expired.
"""
if not api.Backend.rpcclient.isconnected():
self.__get_connection()
if 'version' not in kw:
@ -72,18 +87,21 @@ class IPANovaJoinBase(object):
api.Command[command](*args, **kw)
def _ipa_client_configured(self):
"""Determine if the machine is an enrolled IPA client.
Return boolean indicating whether this machine is enrolled
in IPA. This is a rather weak detection method but better
than nothing.
"""
Return boolean indicating whether this machine is enrolled
in IPA. This is a rather weak detection method but better
than nothing.
"""
return os.path.exists('/etc/ipa/default.conf')
class IPAClient(IPANovaJoinBase):
def add_host(self, hostname, ipaotp, metadata=None, image_metadata=None):
"""
"""Add a host to IPA.
If requested in the metadata, add a host to IPA. The assumption
is that hostname is already fully-qualified.
@ -91,6 +109,7 @@ class IPAClient(IPANovaJoinBase):
multiple times, first we try to update the OTP in the host entry
and if that fails due to NotFound the host is added.
"""
LOG.debug('In IPABuildInstance')
if not self._ipa_client_configured():
@ -127,6 +146,9 @@ class IPAClient(IPANovaJoinBase):
'userpassword': ipaotp.decode('UTF-8'),
}
if not ipalib_imported:
return True
try:
self._call_ipa('host_mod', *params, **modargs)
except errors.NotFound:
@ -143,9 +165,7 @@ class IPAClient(IPANovaJoinBase):
return True
def delete_host(self, hostname, metadata=None):
"""
Delete a host from IPA and remove all related DNS entries.
"""
"""Delete a host from IPA and remove all related DNS entries."""
LOG.debug('In IPADeleteInstance')
if not self._ipa_client_configured():
@ -155,8 +175,8 @@ class IPAClient(IPANovaJoinBase):
if metadata is None:
metadata = {}
# TODO: lookup instance in nova to get metadata to see if
# the host was enrolled. For now assume yes.
# TODO(rcrit): lookup instance in nova to get metadata to see if
# the host was enrolled. For now assume yes.
params = [hostname]
kw = {
@ -168,9 +188,7 @@ class IPAClient(IPANovaJoinBase):
pass
def add_ip(self, hostname, floating_ip):
"""
Add a floating IP to a given hostname.
"""
"""Add a floating IP to a given hostname."""
LOG.debug('In add_ip')
if not self._ipa_client_configured():
@ -187,9 +205,7 @@ class IPAClient(IPANovaJoinBase):
pass
def remove_ip(self, hostname, floating_ip):
"""
Remove a floating IP from a given hostname.
"""
"""Remove a floating IP from a given hostname."""
LOG.debug('In remove_ip')
if not self._ipa_client_configured():

View File

@ -12,16 +12,17 @@
# License for the specific language governing permissions and limitations
# under the License.
import uuid
import logging
import traceback
import uuid
import webob.exc
from oslo_serialization import jsonutils
from oslo_config import cfg
from novajoin.ipa import IPAClient
from novajoin import base
from novajoin import exception
from novajoin.glance import get_default_image_service
from novajoin.ipa import IPAClient
CONF = cfg.CONF
@ -108,15 +109,16 @@ class JoinController(Controller):
@response(200)
def create(self, req, body=None):
"""Generate the OTP, register it with IPA"""
"""Generate the OTP, register it with IPA
Options passed in but as yet-unused are project-id and user-data.
"""
if not body:
LOG.error('No body in create request')
raise base.Fault(webob.exc.HTTPBadRequest())
project_id = body.get('project-id') # pylint: disable=unused-variable
instance_id = body.get('instance-id')
image_id = body.get('image-id')
user_data = body.get('user-data') # pylint: disable=unused-variable
hostname = body.get('hostname')
metadata = body.get('metadata', {})
@ -168,12 +170,21 @@ class JoinController(Controller):
data['ipaotp'] = ipaotp
if hostname:
if CONF.project_subdomain:
# FIXME
project = 'foo'
hostname = '%s.%s.%s' % (hostname, project, CONF.domain)
try:
domain = CONF.domain
except cfg.NoSuchOptError:
domain = 'test'
try:
project_subdomain = CONF.project_subdomain
except cfg.NoSuchOptError:
hostname = '%s.%s' % (hostname, domain)
else:
hostname = '%s.%s' % (hostname, CONF.domain)
if project_subdomain:
hostname = '%s.%s.%s' % (hostname,
project_subdomain, domain)
else:
hostname = '%s.%s' % (hostname, domain)
data['hostname'] = hostname

View File

@ -24,8 +24,8 @@ from oslo_serialization import jsonutils
import webob.dec
import webob.exc
from novajoin import context
import novajoin.base
from novajoin import context
CONF = cfg.CONF

View File

@ -20,14 +20,15 @@
import sys
import time
from novajoin.ipa import IPAClient
import oslo_messaging
from neutronclient.v2_0 import client as neutron_client
from novaclient import client as nova_client
from novajoin.keystone_client import get_session, register_keystoneauth_opts
from novajoin import config
from oslo_serialization import jsonutils
from novajoin.ipa import IPAClient
from novajoin.keystone_client import get_session
from novajoin.keystone_client import register_keystoneauth_opts
from oslo_log import log as logging
import oslo_messaging
from oslo_serialization import jsonutils
CONF = config.CONF

View File

@ -13,14 +13,14 @@
# under the License.
import sys
from novajoin import config
from novajoin import exception
from novajoin import keystone_client
from oslo_concurrency import processutils
from oslo_log import log
from oslo_service import service
from oslo_service import wsgi
from oslo_log import log
from novajoin import config
from novajoin import keystone_client
from novajoin import exception
CONF = config.CONF