Odyssey
Classes | Functions | Variables
cli.stack Namespace Reference

Classes

class  CreateCommand
 
class  EndMaintCommand
 
class  GetEnvCommand
 
class  ListCommand
 
class  MaintCommand
 
class  MigrationCommand
 
class  MonitorCommand
 
class  RemoveCommand
 
class  ScaleCommand
 
class  SetEnvCommand
 
class  SetStackStateCommand
 
class  ShowCommand
 
class  StackCommand
 
class  StartMaintCommand
 
class  UpgradeCommand
 

Functions

def create_stack_aws_resources (stack, region, ecs_cluster, elb_security_group, elb_internal_security_group, eni_security_group, rds_config, pub_subnet_prefix, priv_subnet_prefix, https_cert_hostname, domain, hostnames, **kwargs)
 
def upgrade_cfn_stack (stack, git_sha, passphrase, **kwargs)
 
def get_rds_config (region, cluster, rds_config)
 
def create_db (stack, db_config)
 
def submit_rsql_job (sql, db_config, region, cluster, operator=None)
 
def create_cloudformation_stack_params (stack, **kwargs)
 
def _deploy_dictionary_ (stack)
 

Variables

string RDS_CONFIG_BUCKET = 'homecu.odyssey.rds'
 
string RDS_CONFIG_PATH_FMT = '%(region)s/%(ecs_cluster)s/%(rds_config)s.json'
 

Detailed Description

AWS stack provisioning.

Function Documentation

◆ create_cloudformation_stack_params()

def cli.stack.create_cloudformation_stack_params (   stack,
**  kwargs 
)
Create necessary Params dictionary for cloudformation

Definition at line 1045 of file stack.py.

1045 def create_cloudformation_stack_params(stack, **kwargs):
1046  '''Create necessary Params dictionary for cloudformation'''
1047  registry = REGISTRIES[stack.region]
1048  oauth_client = get_client_oauth_data(stack.dns[0])
1049  return {
1050  'VpcId': stack.aws['vpc_id'],
1051  'ECSCluster': stack.cluster,
1052  'StackName': stack.name,
1053  'StackVersion': stack.version,
1054  'StackDomain': stack.dns[0],
1055  'ContainerRegistry': registry,
1056  'StackDatabaseHost': stack.db['host'],
1057  'StackDatabasePort': str(stack.db['port']),
1058  'StackDatabaseName': stack.db['name'],
1059  'StackDatabaseUsername': stack.db['user'],
1060  'StackDatabasePassword': stack.db['password'],
1061  'Oauth2ClientId': oauth_client[0],
1062  'Oauth2ClientSecret': oauth_client[1],
1063  'AppServiceDesiredCount': str(stack.app_service_count),
1064  'CertificateArn': stack.aws['certificate_arn'],
1065  'HostedZoneId': stack.aws['hosted_zone_id'],
1066  'ELBSecurityGroupsIds': ','.join(stack.aws['elb_security_groups']),
1067  'InternalELBSecurityGroupIds': ','.join(
1068  stack.aws['elb_internal_security_groups']),
1069  'ENISecurityGroupIds': ','.join(stack.aws['eni_security_groups']),
1070  'PrivateSubnetIds': ','.join(stack.aws['private_subnet_ids']),
1071  'SubnetIds': ','.join(stack.aws['subnet_ids']),
1072  'IsMigration': kwargs.get('IsMigration', 'False'),
1073  'Environment': stack.environment,
1074  'EnvironmentName': stack.environment_name,
1075  }
1076 
1077 

◆ create_stack_aws_resources()

def cli.stack.create_stack_aws_resources (   stack,
  region,
  ecs_cluster,
  elb_security_group,
  elb_internal_security_group,
  eni_security_group,
  rds_config,
  pub_subnet_prefix,
  priv_subnet_prefix,
  https_cert_hostname,
  domain,
  hostnames,
**  kwargs 
)
Create required AWS resources for given stack

Definition at line 815 of file stack.py.

