github.com/whamcloud/lemur@v0.0.0-20190827193804-4655df8a52af/packaging/ci/lambda/lemur_ci/pipeline.py (about) 1 import json 2 import boto3 3 4 client = boto3.client('codepipeline') 5 6 class Pipeline: 7 def __init__(self, name): 8 self.name = name 9 10 @property 11 def stages(self): 12 return dict([(s['name'], s) for s in client.get_pipeline(name=self.name)['pipeline']['stages']]) 13 14 @property 15 def states(self): 16 return dict((s['stageName'], s) for s in client.get_pipeline_state(name=self.name)['stageStates']) 17 18 19 class Job: 20 def __init__(self, val): 21 if isinstance(val, dict): 22 self.id = val['id'] 23 self.data = val['data'] 24 else: 25 self.id = val 26 self.data = {} 27 28 @property 29 def details(self): 30 return client.get_job_details(jobId=self.id) 31 32 @property 33 def pipeline(self): 34 return Pipeline(self.details['jobDetails']['data']['pipelineContext']['pipelineName']) 35 36 37 def continue_job_later(job, token, message): 38 """Notify CodePipeline of a continuing job 39 40 This will cause CodePipeline to invoke the function again with the 41 supplied continuation token. 42 43 Args: 44 job: The JobID 45 message: A message to be logged relating to the job status 46 continuation_token: The continuation token 47 48 Raises: 49 Exception: Any exception thrown by .put_job_success_result() 50 51 """ 52 53 # Use the continuation token to keep track of any job execution state 54 # This data will be available when a new job is scheduled to continue the current execution 55 continuation_token = json.dumps(token) 56 57 print('Putting job continuation (%s)' % token) 58 print(message) 59 client.put_job_success_result(jobId=job, continuationToken=continuation_token) 60 61 def put_job_success(job, message): 62 """Notify CodePipeline of a successful job 63 64 Args: 65 job: The CodePipeline job ID 66 message: A message to be logged relating to the job status 67 68 Raises: 69 Exception: Any exception thrown by .put_job_success_result() 70 71 """ 72 print('Putting job success') 73 print(message) 74 client.put_job_success_result(jobId=job) 75 76 def put_job_failure(job, message): 77 """Notify CodePipeline of a failed job 78 79 Args: 80 job: The CodePipeline job ID 81 message: A message to be logged relating to the job status 82 83 Raises: 84 Exception: Any exception thrown by .put_job_failure_result() 85 86 """ 87 print('Putting job failure') 88 print(message) 89 client.put_job_failure_result(jobId=job, failureDetails={'message': message, 'type': 'JobFailed'}) 90 91 def get_user_params(job_data, required_params=[]): 92 """Decodes the JSON user parameters and validates the required properties. 93 94 Args: 95 job_data: The job data structure containing the UserParameters string which should be a valid JSON structure 96 97 Returns: 98 The JSON parameters decoded as a dictionary. 99 100 Raises: 101 Exception: The JSON can't be decoded or a property is missing. 102 103 """ 104 try: 105 # Get the user parameters which contain the stack, artifact and file settings 106 user_parameters = job_data['actionConfiguration']['configuration']['UserParameters'] 107 decoded_parameters = json.loads(user_parameters) 108 109 except Exception as e: 110 # We're expecting the user parameters to be encoded as JSON 111 # so we can pass multiple values. If the JSON can't be decoded 112 # then fail the job with a helpful message. 113 if user_parameters != "": 114 raise Exception('UserParameters could not be decoded as JSON') 115 116 for param in required_params: 117 if param not in decoded_parameters: 118 raise Exception('Your UserParameters JSON must include "%s"' % param) 119 120 return decoded_parameters