Parcourir la source

实现创建虚拟机时,注入ssh-key功能

James Iter il y a 8 ans
Parent
commit
fcfe6513fb
6 fichiers modifiés avec 89 ajouts et 3 suppressions
  1. 40 3
      api/guest.py
  2. 6 0
      misc/init.sql
  3. 6 0
      misc/v0.2_to_v0.3/update.sql
  4. 1 0
      models/rules.py
  5. 34 0
      templates/guest_create.html
  6. 2 0
      views/guest.py

+ 40 - 3
api/guest.py

@@ -64,7 +64,12 @@ def r_create():
 
     if 'node_id' in request.json:
         args_rules.append(
-            Rules.NODE_ID.value,
+            Rules.NODE_ID.value
+        )
+
+    if 'ssh_keys_id' in request.json:
+        args_rules.append(
+            Rules.SSH_KEYS_ID.value
         )
 
     try:
@@ -116,6 +121,17 @@ def r_create():
             ret['state'] = ji.Common.exchange_state(50351)
             return ret
 
+        ssh_keys_id = request.json.get('ssh_keys_id', list())
+        ssh_keys = list()
+        ssh_key_guest_mapping = SSHKeyGuestMapping()
+
+        if ssh_keys_id.__len__() > 0:
+            rows, _ = SSHKey.get_by_filter(
+                filter_str=':'.join(['id', 'in', ','.join(_id.__str__() for _id in ssh_keys_id)]))
+
+            for row in rows:
+                ssh_keys.append(row['public_key'])
+
         quantity = request.json.get('quantity')
 
         while quantity:
@@ -170,6 +186,13 @@ def r_create():
             guest.node_id = int(guest.node_id)
             guest.create()
 
+            ssh_key_guest_mapping.guest_uuid = guest.uuid
+
+            if ssh_keys_id.__len__() > 0:
+                for ssh_key_id in ssh_keys_id:
+                    ssh_key_guest_mapping.ssh_key_id = ssh_key_id
+                    ssh_key_guest_mapping.create()
+
             # 替换占位符为有效内容
             _os_template_initialize_operates = copy.deepcopy(os_template_initialize_operates)
             for k, v in enumerate(_os_template_initialize_operates):
@@ -179,7 +202,8 @@ def r_create():
                     replace('{NETMASK}', config.netmask).\
                     replace('{GATEWAY}', config.gateway).\
                     replace('{DNS1}', config.dns1).\
-                    replace('{DNS2}', config.dns2)
+                    replace('{DNS2}', config.dns2). \
+                    replace('{SSH-KEY}', '\n'.join(ssh_keys))
 
                 _os_template_initialize_operates[k]['command'] = v['command'].replace('{IP}', guest.ip). \
                     replace('{HOSTNAME}', guest.label). \
@@ -187,7 +211,8 @@ def r_create():
                     replace('{NETMASK}', config.netmask). \
                     replace('{GATEWAY}', config.gateway). \
                     replace('{DNS1}', config.dns1). \
