import json import os from subprocess import call import click from git import Repo from owsdev.config import config, grass_session_token, services_json class Service: def __init__( self, name, port, type='ows-python', env={}, use_port_flag=False): self.name = name self.type = type self.port = port self.env = env self.use_port_flag = use_port_flag def local_url(self): return 'http://localhost:{}'.format(self.port) def env_vars(self): env_mappings = { 'AR_MYSQL_DATABASE': config['databases']['art_relations'][ 'schema'], 'AR_MYSQL_HOST': config['databases']['art_relations']['host'], 'AR_MYSQL_PASSWORD': config['databases']['art_relations'][ 'password'], 'AR_MYSQL_PORT': str(config['databases']['art_relations']['port']), 'AR_MYSQL_USER': config['databases']['art_relations']['user'], 'PRICING_MYSQL_DATABASE': config['databases']['pricing'][ 'schema'], 'PRICING_MYSQL_HOST': config['databases']['pricing']['host'], 'PRICING_MYSQL_PASSWORD': config['databases']['pricing'][ 'password'], 'PRICING_MYSQL_PORT': str(config['databases']['pricing']['port']), 'PRICING_MYSQL_USER': config['databases']['pricing']['user'], 'SNOWFLAKE_USER': config['databases']['snowflake']['user'], 'SNOWFLAKE_PASSWORD': config['databases']['snowflake']['password'], 'SNOWFLAKE_ROLE': config['databases']['snowflake']['role'], 'SNOWFLAKE_DATABASE': config['databases']['snowflake']['database'], 'SNOWFLAKE_SCHEMA': config['databases']['snowflake']['schema'], 'SNOWFLAKE_WAREHOUSE': config['databases']['snowflake']['warehouse'], 'DEV_DYNAMO_ENDPOINT_URL': 'http://localhost:{}'.format( config['dynamodblocal']['port']), 'DEV_DYNAMO_ACCESS_KEY_ID': config['dynamodblocal'][ 'access_key_id'], 'DEV_DYNAMO_SECRET_ACCESS_KEY': config['dynamodblocal'][ 'secret_access_key'], 'REDIS_HOST': config['redis']['host'], 'REDIS_PORT': str(config['redis']['port']), 'SERVICE_DEFAULT_PROTOCOL': 'http' } if self.name != 'ows-grass': env_mappings['GRASS_URL'] = get_service('ows-grass').local_url() env_mappings['GRASS_SESSION_TOKEN'] = grass_session_token env_vars = {key: value.format(**env_mappings) for key, value in self.env.items()} env_vars['PORT'] = str(self.port) return env_vars def print_env(self): for key, value in self.env_vars().items(): click.echo('{}={}'.format(key, value)) def run(self): child_env = os.environ.copy() child_env.update(self.env_vars()) service_dir = os.path.join(config['projects_dir'], self.name) python_bin = os.path.join(service_dir, 'env', 'bin', 'python') app_script = os.path.join(service_dir, 'dev.py') service_type = self.type if service_type == 'ows-python': if self.use_port_flag: cmd = '{} {} --port {}'.format(python_bin, app_script, self.port) else: cmd = '{} {}'.format(python_bin, app_script) elif service_type == 'frontend': cmd = 'yarn start' elif service_type == 'proxy-only': click.echo('Service {} is proxy-only.'.format(self.name)) return else: click.echo('Unknown service type: {}'.format(service_type)) return call([cmd], shell=True, env=child_env, cwd=service_dir) def doctor(self): project_dir = os.path.join(config['projects_dir'], self.name) if not os.path.exists(project_dir): click.echo( '{} {}'.format(click.style('Warning', fg='red'), self.name)) click.echo('Directory {} not found'.format(project_dir)) click.echo() return repo = Repo(project_dir) git = repo.git() git.remote('update') status = git.status('--porcelain', '--branch') if status not in ['## master...origin/master', '## master...orchard/master']: click.echo( '{} {}'.format(click.style('Warning', fg='red'), self.name)) click.echo(status) click.echo() def qa_host(self): return 'qa-{}.theorchard.io'.format(self.name) def is_proxied(self): return self.type != 'frontend' def service_spec(service_name): for service in services_json: if service['name'] == service_name: return service raise KeyError('No service named {} found in services.json.'.format(service_name)) def get_service(service_name): spec = service_spec(service_name) return Service(**spec) def known_services(): return [Service(**spec) for spec in services_json] def active_services(): return [get_service(service_name) for service_name in (config['services'])]