github.com/diggerhq/digger/libs@v0.0.0-20240604170430-9d61cdf01cc5/orchestrator/scheduler/models.go (about)

     1  package scheduler
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/diggerhq/digger/libs/orchestrator"
     6  	"github.com/goccy/go-json"
     7  	"log"
     8  )
     9  
    10  type DiggerBatchStatus int8
    11  
    12  const (
    13  	BatchJobCreated     DiggerBatchStatus = 1
    14  	BatchJobStarted     DiggerBatchStatus = 2
    15  	BatchJobFailed      DiggerBatchStatus = 3
    16  	BatchJobSucceeded   DiggerBatchStatus = 4
    17  	BatchJobInvalidated DiggerBatchStatus = 5
    18  )
    19  
    20  type WorkflowInput struct {
    21  	JobString string `json:"job"`
    22  	Id        string `json:"id"`
    23  	CommentId string `json:"comment_id"`
    24  	RunName   string `json:"run_name"`
    25  }
    26  
    27  func (w *WorkflowInput) ToMap() map[string]interface{} {
    28  	return map[string]interface{}{
    29  		"id":         w.Id,
    30  		"job":        w.JobString,
    31  		"comment_id": w.CommentId,
    32  		"run_name":   w.RunName,
    33  	}
    34  }
    35  
    36  type DiggerBatchType string
    37  
    38  const (
    39  	BatchTypePlan  DiggerBatchType = "plan"
    40  	BatchTypeApply DiggerBatchType = "apply"
    41  )
    42  
    43  type DiggerJobStatus int8
    44  
    45  const (
    46  	DiggerJobCreated      DiggerJobStatus = 1
    47  	DiggerJobTriggered    DiggerJobStatus = 2
    48  	DiggerJobFailed       DiggerJobStatus = 3
    49  	DiggerJobStarted      DiggerJobStatus = 4
    50  	DiggerJobSucceeded    DiggerJobStatus = 5
    51  	DiggerJobQueuedForRun DiggerJobStatus = 6
    52  )
    53  
    54  func (d *DiggerJobStatus) ToString() string {
    55  	switch *d {
    56  	case DiggerJobSucceeded:
    57  		return "succeeded"
    58  	case DiggerJobStarted:
    59  		return "running"
    60  	case DiggerJobFailed:
    61  		return "failed"
    62  	case DiggerJobTriggered:
    63  		return "running"
    64  	case DiggerJobCreated:
    65  		return "created"
    66  	case DiggerJobQueuedForRun:
    67  		return "created"
    68  	default:
    69  		return "unknown status"
    70  	}
    71  }
    72  
    73  func (d *DiggerJobStatus) ToEmoji() string {
    74  	switch *d {
    75  	case DiggerJobSucceeded:
    76  		return ":white_check_mark:"
    77  	case DiggerJobStarted:
    78  		return ":arrows_counterclockwise:"
    79  	case DiggerJobFailed:
    80  		return ":x:"
    81  	case DiggerJobTriggered:
    82  		return ":arrows_counterclockwise:"
    83  	case DiggerJobCreated:
    84  		return ":clock11:"
    85  	case DiggerJobQueuedForRun:
    86  		return ":clock11:"
    87  	default:
    88  		return ":question:"
    89  	}
    90  }
    91  
    92  type SerializedJob struct {
    93  	DiggerJobId      string          `json:"digger_job_id"`
    94  	Status           DiggerJobStatus `json:"status"`
    95  	ProjectName      string          `json:"project_name"`
    96  	JobString        []byte          `json:"job_string"`
    97  	PlanFootprint    []byte          `json:"plan_footprint"`
    98  	PRCommentUrl     string          `json:"pr_comment_url"`
    99  	WorkflowRunUrl   *string         `json:"workflow_run_url"`
   100  	ResourcesCreated uint            `json:"resources_created"`
   101  	ResourcesDeleted uint            `json:"resources_deleted"`
   102  	ResourcesUpdated uint            `json:"resources_updated"`
   103  }
   104  
   105  type SerializedBatch struct {
   106  	ID           string                     `json:"id"`
   107  	PrNumber     int                        `json:"pr_number"`
   108  	Status       DiggerBatchStatus          `json:"status"`
   109  	BranchName   string                     `json:"branch_name"`
   110  	RepoFullName string                     `json:"repo_full_name"`
   111  	RepoOwner    string                     `json:"repo_owner"`
   112  	RepoName     string                     `json:"repo_name"`
   113  	BatchType    orchestrator.DiggerCommand `json:"batch_type"`
   114  	Jobs         []SerializedJob            `json:"jobs"`
   115  }
   116  
   117  func (b *SerializedBatch) IsPlan() (bool, error) {
   118  	// TODO: Introduce a batch-level field to check for is plan or apply
   119  	jobSpecs, err := GetJobSpecs(b.Jobs)
   120  	if err != nil {
   121  		log.Printf("error while fetching job specs: %v", err)
   122  		return false, fmt.Errorf("error while fetching job specs: %v", err)
   123  	}
   124  	return orchestrator.IsPlanJobSpecs(jobSpecs), nil
   125  }
   126  
   127  func (b *SerializedBatch) IsApply() (bool, error) {
   128  	jobSpecs, err := GetJobSpecs(b.Jobs)
   129  	if err != nil {
   130  		log.Printf("error while fetching job specs: %v", err)
   131  		return false, fmt.Errorf("error while fetching job specs: %v", err)
   132  	}
   133  	return orchestrator.IsPlanJobSpecs(jobSpecs), nil
   134  }
   135  
   136  func (b *SerializedBatch) ToStatusCheck() string {
   137  	switch b.Status {
   138  	case BatchJobCreated:
   139  		return "pending"
   140  	case BatchJobInvalidated:
   141  		return "failure"
   142  	case BatchJobFailed:
   143  		return "success"
   144  	case BatchJobSucceeded:
   145  		return "success"
   146  	default:
   147  		return "pending"
   148  	}
   149  }
   150  
   151  func (s *SerializedJob) ResourcesSummaryString(isPlan bool) string {
   152  	if !isPlan {
   153  		return ""
   154  	}
   155  
   156  	if s.Status == DiggerJobSucceeded {
   157  		return fmt.Sprintf(" [Resources: %v to create, %v to update, %v to delete]", s.ResourcesCreated, s.ResourcesUpdated, s.ResourcesDeleted)
   158  	} else {
   159  		return "..."
   160  	}
   161  }
   162  
   163  func GetJobSpecs(jobs []SerializedJob) ([]orchestrator.JobJson, error) {
   164  	jobSpecs := make([]orchestrator.JobJson, 0)
   165  	for _, job := range jobs {
   166  		var jobSpec orchestrator.JobJson
   167  		err := json.Unmarshal(job.JobString, &jobSpec)
   168  		if err != nil {
   169  			log.Printf("Failed to convert unmarshall Serialized job")
   170  			return nil, err
   171  		}
   172  		jobSpecs = append(jobSpecs, jobSpec)
   173  	}
   174  	return jobSpecs, nil
   175  }
   176  
   177  func JobsToProjectMap(jobs []SerializedJob) (map[string]SerializedJob, error) {
   178  	res := make(map[string]SerializedJob)
   179  	for _, job := range jobs {
   180  		res[job.ProjectName] = job
   181  	}
   182  	return res, nil
   183  }