Kaynağa Gözat

实现 ip 池模型

James Iter 7 yıl önce
ebeveyn
işleme
6704976e4d
5 değiştirilmiş dosya ile 142 ekleme ve 1 silme
  1. BIN
      .DS_Store
  2. 1 1
      .gitignore
  3. 9 0
      jimvc/api/ip_pool.py
  4. 114 0
      jimvc/models/ip_pool.py
  5. 18 0
      misc/init.sql

BIN
.DS_Store


+ 1 - 1
.gitignore

@@ -60,4 +60,4 @@ target/
 .DS_Store
 
 # Windows venv
-venv/
+venv/

+ 9 - 0
jimvc/api/ip_pool.py

@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+__author__ = 'James Iter'
+__date__ = '2018-12-15'
+__contact__ = 'james.iter.cn@gmail.com'
+__copyright__ = '(c) 2018 by James Iter.'
+

+ 114 - 0
jimvc/models/ip_pool.py

@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+import json
+import jimit as ji
+from IPy import IP, intToIp
+
+from jimvc.models import FilterFieldType
+from jimvc.models import ORM
+
+
+__author__ = 'James Iter'
+__date__ = '2018-12-15'
+__contact__ = 'james.iter.cn@gmail.com'
+__copyright__ = '(c) 2018 by James Iter.'
+
+
+class IPPool(ORM):
+
+    _table_name = 'ip_pool'
+    _primary_key = 'id'
+
+    def __init__(self):
+        super(IPPool, self).__init__()
+        self.id = 0
+        self.start_ip = ''
+        self.end_ip = ''
+        self.netmask = ''
+        self.gateway = ''
+        self.dns1 = ''
+        self.dns2 = ''
+        self.name = ''
+        self.description = ''
+        self.create_time = ji.Common.tus()
+
+    @staticmethod
+    def get_filter_keywords():
+        return {
+            'remark': FilterFieldType.STR.value
+        }
+
+    @staticmethod
+    def get_allow_update_keywords():
+        return []
+
+    @staticmethod
+    def get_allow_content_search_keywords():
+        return ['name']
+
+    def ip_generator(self, occupied_ips=None):
+        """
+        # 可用 IP 生成器
+        :param occupied_ips: 已分配的虚拟机 IP 列表
+        :return: 返回一个可分配的 IP 地址,格式如 '192.168.1.1'
+        """
+
+        assert isinstance(occupied_ips, list)
+
+        occupied_ips_dec = list()
+
+        for occupied_ip in occupied_ips:
+            occupied_ips_dec.append(int(IP(occupied_ip).strDec()))
+
+        for ip_dec in range(int(IP(self.start_ip).strDec()), int(IP(self.end_ip).strDec()) + 1):
+            if ip_dec in occupied_ips_dec:
+                continue
+
+            yield intToIp(ip_dec, 4)
+
+    @staticmethod
+    def vnc_port_generator(occupied_vnc_ports=None):
+        assert isinstance(occupied_vnc_ports, list)
+
+        for vnc_port in range(15900, 20000):
+            if vnc_port in occupied_vnc_ports:
+                continue
+
+            yield vnc_port
+
+    def check_ip(self):
+        network_segment = IP(self.start_ip + '/' + self.netmask, make_net=True)
+
+        ret = dict()
+        # 起止IP必须在同一个网段中
+        if IP(self.end_ip) not in network_segment:
+            ret['state'] = ji.Common.exchange_state(41251)
+            raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
+
+        # 网关必须与将分配给Guest的IP,处于同一个网段中
+        if IP(self.gateway) not in network_segment:
+            ret['state'] = ji.Common.exchange_state(41252)
+            raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
+
+        # 网关不能是网络地址或广播地址
+        if IP(self.gateway) in [network_segment[i] for i in (0, -1)]:
+            ret['state'] = ji.Common.exchange_state(41253)
+            raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
+
+        # 当用户输入的起始IP为网络地址时,自动重置其为该网段中第一个可用IP
+        if self.start_ip == network_segment[0].__str__():
+            self.start_ip = intToIp((int(IP(self.start_ip).strDec()) + 1).__str__(), 4)
+
+        # 当用户输入的结束IP为广播地址时,自动重置其为该网段中最后一个可用IP
+        if self.end_ip == network_segment[-1].__str__():
+            self.end_ip = intToIp((int(IP(self.end_ip).strDec()) - 1).__str__(), 4)
+
+        # 起始的可用IP地址必须小于结束的可用IP地址
+        if IP(self.start_ip) >= IP(self.end_ip):
+            ret['state'] = ji.Common.exchange_state(41254)
+            raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
+
+        return True
+

+ 18 - 0
misc/init.sql

@@ -448,6 +448,24 @@ ALTER TABLE service ADD INDEX (project_id);
 ALTER TABLE service ADD INDEX (name);
 
 
+CREATE TABLE IF NOT EXISTS ip_pool(
+    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
+    start_ip CHAR(15) NOT NULL,
+    end_ip CHAR(15) NOT NULL,
+    netmask CHAR(15) NOT NULL,
+    gateway CHAR(15) NOT NULL,
+    dns1 CHAR(15) NOT NULL DEFAULT '223.5.5.5',
+    dns2 CHAR(15) NOT NULL DEFAULT '8.8.8.8',
+    name VARCHAR(127) NOT NULL,
+    description TEXT,
+    create_time BIGINT UNSIGNED NOT NULL,
+    PRIMARY KEY (id))
+    ENGINE=Innodb
+    DEFAULT CHARSET=utf8;
+
+ALTER TABLE ip_pools ADD INDEX (name);
+
+
 INSERT INTO project (name, description, create_time) VALUES ('我的项目', '由 JimV 创建的默认项目。', UNIX_TIMESTAMP(NOW()) * 1000000);
 INSERT INTO service (project_id, name, description, create_time) VALUES (1, '服务组', '由 JimV 创建的默认服务组。', UNIX_TIMESTAMP(NOW()) * 1000000);