More docstrings, don't autocreate projects
This commit is contained in:
@@ -108,9 +108,9 @@ class LdapDriver(object):
|
|||||||
attr = self.__find_object(dn, '(objectclass=novaKeyPair)')
|
attr = self.__find_object(dn, '(objectclass=novaKeyPair)')
|
||||||
return self.__to_key_pair(uid, attr)
|
return self.__to_key_pair(uid, attr)
|
||||||
|
|
||||||
def get_project(self, name):
|
def get_project(self, pid):
|
||||||
"""Retrieve project by name"""
|
"""Retrieve project by id"""
|
||||||
dn = 'cn=%s,%s' % (name,
|
dn = 'cn=%s,%s' % (pid,
|
||||||
FLAGS.ldap_project_subtree)
|
FLAGS.ldap_project_subtree)
|
||||||
attr = self.__find_object(dn, '(objectclass=novaProject)')
|
attr = self.__find_object(dn, '(objectclass=novaProject)')
|
||||||
return self.__to_project(attr)
|
return self.__to_project(attr)
|
||||||
@@ -452,6 +452,7 @@ class LdapDriver(object):
|
|||||||
return None
|
return None
|
||||||
return manager.KeyPair(
|
return manager.KeyPair(
|
||||||
id = attr['cn'][0],
|
id = attr['cn'][0],
|
||||||
|
name = attr['cn'][0],
|
||||||
owner_id = owner,
|
owner_id = owner,
|
||||||
public_key = attr['sshPublicKey'][0],
|
public_key = attr['sshPublicKey'][0],
|
||||||
fingerprint = attr['keyFingerprint'][0],
|
fingerprint = attr['keyFingerprint'][0],
|
||||||
@@ -464,6 +465,7 @@ class LdapDriver(object):
|
|||||||
member_dns = attr.get('member', [])
|
member_dns = attr.get('member', [])
|
||||||
return manager.Project(
|
return manager.Project(
|
||||||
id = attr['cn'][0],
|
id = attr['cn'][0],
|
||||||
|
name = attr['cn'][0],
|
||||||
project_manager_id = self.__dn_to_uid(attr['projectManager'][0]),
|
project_manager_id = self.__dn_to_uid(attr['projectManager'][0]),
|
||||||
description = attr.get('description', [None])[0],
|
description = attr.get('description', [None])[0],
|
||||||
member_ids = [self.__dn_to_uid(x) for x in member_dns]
|
member_ids = [self.__dn_to_uid(x) for x in member_dns]
|
||||||
|
|||||||
@@ -159,26 +159,27 @@ class KeyPair(AuthBase):
|
|||||||
Even though this object is named KeyPair, only the public key and
|
Even though this object is named KeyPair, only the public key and
|
||||||
fingerprint is stored. The user's private key is not saved.
|
fingerprint is stored. The user's private key is not saved.
|
||||||
"""
|
"""
|
||||||
def __init__(self, id, owner_id, public_key, fingerprint):
|
def __init__(self, id, name, owner_id, public_key, fingerprint):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = id
|
self.name = name
|
||||||
self.owner_id = owner_id
|
self.owner_id = owner_id
|
||||||
self.public_key = public_key
|
self.public_key = public_key
|
||||||
self.fingerprint = fingerprint
|
self.fingerprint = fingerprint
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "KeyPair('%s', '%s', '%s', '%s')" % (self.id,
|
return "KeyPair('%s', '%s', '%s', '%s', '%s')" % (self.id,
|
||||||
self.owner_id,
|
self.name,
|
||||||
self.public_key,
|
self.owner_id,
|
||||||
self.fingerprint)
|
self.public_key,
|
||||||
|
self.fingerprint)
|
||||||
|
|
||||||
|
|
||||||
class Project(AuthBase):
|
class Project(AuthBase):
|
||||||
"""Represents a Project returned from the datastore"""
|
"""Represents a Project returned from the datastore"""
|
||||||
def __init__(self, id, project_manager_id, description, member_ids):
|
def __init__(self, id, name, project_manager_id, description, member_ids):
|
||||||
self.project_manager_id = project_manager_id
|
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = id
|
self.name = name
|
||||||
|
self.project_manager_id = project_manager_id
|
||||||
self.description = description
|
self.description = description
|
||||||
self.member_ids = member_ids
|
self.member_ids = member_ids
|
||||||
|
|
||||||
@@ -205,10 +206,11 @@ class Project(AuthBase):
|
|||||||
return AuthManager().get_credentials(user, self)
|
return AuthManager().get_credentials(user, self)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Project('%s', '%s', '%s', %s)" % (self.id,
|
return "Project('%s', '%s', '%s', '%s', %s)" % (self.id,
|
||||||
self.project_manager_id,
|
self.name,
|
||||||
self.description,
|
self.project_manager_id,
|
||||||
self.member_ids)
|
self.description,
|
||||||
|
self.member_ids)
|
||||||
|
|
||||||
|
|
||||||
class NoMorePorts(exception.Error):
|
class NoMorePorts(exception.Error):
|
||||||
@@ -223,10 +225,16 @@ class Vpn(datastore.BasicModel):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
|
"""Identifier used for key in redis"""
|
||||||
return self.project_id
|
return self.project_id
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, project_id):
|
def create(cls, project_id):
|
||||||
|
"""Creates a vpn for project
|
||||||
|
|
||||||
|
This method finds a free ip and port and stores the associated
|
||||||
|
values in the datastore.
|
||||||
|
"""
|
||||||
# TODO(vish): get list of vpn ips from redis
|
# TODO(vish): get list of vpn ips from redis
|
||||||
port = cls.find_free_port_for_ip(FLAGS.vpn_ip)
|
port = cls.find_free_port_for_ip(FLAGS.vpn_ip)
|
||||||
vpn = cls(project_id)
|
vpn = cls(project_id)
|
||||||
@@ -239,6 +247,7 @@ class Vpn(datastore.BasicModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def find_free_port_for_ip(cls, ip):
|
def find_free_port_for_ip(cls, ip):
|
||||||
|
"""Finds a free port for a given ip from the redis set"""
|
||||||
# TODO(vish): these redis commands should be generalized and
|
# TODO(vish): these redis commands should be generalized and
|
||||||
# placed into a base class. Conceptually, it is
|
# placed into a base class. Conceptually, it is
|
||||||
# similar to an association, but we are just
|
# similar to an association, but we are just
|
||||||
@@ -260,21 +269,26 @@ class Vpn(datastore.BasicModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def num_ports_for_ip(cls, ip):
|
def num_ports_for_ip(cls, ip):
|
||||||
|
"""Calculates the number of free ports for a given ip"""
|
||||||
return datastore.Redis.instance().scard('ip:%s:ports' % ip)
|
return datastore.Redis.instance().scard('ip:%s:ports' % ip)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ip(self):
|
def ip(self):
|
||||||
|
"""The ip assigned to the project"""
|
||||||
return self['ip']
|
return self['ip']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port(self):
|
def port(self):
|
||||||
|
"""The port assigned to the project"""
|
||||||
return int(self['port'])
|
return int(self['port'])
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
"""Saves the association to the given ip"""
|
||||||
self.associate_with('ip', self.ip)
|
self.associate_with('ip', self.ip)
|
||||||
super(Vpn, self).save()
|
super(Vpn, self).save()
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
|
"""Cleans up datastore and adds port back to pool"""
|
||||||
self.unassociate_with('ip', self.ip)
|
self.unassociate_with('ip', self.ip)
|
||||||
datastore.Redis.instance().sadd('ip:%s:ports' % self.ip, self.port)
|
datastore.Redis.instance().sadd('ip:%s:ports' % self.ip, self.port)
|
||||||
super(Vpn, self).destroy()
|
super(Vpn, self).destroy()
|
||||||
@@ -345,19 +359,22 @@ class AuthManager(object):
|
|||||||
@return: User and project that the request represents.
|
@return: User and project that the request represents.
|
||||||
"""
|
"""
|
||||||
# TODO(vish): check for valid timestamp
|
# TODO(vish): check for valid timestamp
|
||||||
(access_key, sep, project_name) = access.partition(':')
|
(access_key, sep, project_id) = access.partition(':')
|
||||||
|
|
||||||
user = self.get_user_from_access_key(access_key)
|
user = self.get_user_from_access_key(access_key)
|
||||||
if user == None:
|
if user == None:
|
||||||
raise exception.NotFound('No user found for access key %s' %
|
raise exception.NotFound('No user found for access key %s' %
|
||||||
access_key)
|
access_key)
|
||||||
if project_name is '':
|
|
||||||
project_name = user.name
|
|
||||||
|
|
||||||
project = self.get_project(project_name)
|
# NOTE(vish): if we stop using project name as id we need better
|
||||||
|
# logic to find a default project for user
|
||||||
|
if project_id is '':
|
||||||
|
project_id = user.name
|
||||||
|
|
||||||
|
project = self.get_project(project_id)
|
||||||
if project == None:
|
if project == None:
|
||||||
raise exception.NotFound('No project called %s could be found' %
|
raise exception.NotFound('No project called %s could be found' %
|
||||||
project_name)
|
project_id)
|
||||||
if not self.is_admin(user) and not self.is_project_member(user,
|
if not self.is_admin(user) and not self.is_project_member(user,
|
||||||
project):
|
project):
|
||||||
raise exception.NotFound('User %s is not a member of project %s' %
|
raise exception.NotFound('User %s is not a member of project %s' %
|
||||||
@@ -521,9 +538,9 @@ class AuthManager(object):
|
|||||||
Vpn.create(name)
|
Vpn.create(name)
|
||||||
with self.driver_class() as drv:
|
with self.driver_class() as drv:
|
||||||
return drv.create_project(name,
|
return drv.create_project(name,
|
||||||
User.safe_id(manager_user),
|
User.safe_id(manager_user),
|
||||||
description,
|
description,
|
||||||
member_users)
|
member_users)
|
||||||
|
|
||||||
def get_projects(self):
|
def get_projects(self):
|
||||||
"""Retrieves list of all projects"""
|
"""Retrieves list of all projects"""
|
||||||
@@ -531,10 +548,10 @@ class AuthManager(object):
|
|||||||
return drv.get_projects()
|
return drv.get_projects()
|
||||||
|
|
||||||
|
|
||||||
def get_project(self, project):
|
def get_project(self, pid):
|
||||||
"""Get project object by id"""
|
"""Get project object by id"""
|
||||||
with self.driver_class() as drv:
|
with self.driver_class() as drv:
|
||||||
return drv.get_project(Project.safe_id(project))
|
return drv.get_project(pid)
|
||||||
|
|
||||||
def add_to_project(self, user, project):
|
def add_to_project(self, user, project):
|
||||||
"""Add user to project"""
|
"""Add user to project"""
|
||||||
@@ -580,13 +597,11 @@ class AuthManager(object):
|
|||||||
with self.driver_class() as drv:
|
with self.driver_class() as drv:
|
||||||
return drv.get_users()
|
return drv.get_users()
|
||||||
|
|
||||||
def create_user(self, user, access=None, secret=None,
|
def create_user(self, name, access=None, secret=None, admin=False):
|
||||||
admin=False, create_project=True):
|
|
||||||
"""Creates a user
|
"""Creates a user
|
||||||
|
|
||||||
@type user: str
|
@type name: str
|
||||||
@param name: Name of the user to create. The name will also be
|
@param name: Name of the user to create.
|
||||||
used as the user id.
|
|
||||||
|
|
||||||
@type access: str
|
@type access: str
|
||||||
@param access: Access Key (defaults to a random uuid)
|
@param access: Access Key (defaults to a random uuid)
|
||||||
@@ -607,29 +622,12 @@ class AuthManager(object):
|
|||||||
if access == None: access = str(uuid.uuid4())
|
if access == None: access = str(uuid.uuid4())
|
||||||
if secret == None: secret = str(uuid.uuid4())
|
if secret == None: secret = str(uuid.uuid4())
|
||||||
with self.driver_class() as drv:
|
with self.driver_class() as drv:
|
||||||
user = User.safe_id(user)
|
return drv.create_user(name, access, secret, admin)
|
||||||
result = drv.create_user(user, access, secret, admin)
|
|
||||||
if create_project:
|
|
||||||
# NOTE(vish): if the project creation fails, we delete
|
|
||||||
# the user and return an exception
|
|
||||||
try:
|
|
||||||
drv.create_project(user, user, user)
|
|
||||||
except Exception:
|
|
||||||
with self.driver_class() as drv:
|
|
||||||
drv.delete_user(user)
|
|
||||||
raise
|
|
||||||
return result
|
|
||||||
|
|
||||||
def delete_user(self, user, delete_project=True):
|
def delete_user(self, user):
|
||||||
"""Deletes a user"""
|
"""Deletes a user"""
|
||||||
with self.driver_class() as drv:
|
with self.driver_class() as drv:
|
||||||
user = User.safe_id(user)
|
drv.delete_user(User.safe_id(user))
|
||||||
if delete_project:
|
|
||||||
try:
|
|
||||||
drv.delete_project(user)
|
|
||||||
except exception.NotFound:
|
|
||||||
pass
|
|
||||||
drv.delete_user(user)
|
|
||||||
|
|
||||||
def generate_key_pair(self, user, key_name):
|
def generate_key_pair(self, user, key_name):
|
||||||
"""Generates a key pair for a user
|
"""Generates a key pair for a user
|
||||||
|
|||||||
Reference in New Issue
Block a user