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:
parent
02aae0e7d4
commit
ef2c9baa36
@ -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.
|
|
@ -18,17 +18,18 @@
|
|||||||
import paste.urlmap
|
import paste.urlmap
|
||||||
import routes
|
import routes
|
||||||
import webob.dec
|
import webob.dec
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_context import context
|
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
from oslo_middleware import request_id
|
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
from oslo_service import wsgi
|
from oslo_service import wsgi
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
from oslo_utils import strutils
|
from oslo_utils import strutils
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import six.moves.urllib.parse as urlparse
|
import six.moves.urllib.parse as urlparse
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
from novajoin import exception
|
from novajoin import exception
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
@ -1,4 +1,17 @@
|
|||||||
#!/usr/bin/python
|
#!/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 getpass
|
||||||
import logging
|
import logging
|
||||||
@ -7,17 +20,19 @@ import pwd
|
|||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
from ipalib import errors
|
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
|
from novajoin.errors import ConfigurationError
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
class NovajoinRole(object):
|
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
|
Assumes that ipalib is imported and initialized and an RPC context
|
||||||
already exists.
|
already exists.
|
||||||
@ -30,9 +45,7 @@ class NovajoinRole(object):
|
|||||||
self.ccache_name = None
|
self.ccache_name = None
|
||||||
|
|
||||||
def _get_fqdn(self):
|
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 = ""
|
fqdn = ""
|
||||||
try:
|
try:
|
||||||
fqdn = socket.getfqdn()
|
fqdn = socket.getfqdn()
|
||||||
@ -67,8 +80,7 @@ class NovajoinRole(object):
|
|||||||
os.environ['KRB5CCNAME'] = current_ccache
|
os.environ['KRB5CCNAME'] = current_ccache
|
||||||
|
|
||||||
def _call_ipa(self, command, args, kw):
|
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
|
Duplicates are ignored to be idempotent. Other errors are
|
||||||
ignored implitly because they are encapsulated in the result
|
ignored implitly because they are encapsulated in the result
|
||||||
|
@ -18,6 +18,7 @@ import copy
|
|||||||
import inspect
|
import inspect
|
||||||
import itertools
|
import itertools
|
||||||
import random
|
import random
|
||||||
|
import six
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@ -26,9 +27,9 @@ from oslo_config import cfg
|
|||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
|
|
||||||
from novajoin import exception
|
from novajoin import exception
|
||||||
from novajoin import keystone_client
|
from novajoin import keystone_client
|
||||||
import six
|
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@ -39,12 +40,20 @@ GLANCE_APIVERSION = 2
|
|||||||
|
|
||||||
|
|
||||||
def get_api_servers():
|
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.
|
list, looping around to the beginning if necessary.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
api_servers = []
|
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)
|
catalog = keystone_client.get_service_catalog(ks)
|
||||||
|
|
||||||
image_service = catalog.url_for(service_type='image')
|
image_service = catalog.url_for(service_type='image')
|
||||||
|
@ -15,9 +15,15 @@
|
|||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from ipalib import api
|
try:
|
||||||
from ipalib import errors
|
from ipalib import api
|
||||||
from ipapython.ipautil import kinit_keytab
|
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_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
@ -31,7 +37,12 @@ LOG = logging.getLogger(__name__)
|
|||||||
class IPANovaJoinBase(object):
|
class IPANovaJoinBase(object):
|
||||||
|
|
||||||
def __init__(self):
|
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())
|
self.ccache = "MEMORY:" + str(uuid.uuid4())
|
||||||
os.environ['KRB5CCNAME'] = self.ccache
|
os.environ['KRB5CCNAME'] = self.ccache
|
||||||
if self._ipa_client_configured() and not api.isdone('finalize'):
|
if self._ipa_client_configured() and not api.isdone('finalize'):
|
||||||
@ -39,7 +50,7 @@ class IPANovaJoinBase(object):
|
|||||||
api.finalize()
|
api.finalize()
|
||||||
|
|
||||||
def __get_connection(self):
|
def __get_connection(self):
|
||||||
"""Make a connection to IPA or raise an error"""
|
"""Make a connection to IPA or raise an error."""
|
||||||
tries = 0
|
tries = 0
|
||||||
|
|
||||||
while tries <= self.ntries:
|
while tries <= self.ntries:
|
||||||
@ -48,7 +59,8 @@ class IPANovaJoinBase(object):
|
|||||||
except (errors.CCacheError, errors.TicketExpired) as e:
|
except (errors.CCacheError, errors.TicketExpired) as e:
|
||||||
LOG.debug("kinit again: %s", e)
|
LOG.debug("kinit again: %s", e)
|
||||||
# pylint: disable=no-member
|
# 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,
|
CONF.keytab,
|
||||||
self.ccache)
|
self.ccache)
|
||||||
tries += 1
|
tries += 1
|
||||||
@ -56,9 +68,12 @@ class IPANovaJoinBase(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def _call_ipa(self, command, *args, **kw):
|
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.
|
previously had a connection but the ticket expired.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not api.Backend.rpcclient.isconnected():
|
if not api.Backend.rpcclient.isconnected():
|
||||||
self.__get_connection()
|
self.__get_connection()
|
||||||
if 'version' not in kw:
|
if 'version' not in kw:
|
||||||
@ -72,18 +87,21 @@ class IPANovaJoinBase(object):
|
|||||||
api.Command[command](*args, **kw)
|
api.Command[command](*args, **kw)
|
||||||
|
|
||||||
def _ipa_client_configured(self):
|
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')
|
return os.path.exists('/etc/ipa/default.conf')
|
||||||
|
|
||||||
|
|
||||||
class IPAClient(IPANovaJoinBase):
|
class IPAClient(IPANovaJoinBase):
|
||||||
|
|
||||||
def add_host(self, hostname, ipaotp, metadata=None, image_metadata=None):
|
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
|
If requested in the metadata, add a host to IPA. The assumption
|
||||||
is that hostname is already fully-qualified.
|
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
|
multiple times, first we try to update the OTP in the host entry
|
||||||
and if that fails due to NotFound the host is added.
|
and if that fails due to NotFound the host is added.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
LOG.debug('In IPABuildInstance')
|
LOG.debug('In IPABuildInstance')
|
||||||
|
|
||||||
if not self._ipa_client_configured():
|
if not self._ipa_client_configured():
|
||||||
@ -127,6 +146,9 @@ class IPAClient(IPANovaJoinBase):
|
|||||||
'userpassword': ipaotp.decode('UTF-8'),
|
'userpassword': ipaotp.decode('UTF-8'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if not ipalib_imported:
|
||||||
|
return True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._call_ipa('host_mod', *params, **modargs)
|
self._call_ipa('host_mod', *params, **modargs)
|
||||||
except errors.NotFound:
|
except errors.NotFound:
|
||||||
@ -143,9 +165,7 @@ class IPAClient(IPANovaJoinBase):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def delete_host(self, hostname, metadata=None):
|
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')
|
LOG.debug('In IPADeleteInstance')
|
||||||
|
|
||||||
if not self._ipa_client_configured():
|
if not self._ipa_client_configured():
|
||||||
@ -155,8 +175,8 @@ class IPAClient(IPANovaJoinBase):
|
|||||||
if metadata is None:
|
if metadata is None:
|
||||||
metadata = {}
|
metadata = {}
|
||||||
|
|
||||||
# TODO: lookup instance in nova to get metadata to see if
|
# TODO(rcrit): lookup instance in nova to get metadata to see if
|
||||||
# the host was enrolled. For now assume yes.
|
# the host was enrolled. For now assume yes.
|
||||||
|
|
||||||
params = [hostname]
|
params = [hostname]
|
||||||
kw = {
|
kw = {
|
||||||
@ -168,9 +188,7 @@ class IPAClient(IPANovaJoinBase):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def add_ip(self, hostname, floating_ip):
|
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')
|
LOG.debug('In add_ip')
|
||||||
|
|
||||||
if not self._ipa_client_configured():
|
if not self._ipa_client_configured():
|
||||||
@ -187,9 +205,7 @@ class IPAClient(IPANovaJoinBase):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def remove_ip(self, hostname, floating_ip):
|
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')
|
LOG.debug('In remove_ip')
|
||||||
|
|
||||||
if not self._ipa_client_configured():
|
if not self._ipa_client_configured():
|
||||||
|
@ -12,16 +12,17 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import uuid
|
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
|
import uuid
|
||||||
import webob.exc
|
import webob.exc
|
||||||
from oslo_serialization import jsonutils
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from novajoin.ipa import IPAClient
|
|
||||||
from novajoin import base
|
from novajoin import base
|
||||||
from novajoin import exception
|
from novajoin import exception
|
||||||
from novajoin.glance import get_default_image_service
|
from novajoin.glance import get_default_image_service
|
||||||
|
from novajoin.ipa import IPAClient
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@ -108,15 +109,16 @@ class JoinController(Controller):
|
|||||||
|
|
||||||
@response(200)
|
@response(200)
|
||||||
def create(self, req, body=None):
|
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:
|
if not body:
|
||||||
LOG.error('No body in create request')
|
LOG.error('No body in create request')
|
||||||
raise base.Fault(webob.exc.HTTPBadRequest())
|
raise base.Fault(webob.exc.HTTPBadRequest())
|
||||||
|
|
||||||
project_id = body.get('project-id') # pylint: disable=unused-variable
|
|
||||||
instance_id = body.get('instance-id')
|
instance_id = body.get('instance-id')
|
||||||
image_id = body.get('image-id')
|
image_id = body.get('image-id')
|
||||||
user_data = body.get('user-data') # pylint: disable=unused-variable
|
|
||||||
hostname = body.get('hostname')
|
hostname = body.get('hostname')
|
||||||
metadata = body.get('metadata', {})
|
metadata = body.get('metadata', {})
|
||||||
|
|
||||||
@ -168,12 +170,21 @@ class JoinController(Controller):
|
|||||||
|
|
||||||
data['ipaotp'] = ipaotp
|
data['ipaotp'] = ipaotp
|
||||||
if hostname:
|
if hostname:
|
||||||
if CONF.project_subdomain:
|
try:
|
||||||
# FIXME
|
domain = CONF.domain
|
||||||
project = 'foo'
|
except cfg.NoSuchOptError:
|
||||||
hostname = '%s.%s.%s' % (hostname, project, CONF.domain)
|
domain = 'test'
|
||||||
|
|
||||||
|
try:
|
||||||
|
project_subdomain = CONF.project_subdomain
|
||||||
|
except cfg.NoSuchOptError:
|
||||||
|
hostname = '%s.%s' % (hostname, domain)
|
||||||
else:
|
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
|
data['hostname'] = hostname
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ from oslo_serialization import jsonutils
|
|||||||
import webob.dec
|
import webob.dec
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
from novajoin import context
|
|
||||||
import novajoin.base
|
import novajoin.base
|
||||||
|
from novajoin import context
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
@ -20,14 +20,15 @@
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from novajoin.ipa import IPAClient
|
|
||||||
import oslo_messaging
|
|
||||||
from neutronclient.v2_0 import client as neutron_client
|
from neutronclient.v2_0 import client as neutron_client
|
||||||
from novaclient import client as nova_client
|
from novaclient import client as nova_client
|
||||||
from novajoin.keystone_client import get_session, register_keystoneauth_opts
|
|
||||||
from novajoin import config
|
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
|
from oslo_log import log as logging
|
||||||
|
import oslo_messaging
|
||||||
|
from oslo_serialization import jsonutils
|
||||||
|
|
||||||
|
|
||||||
CONF = config.CONF
|
CONF = config.CONF
|
||||||
|
@ -13,14 +13,14 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from novajoin import config
|
||||||
|
from novajoin import exception
|
||||||
|
from novajoin import keystone_client
|
||||||
from oslo_concurrency import processutils
|
from oslo_concurrency import processutils
|
||||||
|
from oslo_log import log
|
||||||
from oslo_service import service
|
from oslo_service import service
|
||||||
from oslo_service import wsgi
|
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
|
CONF = config.CONF
|
||||||
|
Loading…
Reference in New Issue
Block a user