Add compute discovery
* Also add a shell CLI for interactive sessions * Add separate admin auth cred support
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
37
cachemonkey/cmd/shell.py
Normal 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
60
cachemonkey/discover.py
Normal 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 []
|
||||
|
||||
Reference in New Issue
Block a user