[Et-mgmt-commits-list] [SCM] virt-factory branch, master now at 467b2b496438edeb81b461f565a289680b543403

Jeff Ortel jortel at redhat.com
Tue May 29 13:39:51 UTC 2007


Hello,

This is an automated email from the git hooks/update script, it was
generated because a ref change was pushed to the repository.

Updating branch, master,
       via  467b2b496438edeb81b461f565a289680b543403 (commit)
       via  a4c799f8f98ce9416a0351790619613a9721b7e7 (commit)
      from  5c22e13fc07c889bf3ef20f839d704e4671fba04 (commit)

- Log -----------------------------------------------------------------
commit 467b2b496438edeb81b461f565a289680b543403
Merge: a4c799f... 5c22e13...
Author: Jeff Ortel <jortel at dhcp231-152.rdu.redhat.com>
Date:   Tue May 29 09:39:39 2007 -0400

    Merge branch 'master' of git+ssh://g-jortel@et.redhat.com/git/virt-factory

commit a4c799f8f98ce9416a0351790619613a9721b7e7
Author: Jeff Ortel <jortel at localhost.localdomain>
Date:   Fri May 25 15:21:33 2007 -0400

    Added base class for ORM objects that provides a basic
    data() method that returns a the object's table-mapped
    attributes in a dictonary.
    a
-----------------------------------------------------------------------

Diffstat:
 service/modules/baseobj.py  |   27 +++---
 service/modules/regtoken.py |  190 +++++++++++++++++++++++++------------------
 service/modules/task.py     |   26 ++----
 service/modules/user.py     |   80 ++++++++-----------
 service/server/db.py        |   52 ++++++++----
 5 files changed, 200 insertions(+), 175 deletions(-)

diff --git a/service/modules/baseobj.py b/service/modules/baseobj.py
index 1a6f2c3..74dc7ea 100755
--- a/service/modules/baseobj.py
+++ b/service/modules/baseobj.py
@@ -133,33 +133,34 @@ class FieldValidator:
         if len(violations) > 0:
             raise InvalidArgumentsException(invalid_fields=violations)
         
-    def verify_int(self, keyset):
+    def verify_int(self, keyset, positive=False, strict=False):
         violations = {}
         for key in keyset:
             try:
-                int(self.data.get(key, 0))
+                if strict:
+                    n = int(self.data.get(key, None))
+                else:
+                    n = int(self.data.get(key, 0))
+                if positive:
+                    if n < 0:
+                        violations[key] = REASON_RANGE
             except:
                 violations[key] = REASON_FORMAT
         if len(violations) > 0:
             raise InvalidArgumentsException(invalid_fields=violations)
         
-    def verify_enum(self, key, values):
+    def verify_enum(self, key, values, strict=False):
         try:
-            value = self.data[key]
+            if strict:
+                value = self.data.get(key, None)
+            else:
+                value = self.data.get(key, values[0])
             if value not in values:
                 raise Exception
         except:
             violation = { key:REASON_RANGE }
             raise InvalidArgumentsException(invalid_fields=(violation,))
-        
-    def prunedata(self, data=None):
-        if data is None: data = self.data
-        for key in data.keys():
-            if data[key] is None:
-                del data[key]
-        return data
-    
-    prune = classmethod(prunedata)
+
         
         
         
\ No newline at end of file
diff --git a/service/modules/regtoken.py b/service/modules/regtoken.py
index 44d564f..d47d1a7 100755
--- a/service/modules/regtoken.py
+++ b/service/modules/regtoken.py
@@ -127,68 +127,104 @@ class RegToken(web_svc.AuthWebSvc):
 
     def add(self, token, args):
          """
-         Create a registration token.   Only profile_id and uses_remaining are used as input.
+         Create a token.
+         @param args: A dictionary of token attributes.
+             - token
+             - profile_id (optional)
+             - uses_remaining
+         @type args: dict
          """
