Jelajahi Sumber

实现boot_jobs操作接口

James Iter 9 tahun lalu
induk
melakukan
dea242586e
6 mengubah file dengan 163 tambahan dan 18 penghapusan
  1. 75 0
      api/guest.py
  2. 4 0
      api_route_table.py
  3. 3 1
      config.json
  4. 25 0
      models/guest.py
  5. 21 17
      models/rules.py
  6. 35 0
      tests/test_guest.py

+ 75 - 0
api/guest.py

@@ -574,3 +574,78 @@ def r_update(uuid):
         return ret
     except ji.PreviewingError, e:
         return json.loads(e.message)
+
+
+@Utils.dumps2response
+def r_add_boot_jobs(uuid, boot_jobs_id):
+
+    args_rules = [
+        Rules.UUID.value,
+        Rules.BOOT_JOBS_ID.value
+    ]
+
+    try:
+        ji.Check.previewing(args_rules, {'uuid': uuid, 'boot_jobs_id': boot_jobs_id})
+
+        guest = Guest()
+        guest.uuid = uuid
+        guest.get_by('uuid')
+
+        guest.add_boot_jobs(boot_jobs_id=boot_jobs_id.split(','))
+
+        ret = dict()
+        ret['state'] = ji.Common.exchange_state(20000)
+        ret['data'] = guest.get_boot_jobs()
+        return ret
+
+    except ji.PreviewingError, e:
+        return json.loads(e.message)
+
+
+@Utils.dumps2response
+def r_get_boot_jobs(uuid):
+
+    args_rules = [
+        Rules.UUID.value
+    ]
+
+    try:
+        ji.Check.previewing(args_rules, {'uuid': uuid})
+        guest = Guest()
+        guest.uuid = uuid
+        guest.get_by('uuid')
+
+        ret = dict()
+        ret['state'] = ji.Common.exchange_state(20000)
+        ret['data'] = guest.get_boot_jobs()
+        return ret
+
+    except ji.PreviewingError, e:
+        return json.loads(e.message)
+
+
+@Utils.dumps2response
+def r_delete_boot_jobs(uuid, boot_jobs_id):
+
+    args_rules = [
+        Rules.UUID.value,
+        Rules.BOOT_JOBS_ID.value
+    ]
+
+    try:
+        ji.Check.previewing(args_rules, {'uuid': uuid, 'boot_jobs_id': boot_jobs_id})
+
+        guest = Guest()
+        guest.uuid = uuid
+        guest.get_by('uuid')
+
+        guest.delete_boot_jobs(boot_jobs_id=boot_jobs_id.split(','))
+
+        ret = dict()
+        ret['state'] = ji.Common.exchange_state(20000)
+        ret['data'] = guest.get_boot_jobs()
+        return ret
+
+    except ji.PreviewingError, e:
+        return json.loads(e.message)
+

+ 4 - 0
api_route_table.py

