Add compute discovery

* Also add a shell CLI for interactive sessions
* Add separate admin auth cred support
This commit is contained in:
Brian Elliott
2014-06-06 13:01:48 -05:00
parent e78a4864f8
commit ce48babb70
5 changed files with 154 additions and 13 deletions

View File

@@ -26,19 +26,32 @@ opts = [
cfg.StrOpt('url', help='Auth system endpoint URL'),
cfg.StrOpt('username', help='Username for auth'),
cfg.StrOpt('password', help='Password for auth'),
cfg.StrOpt('tenant', help='Tenant name'),
cfg.StrOpt('region', help='Region'),
cfg.BoolOpt('insecure', default=False,
help='Skip SSL certification validation')
]
# register 2 groups: one for a non-priviledged user, and one for an admin user
CONF.register_opts(opts, group='auth')
CONF.register_opts(opts, group='admin_auth')
class Client(object):
def __init__(self):
url, username, password, region = self._config()
self.keystoneclient = client.Client(auth_url=url, username=username,
password=password,
region_name=region)
def __init__(self, group='auth'):
self.group = group
cfg_group = getattr(CONF, group)
kwargs = self._config(cfg_group)
if cfg_group.tenant:
kwargs['tenant_id'] = cfg_group.tenant
LOG.warn(kwargs)
self.keystoneclient = client.Client(insecure=cfg_group.insecure,
debug=True,
**kwargs)
def auth(self):
if not self.keystoneclient.authenticate():
@@ -48,28 +61,39 @@ class Client(object):
def catalog(self):
return self.keystoneclient.service_catalog
@property
def tenant(self):
cfg_group = getattr(CONF, self.group)
return cfg_group.tenant
@property
def token(self):
return self.keystoneclient.auth_token
def _config(self):
def _config(self, group='auth'):
# check for presence of required config options
url = CONF.auth.url
kwargs = {}
url = group.url
if not url:
raise ValueError('Missing required url for auth')
kwargs['auth_url'] = url
username = CONF.auth.username
username = group.username
if not username:
raise ValueError('Missing required username for auth')
kwargs['username'] = username
password = CONF.auth.password
password = group.password
if not password:
raise ValueError('Missing required password for auth')
kwargs['password'] = password
# the region scopes the catalog object for easier endpoint
# identification
region = CONF.auth.region
region = group.region
if not region:
raise ValueError('Missing required region for auth')
kwargs['region_name'] = region
return url, username, password, region
return kwargs

View File

@@ -17,6 +17,7 @@ import os
from oslo.config import cfg
from cachemonkey import discover
from cachemonkey.openstack.common import importutils
from cachemonkey.openstack.common import log as logging
@@ -30,6 +31,9 @@ opts = [
cfg.StrOpt('fetcher_class',
default='cachemonkey.fetcher.glance.GlanceFetcher',
help='Class to determine how to fetch images.'),
cfg.StrOpt('distributor_class',
default='cachemonkey.distributor.glance.GlanceFetcher',
help='Class to determine how to fetch images.'),
cfg.StrOpt('data_dir', default='/var/lib/cachemonkey',
help='Directory containing image data'),
@@ -45,11 +49,26 @@ class Cacher(object):
self.fetcher = importutils.import_object(
CONF.cachemonkey.fetcher_class)
self.discoverer = discover.ComputeDiscoverer()
self.images = []
def cache(self):
self.images = []
images = self.lister.images()
for image in images:
self._get(image)
# TODO(belliott) distribute to hosts
filename = self._get(image)
image = {'meta': image, 'filename': filename}
self.images.append(image)
# HACK(belliott) - just process first image for testing
break
# update set of known computes
self.discoverer.discover()
# TODO(belliott) prep for distribution and distribute
#self.distributor.distribute(image, filename)
def _get(self, image):
# first see if the image was previously downloaded

37
cachemonkey/cmd/shell.py Normal file
View File

@@ -0,0 +1,37 @@
# Copyright 2014 Rackspace Hosting
# All Rights Reserved.
#
# 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 sys
from oslo.config import cfg
import pbr.version
from cachemonkey.openstack.common import log as logging
project = 'cachemonkey'
def _version():
vinfo = pbr.version.VersionInfo(project)
return vinfo.version_string()
def main():
version = _version()
cfg.CONF(sys.argv[1:], project=project, version=version)
logging.setup(project, version=version)
from IPython import embed
embed()

60
cachemonkey/discover.py Normal file
View File

@@ -0,0 +1,60 @@
# Copyright 2014 Rackspace Hosting
# All Rights Reserved.
#
# 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.
from oslo.config import cfg
import requests
from cachemonkey import auth
from cachemonkey.openstack.common import log as logging
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
opts = [
cfg.StrOpt('admin_auth_group',
default='admin_auth',
help='Config group to obtain compute admin credentials from'),
]
CONF.register_opts(opts, group='cachemonkey')
class ComputeDiscoverer(object):
def __init__(self):
self.authclient = auth.Client(CONF.cachemonkey.admin_auth_group)
#self.authclient.auth()
def discover(self):
# do a nova service-list
endpoints = self.authclient.catalog.get_endpoints()
endpoints = endpoints['compute']
if len(endpoints) > 1:
raise ValueError('More than one compute endpoint? %s' % endpoints)
endpoint = endpoints[0]['publicURL']
url = '%s/os-services' % endpoint
headers = {
'Content-type': 'application/json',
'Accept': 'application/json',
'X-Auth-Token': self.authclient.token,
}
r = requests.get(url, headers=headers, verify=False)
LOG.debug("Service list response code: %d" % r.status_code)
LOG.debug("Servicer list response: %s" % r.text)
# TODO(belliott) parse response, handle errors
return []

View File

@@ -34,3 +34,4 @@ upload-dir = doc/build/html
[entry_points]
console_scripts =
cachemonkey-server = cachemonkey.cmd.server:main
cachemonkey-shell = cachemonkey.cmd.shell:main