-         args["token"] = self.generate(token)
-       
-         u = RegTokenData.produce(args,OP_ADD)
-         self.logger.info(str(u.to_datastruct()))
+         required = ('token')
+         optional = ('profile_id', 'uses_remaining')
+         validator = FieldValidator(args)
+         validator.verify_required(required)
+         validator.verify_int('uses_remaining', positive=True)
+         session = db.open_session()
+         try:
+             regtoken = db.RegToken()
+             for key in (required+optional):
+                 setattr(regtoken, key, args.get(key, None))
+             session.save(regtoken)
+             session.flush()
+             return success(regtoken.id)
+         finally:
+             session.close()
 
-         if u.profile_id is not None:
-             try:
-                 self.profile_obj = profile.Profile()
-                 self.profile_obj.get(token, { "id" : u.profile_id})
-             except VirtFactoryException:
-                 raise OrphanedObjectException(comment='profile_id',traceback=traceback.format_exc())
-
-         return self.db.simple_add(u.to_datastruct())
 
     def delete(self, token, args):
          """
-         Delete.  args must only contain the id field.
+         Deletes a token.
+         @param args: A dictionary of user attributes.
+             - id
+         @type args: dict
          """
-
-         u = RegTokenData.produce(args,OP_DELETE) # force validation
-         return self.db.simple_delete(args)
-
+         required = ('id',)
+         FieldValidator(args).verify_required(required)
+         session = db.open_session()
+         try:
+             rtid = args['id']
+             rt = session.get(db.RegToken, rtid)
+             if rt is None:
+                 raise NoSuchObjectException(comment=rtid)
+             session.delete(rt)
+             session.flush()
+             return success()
+         finally:
+             session.close()
+             
+             
     def get_by_token(self, token, args):
-         results = self.db.simple_list({}, { "token" : "'%s'" % args["token"]})
-         self.logger.info("get_by_token" + str(results))
-         return results
-
-    def list(self, token, args):
          """
-         Return a list of tokens.  The args list is currently *NOT*
-         used.  Ideally we need to include LIMIT information here for
-         GUI pagination when we start worrying about hundreds of systems.
+         Get all regtokens by token.
+         @param args: A dictionary of token attributes.
+             - token
+         @type args: dict
+         @return: A list of regtokens.
+         @rtype: [dict,]
+             - id
+             - token
+             - profile_id (optional)
+             - uses_remaining (optional)
+         # TODO: paging.
+         # TODO: nested structures.
          """
+         required = ('token',)
+         FieldValidator(args).verify_required(required)
+         session = db.open_session()
+         try:
+             result = []
+             query = session.query(db.RegToken)
+             for rt in query.select_by(token=args['token']):
+                 result.append(rt.data())
+             return success(result)
+         finally:
+             session.close()
 
-         # FIXME: make nested lists be able to do outer joins, or else fill
-         # in "EMPTY" database rows for unset profiles and make those undeleteable.
-
-         return self.db.nested_list(
-            [ profile.Profile.DB_SCHEMA ],
-            args,
-            { "profiles.id" : "regtokens.profile_id" }
-         )
 
-    def __decrement_uses_remaining(self, id, uses):
-        """
-        Decrement the uses remaining for a registration token.
-        """
-        st = """
-        UPDATE
-              regtokens
-        SET
-              uses_remaining=:uses
-        WHERE
-              id=:id
+    def list(self, token, args):
          """
-        
-        self.db.cursor.execute(st, {'uses':(uses-1), 'id':id})
-        self.db.connection.commit()
+         Get all regtokens.
+         @param args: Not used.
+         @type args: dict
+         @return: A list of regtokens.
+         @rtype: [dict,]
+             - id
+             - token
+             - profile_id (optional)
+             - uses_remaining (optional)
+         # TODO: paging.
+         # TODO: nested structures.
+         """
+         session = db.open_session()
+         try:
+             result = []
+             query = session.query(db.RegToken)
+             for rt in query.select():
+                 result.append(rt.data())
+             return success(result)
+         finally:
+             session.close()
 
-         
 
     def check(self, regtoken):
         """
