| #!/usr/bin/python3 |
| |
| # ***************************************************************************** |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # |
| # ****************************************************************************** |
| |
| import argparse |
| import json |
| import logging |
| import os |
| import sys |
| import traceback |
| import subprocess |
| from datalab.fab import * |
| from datalab.ssn_lib import * |
| from fabric import * |
| from patchwork.files import exists |
| from patchwork import files |
| |
| parser = argparse.ArgumentParser() |
| parser.add_argument('--hostname', type=str, default='') |
| parser.add_argument('--keyfile', type=str, default='') |
| parser.add_argument('--additional_config', type=str, default='{"empty":"string"}') |
| parser.add_argument('--datalab_path', type=str, default='') |
| parser.add_argument('--os_user', type=str, default='') |
| parser.add_argument('--cloud_provider', type=str, default='') |
| parser.add_argument('--os_family', type=str, default='') |
| parser.add_argument('--request_id', type=str, default='') |
| parser.add_argument('--resource', type=str, default='') |
| parser.add_argument('--service_base_name', type=str, default='') |
| parser.add_argument('--billing_dataset_name', type=str, default='') |
| parser.add_argument('--default_endpoint_name', type=str, default='') |
| parser.add_argument('--tag_resource_id', type=str, default=None) |
| parser.add_argument('--billing_tag', type=str, default=None) |
| parser.add_argument('--account_id', type=str, default=None) |
| parser.add_argument('--billing_bucket', type=str, default=None) |
| parser.add_argument('--aws_job_enabled', type=str, default=None) |
| parser.add_argument('--report_path', type=str, default=None) |
| parser.add_argument('--authentication_file', type=str, default=None) |
| parser.add_argument('--offer_number', type=str, default=None) |
| parser.add_argument('--currency', type=str, default=None) |
| parser.add_argument('--locale', type=str, default=None) |
| parser.add_argument('--region_info', type=str, default=None) |
| parser.add_argument('--billing_enabled', type=str, default=False) |
| parser.add_argument('--ldap_login', type=str, default=None) |
| parser.add_argument('--tenant_id', type=str, default=None) |
| parser.add_argument('--application_id', type=str, default=None) |
| parser.add_argument('--subscription_id', type=str, default=None) |
| parser.add_argument('--datalake_store_name', type=str, default=None) |
| parser.add_argument('--validate_permission_scope', type=str, default=None) |
| parser.add_argument('--cloud_params', type=str, default='') |
| parser.add_argument('--datalab_id', type=str, default=None) |
| parser.add_argument('--usage_date', type=str, default=None) |
| parser.add_argument('--product', type=str, default=None) |
| parser.add_argument('--usage_type', type=str, default=None) |
| parser.add_argument('--usage', type=str, default=None) |
| parser.add_argument('--cost', type=str, default=None) |
| parser.add_argument('--resource_id', type=str, default=None) |
| parser.add_argument('--tags', type=str, default=None) |
| parser.add_argument('--keycloak_client_id', type=str, default=None) |
| parser.add_argument('--keycloak_client_secret', type=str, default=None) |
| parser.add_argument('--keycloak_auth_server_url', type=str, default=None) |
| args = parser.parse_args() |
| |
| datalab_conf_dir = args.datalab_path + 'conf/' |
| web_path = args.datalab_path + 'webapp/' |
| local_log_filename = "{}_UI.log".format(args.request_id) |
| local_log_filepath = "/logs/" + args.resource + "/" + local_log_filename |
| logging.basicConfig(format='%(levelname)-8s [%(asctime)s] %(message)s', |
| level=logging.INFO, |
| filename=local_log_filepath) |
| mongo_passwd = id_generator() |
| keystore_passwd = id_generator() |
| |
| |
| def copy_ssn_libraries(): |
| try: |
| conn.sudo('mkdir -p /usr/lib/python3.8/datalab/') |
| conn.run('mkdir -p /tmp/datalab_libs/') |
| subprocess.run('scp -i {} /usr/lib/python3.8/datalab/*.py {}:/tmp/datalab_libs/'.format(args.keyfile, host_string), shell=True, check=True) |
| conn.run('chmod a+x /tmp/datalab_libs/*') |
| conn.sudo('mv /tmp/datalab_libs/* /usr/lib/python3.8/datalab/') |
| if exists(conn, '/usr/lib64'): |
| conn.sudo('mkdir -p /usr/lib64/python3.8') |
| conn.sudo('ln -fs /usr/lib/python3.8/datalab /usr/lib64/python3.8/datalab') |
| except Exception as err: |
| traceback.print_exc() |
| print('Failed to copy ssn libraries: ', str(err)) |
| sys.exit(1) |
| |
| |
| def configure_mongo(mongo_passwd, default_endpoint_name): |
| try: |
| if not exists(conn,"/lib/systemd/system/mongod.service"): |
| if os.environ['conf_os_family'] == 'debian': |
| subprocess.run('sed -i "s/MONGO_USR/mongodb/g" /root/templates/mongod.service_template', shell=True, check=True) |
| elif os.environ['conf_os_family'] == 'redhat': |
| subprocess.run('sed -i "s/MONGO_USR/mongod/g" /root/templates/mongod.service_template', shell=True, check=True) |
| subprocess.run('scp -i {} /root/templates/mongod.service_template {}:/tmp/mongod.service'.format(args.keyfile, |
| host_string), shell=True, check=True) |
| conn.sudo('mv /tmp/mongod.service /lib/systemd/system/mongod.service') |
| conn.sudo('systemctl daemon-reload') |
| conn.sudo('systemctl enable mongod.service') |
| subprocess.run('sed -i "s|PASSWORD|{}|g" /root/scripts/resource_status.py'.format(mongo_passwd), shell=True, check=True) |
| subprocess.run('scp -i {} /root/scripts/resource_status.py {}:/tmp/resource_status.py'.format(args.keyfile, |
| host_string), shell=True, check=True) |
| conn.sudo('mv /tmp/resource_status.py ' + os.environ['ssn_datalab_path'] + 'tmp/') |
| subprocess.run('sed -i "s|PASSWORD|{}|g" /root/scripts/configure_mongo.py'.format(mongo_passwd), shell=True, check=True) |
| subprocess.run('scp -i {} /root/scripts/configure_mongo.py {}:/tmp/configure_mongo.py'.format(args.keyfile, |
| host_string), shell=True, check=True) |
| conn.sudo('mv /tmp/configure_mongo.py ' + args.datalab_path + 'tmp/') |
| subprocess.run('scp -i {} /root/files/{}/mongo_roles.json {}:/tmp/mongo_roles.json'.format(args.keyfile, |
| args.cloud_provider, |
| host_string), shell=True, check=True) |
| subprocess.run('scp -i {} /root/files/local_endpoint.json {}:/tmp/local_endpoint.json'.format(args.keyfile, |
| host_string), shell=True, check=True) |
| conn.sudo('mv /tmp/mongo_roles.json ' + args.datalab_path + 'tmp/') |
| conn.sudo('sed -i "s|DEF_ENDPOINT_NAME|{0}|g" /tmp/local_endpoint.json'.format(default_endpoint_name)) |
| conn.sudo('sed -i "s|CLOUD_PROVIDER|{0}|g" /tmp/local_endpoint.json'.format( |
| os.environ['conf_cloud_provider'].upper())) |
| conn.sudo('mv /tmp/local_endpoint.json ' + args.datalab_path + 'tmp/') |
| conn.sudo('pip3 install -U six==1.15.0 patchwork') |
| conn.sudo("python3 " + args.datalab_path + "tmp/configure_mongo.py --datalab_path {} ".format( |
| args.datalab_path)) |
| except Exception as err: |
| traceback.print_exc() |
| print('Failed to configure MongoDB: ', str(err)) |
| sys.exit(1) |
| |
| |
| def build_ui(): |
| try: |
| # Building Front-end |
| conn.sudo('sed -i "s|CLOUD_PROVIDER|{}|g" ' + args.datalab_path + 'sources/services/self-service/src/main/resources/webapp/src/dictionary/global.dictionary.ts'.format(args.cloud_provider)) |
| |
| if args.cloud_provider == 'azure' and os.environ['azure_datalake_enable'] == 'true': |
| conn.sudo('sed -i "s|\'use_ldap\': true|{}|g" ' + args.datalab_path + 'sources/services/self-service/src/main/resources/webapp/src/dictionary/azure.dictionary.ts'.format( |
| '\'use_ldap\': false')) |
| |
| conn.sudo('bash -c "cd {}sources/services/self-service/src/main/resources/webapp/ && echo "N" | npm install"'.format(args.datalab_path)) |
| manage_npm_pkg('bash -c "cd {}sources/services/self-service/src/main/resources/webapp/ && npm run build.prod"'.format(args.datalab_path)) |
| conn.sudo('sudo chown -R {} {}/*'.format(args.os_user, args.datalab_path)) |
| |
| # Building Back-end |
| if 'conf_repository_user' in os.environ and 'conf_repository_pass' in os.environ and 'conf_repository_address' in os.environ: |
| conn.sudo( |
| 'wget -P {0}sources/services/provisioning-service/target/ --user={1} --password={2} {3}/repository/packages/{4}/provisioning-service-{4}.jar --no-check-certificate' |
| .format(args.datalab_path, os.environ['conf_repository_user'], os.environ['conf_repository_pass'], os.environ['conf_repository_address'], os.environ['conf_release_tag'])) |
| conn.sudo( |
| 'wget -P {0}sources/services/self-service/target/ --user={1} --password={2} {3}/repository/packages/{4}/self-service-{4}.jar --no-check-certificate' |
| .format(args.datalab_path, os.environ['conf_repository_user'], os.environ['conf_repository_pass'], |
| os.environ['conf_repository_address'], os.environ['conf_release_tag'])) |
| conn.sudo( |
| 'wget -P {0}sources/services/billing-{4}/target/ --user={1} --password={2} {3}/repository/packages/{5}/billing-{4}-{5}.jar --no-check-certificate' |
| .format(args.datalab_path, os.environ['conf_repository_user'], os.environ['conf_repository_pass'], |
| os.environ['conf_repository_address'], args.cloud_provider, os.environ['conf_release_tag'])) |
| else: |
| try: |
| conn.sudo('bash -c "cd {}sources/ && /opt/maven/bin/mvn -P{} -DskipTests package 2>&1 > /tmp/maven.log"'.format(args.datalab_path, args.cloud_provider)) |
| except: |
| conn.run('if ! grep -w -E "(ERROR)" /tmp/maven.log > /tmp/maven_error.log; then echo "no_error" > /tmp/maven_error.log;fi') |
| conn.run('cat /tmp/maven_error.log') |
| print('Failed to build Back-end: ', str(err)) |
| sys.exit(1) |
| conn.sudo('mkdir -p {}webapp/'.format(args.datalab_path)) |
| for service in ['self-service', 'provisioning-service', 'billing']: |
| conn.sudo('mkdir -p {}webapp/{}/lib/'.format(args.datalab_path, service)) |
| conn.sudo('mkdir -p {}webapp/{}/conf/'.format(args.datalab_path, service)) |
| conn.sudo('cp {0}sources/services/self-service/self-service.yml {0}webapp/self-service/conf/'.format( |
| args.datalab_path)) |
| conn.sudo('cp {0}sources/services/self-service/target/self-service-*.jar {0}webapp/self-service/lib/'.format( |
| args.datalab_path)) |
| conn.sudo( |
| 'cp {0}sources/services/provisioning-service/provisioning.yml {0}webapp/provisioning-service/conf/'.format( |
| args.datalab_path)) |
| conn.sudo('cp {0}sources/services/provisioning-service/target/provisioning-service-*.jar ' |
| '{0}webapp/provisioning-service/lib/'.format(args.datalab_path)) |
| |
| if args.cloud_provider == 'azure': |
| conn.sudo('cp {0}sources/services/billing-azure/billing.yml {0}webapp/billing/conf/'.format(args.datalab_path)) |
| conn.sudo('cp {0}sources/services/billing-azure/target/billing-azure*.jar {0}webapp/billing/lib/'.format( |
| args.datalab_path)) |
| elif args.cloud_provider == 'aws': |
| conn.sudo('cp {0}sources/services/billing-aws/billing.yml {0}webapp/billing/conf/'.format(args.datalab_path)) |
| conn.sudo('cp {0}sources/services/billing-aws/src/main/resources/application.yml ' |
| '{0}webapp/billing/conf/billing_app.yml'.format(args.datalab_path)) |
| conn.sudo( |
| 'cp {0}sources/services/billing-aws/target/billing-aws*.jar {0}webapp/billing/lib/'.format( |
| args.datalab_path)) |
| elif args.cloud_provider == 'gcp': |
| conn.sudo('cp {0}sources/services/billing-gcp/billing.yml {0}webapp/billing/conf/'.format(args.datalab_path)) |
| conn.sudo( |
| 'cp {0}sources/services/billing-gcp/target/billing-gcp*.jar {0}webapp/billing/lib/'.format( |
| args.datalab_path)) |
| except Exception as err: |
| traceback.print_exc() |
| print('Failed to build UI: ', str(err)) |
| sys.exit(1) |
| |
| |
| ############## |
| # Run script # |
| ############## |
| if __name__ == "__main__": |
| print("Configure connections") |
| try: |
| global conn |
| conn = datalab.fab.init_datalab_connection(args.hostname, args.os_user, args.keyfile) |
| host_string = args.os_user + '@' + args.hostname |
| deeper_config = json.loads(args.additional_config) |
| except: |
| sys.exit(2) |
| |
| print("Copying DataLab libraries to SSN") |
| copy_ssn_libraries() |
| |
| print("Installing Supervisor") |
| ensure_supervisor() |
| |
| print("Installing MongoDB") |
| ensure_mongo() |
| |
| print("Configuring MongoDB") |
| configure_mongo(mongo_passwd, args.default_endpoint_name) |
| |
| conn.sudo('bash -c "echo DATALAB_CONF_DIR={} >> /etc/profile"'.format(datalab_conf_dir)) |
| conn.sudo('bash -c "echo export DATALAB_CONF_DIR >> /etc/profile"') |
| |
| print("Installing build dependencies for UI") |
| install_build_dep() |
| |
| print("Building UI") |
| build_ui() |
| |
| print("Starting Self-Service(UI)") |
| start_ss(args.keyfile, host_string, datalab_conf_dir, web_path, |
| args.os_user, mongo_passwd, keystore_passwd, args.cloud_provider, |
| args.service_base_name, args.tag_resource_id, args.billing_tag, args.account_id, |
| args.billing_bucket, args.aws_job_enabled, args.datalab_path, args.billing_enabled, args.cloud_params, |
| args.authentication_file, args.offer_number, args.currency, args.locale, |
| args.region_info, args.ldap_login, args.tenant_id, args.application_id, |
| args.hostname, args.datalake_store_name, args.subscription_id, args.validate_permission_scope, |
| args.datalab_id, args.usage_date, args.product, args.usage_type, |
| args.usage, args.cost, args.resource_id, args.tags, args.billing_dataset_name, args.keycloak_client_id, |
| args.keycloak_client_secret, args.keycloak_auth_server_url) |
| |
| conn.close() |