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