@@ -243,39 +279,31 @@ class RegToken(web_svc.AuthWebSvc):
 
     def get(self, token, args):
          """
-         Return a specific record.  Only the "id" is required in args.
-         """
-
-         u = RegTokenData.produce(args,OP_GET) # force validation
-
-         st = """
-         SELECT id,token,profile_id,uses_remaining
-         FROM regtokens WHERE id=:id
+         Get a regtoken by id.
+         @param args: A dictionary of token attributes.
+             - id
+         @type args: dict
+         @return: A list of regtokens.
+         @rtype: [dict,]
+             - id
+             - token
+             - profile_id (optional)
+             - uses_remaining (optional)
+         # TODO: paging.
+         # TODO: nested structures.
          """
-
-         self.db.cursor.execute(st,{ "id" : u.id })
-         x = self.db.cursor.fetchone()
-
-         if x is None:
-             raise NoSuchObjectException(comment="regtoken_get")
-
-         data = {
-                "id"                 : x[0],
-                "token"              : x[1],
-                "profile_id"           : x[2],
-                "uses_remaining"     : x[3]
-         }
-
-         data = ProfileData.produce(data).to_datastruct(True)
-
-         if x[2] is not None:
-             profile_obj = profile.Profile()
-             profile_results = profile_obj.get(None, { "id" : x[2] })
-             if not profile_results.ok():
-                 raise OrphanedObjectException(comment="profile_id")
-             data["profile"] = profile_results.data
-
-         return success(data)
+         required = ('id',)
+         FieldValidator(args).verify_required(required)
+         session = db.open_session()
+         try:
+             result = []
+             rtid = args['id']
+             rt = session.get(db.RegToken, rtid)
+             if rt is None:
+                 raise NoSuchObjectException(comment=rtid)
+             return success(rt.data())
+         finally:
+             session.close()
 
 
 
diff --git a/service/modules/task.py b/service/modules/task.py
index 9152716..068517e 100755
--- a/service/modules/task.py
+++ b/service/modules/task.py
@@ -120,10 +120,10 @@ class Task(web_svc.AuthWebSvc):
     def list(self, token, args):
          """
          Get all tasks.
-         @param args: A dictionary of attributes.
+         @param args: A dictionary of task attributes.
          @type args: dict
          @return: A list of tasks.
-         @rtype: dictionary
+         @rtype: [dict,]
              - id
              - user_id
              - action_type
@@ -131,14 +131,15 @@ class Task(web_svc.AuthWebSvc):
              - deployment_id
              - state
              - time
-         # FIXME: implement paging
+         # TODO: paging
+         # TODO: nested structures.
          """
          session = db.open_session()
          try:
              result = []
              query = session.query(db.Task)
              for task in query.select():
-                 result.append(self.__taskdata(task))
+                 result.append(task.data())
              return success(result)
          finally:
              session.close()
@@ -150,6 +151,7 @@ class Task(web_svc.AuthWebSvc):
          @param args: A dictionary of task attributes.
              - id
          @type args: dict
+         # TODO: nested structures.
          """
          required = ('id',)
          FieldValidator(args).verify_required(required)
@@ -158,22 +160,10 @@ class Task(web_svc.AuthWebSvc):
              taskid = args['id']
              task = session.get(db.Task, taskid)
              if task is None:
-                 raise NoSuchObjectException(comment=task)
-             return success(self.__taskdata(task))
+                 raise NoSuchObjectException(comment=taskid)
+             return success(task.data())
          finally:
              session.close()
-
-
-    def __taskdata(self, task):
-        result =\
-            {'id':task.id,
-             'user_id':task.user_id,
-             'action_type':task.action_type,
-             'machine_id':task.machine_id,
-             'deployment_id':task.deployment_id,
-             'state':task.state,
-             'time':task.time}
-        return FieldValidator.prune(result)
  
 methods = Task()
 register_rpc = methods.register_rpc
diff --git a/service/modules/user.py b/service/modules/user.py
index a4900a8..adf2eba 100755
--- a/service/modules/user.py
+++ b/service/modules/user.py
@@ -38,10 +38,10 @@ class User(web_svc.AuthWebSvc):
         self.__lock = threading.Lock()
 
 
-    def add(self, token, user_args):
+    def add(self, token, args):
          """
          Create a user.