@@ -66,6 +66,10 @@ add_rule_api(guest.blueprints, '', api_func='guest.r_get_by_filter', methods=['G
 add_rule_api(guest.blueprints, '/_search', api_func='guest.r_content_search', methods=['GET'])
 add_rule_api(guest.blueprint, '/<uuid>', api_func='guest.r_update', methods=['PATCH'])
 add_rule_api(guest.blueprints, '/<uuids>', api_func='guest.r_delete', methods=['DELETE'])
+add_rule_api(guest.blueprint, '/_boot_jobs/<uuid>/<boot_jobs_id>', api_func='guest.r_add_boot_jobs', methods=['PUT'])
+add_rule_api(guest.blueprint, '/_boot_jobs/<uuid>', api_func='guest.r_get_boot_jobs', methods=['GET'])
+add_rule_api(guest.blueprint, '/_boot_jobs/<uuid>/<boot_jobs_id>', api_func='guest.r_delete_boot_jobs',
+             methods=['DELETE'])
 
 # Disk操作
 add_rule_api(disk.blueprint, '', api_func='disk.r_create', methods=['POST'])

+ 3 - 1
config.json

@@ -34,5 +34,7 @@
   "vnc_port_used_set": "S:VNCPort:Used",
   "downstream_queue": "Q:Downstream",
   "upstream_queue": "Q:Upstream",
-  "hosts_info": "H:HostsInfo"
+  "hosts_info": "H:HostsInfo",
+  "guest_boot_jobs": "S:GuestBootJobs",
+  "guest_boot_jobs_wait_time": 600
 }

+ 25 - 0
models/guest.py

@@ -65,6 +65,31 @@ class Guest(ORM):
     def emit_instruction(message):
         db.r.publish(app.config['instruction_channel'], message=message)
 
+    def get_boot_jobs_key(self):
+        return ':'.join([app.config['guest_boot_jobs'], self.uuid])
+
+    def add_boot_jobs(self, boot_jobs_id):
+        if not isinstance(boot_jobs_id, list):
+            raise
+
+        key = self.get_boot_jobs_key()
+        db.r.sadd(key, *boot_jobs_id)
+        db.r.expire(key, app.config['guest_boot_jobs_wait_time'])
+
+    def get_boot_jobs(self):
+        return list(db.r.smembers(self.get_boot_jobs_key()))
+
+    def delete_boot_jobs(self, boot_jobs_id):
+        if not isinstance(boot_jobs_id, list):
+            raise
+
+        key = self.get_boot_jobs_key()
+        db.r.srem(key, *boot_jobs_id)
+
+        # 如果集合下还有值,则更新启动作业有效时间
+        if db.r.exists(key):
+            db.r.expire(key, app.config['guest_boot_jobs_wait_time'])
+
 
 class Disk(ORM):
 

+ 21 - 17
models/rules.py

@@ -12,37 +12,41 @@ __copyright__ = '(c) 2017 by James Iter.'
 
 
 class Rules(Enum):
-    OFFSET = ('regex:^\d{1,17}$', 'offset')
-    LIMIT = ('regex:^\d{1,17}$', 'limit')
-    PAGE = ('regex:^\d{1,17}$', 'page')
-    PAGE_SIZE = ('regex:^\d{1,17}$', 'page_size')
+    # 正则表达式方便校验其来自URL的参数
+    REG_NUMBER = 'regex:^\d{1,17}$'
+    REG_NUMBERS = 'regex:^(\d{1,17})(,\d{1,17})*$'
+    REG_UUIDS = 'regex:^([\w-]{36})(,[\w-]{36})*$'
+    REG_IP = 'regex:^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))$'
+
+    OFFSET = (REG_NUMBER, 'offset')
+    LIMIT = (REG_NUMBER, 'limit')
+    PAGE = (REG_NUMBER, 'page')
+    PAGE_SIZE = (REG_NUMBER, 'page_size')
     ORDER_BY = (basestring, 'order_by', (1, 30))
     ORDER = (basestring, 'order', ['asc', 'desc'])
     KEYWORD = (basestring, 'keyword')
 
-    ID = ('regex:^\d{1,17}$', 'id')
-    IDS = ('regex:^(\d{1,17})(,\d{1,17})*$', 'ids')
-
-    # 正则表达式方便校验其来自URL的参数
-    IP = 'regex:^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))$'
+    ID = (REG_NUMBER, 'id')
+    IDS = (REG_NUMBERS, 'ids')
+    BOOT_JOBS_ID = (REG_NUMBERS, 'boot_jobs_id')
 
     CONFIG_ID = (int, 'id')
     GLUSTERFS_VOLUME = (basestring, 'glusterfs_volume')
     STORAGE_PATH = (basestring, 'storage_path')
     VM_NETWORK = (basestring, 'vm_network')
     VM_MANAGE_NETWORK = (basestring, 'vm_manage_network')
-    START_IP = (IP, 'start_ip')
-    END_IP = (IP, 'end_ip')
+    START_IP = (REG_IP, 'start_ip')
+    END_IP = (REG_IP, 'end_ip')
     START_VNC_PORT = (int, 'start_vnc_port')
-    NETMASK = (IP, 'netmask')
-    GATEWAY = (IP, 'gateway')
-    DNS1 = (IP, 'dns1')
-    DNS2 = (IP, 'dns2')
+    NETMASK = (REG_IP, 'netmask')
+    GATEWAY = (REG_IP, 'gateway')
+    DNS1 = (REG_IP, 'dns1')
+    DNS2 = (REG_IP, 'dns2')
     RSA_PRIVATE = (basestring, 'rsa_private')
     RSA_PUBLIC = (basestring, 'rsa_public')
 
     UUID = (basestring, 'uuid', (36, 36))
-    UUIDS = ('regex:^([\w-]{36})(,[\w-]{36})*$', 'uuids')
+    UUIDS = (REG_UUIDS, 'uuids')
     CPU = (int, 'cpu')
     MEMORY = (int, 'memory')
     OS_TEMPLATE_ID = (int, 'os_template_id')
@@ -54,7 +58,7 @@ class Rules(Enum):
     DESTINATION_HOST = (basestring, 'destination_host', (5, 64))
     DISK_UUID = (basestring, 'disk_uuid', (36, 36))
     DISK_SIZE = (int, 'size')
-    DISK_SIZE_STR = ('regex:^\d{1,17}$', 'size')
+    DISK_SIZE_STR = (REG_NUMBER, 'size')
 
     REMARK = (basestring, 'remark')
     USE_FOR = (int, 'use_for')

+ 35 - 0
tests/test_guest.py

@@ -253,6 +253,41 @@ class TestGuest(unittest.TestCase):
     #     print json.dumps(j_r, ensure_ascii=False)
     #     self.assertEqual('200', j_r['state']['code'])
 
+    # def test_71_add_boot_jobs_id(self):
+    #     TestGuest.uuid = 'ba38a067-83cb-49e8-bfc1-7dce7d5e34e6'
+    #     url = TestGuest.base_url + '/guest/_boot_jobs/' + TestGuest.uuid + '/' + '1,2,4'
+    #     headers = {'content-type': 'application/json'}
+    #     r = requests.put(url, headers=headers)
+    #     j_r = json.loads(r.content)
+    #     print json.dumps(j_r, ensure_ascii=False)
+    #     self.assertEqual('200', j_r['state']['code'])
+
+    def test_72_get_boot_jobs_id(self):
+        TestGuest.uuid = 'ba38a067-83cb-49e8-bfc1-7dce7d5e34e6'
+        url = TestGuest.base_url + '/guest/_boot_jobs/' + TestGuest.uuid
+        headers = {'content-type': 'application/json'}
+        r = requests.get(url, headers=headers)
+        j_r = json.loads(r.content)
+        print json.dumps(j_r, ensure_ascii=False)
+        self.assertEqual('200', j_r['state']['code'])
+
+    # def test_73_delete_boot_jobs_id(self):
+    #     TestGuest.uuid = 'ba38a067-83cb-49e8-bfc1-7dce7d5e34e6'
+    #     url = TestGuest.base_url + '/guest/_boot_jobs/' + TestGuest.uuid + '/' + '1,2,3'
+    #     headers = {'content-type': 'application/json'}
+    #     r = requests.delete(url, headers=headers)
+    #     j_r = json.loads(r.content)
+    #     print json.dumps(j_r, ensure_ascii=False)
+    #     self.assertEqual('200', j_r['state']['code'])
+    #
+    # def test_74_delete_boot_jobs_id(self):
+    #     TestGuest.uuid = 'ba38a067-83cb-49e8-bfc1-7dce7d5e34e6'
+    #     url = TestGuest.base_url + '/guest/_boot_jobs/' + TestGuest.uuid + '/' + '4'
+    #     headers = {'content-type': 'application/json'}
+    #     r = requests.delete(url, headers=headers)
+    #     j_r = json.loads(r.content)
+    #     print json.dumps(j_r, ensure_ascii=False)
+    #     self.assertEqual('200', j_r['state']['code'])
 
 if __name__ == '__main__':
     unittest.main()