· 7 years ago · Nov 30, 2018, 07:32 PM
1import MySQLdb
2import os
3import sys
4from sqlalchemy import create_engine, MetaData
5from sqlalchemy.sql import text
6from sqlalchemy.orm import scoped_session, sessionmaker
7from sqlalchemy import Column, String, Integer, Date, Table, ForeignKey, Float
8from sqlalchemy.orm import relationship
9from sqlalchemy.ext.declarative import declarative_base
10from urllib import quote_plus as urlquote
11from multiprocessing.dummy import Pool as ThreadPool
12import json
13import urllib
14import smtplib
15from email.mime.text import MIMEText
16import requests
17import paramiko
18import time
19from config import *
20import boto3
21from models import Subscription, Server
22
23# Set PID file, this prevents the script from running if already running
24pid = str(os.getpid())
25pidfile = "/tmp/main-py.pid"
26if os.path.isfile(pidfile):
27 print "%s already exists, exiting" % pidfile
28 sys.exit()
29file(pidfile, 'w').write(pid)
30
31# Setup SQLAlchemy
32engine = create_engine('mysql://ghostifidbuser:%s@localhost:3306/ghostifi' % urlquote(DB_PASSWORD), echo=False)
33metadata = MetaData(bind=engine)
34Session = scoped_session(sessionmaker(engine, autoflush=True))
35session = Session()
36Base = declarative_base()
37Base.metadata.create_all(engine)
38
39try:
40 # Create lists which will be populated by SQL queries
41 servers_to_create = []
42 servers_to_destroy = []
43
44 # Get all active subscriptions, joined to servers
45 active_subscriptions = session.query(Subscription, Server).outerjoin(Server, Subscription.id == Server.wp_edd_sub_id).filter(Subscription.status=="Active").all()
46
47 # Find active subscriptions which do not have existing servers (create these)
48 for subscription in active_subscriptions:
49 # If subscription exists for this server, skip, else append to the server create list
50 if subscription[1]:
51 pass
52 else:
53 servers_to_create.append(subscription[0])
54
55 # Get all existing servers, joined to subscriptions
56 active_servers = session.query(Server, Subscription).outerjoin(Subscription, Subscription.id == Server.wp_edd_sub_id).all()
57
58 # Find existing servers which do not have active subscriptions (destroy these)
59 for server in active_servers:
60 # If subscription exists for this server, skip, else append to the server destroy list
61 if server[1]:
62 pass
63 else:
64 servers_to_destroy.append(server[0])
65
66 # Get servers marked for delete
67 delete_request_servers = session.query(Server, Subscription).outerjoin(Subscription, Subscription.id == Server.wp_edd_sub_id).filter(Server.delete_request == 1).all()
68
69 for server in delete_request_servers:
70 servers_to_destroy.append(server[0])
71
72 # Get all servers which need to be rebuilt now (rebuild these)
73 servers_to_rebuild_now = session.query(Server).filter(Server.rebuild_now_status==1).all()
74
75 # Make the Pool of workers
76 pool = ThreadPool(4)
77
78 def thread_servers_to_create(self):
79 # Setup SQLAlchemy
80 session = Session()
81 # If product is The VPS VPN Monthly or Yearly, set the VPS plan_id to 201 (25GB SSD/1GB RAM)
82 if self.product_id == 5747 or self.product_id == 5745:
83 vps_plan_id = '201'
84 bandwidth_limit_this_month = 1000.00
85
86 # Get username, email out of wp_users table. Using a raw query because this is a one-off
87 sql = text('Select wp_users.user_login, wp_users.user_email from wp_edd_subscriptions left join wp_edd_customers on wp_edd_subscriptions.customer_id = wp_edd_customers.id left join wp_users on wp_edd_customers.user_id = wp_users.id where wp_edd_subscriptions.id = :id')
88 query = session.execute(sql, {'id': self.id}).fetchone()
89 username = query[0]
90 email = query[1]
91 # Create a new server object
92 new_server = Server(self.customer_id, self.product_id, self.id, '0.0.0.0', '', email, '', '', 'Installing', bandwidth_limit_this_month, vps_plan_id, username, '')
93 # Save to database
94 session.add(new_server)
95 session.commit()
96 new_server.create()
97 session.commit()
98 # Close session
99 session.close()
100
101 def thread_servers_to_destroy(self):
102 # Change status to Rebuilding to display this in the user dashboard
103 self.status = 'Destroying'
104 session.add(self)
105 # Update database set status from Running to Rebuilding
106 session.commit()
107 # Run rebuild function
108 self.destroy()
109 # Commit changes - update status, rebuild_location, bandwidth_this_month etc
110 session.delete(self)
111 session.commit()
112
113 def thread_servers_to_rebuild_now(self):
114 # Change status to Rebuilding to display this in the user dashboard
115 self.status = 'Rebuilding'
116 self.rebuild_now_status = 0
117 session.add(self)
118 # Update database set status from Running to Rebuilding
119 session.commit()
120 # Run rebuild function
121 self.rebuild('rebuild_now')
122 # Commit changes - update status, rebuild_location, bandwidth_this_month etc
123 session.add(self)
124 session.commit()
125
126 # Start a thread for each servers_to_create
127 results = pool.map(thread_servers_to_create, servers_to_create)
128
129 # Start a thread for each servers_to_destroy
130 results = pool.map(thread_servers_to_destroy, servers_to_destroy)
131
132 # Start a thread for each servers_to_rebuild_now
133 results = pool.map(thread_servers_to_rebuild_now, servers_to_rebuild_now)
134
135 # close the pool and wait for the work to finish
136 pool.close()
137 pool.join()
138 session.close()
139
140finally:
141 os.unlink(pidfile)