-                    replace('{DNS2}', config.dns2)
+                    replace('{DNS2}', config.dns2). \
+                    replace('{SSH-KEY}', '\n'.join(ssh_keys))
 
             message = {
                 '_object': 'guest',
@@ -746,6 +771,10 @@ def r_get(uuids):
 
         if ret['data']['uuid'] in guest_uuid_ssh_key_id_mapping:
             for ssh_key_id in guest_uuid_ssh_key_id_mapping[ret['data']['uuid']]:
+
+                if ssh_key_id not in ssh_key_id_mapping:
+                    continue
+
                 ret['data']['ssh_keys'].append(ssh_key_id_mapping[ssh_key_id])
 
     else:
@@ -755,6 +784,10 @@ def r_get(uuids):
 
             if ret['data'][i]['uuid'] in guest_uuid_ssh_key_id_mapping:
                 for ssh_key_id in guest_uuid_ssh_key_id_mapping[ret['data'][i]['uuid']]:
+
+                    if ssh_key_id not in ssh_key_id_mapping:
+                        continue
+
                     ret['data'][i]['ssh_keys'].append(ssh_key_id_mapping[ssh_key_id])
 
     return ret
@@ -796,6 +829,10 @@ def r_get_by_filter():
 
         if ret['data'][i]['uuid'] in guest_uuid_ssh_key_id_mapping:
             for ssh_key_id in guest_uuid_ssh_key_id_mapping[ret['data'][i]['uuid']]:
+
+                if ssh_key_id not in ssh_key_id_mapping:
+                    continue
+
                 ret['data'][i]['ssh_keys'].append(ssh_key_id_mapping[ssh_key_id])
 
     return ret

+ 6 - 0
misc/init.sql

@@ -402,6 +402,8 @@ IPV6INIT=no
 NAME=eth0', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (1, 1, 2, '/etc/hostname', '{HOSTNAME}', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (1, 0, 3, '', '', 'echo "root:{PASSWORD}" | chpasswd');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (1, 0, 4, '', '', 'mkdir -p /root/.ssh');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (1, 1, 5, '/root/.ssh/authorized_keys', '{SSH-KEY}', '');
 
 -- For CentOS-SysV
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 1, 0, '/etc/resolv.conf', 'nameserver {DNS1}
@@ -418,6 +420,8 @@ NAME=eth0', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 1, 2, '/etc/sysconfig/network', 'NETWORKING=yes
 HOSTNAME="{HOSTNAME}"', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 0, 3, '', '', 'echo "root:{PASSWORD}" | chpasswd');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 0, 4, '', '', 'mkdir -p /root/.ssh');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 1, 5, '/root/.ssh/authorized_keys', '{SSH-KEY}', '');
 
 -- For Gentoo-OpenRC
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 1, 0, '/etc/resolv.conf', 'nameserver {DNS1}
@@ -426,6 +430,8 @@ INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_i
 routes_eth0="default via {GATEWAY}"', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 1, 2, '/etc/conf.d/hostname', 'hostname="{HOSTNAME}"', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 0, 3, '', '', 'echo "root:{PASSWORD}" | chpasswd');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 0, 4, '', '', 'mkdir -p /root/.ssh');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 1, 5, '/root/.ssh/authorized_keys', '{SSH-KEY}', '');
 
 -- For Windows
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (4, 1, 0, '/Windows/jimv_init.bat', 'netsh interface ip set address name="Ethernet" source=static {IP} {NETMASK} {GATEWAY}

+ 6 - 0
misc/v0.2_to_v0.3/update.sql

@@ -115,6 +115,8 @@ IPV6INIT=no
 NAME=eth0', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (1, 1, 2, '/etc/hostname', '{HOSTNAME}', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (1, 0, 3, '', '', 'echo "root:{PASSWORD}" | chpasswd');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (1, 0, 4, '', '', 'mkdir -p /root/.ssh');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (1, 1, 5, '/root/.ssh/authorized_keys', '{SSH-KEY}', '');
 
 -- For CentOS-SysV
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 1, 0, '/etc/resolv.conf', 'nameserver {DNS1}
@@ -131,6 +133,8 @@ NAME=eth0', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 1, 2, '/etc/sysconfig/network', 'NETWORKING=yes
 HOSTNAME="{HOSTNAME}"', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 0, 3, '', '', 'echo "root:{PASSWORD}" | chpasswd');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 0, 4, '', '', 'mkdir -p /root/.ssh');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (2, 1, 5, '/root/.ssh/authorized_keys', '{SSH-KEY}', '');
 
 -- For Gentoo-OpenRC
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 1, 0, '/etc/resolv.conf', 'nameserver {DNS1}
@@ -139,6 +143,8 @@ INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_i
 routes_eth0="default via {GATEWAY}"', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 1, 2, '/etc/conf.d/hostname', 'hostname="{HOSTNAME}"', '');
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 0, 3, '', '', 'echo "root:{PASSWORD}" | chpasswd');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 0, 4, '', '', 'mkdir -p /root/.ssh');
+INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (3, 1, 5, '/root/.ssh/authorized_keys', '{SSH-KEY}', '');
 
 -- For Windows
 INSERT INTO os_template_initialize_operate (os_template_initialize_operate_set_id, kind, sequence, path, content, command) VALUES (4, 1, 0, '/Windows/jimv_init.bat', 'netsh interface ip set address name="Ethernet" source=static {IP} {NETMASK} {GATEWAY}

+ 1 - 0
models/rules.py

@@ -57,6 +57,7 @@ class Rules(Enum):
     BPS_MAX_LENGTH = (int, 'iops_max_length')
 
     SSH_KEY_ID_EXT = (REG_NUMBER, 'ssh_key_id')
+    SSH_KEYS_ID = (list, 'ssh_keys_id')
     PUBLIC_KEY = (basestring, 'public_key')
 
     UUID = (basestring, 'uuid', (36, 36))

+ 34 - 0
templates/guest_create.html

@@ -107,6 +107,7 @@
         });
 
         refresh_os_template_image_id_selectpicker($('#os_template_image_id'));
+        refresh_ssh_keys_checkboxer($('#ssh_keys_id_div'));
     });
 
     function get_os_templates_profile_mapping_by_id() {
@@ -154,6 +155,26 @@
             }
         });
     }
+    
+    function refresh_ssh_keys_checkboxer(checkboxer) {
+        $.ajax({
+            url : '/api/ssh_keys',
+            type : 'GET',
+            contentType: "application/json; charset=utf-8",
+            dataType: 'json',
+            async: false,
+            error : function() {
+            },
+            success : function(data, textStatus, xhr) {
+                checkboxer.empty();
+                $.each(data.data, function(k, v) {
+                    checkboxer.append(
+                        '<label class="checkbox-inline"><input type="checkbox" name="ssh_keys_id" value="' + v['id'] + '">' + v['label'] + '</label>'
+                    );
+                });
+            }
+        });
+    }
 
     $(function() { "use strict";
         $("#quantity").TouchSpin({
@@ -284,6 +305,19 @@
                             </div>
                         </div>
                     </div>
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label"><span class="glyph-icon icon-key"></span>&nbsp;&nbsp;SSH-KEY</label>
+                        <div class="col-sm-6" id="ssh_keys_id_div">
+                            <label class="checkbox-inline">
+                                <input type="checkbox" name="ssh_keys_id" value="option1">
+                                Checkbox 1
+                            </label>
+                            <label class="checkbox-inline">
+                                <input type="checkbox" name="ssh_keys_id" value="option2">
+                                Checkbox 2
+                            </label>
+                        </div>
+                    </div>
                     <div class="form-group">
                         <label class="col-sm-2 control-label"><span class="glyph-icon icon-elusive-shuffle"></span>&nbsp;&nbsp;创建模式</label>
                         <div class="col-sm-6">

+ 2 - 0
views/guest.py

@@ -128,6 +128,7 @@ def create():
         remark = request.form.get('remark')
         allocation_by_random = 'allocation_by_random' in request.form
         node_id = request.form.get('node_id')
+        ssh_keys_id = request.form.getlist('ssh_keys_id')
 
         if not isinstance(ability, basestring):
             pass
@@ -146,6 +147,7 @@ def create():
             "quantity": int(quantity),
             "remark": remark,
             "password": password,
+            "ssh_keys_id": ssh_keys_id,
             "lease_term": 100
         }