From: Tony Mack Date: Fri, 14 Sep 2012 15:35:23 +0000 (-0400) Subject: initialize client and admin connections to nova X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=548acca1a538d7146f823a9f23f5362cf24f5114;p=plcapi.git initialize client and admin connections to nova --- diff --git a/PLC/Method.py b/PLC/Method.py index 783bc5d2..3d7383c5 100644 --- a/PLC/Method.py +++ b/PLC/Method.py @@ -12,11 +12,11 @@ import time import pprint from types import StringTypes - +from PLC.NovaShell import NovaShell from PLC.Faults import * from PLC.Parameter import Parameter, Mixed, python_type, xmlrpc_type from PLC.Auth import Auth -from PLC.Debug import profile, log +from PLC.Debug import profile from PLC.Events import Event, Events from PLC.Nodes import Node, Nodes from PLC.Persons import Person, Persons @@ -37,6 +37,8 @@ class Method (object): dictionaries of possibly mixed types, values, and/or Parameters (e.g., [int, bool, ...] or {'arg1': int, 'arg2': bool}). +w +w Once function decorators in Python 2.4 are fully supported, consider wrapping calls with accepts() and returns() functions instead of performing type checking manually. @@ -62,6 +64,8 @@ class Method (object): def __init__(self, api,caller=None): self.name = self.__class__.__name__ self.api = api + self.admin_shell = NovaShell() + self.client_shell = None if caller: # let a method call another one by propagating its caller @@ -99,97 +103,18 @@ class Method (object): result = self.call(*args, **kwds) runtime = time.time() - start - if self.api.config.PLC_API_DEBUG or hasattr(self, 'message'): - self.log(None, runtime, *args) - return result except PLCFault, fault: caller = "" - if isinstance(self.caller, Person): - caller = 'person_id %s' % self.caller['person_id'] - elif isinstance(self.caller, Node): - caller = 'node_id %s' % self.caller['node_id'] + if self.caller: + caller = 'user: %s' % self.caller.name # Prepend caller and method name to expected faults fault.faultString = caller + ": " + self.name + ": " + fault.faultString - runtime = time.time() - start - - if self.api.config.PLC_API_DEBUG: - self.log(fault, runtime, *args) - raise fault - def log(self, fault, runtime, *args): - """ - Log the transaction - """ - - # Do not log system or Get calls - #if self.name.startswith('system') or self.name.startswith('Get'): - # return False - # Do not log ReportRunlevel - if self.name.startswith('system'): - return False - if self.name.startswith('ReportRunlevel'): - return False - - # Create a new event - event = Event(self.api) - event['fault_code'] = 0 - if fault: - event['fault_code'] = fault.faultCode - event['runtime'] = runtime - - # Redact passwords and sessions - newargs = args - if args: - newargs = [] - for arg in args: - if not isinstance(arg, dict): - newargs.append(arg) - continue - # what type of auth this is - if arg.has_key('AuthMethod'): - auth_methods = ['session', 'password', 'capability', 'gpg', 'hmac','anonymous'] - auth_method = arg['AuthMethod'] - if auth_method in auth_methods: - event['auth_type'] = auth_method - for password in 'AuthString', 'session', 'password': - if arg.has_key(password): - arg = arg.copy() - arg[password] = "Removed by API" - newargs.append(arg) - - # Log call representation - # XXX Truncate to avoid DoS - event['call'] = self.name + pprint.saferepr(newargs) - event['call_name'] = self.name - - # Both users and nodes can call some methods - if isinstance(self.caller, Person): - event['person_id'] = self.caller['person_id'] - elif isinstance(self.caller, Node): - event['node_id'] = self.caller['node_id'] - - event.sync(commit = False) - - if hasattr(self, 'event_objects') and isinstance(self.event_objects, dict): - for key in self.event_objects.keys(): - for object_id in self.event_objects[key]: - event.add_object(key, object_id, commit = False) - - - # Set the message for this event - if fault: - event['message'] = fault.faultString - elif hasattr(self, 'message'): - event['message'] = self.message - - # Commit - event.sync() - def help(self, indent = " "): """ Text documentation for the method. @@ -390,4 +315,23 @@ class Method (object): raise PLCInvalidArgument("'%s' not specified" % key, name) if auth is not None: - auth.check(self, *args) + # assume auth structure is first argument + self.authenticate(args[0]) + + def authenticate(self, auth): + + # establish nova connection + self.client_shell = NovaShell(user=auth['Username'], + password=auth['AuthString'], + tenant=auth['Tenant']) + self.client_shell.authenticate() + self.caller = self.client_shell.keystone.users.find(name=auth['Username']) + self.caller_tenant = self.client_shell.keystone.tenants.find(name=auth['Tenant']) + caller_roles = self.client_shell.keystone.roles.roles_for_user(self.caller, self.caller_tenant) + role_names = [role.name for role in caller_roles] + if not set(role_names).intersection(self.roles): + method_message="method %s has roles [%s]"%(self.name,','.join(self.roles)) + person_message="caller %s has roles [%s]"%(self.caller.name,','.join(role_names)) + raise PLCAuthenticationFailure, "PasswordAuth: missing role, %s -- %s"%(method_message,person_message) + +