def create_appscale_user(password, uaserver): """ Creates the user account with the email address and password provided. """ does_user_exist = uaserver.does_user_exist(hermes_constants.USER_EMAIL, appscale_info.get_secret()) if does_user_exist == "true": logging.debug("User {0} already exists, so not creating it again.". format(hermes_constants.USER_EMAIL)) return True else: if uaserver.commit_new_user(hermes_constants.USER_EMAIL, password, hermes_constants.ACCOUNT_TYPE, appscale_info.get_secret()) == "true": return True else: logging.error("Error while creating an Appscale user.") return False
def get_all_stats(): """ Collects platform stats from all deployment nodes. Returns: A dictionary containing all the monitoring stats, if all nodes are accessible. {"success": False, "error": message} otherwise. """ all_stats = {} secret = appscale_info.get_secret() logging.debug("Retrieved deployment secret: {}".format(secret)) for ip in appscale_info.get_all_ips(): appcontroller_endpoint = "https://{}:{}".format(ip, hermes_constants.APPCONTROLLER_PORT) logging.debug("Connecting to AC at: {}".format(appcontroller_endpoint)) # Do a SOAP call to the AppController on that IP to get stats. server = SOAPpy.SOAPProxy(appcontroller_endpoint) try: all_stats[ip] = json.loads(server.get_all_stats(secret)) except SOAPpy.SOAPException as soap_exception: logging.exception("Exception while performing SOAP call to " "{}".format(appcontroller_endpoint)) logging.exception(soap_exception) all_stats[ip] = {JSONTags.ERROR: JSONTags.UNREACHABLE} except socket_error as serr: logging.error("Socket error while performing SOAP call to " "{}".format(appcontroller_endpoint)) logging.error(serr) all_stats[ip] = {JSONTags.ERROR: JSONTags.UNREACHABLE} return all_stats
def create_java_start_cmd(app_name, port, load_balancer_host): """ Creates the start command to run the java application server. Args: app_name: The name of the application to run port: The local port the application server will bind to load_balancer_host: The host of the load balancer Returns: A string of the start command. """ db_location = DATASTORE_PATH # The Java AppServer needs the NGINX_PORT flag set so that it will read the # local FS and see what port it's running on. The value doesn't matter. cmd = ["cd " + constants.JAVA_APPSERVER + " &&", "./genKeystore.sh &&", "./appengine-java-sdk-repacked/bin/dev_appserver.sh", "--port=" + str(port), #this jvm flag allows javax.email to connect to the smtp server "--jvm_flag=-Dsocket.permit_connect=true", "--disable_update_check", "--cookie_secret=" + appscale_info.get_secret(), "--address=" + appscale_info.get_private_ip(), "--datastore_path=" + db_location, "--login_server=" + load_balancer_host, "--appscale_version=1", "--APP_NAME=" + app_name, "--NGINX_ADDRESS=" + load_balancer_host, "--NGINX_PORT=anything", os.path.dirname(locate_dir("/var/apps/" + app_name +"/app/", \ "WEB-INF")) ] return ' '.join(cmd)
def get_task_headers(self, request): """ Gets the task headers used for a task web request. Args: request: A taskqueue_service_pb.TaskQueueAddRequest Returns: A dictionary of key/values for a web request. """ headers = {} for header in request.header_list(): headers[header.key()] = header.value() eta = self.__when_to_run(request) # This header is how we authenticate that it's an internal request secret = appscale_info.get_secret() secret_hash = hashlib.sha1(request.app_id() + '/' + \ secret).hexdigest() headers['X-AppEngine-Fake-Is-Admin'] = secret_hash #headers['X-AppEngine-Development-Payload'] = secret_hash headers['X-AppEngine-QueueName'] = request.queue_name() headers['X-AppEngine-TaskName'] = request.task_name() headers['X-AppEngine-TaskRetryCount'] = '0' headers['X-AppEngine-TaskExecutionCount'] = '0' headers['X-AppEngine-TaskETA'] = str(int(eta.strftime("%s"))) return headers
def create_java_start_cmd(app_name, port, load_balancer_host, load_balancer_port, db_locations): """ Creates the start command to run the java application server. Args: app_name: The name of the application to run port: The local port the application server will bind to load_balancer_host: The host of the load balancer load_balancer_port: The port of the load balancer xmpp_ip: The IP of the XMPP service Returns: A string of the start command. """ db_location = choose_db_location(db_locations) cmd = ["cd " + constants.JAVA_APPSERVER + " &&", "./genKeystore.sh &&", "./appengine-java-sdk-repacked/bin/dev_appserver.sh", "--port=" + str(port), "--cookie_secret=" + appscale_info.get_secret(), "--address=" + appscale_info.get_private_ip(), "--datastore_path=" + db_location, "--login_server=" + load_balancer_host, "--appscale_version=1", "--NGINX_ADDRESS=" + load_balancer_host, "--NGINX_PORT=" + str(load_balancer_port), "/var/apps/" + app_name +"/app/war/", ] return ' '.join(cmd)
def get_all_stats(): """ Collects platform stats from all deployment nodes. Returns: A dictionary containing all the monitoring stats, if all nodes are accessible. {"success": False, "error": message} otherwise. """ all_stats = {} secret = appscale_info.get_secret() logging.debug("Retrieved deployment secret: {}".format(secret)) for ip in appscale_info.get_all_ips(): appcontroller_endpoint = "https://{}:{}".format( ip, hermes_constants.APPCONTROLLER_PORT) logging.debug("Connecting to AC at: {}".format(appcontroller_endpoint)) # Do a SOAP call to the AppController on that IP to get stats. server = SOAPpy.SOAPProxy(appcontroller_endpoint) try: all_stats[ip] = server.get_all_stats(secret) except SOAPpy.SOAPException as soap_exception: logging.exception("Exception while performing SOAP call to " "{}".format(appcontroller_endpoint)) logging.exception(soap_exception) all_stats[ip] = {JSONTags.ERROR: JSONTags.UNREACHABLE} except socket_error as serr: logging.error("Socket error while performing SOAP call to " "{}".format(appcontroller_endpoint)) logging.error(serr) all_stats[ip] = {JSONTags.ERROR: JSONTags.UNREACHABLE} return all_stats
def deploy_apps(app_paths): """ Deploys all apps that reside in /opt/appscale/apps. Args: app_paths: A list of the full paths of the apps to be deployed. Returns: True on success, False otherwise. """ uaserver = SOAPpy.SOAPProxy('https://{0}:{1}'.format( appscale_info.get_db_master_ip(), UA_SERVER_PORT)) acc = AppControllerClient(appscale_info.get_login_ip(), appscale_info.get_secret()) # Wait for Cassandra to come up after a restore. time.sleep(15) for app_path in app_paths: # Extract app ID. app_id = app_path[app_path.rfind('/') + 1:app_path.find('.')] if not app_id: logging.error( "Malformed source code archive. Cannot complete " "application recovery for '{}'. Aborting...".format(app_path)) return False # Retrieve app admin via uaserver. app_data = uaserver.get_app_data(app_id, appscale_info.get_secret()) app_admin_re = re.search("\napp_owner:(.+)\n", app_data) if app_admin_re: app_admin = app_admin_re.group(1) else: logging.error( "Missing application data. Cannot complete application " "recovery for '{}'. Aborting...".format(app_id)) return False file_suffix = re.search("\.(.*)\Z", app_path).group(1) logging.warning( "Restoring app '{}', from '{}', with owner '{}'.".format( app_id, app_path, app_admin)) acc.upload_app(app_path, file_suffix, app_admin) return True
def deploy_apps(app_paths): """ Deploys all apps that reside in /opt/appscale/apps. Args: app_paths: A list of the full paths of the apps to be deployed. Returns: True on success, False otherwise. """ uaserver = SOAPpy.SOAPProxy('https://{0}:{1}'.format( appscale_info.get_db_master_ip(), UA_SERVER_PORT)) acc = AppControllerClient(appscale_info.get_login_ip(), appscale_info.get_secret()) # Wait for Cassandra to come up after a restore. time.sleep(15) for app_path in app_paths: # Extract app ID. app_id = app_path[app_path.rfind('/')+1:app_path.find('.')] if not app_id: logging.error("Malformed source code archive. Cannot complete " "application recovery for '{}'. Aborting...".format(app_path)) return False # Retrieve app admin via uaserver. app_data = uaserver.get_app_data(app_id, appscale_info.get_secret()) app_admin_re = re.search("\napp_owner:(.+)\n", app_data) if app_admin_re: app_admin = app_admin_re.group(1) else: logging.error("Missing application data. Cannot complete application " "recovery for '{}'. Aborting...".format(app_id)) return False file_suffix = re.search("\.(.*)\Z", app_path).group(1) logging.warning("Restoring app '{}', from '{}', with owner '{}'.". format(app_id, app_path, app_admin)) acc.upload_app(app_path, file_suffix, app_admin) return True
def does_user_exist(email, server): """ Checks to see if a user already exists. Args: email: A str, an email address to check. server: A SOAP server accessor. Returns: True if the user exists, False otherwise. """ secret = appscale_info.get_secret() return server.does_user_exist(email, secret) == "true"
def delete_user(server, email): """ Deletes a user. Args: server: A SOAP server accessor. email: A str, the user email. Returns: True on success, False otherwise. """ secret = appscale_info.get_secret() server.disable_user(email, secret) return server.delete_user(email, secret) == "true"
def create_xmpp_user(password, uaserver): """ Creates the XMPP account. If the user's email is [email protected], then that means their XMPP account name is a@login_ip. """ username_regex = re.compile('\A(.*)@') username = username_regex.match(hermes_constants.USER_EMAIL).groups()[0] xmpp_user = "******".format(username, appscale_info.get_login_ip()) xmpp_pass = appscale_utils.encrypt_password(xmpp_user, password) does_user_exist = uaserver.does_user_exist(xmpp_user, appscale_info.get_secret()) if does_user_exist == "true": logging.debug("XMPP User {0} already exists, so not creating it again.". format(xmpp_user)) return True else: if uaserver.commit_new_user(xmpp_user, xmpp_pass, hermes_constants.ACCOUNT_TYPE, appscale_info.get_secret()) == "true": logging.info("XMPP username is {0}".format(xmpp_user)) return True else: logging.error("Error while creating an XMPP user.") return False
def create_new_user(server, email, password): """ Creates a new user. Args: server: A SOAP server accessor. email: A str, the user email. password: A str, the user password. Returns: True on success, False otherwise. """ secret = appscale_info.get_secret() ret = server.commit_new_user(email, password, "user", secret) return not ret.startswith("Error:")
def create_python_start_cmd(app_name, login_ip, port, load_balancer_host, load_balancer_port, xmpp_ip, db_locations, py_version): """ Creates the start command to run the python application server. Args: app_name: The name of the application to run login_ip: The public IP port: The local port the application server will bind to load_balancer_host: The host of the load balancer load_balancer_port: The port of the load balancer xmpp_ip: The IP of the XMPP service py_version: The version of python to use Returns: A string of the start command. """ db_location = choose_db_location(db_locations) python = choose_python_executable(py_version) cmd = [python, constants.APPSCALE_HOME + "/AppServer/old_dev_appserver.py", "-p " + str(port), "--cookie_secret " + appscale_info.get_secret(), "--login_server " + login_ip, "--admin_console_server ''", "--enable_console", "--nginx_port " + str(load_balancer_port), "--nginx_host " + str(load_balancer_host), "--require_indexes", "--enable_sendmail", "--xmpp_path " + xmpp_ip, "--uaserver_path " + db_location + ":"\ + str(constants.UA_SERVER_PORT), "--datastore_path " + db_location + ":"\ + str(constants.DB_SERVER_PORT), "--history_path /var/apps/" + app_name\ + "/data/app.datastore.history", "/var/apps/" + app_name + "/app", "-a " + appscale_info.get_private_ip()] if app_name in TRUSTED_APPS: cmd.extend([TRUSTED_FLAG]) return ' '.join(cmd)
def create_python_start_cmd(app_name, login_ip, port, load_balancer_host, load_balancer_port, xmpp_ip, db_locations, py_version): """ Creates the start command to run the python application server. Args: app_name: The name of the application to run login_ip: The public IP port: The local port the application server will bind to load_balancer_host: The host of the load balancer load_balancer_port: The port of the load balancer xmpp_ip: The IP of the XMPP service py_version: The version of python to use Returns: A string of the start command. """ db_location = choose_db_location(db_locations) python = choose_python_executable(py_version) cmd = [python, constants.APPSCALE_HOME + "/AppServer/old_dev_appserver.py", "-p " + str(port), "--cookie_secret " + appscale_info.get_secret(), "--login_server " + login_ip, "--admin_console_server ''", "--enable_console", "--nginx_host " + str(load_balancer_host), "--require_indexes", "--enable_sendmail", "--xmpp_path " + xmpp_ip, "--uaserver_path " + db_location + ":"\ + str(constants.UA_SERVER_PORT), "--datastore_path " + db_location + ":"\ + str(constants.DB_SERVER_PORT), "--history_path /var/apps/" + app_name\ + "/data/app.datastore.history", "/var/apps/" + app_name + "/app", "-a " + appscale_info.get_private_ip()] if app_name in TRUSTED_APPS: cmd.extend([TRUSTED_FLAG]) return ' '.join(cmd)
def create_java_stop_cmd(port): """ This creates the stop command for an application which is uniquely identified by a port number. Additional portions of the start command are included to prevent the termination of other processes. Args: port: The port which the application server is running Returns: A string of the stop command. """ cmd = ["appengine-java-sdk-repacked/bin/dev_appserver.sh", "--port=" + str(port), "--address=" + appscale_info.get_private_ip(), "--cookie_secret=" + appscale_info.get_secret()] cmd = ' '.join(cmd) stop_cmd = "ps aux | grep '" + cmd + \ "' | grep -v grep | awk '{print $2'}' xargs -d '\n' kill -9" return stop_cmd
def main(): shutdown.install_signal_handlers() # The timezone must be set in the devappserver2 process rather than just in # the runtime so printed log timestamps are consistent and the taskqueue stub # expects the timezone to be UTC. The runtime inherits the environment. os.environ['TZ'] = 'UTC' if hasattr(time, 'tzset'): # time.tzet() should be called on Unix, but doesn't exist on Windows. time.tzset() options = PARSER.parse_args() os.environ['MY_IP_ADDRESS'] = options.host os.environ['MY_PORT'] = str(options.port) os.environ['COOKIE_SECRET'] = appscale_info.get_secret() os.environ['NGINX_HOST'] = options.nginx_host dev_server = DevelopmentServer() try: dev_server.start(options) shutdown.wait_until_shutdown() finally: dev_server.stop()
def deploy_sensor_app(): """ Uploads the sensor app for registered deployments. """ deployment_id = helper.get_deployment_id() #If deployment is not registered, then do nothing. if not deployment_id: return uaserver = SOAPpy.SOAPProxy('https://{0}:{1}'.format( appscale_info.get_db_master_ip(), hermes_constants.UA_SERVER_PORT)) # If the appscalesensor app is already running, then do nothing. is_app_enabled = uaserver.is_app_enabled(hermes_constants.APPSCALE_SENSOR, appscale_info.get_secret()) if is_app_enabled == "true": return pwd = appscale_utils.encrypt_password( hermes_constants.USER_EMAIL, appscale_utils.random_password_generator()) if create_appscale_user(pwd, uaserver) and create_xmpp_user(pwd, uaserver): logging.debug("Created new user and now tarring app to be deployed.") file_path = os.path.join(os.path.dirname(__file__), '../Apps/sensor') app_dir_location = os.path.join(hermes_constants.APP_DIR_LOCATION, hermes_constants.APPSCALE_SENSOR) archive = tarfile.open(app_dir_location, "w|gz") archive.add(file_path, arcname=hermes_constants.APPSCALE_SENSOR) archive.close() try: logging.info( "Deploying the sensor app for registered deployments.") acc = appscale_info.get_appcontroller_client() acc.upload_app(app_dir_location, hermes_constants.FILE_SUFFIX, hermes_constants.USER_EMAIL) except AppControllerException: logging.exception("AppControllerException while trying to deploy " "appscalesensor app.") else: logging.error("Error while creating or accessing the user to deploy " "appscalesensor app.")
def create_python_stop_cmd(port): """ This creates the stop command for an application which is uniquely identified by a port number. Additional portions of the start command are included to prevent the termination of other processes. Args: port: The port which the application server is running Returns: A string of the stop command. """ cmd = ["python2.5", constants.APPSCALE_HOME + "/AppServer/dev_appserver.py", "-p " + str(port), "--cookie_secret " + appscale_info.get_secret()] cmd = ' '.join(cmd) stop_cmd = "ps aux | grep '" + cmd +\ "' | grep -v grep | awk '{ print $2 }' | xargs -r kill -9" return stop_cmd
def create_python27_start_cmd(app_name, login_ip, port, load_balancer_host, xmpp_ip): """ Creates the start command to run the python application server. Args: app_name: The name of the application to run login_ip: The public IP port: The local port the application server will bind to load_balancer_host: The host of the load balancer xmpp_ip: The IP of the XMPP service Returns: A string of the start command. """ db_location = DATASTORE_PATH cmd = ["python", constants.APPSCALE_HOME + "/AppServer/dev_appserver.py", "--port " + str(port), "--admin_port " + str(port + 10000), "--cookie_secret " + appscale_info.get_secret(), "--login_server " + login_ip, "--skip_sdk_update_check", "--nginx_host " + str(load_balancer_host), "--require_indexes", "--enable_sendmail", "--xmpp_path " + xmpp_ip, "--php_executable_path=" + str(PHP_CGI_LOCATION), "--uaserver_path " + db_location + ":"\ + str(constants.UA_SERVER_PORT), "--datastore_path " + db_location + ":"\ + str(constants.DB_SERVER_PORT), "/var/apps/" + app_name + "/app", "--host " + appscale_info.get_private_ip()] if app_name in TRUSTED_APPS: cmd.extend([TRUSTED_FLAG]) return ' '.join(cmd)
def deploy_sensor_app(): """ Uploads the sensor app for registered deployments. """ deployment_id = helper.get_deployment_id() #If deployment is not registered, then do nothing. if not deployment_id: return uaserver = SOAPpy.SOAPProxy('https://{0}:{1}'.format( appscale_info.get_db_master_ip(), hermes_constants.UA_SERVER_PORT)) # If the appscalesensor app is already running, then do nothing. is_app_enabled = uaserver.is_app_enabled(hermes_constants.APPSCALE_SENSOR, appscale_info.get_secret()) if is_app_enabled == "true": return pwd = appscale_utils.encrypt_password(hermes_constants.USER_EMAIL, appscale_utils.random_password_generator()) if create_appscale_user(pwd, uaserver) and create_xmpp_user(pwd, uaserver): logging.debug("Created new user and now tarring app to be deployed.") file_path = os.path.join(os.path.dirname(__file__), '../Apps/sensor') app_dir_location = os.path.join(hermes_constants.APP_DIR_LOCATION, hermes_constants.APPSCALE_SENSOR) archive = tarfile.open(app_dir_location, "w|gz") archive.add(file_path, arcname= hermes_constants.APPSCALE_SENSOR) archive.close() try: logging.info("Deploying the sensor app for registered deployments.") acc = appscale_info.get_appcontroller_client() acc.upload_app(app_dir_location, hermes_constants.FILE_SUFFIX, hermes_constants.USER_EMAIL) except AppControllerException: logging.exception("AppControllerException while trying to deploy " "appscalesensor app.") else: logging.error("Error while creating or accessing the user to deploy " "appscalesensor app.")
def create_java_start_cmd(app_name, port, load_balancer_host, db_locations): """ Creates the start command to run the java application server. Args: app_name: The name of the application to run port: The local port the application server will bind to load_balancer_host: The host of the load balancer xmpp_ip: The IP of the XMPP service Returns: A string of the start command. """ db_location = choose_db_location(db_locations) # The Java AppServer needs the NGINX_PORT flag set so that it will read the # local FS and see what port it's running on. The value doesn't matter. cmd = ["cd " + constants.JAVA_APPSERVER + " &&", "./genKeystore.sh &&", "./appengine-java-sdk-repacked/bin/dev_appserver.sh", "--port=" + str(port), #this jvm flag allows javax.email to connect to the smtp server "--jvm_flag=-Dsocket.permit_connect=true", "--disable_update_check", "--cookie_secret=" + appscale_info.get_secret(), "--address=" + appscale_info.get_private_ip(), "--datastore_path=" + db_location, "--login_server=" + load_balancer_host, "--appscale_version=1", "--APP_NAME=" + app_name, "--NGINX_ADDRESS=" + load_balancer_host, "--NGINX_PORT=anything", "/var/apps/" + app_name +"/app/war/", ] return ' '.join(cmd)
def create_python_stop_cmd(port, py_version): """ This creates the stop command for an application which is uniquely identified by a port number. Additional portions of the start command are included to prevent the termination of other processes. Args: port: The port which the application server is running py_version: The python version the app is currently using Returns: A string of the stop command. """ python = choose_python_executable(py_version) cmd = [ python, constants.APPSCALE_HOME + "/AppServer/old_dev_appserver.py", "-p " + str(port), "--cookie_secret " + appscale_info.get_secret(), ] cmd = " ".join(cmd) stop_cmd = "ps aux | grep '" + cmd + "' | grep -v grep | awk '{ print $2 }' | xargs -r kill -9" return stop_cmd
DEFAULT_PORT = 4342 # The port avaialble from the outside via SSL. DEFAULT_SSL_PORT = 4343 # The default datastore used. datastore_type = DEFAULT_DATASTORE # The port this application binds to. bindport = DEFAULT_PORT # The datastore error codes. ERROR_CODES = [] # Global secret to validate incoming soap requests. super_secret = appscale_info.get_secret() # Datastore accessor. db = [] # The schema we use to store user information. user_schema = [] # The schema we use to store app information. app_schema = [] # The application name regex to validate an application ID. APPNAME_REGEX = r'^[\d\w\.@-]+$' # Different types of valid users created. VALID_USER_TYPES = ["user", "xmpp_user", "app", "channel"]
""" This script dumps all users. """ import M2Crypto import os import SOAPpy import string import sys sys.path.append(os.path.join(os.path.dirname(__file__), "../lib")) import appscale_info import constants def get_soap_accessor(): """ Returns the SOAP server accessor to deal with application and users. Returns: A soap server accessor. """ db_ip = appscale_info.get_db_master_ip() bindport = constants.UA_SERVER_PORT return SOAPpy.SOAPProxy("https://{0}:{1}".format(db_ip, bindport)) if __name__ == "__main__": server = get_soap_accessor() users = server.get_all_users(appscale_info.get_secret()) users = users.split(':') for user in users: print user