-         @param user_args: A dictionary of user attributes.
+         @param args: A dictionary of user attributes.
              - username
              - password
              - first
@@ -49,17 +49,17 @@ class User(web_svc.AuthWebSvc):
              - last
              - description
              - email
-         @type user_args: dict
+         @type args: dict
          """
          required = ('username','password', 'first', 'last', 'email')
          optional = ('middle', 'description')
-         FieldValidator(user_args).verify_required(required)
+         FieldValidator(args).verify_required(required)
          session = db.open_session()
          self.__lock.acquire()
          try:
              user = db.User()
              for key in (required+optional):
-                 setattr(user, key, user_args.get(key, None))
+                 setattr(user, key, args.get(key, None))
              session.save(user)
              session.flush()
              return success(user.id)
@@ -68,10 +68,10 @@ class User(web_svc.AuthWebSvc):
              session.close()
 
 
-    def edit(self, token, user_args):
+    def edit(self, token, args):
          """
          Edit a user.
-         @param user_args: A dictionary of user attributes.
+         @param args: A dictionary of user attributes.
              - id
              - username (optional)
              - password (optional)
@@ -80,45 +80,43 @@ class User(web_svc.AuthWebSvc):
              - last (optional)
              - description (optional)
              - email (optional)
-         @type user_args: dict.
-         # FIXME: don't allow delete if only 1 user left
-         # FIXME: consider an undeletable but modifiable admin user
-         # FIXME: password should be stored encrypted.
+         @type args: dict.
+         # TODO: password should be stored encrypted.
          """
          required = ('id',)
          optional = ('username','password', 'first', 'middle', 'last', 'email', 'description')
-         FieldValidator(user_args).verify_required(required)
+         FieldValidator(args).verify_required(required)
          session = db.open_session()
          self.__lock.acquire()
          try:
-             userid = user_args['id']
+             userid = args['id']
              user = session.get(db.User, userid)
              if user is None:
                  raise NoSuchObjectException(comment=userid)
              for key in optional:
                  current = getattr(user, key)
-                 setattr(user, key, user_args.get(key, current))
+                 setattr(user, key, args.get(key, current))
              session.save(user)
              session.flush()
-             return success(user_args)
+             return success(args)
          finally:
              self.__lock.release()
              session.close()
 
 
-    def delete(self, token, user_args):
+    def delete(self, token, args):
          """
          Deletes a user.
-         @param user_args: A dictionary of user attributes.
+         @param args: A dictionary of user attributes.
              - id
-         @type user_args: dict
+         @type args: dict
          """
          required = ('id',)
-         FieldValidator(user_args).verify_required(required)
+         FieldValidator(args).verify_required(required)
          session = db.open_session()
          self.__lock.acquire()
          try:
-             userid = user_args['id']
+             userid = args['id']
              user = session.get(db.User, userid)
              if user is None:
                  raise NoSuchObjectException(comment=userid)
@@ -132,15 +130,15 @@ class User(web_svc.AuthWebSvc):
              session.close()
 
 
-    def list(self, token, user_args):
+    def list(self, token, args):
          """
          Get all users.
-         @param user_args: A dictionary of user attributes.
+         @param args: A dictionary of user attributes.
              - offset (optional)
              - limit (optional default=100)
-         @type user_args: dict
+         @type args: dict
          @return: A list of users.
-         @rtype: dictionary
+         @rtype: [dict,]
              - id
              - username
              - first
@@ -148,54 +146,42 @@ class User(web_svc.AuthWebSvc):
              - last
              - description (optional)
              - email
-         # FIXME: implement paging
+         # TODO: paging
          """
          optional = ('offset', 'limit')
-         validator = FieldValidator(user_args)
+         validator = FieldValidator(args)
          validator.verify_int(optional)
-         offset = user_args.get(optional[0], 0)
-         limit = user_args.get(optional[1], 100)
+         offset = args.get(optional[0], 0)
+         limit = args.get(optional[1], 100)
 
          session = db.open_session()
          try:
              result = []
              query = session.query(db.User)
              for user in query.select():
-                 result.append(self.__userdata(user))
+                 result.append(user.data())
              return success(result)
          finally:
              session.close()
 
-    def get(self, token, user_args):
+    def get(self, token, args):
          """
          Get a user by id.
