~openstack-gd/nova/nova-avail-zones

« back to all changes in this revision

Viewing changes to nova/cloudpipe/pipelib.py

  • Committer: Tarmac
  • Author(s): Vishvananda Ishaya
  • Date: 2010-12-22 18:24:00 UTC
  • mfrom: (396.6.14 project-vpns)
  • Revision ID: tarmac-20101222182400-vh0j8lwp72auht1r
Fixes per-project vpns (cloudpipe) and adds manage commands and support for certificate revocation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
"""
24
24
 
25
 
import base64
26
25
import logging
27
26
import os
 
27
import string
28
28
import tempfile
29
29
import zipfile
30
30
 
31
31
from nova import context
 
32
from nova import crypto
 
33
from nova import db
32
34
from nova import exception
33
35
from nova import flags
34
36
from nova import utils
39
41
 
40
42
FLAGS = flags.FLAGS
41
43
flags.DEFINE_string('boot_script_template',
42
 
                    utils.abspath('cloudpipe/bootscript.sh'),
43
 
                    'Template for script to run on cloudpipe instance boot')
 
44
                    utils.abspath('cloudpipe/bootscript.template'),
 
45
                    _('Template for script to run on cloudpipe instance boot'))
 
46
flags.DEFINE_string('dmz_net',
 
47
                    '10.0.0.0',
 
48
                    _('Network to push into openvpn config'))
 
49
flags.DEFINE_string('dmz_mask',
 
50
                    '255.255.255.0',
 
51
                    _('Netmask to push into openvpn config'))
 
52
 
 
53
 
 
54
LOG = logging.getLogger('nova-cloudpipe')
44
55
 
45
56
 
46
57
class CloudPipe(object):
48
59
        self.controller = cloud.CloudController()
49
60
        self.manager = manager.AuthManager()
50
61
 
51
 
    def launch_vpn_instance(self, project_id):
52
 
        logging.debug(_("Launching VPN for %s") % (project_id))
53
 
        project = self.manager.get_project(project_id)
 
62
    def get_encoded_zip(self, project_id):
54
63
        # Make a payload.zip
55
64
        tmpfolder = tempfile.mkdtemp()
56
65
        filename = "payload.zip"
57
66
        zippath = os.path.join(tmpfolder, filename)
58
67
        z = zipfile.ZipFile(zippath, "w", zipfile.ZIP_DEFLATED)
59
 
 
60
 
        z.write(FLAGS.boot_script_template, 'autorun.sh')
 
68
        shellfile = open(FLAGS.boot_script_template, "r")
 
69
        s = string.Template(shellfile.read())
 
70
        shellfile.close()
 
71
        boot_script = s.substitute(cc_dmz=FLAGS.cc_dmz,
 
72
                                   cc_port=FLAGS.cc_port,
 
73
                                   dmz_net=FLAGS.dmz_net,
 
74
                                   dmz_mask=FLAGS.dmz_mask,
 
75
                                   num_vpn=FLAGS.cnt_vpn_clients)
 
76
        # genvpn, sign csr
 
77
        crypto.generate_vpn_files(project_id)
 
78
        z.writestr('autorun.sh', boot_script)
 
79
        crl = os.path.join(crypto.ca_folder(project_id), 'crl.pem')
 
80
        z.write(crl, 'crl.pem')
 
81
        server_key = os.path.join(crypto.ca_folder(project_id), 'server.key')
 
82
        z.write(server_key, 'server.key')
 
83
        ca_crt = os.path.join(crypto.ca_path(project_id))
 
84
        z.write(ca_crt, 'ca.crt')
 
85
        server_crt = os.path.join(crypto.ca_folder(project_id), 'server.crt')
 
86
        z.write(server_crt, 'server.crt')
61
87
        z.close()
62
 
 
63
 
        key_name = self.setup_key_pair(project.project_manager_id, project_id)
64
88
        zippy = open(zippath, "r")
65
 
        context = context.RequestContext(user=project.project_manager,
66
 
                                         project=project)
67
 
 
68
 
        reservation = self.controller.run_instances(context,
69
 
            # Run instances expects encoded userdata, it is decoded in the
70
 
            # get_metadata_call. autorun.sh also decodes the zip file, hence
71
 
            # the double encoding.
72
 
            user_data=zippy.read().encode("base64").encode("base64"),
 
89
        # NOTE(vish): run instances expects encoded userdata, it is decoded
 
90
        # in the get_metadata_call. autorun.sh also decodes the zip file,
 
91
        # hence the double encoding.
 
92
        encoded = zippy.read().encode("base64").encode("base64")
 
93
        zippy.close()
 
94
        return encoded
 
95
 
 
96
    def launch_vpn_instance(self, project_id):
 
97
        LOG.debug(_("Launching VPN for %s") % (project_id))
 
98
        project = self.manager.get_project(project_id)
 
99
        ctxt = context.RequestContext(user=project.project_manager,
 
100
                                      project=project)
 
101
        key_name = self.setup_key_pair(ctxt)
 
102
        group_name = self.setup_security_group(ctxt)
 
103
 
 
104
        reservation = self.controller.run_instances(ctxt,
 
105
            user_data=self.get_encoded_zip(project_id),
73
106
            max_count=1,
74
107
            min_count=1,
75
108
            instance_type='m1.tiny',
76
109
            image_id=FLAGS.vpn_image_id,
77
110
            key_name=key_name,
78
 
            security_groups=["vpn-secgroup"])
79
 
        zippy.close()
80
 
 
81
 
    def setup_key_pair(self, user_id, project_id):
82
 
        key_name = '%s%s' % (project_id, FLAGS.vpn_key_suffix)
 
111
            security_group=[group_name])
 
112
 
 
113
    def setup_security_group(self, context):
 
114
        group_name = '%s%s' % (context.project.id, FLAGS.vpn_key_suffix)
 
115
        if db.security_group_exists(context, context.project.id, group_name):
 
116
            return group_name
 
117
        group = {'user_id': context.user.id,
 
118
                 'project_id': context.project.id,
 
119
                 'name': group_name,
 
120
                 'description': 'Group for vpn'}
 
121
        group_ref = db.security_group_create(context, group)
 
122
        rule = {'parent_group_id': group_ref['id'],
 
123
                'cidr': '0.0.0.0/0',
 
124
                'protocol': 'udp',
 
125
                'from_port': 1194,
 
126
                'to_port': 1194}
 
127
        db.security_group_rule_create(context, rule)
 
128
        rule = {'parent_group_id': group_ref['id'],
 
129
                'cidr': '0.0.0.0/0',
 
130
                'protocol': 'icmp',
 
131
                'from_port': -1,
 
132
                'to_port': -1}
 
133
        db.security_group_rule_create(context, rule)
 
134
        # NOTE(vish): No need to trigger the group since the instance
 
135
        #             has not been run yet.
 
136
        return group_name
 
137
 
 
138
    def setup_key_pair(self, context):
 
139
        key_name = '%s%s' % (context.project.id, FLAGS.vpn_key_suffix)
83
140
        try:
84
 
            private_key, fingerprint = self.manager.generate_key_pair(user_id,
85
 
                                                                      key_name)
 
141
            result = cloud._gen_key(context, context.user.id, key_name)
 
142
            private_key = result['private_key']
86
143
            try:
87
 
                key_dir = os.path.join(FLAGS.keys_path, user_id)
 
144
                key_dir = os.path.join(FLAGS.keys_path, context.user.id)
88
145
                if not os.path.exists(key_dir):
89
146
                    os.makedirs(key_dir)
90
 
                file_name = os.path.join(key_dir, '%s.pem' % key_name)
91
 
                with open(file_name, 'w') as f:
 
147
                key_path = os.path.join(key_dir, '%s.pem' % key_name)
 
148
                with open(key_path, 'w') as f:
92
149
                    f.write(private_key)
93
150
            except:
94
151
                pass
95
152
        except exception.Duplicate:
96
153
            pass
97
154
        return key_name
98
 
 
99
 
    # def setup_secgroups(self, username):
100
 
    #     conn = self.euca.connection_for(username)
101
 
    #     try:
102
 
    #         secgroup = conn.create_security_group("vpn-secgroup",
103
 
    #                                               "vpn-secgroup")
104
 
    #         secgroup.authorize(ip_protocol = "udp", from_port = "1194",
105
 
    #                            to_port = "1194", cidr_ip = "0.0.0.0/0")
106
 
    #         secgroup.authorize(ip_protocol = "tcp", from_port = "80",
107
 
    #                            to_port = "80", cidr_ip = "0.0.0.0/0")
108
 
    #         secgroup.authorize(ip_protocol = "tcp", from_port = "22",
109
 
    #                            to_port = "22", cidr_ip = "0.0.0.0/0")
110
 
    #     except:
111
 
    #         pass