def start(machine_arn,
              input,
              exec_name=None,
              sfn_client=BotoClientFactory.client_for(Service.STEPFUNCTIONS)):

        if not exec_name:
            exec_name = '-'.join(('aws-sfn-machine', str(uuid.uuid4())[0:8]))

        response = sfn_client.start_execution(stateMachineArn=machine_arn,
                                              name=exec_name,
                                              input=input)

        logger.debug(
            json.dumps(response,
                       indent=4,
                       sort_keys=False,
                       default=json_serial))

        try:
            machine_exec_arn = response['executionArn']
            return machine_exec_arn
        except:
            logger.error(
                'Failed to retreive executionArn from start_execution response'
            )
Ejemplo n.º 2
0
    def validate(self, cfn_client=BotoClientFactory.client_for(Service.CLOUDFORMATION)):
        """
        Validates the template using boto3, returning True/False.
        Difficult to tell if the validation is "deeper" than simple YAML validation, i.e. if Cloudformation semantics
          are validated as well. See:
          http://boto3.readthedocs.io/en/latest/reference/services/cloudformation.html#CloudFormation.Client.validate_template

        Can raise botocore.client.ClientError in exceptional circumstances.

        :param cfn_client:
        :return:
        """
        logger.debug('Validating...')
        try:
            cfn_client.validate_template(TemplateBody=self.template)
        except ClientError as ce:
            # Validation error is signaled via exception with these response elements/values
            if ce.response['Error']['Code'] == 'ValidationError':
                logger.error('Received ValidationError')
                logger.error(ce)
                return False
            else:
                # Some other type of error occured, so raise as exception
                print('Received unexpected botocore.client.ClientError code')
                raise ce
        else:
            return True
Ejemplo n.º 3
0
    def stack_create_complete(self, cfn_client=BotoClientFactory.client_for(Service.CLOUDFORMATION)):
        """
        Returns True if CFN stack for stack_name exists and is in CREATE_COMPLETE state, False otherwise.
        """
        try:
            logger.debug('Attempting to describe stack {}: '.format(self.stack_name))

            response = cfn_client.describe_stacks(
                StackName=self.stack_name
            )

            logger.debug('\t{name}: {status}'.format(
                name=response['Stacks'][0]['StackName'],
                status=response['Stacks'][0]['StackStatus']
            ))
        except ClientError as ce:
            if ce.response['Error']['Code'] == 'ValidationError':
                return False
            else:
                # Unexpected error code
                logger.error('Received unexpected botocore.client.ClientError code')
                raise ce

        try:
            response_stack_name = response['Stacks'][0]['StackName']
            response_stack_stat = response['Stacks'][0]['StackStatus']
        except KeyError as be:
            logger.error('Failed parsing describe_stacks response object')
            raise be

        if response_stack_name == self.stack_name:
            return response_stack_stat == 'CREATE_COMPLETE'
        else:
            raise Exception('Returned stack has unexpected name: {}'.format(response_stack_name))
Ejemplo n.º 4
0
    def invoke(lambda_function_name,
               event_data,
               lambda_client=BotoClientFactory.client_for(Service.LAMBDA)):

        response = lambda_client.invoke(FunctionName=lambda_function_name,
                                        InvocationType='RequestResponse',
                                        LogType='None',
                                        Payload=event_data)

        logging.debug('invoke response code: {}'.format(
            response['StatusCode']))

        success = True
        if 'FunctionError' in response:
            logging.debug('invoke response error: {}'.format(
                response['FunctionError']))
            success = False

        if 'LogResult' in response:
            logging.debug('invoke response log: {}'.format(
                response['LogResult']))

        if 'Payload' in response:
            streaming_body = response['Payload']
            response_bytes = streaming_body.read()
            return success, response_bytes.decode("utf-8")
        else:
            success = False
            return success, {'MSG': 'Payload not in response'}
Ejemplo n.º 5
0
    def get_output(execution_arn,
                   sfn_client=BotoClientFactory.client_for(
                       Service.STEPFUNCTIONS)):
        response = sfn_client.describe_execution(executionArn=execution_arn)

        logger.debug(
            json.dumps(response,
                       indent=4,
                       sort_keys=False,
                       default=json_serial))

        return response['output']
Ejemplo n.º 6
0
    def create(self, template_url, parameters, timeout, capabilities, tags,
               cfn_client=BotoClientFactory.client_for(Service.CLOUDFORMATION)):

        logger.debug('Creating stack..')

        return cfn_client.create_stack(
            StackName=self.stack_name,
            TemplateURL=template_url,
            Parameters=parameters,
            DisableRollback=False,
            TimeoutInMinutes=timeout,
            Capabilities=capabilities,
            Tags=tags
        )
Ejemplo n.º 7
0
    def upload_template(self, s3_cli=BotoClientFactory.client_for(Service.S3)):
        s3_cli.upload_fileobj(
            Fileobj=io.BytesIO(self.template_string.encode('utf-8')),
            Bucket=self.conf["RESOURCE_CFN_TMPL_DEPLOY_BUCKET"],
            Key=self.conf["RESOURCE_CFN_TMPL_DEPLOY_KEY"]
        )

        template_upload_exists = S3Upload.object_exists(
            bucket_name=self.conf["RESOURCE_CFN_TMPL_DEPLOY_BUCKET"],
            key_name=self.conf["RESOURCE_CFN_TMPL_DEPLOY_KEY"]
        )

        if not template_upload_exists:
            raise StackLaunchException('Template does not exist in S3. Upload failed?')
Ejemplo n.º 8
0
        def __init__(self,
                     build_dir,
                     script_file,
                     requirements_file,
                     deployment_zip,
                     deployment_bucket,
                     deployment_key,
                     conf,
                     lambda_client=BotoClientFactory.client_for(
                         Service.LAMBDA)):

            self.conf = conf
            self.build_dir = build_dir
            self.script_file = script_file
            self.requirements_file = requirements_file
            self.lambda_client = lambda_client
            self.deployment_zip = deployment_zip
            self.deployment_bucket = deployment_bucket
            self.deployment_key = deployment_key
            self.rkstr8_path = conf["RKSTR8_PKG_LOCAL_PATH"]