-         @param user_args: A dictionary of user attributes.
+         @param args: A dictionary of user attributes.
              - id
-         @type user_args: dict
+         @type args: dict
          """
          required = ('id',)
-         FieldValidator(user_args).verify_required(required)
+         FieldValidator(args).verify_required(required)
          session = db.open_session()
          try:
-             userid = user_args['id']
+             userid = args['id']
              user = session.get(db.User, userid)
              if user is None:
                  raise NoSuchObjectException(comment=userid)
-             return success(self.__userdata(user))
+             return success(user.data())
          finally:
              session.close()
-     
-    def __userdata(self, user):
-        result =\
-            {'id':user.id,
-              'username':user.username,
-              'password':user.password,
-              'first':user.first,
-              'middle':user.middle,
-              'last':user.last,
-              'description':user.description,
-              'email':user.email } 
-        return FieldValidator.prune(result)
 
  
 methods = User()
diff --git a/service/server/db.py b/service/server/db.py
index 2256227..ae4f19c 100644
--- a/service/server/db.py
+++ b/service/server/db.py
@@ -159,35 +159,49 @@ tables =\
         Column('message', String(4000)))
 )
 
+#
+# provides a static dictionary of tables.
+#
 table = dict([(t.name, t) for t in tables])
 
+
 indexes =\
 (
     #Index('username', table['users'].c.username, unique=True),
 )
 
 
-class User(object):
+class Base(object):
+    def data(self):
+        result = {}
+        for key in ormbindings.get(self.__class__, ()):
+            value = getattr(self, key)
+            if value is not None:
+                result[key] = value
+        return result
+
+
+class User(Base):
     pass
-class Distribution(object):
+class Distribution(Base):
     pass
-class Profile(object):
+class Profile(Base):
     pass
-class Machine(object):
+class Machine(Base):
     pass
-class Deployment(object):
+class Deployment(Base):
     pass
-class RegToken(object):
+class RegToken(Base):
     pass
-class Session(object):
+class Session(Base):
     pass
-class SchemaVersion(object):
+class SchemaVersion(Base):
     pass
-class Task(object):
+class Task(Base):
     pass
-class Event(object):
+class Event(Base):
     pass
-class UpgradeLogMessage(object):
+class UpgradeLogMessage(Base):
     pass
 
 
@@ -245,6 +259,14 @@ mappers =\
 )
 
 
+#
+# provides a static dictionary of orm classes to mapped
+# table column names.
+#
+ormbindings =\
+    dict([(m.class_,[c.name for c in m.local_table.columns]) for m in mappers ])
+
+
 class Database:
     """
     Represents the database and provides database lifecycle and
@@ -318,7 +340,6 @@ class Facade:
                 raise SQLException(
                            comment = str(e),
                            traceback=traceback.format_exc())
-        
 
 
 def open_session():
@@ -335,8 +356,8 @@ def open_session():
 
 if __name__ == '__main__':
     database = Database('postgres://jortel:jortel@localhost/virtfactory')
-    database.drop()
-    database.create()
+    #database.drop()
+    #database.create()
         
     ssn = open_session()
     try:
@@ -344,7 +365,6 @@ if __name__ == '__main__':
         user.username = 'jortel'
         user.password = 'mypassword'
         user.first = 'Elvis'
-        user.middle = 'Marvin'
         user.last = 'Prestley'
         user.description = 'The King.'
         user.email = 'elvis at redhat.com'
@@ -356,7 +376,7 @@ if __name__ == '__main__':
 
         ssn.save(session)
         ssn.flush()
-        
+
         ssn.delete(user)
         ssn.flush()
     finally:

hooks/update
---
Git Source Code Management System
hooks/update refs/heads/master \
  5c22e13fc07c889bf3ef20f839d704e4671fba04 \
  467b2b496438edeb81b461f565a289680b543403




More information about the Et-mgmt-commits-list mailing list