package models import ( "github.com/porter-dev/porter/api/types" "gorm.io/gorm" ) // Stack represents the metadata for a stack on Porter type Stack struct { gorm.Model ProjectID uint ClusterID uint Namespace string Name string UID string `gorm:"unique"` Revisions []StackRevision } func (s *Stack) ToStackType() *types.Stack { revisions := []types.StackRevisionMeta{} for _, rev := range s.Revisions { revisions = append(revisions, rev.ToStackRevisionMetaType(s.UID)) } var latestRevision *types.StackRevision if len(s.Revisions) > 0 { latestRevision = s.Revisions[0].ToStackRevisionType(s.UID) } return &types.Stack{ CreatedAt: s.CreatedAt, UpdatedAt: s.UpdatedAt, Name: s.Name, Namespace: s.Namespace, ID: s.UID, LatestRevision: latestRevision, Revisions: revisions, } } // StackRevision represents the revision information for the stack type StackRevision struct { gorm.Model RevisionNumber uint StackID uint Status string Reason string Message string Resources []StackResource SourceConfigs []StackSourceConfig EnvGroups []StackEnvGroup } func (s StackRevision) ToStackRevisionMetaType(stackID string) types.StackRevisionMeta { return types.StackRevisionMeta{ CreatedAt: s.CreatedAt, ID: s.RevisionNumber, Status: types.StackRevisionStatus(s.Status), StackID: stackID, } } func (s StackRevision) ToStackRevisionType(stackID string) *types.StackRevision { metaType := s.ToStackRevisionMetaType(stackID) sourceConfigs := make([]types.StackSourceConfig, 0) for _, sourceConfig := range s.SourceConfigs { sourceConfigs = append(sourceConfigs, *sourceConfig.ToStackSourceConfigType(stackID, s.RevisionNumber)) } resources := make([]types.StackResource, 0) for _, stackResource := range s.Resources { resources = append(resources, *stackResource.ToStackResource(stackID, s.RevisionNumber, s.SourceConfigs)) } envGroups := make([]types.StackEnvGroup, 0) for _, stackEnvGroup := range s.EnvGroups { envGroups = append(envGroups, *stackEnvGroup.ToStackEnvGroupType(stackID, s.RevisionNumber)) } return &types.StackRevision{ StackRevisionMeta: &metaType, SourceConfigs: sourceConfigs, Resources: resources, EnvGroups: envGroups, Reason: s.Reason, Message: s.Message, } } type StackResource struct { gorm.Model Name string UID string StackRevisionID uint StackSourceConfigUID string HelmRevisionID uint Values []byte TemplateRepoURL string TemplateName string TemplateVersion string } func (s StackResource) ToStackResource(stackID string, stackRevisionID uint, sourceConfigs []StackSourceConfig) *types.StackResource { // find the relevant source config var linkedSourceConfig StackSourceConfig for _, sourceConfig := range sourceConfigs { if sourceConfig.UID == s.StackSourceConfigUID { linkedSourceConfig = sourceConfig break } } return &types.StackResource{ CreatedAt: s.CreatedAt, UpdatedAt: s.UpdatedAt, Name: s.Name, ID: s.UID, StackSourceConfig: linkedSourceConfig.ToStackSourceConfigType(stackID, stackRevisionID), StackID: stackID, // Note that `StackRevisionID` on the API refers to the numerical auto-incremented revision ID, not // the stack_revision_id in the database. StackRevisionID: stackRevisionID, StackAppData: &types.StackResourceAppData{ TemplateRepoURL: s.TemplateRepoURL, TemplateName: s.TemplateName, TemplateVersion: s.TemplateVersion, }, } } type StackSourceConfig struct { gorm.Model // A unique identifier for this source config, this will allow us identify a same source config // across multiple revisions and updates. This is not the same as the UID or ID which are updated over revisions. StableSourceConfigID string StackRevisionID uint Name string UID string ImageRepoURI string ImageTag string // TODO: add git-specific information } func (s StackSourceConfig) ToStackSourceConfigType(stackID string, stackRevisionID uint) *types.StackSourceConfig { return &types.StackSourceConfig{ CreatedAt: s.CreatedAt, UpdatedAt: s.UpdatedAt, StackID: stackID, StackRevisionID: stackRevisionID, Name: s.Name, ID: s.UID, ImageRepoURI: s.ImageRepoURI, ImageTag: s.ImageTag, StableSourceConfigID: s.StableSourceConfigID, } } type StackEnvGroup struct { gorm.Model StackRevisionID uint Name string Namespace string ProjectID uint ClusterID uint UID string EnvGroupVersion uint } func (s StackEnvGroup) ToStackEnvGroupType(stackID string, stackRevisionID uint) *types.StackEnvGroup { return &types.StackEnvGroup{ CreatedAt: s.CreatedAt, UpdatedAt: s.UpdatedAt, StackID: stackID, StackRevisionID: stackRevisionID, Name: s.Name, ID: s.UID, EnvGroupVersion: s.EnvGroupVersion, } }