815 def create_stack_aws_resources(stack,
816  region,
817  ecs_cluster,
818  elb_security_group,
819  elb_internal_security_group,
820  eni_security_group,
821  rds_config,
822  pub_subnet_prefix,
823  priv_subnet_prefix,
824  https_cert_hostname,
825  domain,
826  hostnames,
827  **kwargs):
828  '''Create required AWS resources for given stack'''
829  verbose = kwargs.get('verbose', False)
830  db_config = get_rds_config(region,
831  ecs_cluster,
832  rds_config)
833 
834  def get_vpc_subnets(vpc, prefix):
835  def name_tag(tags):
836  return [x['Value'] for x in tags
837  if x['Key'] == 'Name'][0]
838  return [x for x in vpc.subnets.all()
839  if name_tag(x.tags).startswith(prefix)]
840 
841  def get_sg(name, region):
842  ec2_api = boto3.client('ec2', region_name=region)
843  return ec2_api.describe_security_groups(Filters=[{
844  'Name': 'group-name',
845  'Values': [name]
846  }])['SecurityGroups'][0]
847 
848  def get_https_cert(name, region):
849  acm_api = boto3.client('acm', region_name=region)
850  certs = acm_api.list_certificates()['CertificateSummaryList']
851  for x in certs:
852  if x['DomainName'] == name:
853  return x
854 
855  def get_hosted_zone_id(domain):
856  r53_api = boto3.client('route53')
857  response = r53_api.list_hosted_zones_by_name(
858  DNSName=domain,
859  MaxItems='1'
860  )
861  if len(response.get('HostedZones', [])) == 0:
862  raise SystemExit("Unable to find hosted zone by name")
863  return response['HostedZones'][0]['Id']
864 
865  elb_sg = get_sg(elb_security_group, region)
866  elb_int_sg = get_sg(elb_internal_security_group, region)
867  eni_sg = get_sg(eni_security_group, region)
868  ec2_res = boto3.resource('ec2', region_name=region)
869  vpc = ec2_res.Vpc(elb_sg['VpcId'])
870  elb_subnets = get_vpc_subnets(vpc, pub_subnet_prefix)
871  if not elb_subnets:
872  raise SystemExit("No usable subnets found")
873  eni_subnets = get_vpc_subnets(vpc, priv_subnet_prefix)
874  if not eni_subnets:
875  raise SystemExit("No usable private subnets found")
876 
877  cert_name = '%s.%s' % (https_cert_hostname, domain)
878  cert = get_https_cert(cert_name, region)
879 
880  hosted_zone_id = get_hosted_zone_id(domain)
881 
882  if cert is None:
883  raise SystemExit("No HTTPS cert found for: %s" % cert_name)
884 
885  stack.set("aws", {
886  'vpc_id': vpc.vpc_id,
887  'certificate_arn': cert['CertificateArn'],
888  'elb_security_groups': [elb_sg['GroupId']],
889  'elb_internal_security_groups': [elb_int_sg['GroupId']],
890  'eni_security_groups': [eni_sg['GroupId']],
891  'private_subnet_ids': [x.id for x in eni_subnets],
892  'subnet_ids': [x.id for x in elb_subnets],
893  'hosted_zone_id': hosted_zone_id,
894  })
895 
896  if kwargs.get('create_database', True):
897  db_creds = create_db(stack, db_config)
898  stack.set("db", {
899  "host": db_config['host'],
900  "port": db_config['port'],
901  "name": db_creds['db'],
902  "user": db_creds['user'],
903  "password": db_creds['password'],
904  "rds_config": rds_config,
905  })
906 
907  stack_cf_params = create_cloudformation_stack_params(stack, **kwargs)
908 
909  stack_cf_id = cloudformation.create_cloudformation_stack(
910  stack,
911  stack_cf_params,
912  verbose=verbose
913  )
914  if stack_cf_id is None:
915  raise SystemExit("Unable to create Cloudformation Stack for Stack")
916 
917  print("Created Cloudformation Stack: %s" % stack_cf_id)
918 
919  stack.deploy = _deploy_dictionary_(stack)
920 
921  stack.update_state('active')
922 
923