README ¶
Readable, Creatable, Editable?
ModelController requires three types to work with a model type:
- Readable, the set of all fields visible through the API
- Creatable, the set of all fields that can be set upon creation through the API
- Editable, the set of all fields that can be mutated through the API
Go's struct nesting means we can have the Readable contain the Creatable type, and the Creatable contain the Editable type.
For naming, for a model type called v2models.X
, the three types would be X
, CreatableX
, and EditableX
. These types will be picked up by Swaggo and Gin.
Wow, what a lot of struct tags:
Do use:
json
controls the field name when parsing to/from json (always add)form
controls the field name when parsing from query parameters (always add)- Struct types can't ever be parsed from query parameters, so
form:"-"
should be used to skip them during parsing
- Struct types can't ever be parsed from query parameters, so
swaggertype
can override the type of the field documented on Swagger, useful for anything recursive (only add when Swaggo is parsing the type incorrectly)enums
controls possible values for the field as documented on Swagger (add when reasonable)default
controls (add when reasonable):- default values for the field on Swagger (as in, Swagger will fill in the default for you)
- default values applied internally by Sherlock when it goes to create an entry
I suggest tags be in the order above. Swaggo and Gin both use the tags on these structs.
Don't use
validate:"required"
which will document fields as required on Swagger, but in an over-zealous way that interferes with omitting them in query parameters on list calls
Documentation ¶
Index ¶
- type AppVersion
- type AppVersionController
- type Changeset
- type ChangesetController
- func (c ChangesetController) Apply(selectors []string, user *auth.User) ([]Changeset, error)
- func (c ChangesetController) Plan(request ChangesetPlanRequest, user *auth.User) ([]Changeset, error)
- func (c ChangesetController) PlanAndApply(request ChangesetPlanRequest, user *auth.User) ([]Changeset, error)
- type ChangesetPlanRequest
- type ChangesetPlanRequestChartReleaseEntry
- type ChangesetPlanRequestEnvironmentEntry
- type Chart
- type ChartController
- type ChartRelease
- type ChartReleaseController
- type ChartVersion
- type ChartVersionController
- type Cluster
- type ClusterController
- type ControllerSet
- type Creatable
- type CreatableAppVersion
- type CreatableChangeset
- type CreatableChart
- type CreatableChartRelease
- type CreatableChartVersion
- type CreatableCluster
- type CreatableEnvironment
- type Editable
- type EditableAppVersion
- type EditableChangeset
- type EditableChart
- type EditableChartRelease
- type EditableChartVersion
- type EditableCluster
- type EditableEnvironment
- type Environment
- type EnvironmentController
- type ModelController
- func (c ModelController[M, R, C, E]) Create(creatable C, user *auth.User) (R, bool, error)
- func (c ModelController[M, R, C, E]) Delete(selector string, user *auth.User) (R, error)
- func (c ModelController[M, R, C, E]) Edit(selector string, editable E, user *auth.User) (R, error)
- func (c ModelController[M, R, C, E]) Get(selector string) (R, error)
- func (c ModelController[M, R, C, E]) GetOtherValidSelectors(selector string) ([]string, error)
- func (c ModelController[M, R, C, E]) ListAllMatching(filter R, limit int) ([]R, error)
- type Readable
- type ReadableBaseType
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AppVersion ¶
type AppVersion struct { ReadableBaseType ChartInfo *Chart `json:"chartInfo,omitempty" form:"-"` ParentAppVersionInfo *AppVersion `json:"parentAppVersionInfo,omitempty" swaggertype:"object" form:"-"` CreatableAppVersion }
type AppVersionController ¶
type AppVersionController = ModelController[v2models.AppVersion, AppVersion, CreatableAppVersion, EditableAppVersion]
type Changeset ¶ added in v0.0.50
type Changeset struct { ReadableBaseType ChartReleaseInfo *ChartRelease `json:"chartReleaseInfo,omitempty" form:"-"` AppliedAt *time.Time `json:"appliedAt,omitempty" form:"appliedAt"` SupersededAt *time.Time `json:"supersededAt,omitempty" form:"supersededAt"` NewAppVersions []AppVersion `json:"newAppVersions,omitempty" form:"-"` NewChartVersions []ChartVersion `json:"newChartVersions,omitempty" form:"-"` FromResolvedAt *time.Time `json:"fromResolvedAt,omitempty" form:"fromResolvedAt"` FromAppVersionResolver *string `json:"fromAppVersionResolver,omitempty" form:"fromAppVersionResolver"` FromAppVersionExact *string `json:"fromAppVersionExact,omitempty" form:"fromAppVersionExact"` FromAppVersionBranch *string `json:"fromAppVersionBranch,omitempty" form:"fromAppVersionBranch"` FromAppVersionCommit *string `json:"fromAppVersionCommit,omitempty" form:"fromAppVersionCommit"` FromAppVersionFollowChartRelease string `json:"fromAppVersionFollowChartRelease,omitempty" form:"fromAppVersionFollowChartRelease"` FromAppVersionReference string `json:"fromAppVersionReference,omitempty" form:"fromAppVersionReference"` FromChartVersionResolver *string `json:"fromChartVersionResolver,omitempty" form:"fromChartVersionResolver"` FromChartVersionExact *string `json:"fromChartVersionExact,omitempty" form:"fromChartVersionExact"` FromChartVersionFollowChartRelease string `json:"fromChartVersionFollowChartRelease,omitempty" form:"fromChartVersionFollowChartRelease"` FromChartVersionReference string `json:"fromChartVersionReference,omitempty" form:"fromChartVersionReference"` FromHelmfileRef *string `json:"fromHelmfileRef,omitempty" form:"fromHelmfileRef"` FromFirecloudDevelopRef *string `json:"fromFirecloudDevelopRef,omitempty" form:"fromFirecloudDevelopRef"` ToResolvedAt *time.Time `json:"toResolvedAt,omitempty" from:"toResolvedAt"` ToAppVersionReference string `json:"toAppVersionReference,omitempty" form:"toAppVersionReference"` ToChartVersionReference string `json:"toChartVersionReference,omitempty" form:"toChartVersionReference"` CreatableChangeset }
type ChangesetController ¶ added in v0.0.50
type ChangesetController struct { ModelController[v2models.Changeset, Changeset, CreatableChangeset, EditableChangeset] *v2models.ChangesetEventStore }
func (ChangesetController) Plan ¶ added in v0.0.50
func (c ChangesetController) Plan(request ChangesetPlanRequest, user *auth.User) ([]Changeset, error)
func (ChangesetController) PlanAndApply ¶ added in v0.0.50
func (c ChangesetController) PlanAndApply(request ChangesetPlanRequest, user *auth.User) ([]Changeset, error)
type ChangesetPlanRequest ¶ added in v0.0.50
type ChangesetPlanRequest struct { ChartReleases []ChangesetPlanRequestChartReleaseEntry `json:"chartReleases"` Environments []ChangesetPlanRequestEnvironmentEntry `json:"environments"` }
type ChangesetPlanRequestChartReleaseEntry ¶ added in v0.0.50
type ChangesetPlanRequestChartReleaseEntry struct { CreatableChangeset UseExactVersionsFromOtherChartRelease *string `json:"useExactVersionsFromOtherChartRelease"` }
type ChangesetPlanRequestEnvironmentEntry ¶ added in v0.0.50
type ChangesetPlanRequestEnvironmentEntry struct { Environment string UseExactVersionsFromOtherEnvironment *string `json:"useExactVersionsFromOtherEnvironment"` FollowVersionsFromOtherEnvironment *string `json:"followVersionsFromOtherEnvironment"` IncludeCharts []string `json:"includeCharts"` // If omitted, will include all charts ExcludeCharts []string `json:"excludeCharts"` }
type Chart ¶
type Chart struct { ReadableBaseType CreatableChart }
type ChartController ¶
type ChartController = ModelController[v2models.Chart, Chart, CreatableChart, EditableChart]
type ChartRelease ¶
type ChartRelease struct { ReadableBaseType ChartInfo *Chart `json:"chartInfo,omitempty" form:"-"` ClusterInfo *Cluster `json:"clusterInfo,omitempty" form:"-"` EnvironmentInfo *Environment `json:"environmentInfo,omitempty" form:"-"` AppVersionReference string `json:"appVersionReference,omitempty" form:"appVersionReference"` AppVersionInfo *AppVersion `json:"appVersionInfo,omitempty" form:"-"` ChartVersionReference string `json:"chartVersionReference,omitempty" form:"chartVersionReference"` ChartVersionInfo *ChartVersion `json:"chartVersionInfo,omitempty" form:"-"` DestinationType string `json:"destinationType" form:"destinationType" enum:"environment,cluster"` // Calculated field CreatableChartRelease }
type ChartReleaseController ¶
type ChartReleaseController = ModelController[v2models.ChartRelease, ChartRelease, CreatableChartRelease, EditableChartRelease]
type ChartVersion ¶
type ChartVersion struct { ReadableBaseType ChartInfo *Chart `json:"chartInfo,omitempty" form:"-"` ParentChartVersionInfo *ChartVersion `json:"parentChartVersionInfo,omitempty" swaggertype:"object" form:"-"` CreatableChartVersion }
type ChartVersionController ¶
type ChartVersionController = ModelController[v2models.ChartVersion, ChartVersion, CreatableChartVersion, EditableChartVersion]
type Cluster ¶
type Cluster struct { ReadableBaseType CreatableCluster }
Cluster @description The full set of Cluster fields that can be read or used for filtering queries
type ClusterController ¶
type ClusterController = ModelController[v2models.Cluster, Cluster, CreatableCluster, EditableCluster]
type ControllerSet ¶
type ControllerSet struct { ClusterController *ClusterController EnvironmentController *EnvironmentController ChartController *ChartController ChartVersionController *ChartVersionController AppVersionController *AppVersionController ChartReleaseController *ChartReleaseController ChangesetController *ChangesetController }
func NewControllerSet ¶
func NewControllerSet(stores *v2models.StoreSet) *ControllerSet
type Creatable ¶
type Creatable[R Readable] interface { // contains filtered or unexported methods }
Creatable represents the set of fields that can be set upon creation by a user. The fields available on a Creatable are a subset of those available on a Readable. Generally, a Creatable will embed an Editable, since all fields that can be edited can be set upon creation.
type CreatableAppVersion ¶
type CreatableAppVersion struct { Chart string `json:"chart" form:"chart"` // Required when creating AppVersion string `json:"appVersion" form:"appVersion"` // Required when creating GitCommit string `json:"gitCommit" form:"gitCommit"` GitBranch string `json:"gitBranch" form:"gitBranch"` ParentAppVersion string `json:"parentAppVersion" form:"parentAppVersion"` EditableAppVersion }
type CreatableChangeset ¶ added in v0.0.50
type CreatableChangeset struct { ToAppVersionResolver *string `json:"toAppVersionResolver,omitempty" form:"toAppVersionResolver"` ToAppVersionExact *string `json:"toAppVersionExact,omitempty" form:"toAppVersionExact"` ToAppVersionBranch *string `json:"toAppVersionBranch,omitempty" form:"toAppVersionBranch"` ToAppVersionCommit *string `json:"toAppVersionCommit,omitempty" form:"toAppVersionCommit"` ToAppVersionFollowChartRelease string `json:"toAppVersionFollowChartRelease,omitempty" form:"toAppVersionFollowChartRelease"` ToChartVersionResolver *string `json:"toChartVersionResolver,omitempty" form:"toChartVersionResolver"` ToChartVersionExact *string `json:"toChartVersionExact,omitempty" form:"toChartVersionExact"` ToChartVersionFollowChartRelease string `json:"toChartVersionFollowChartRelease,omitempty" form:"toChartVersionFollowChartRelease"` ToHelmfileRef *string `json:"toHelmfileRef,omitempty" form:"toHelmfileRef"` ToFirecloudDevelopRef *string `json:"toFirecloudDevelopRef,omitempty" form:"toFirecloudDevelopRef"` ChartRelease string `json:"chartRelease" form:"chartRelease"` EditableChangeset }
type CreatableChart ¶
type CreatableChart struct { Name string `json:"name" form:"name"` // Required when creating EditableChart }
type CreatableChartRelease ¶
type CreatableChartRelease struct { Chart string `json:"chart" form:"chart"` // Required when creating Cluster string `json:"cluster" form:"cluster"` // When creating, will default the environment's default cluster, if provided. Either this or environment must be provided. Environment string `json:"environment" form:"environment"` // Either this or cluster must be provided. Name string `json:"name" form:"name"` // When creating, will be calculated if left empty Namespace string `json:"namespace" form:"namespace"` // When creating, will default to the environment's default namespace, if provided AppVersionResolver *string `json:"appVersionResolver" form:"appVersionResolver" enums:"branch,commit,exact,follow,none"` // // When creating, will default to automatically reference any provided app version fields AppVersionExact *string `json:"appVersionExact" form:"appVersionExact"` AppVersionBranch *string `json:"appVersionBranch" form:"appVersionBranch"` // When creating, will default to the app's mainline branch if no other app version info is present AppVersionCommit *string `json:"appVersionCommit" form:"appVersionCommit"` AppVersionFollowChartRelease string `json:"appVersionFollowChartRelease" form:"appVersionFollowChartRelease"` ChartVersionResolver *string `json:"chartVersionResolver" form:"chartVersionResolver" enums:"latest,exact,follow"` // When creating, will default to automatically reference any provided chart version ChartVersionExact *string `json:"chartVersionExact" form:"chartVersionExact"` ChartVersionFollowChartRelease string `json:"chartVersionFollowChartRelease" form:"chartVersionFollowChartRelease"` HelmfileRef *string `json:"helmfileRef" form:"helmfileRef" default:"HEAD"` FirecloudDevelopRef *string `json:"firecloudDevelopRef" form:"firecloudDevelopRef"` EditableChartRelease }
type CreatableChartVersion ¶
type CreatableChartVersion struct { Chart string `json:"chart" form:"chart"` // Required when creating ChartVersion string `json:"chartVersion" form:"chartVersion"` // Required when creating ParentChartVersion string `json:"parentChartVersion" form:"parentChartVersion"` EditableChartVersion }
type CreatableCluster ¶
type CreatableCluster struct { Name string `json:"name" form:"name"` // Required when creating Provider string `json:"provider" form:"provider" enums:"google,azure" default:"google"` GoogleProject string `json:"googleProject" form:"googleProject"` // Required when creating if provider is 'google' AzureSubscription string `json:"azureSubscription" form:"azureSubscription"` // Required when creating if providers is 'azure' Location string `json:"location" form:"location" default:"us-central1-a"` EditableCluster }
CreatableCluster @description The subset of Cluster fields that can be set upon creation
type CreatableEnvironment ¶
type CreatableEnvironment struct { Base string `json:"base" form:"base"` // Required when creating ChartReleasesFromTemplate *bool `json:"chartReleasesFromTemplate" form:"chartReleasesFromTemplate" default:"true"` // Upon creation of a dynamic environment, if this is true the template's chart releases will be copied to the new environment Lifecycle string `json:"lifecycle" form:"lifecycle" default:"dynamic"` Name string `json:"name" form:"name"` // When creating, will be calculated if dynamic, required otherwise TemplateEnvironment string `json:"templateEnvironment" form:"templateEnvironment"` // Required for dynamic environments UniqueResourcePrefix string `json:"uniqueResourcePrefix" form:"uniqueResourcePrefix"` // When creating, will be calculated if left empty DefaultNamespace string `json:"defaultNamespace" form:"defaultNamespace"` // When creating, will be calculated if left empty NamePrefix string `json:"namePrefix" form:"namePrefix"` // Used for dynamic environment name generation only, to override using the owner email handle and template name EditableEnvironment }
type Editable ¶
Editable represents the set of fields that can be mutated by a user. The fields available on an Editable are a subset of those available on a Creatable.
type EditableAppVersion ¶
type EditableAppVersion struct {
Description string `json:"description" form:"description"` // Generally the Git commit message
}
type EditableChangeset ¶ added in v0.0.50
type EditableChangeset struct{}
type EditableChart ¶
type EditableChart struct { ChartRepo *string `json:"chartRepo" form:"chartRepo" default:"terra-helm"` AppImageGitRepo *string `json:"appImageGitRepo" form:"appImageGitRepo"` AppImageGitMainBranch *string `json:"appImageGitMainBranch" form:"appImageGitMainBranch"` ChartExposesEndpoint *bool `json:"chartExposesEndpoint" form:"chartExposesEndpoint" default:"false"` // Indicates if the default subdomain, protocol, and port fields are relevant for this chart LegacyConfigsEnabled *bool `json:"legacyConfigsEnabled" form:"legacyConfigsEnbled" default:"false"` // Indicates whether a chart requires config rendering from firecloud-develop DefaultSubdomain *string `json:"defaultSubdomain" form:"defaultSubdomain"` // When creating, will default to the name of the chart DefaultProtocol *string `json:"defaultProtocol" form:"defaultProtocol" default:"https"` DefaultPort *uint `json:"defaultPort" form:"defaultPort" default:"443"` }
type EditableChartRelease ¶
type EditableChartRelease struct { Subdomain *string `json:"subdomain,omitempty" form:"subdomain"` // When creating, will use the chart's default if left empty Protocol *string `json:"protocol,omitempty" form:"protocol"` // When creating, will use the chart's default if left empty Port *uint `json:"port,omitempty" form:"port"` // When creating, will use the chart's default if left empty }
type EditableChartVersion ¶
type EditableChartVersion struct {
Description string `json:"description" form:"description"` // Generally the Git commit message
}
type EditableCluster ¶
type EditableCluster struct { Base *string `json:"base" form:"base"` // Required when creating Address *string `json:"address" form:"address"` // Required when creating RequiresSuitability *bool `json:"requiresSuitability" form:"requiresSuitability" default:"false"` HelmfileRef *string `json:"helmfileRef" form:"helmfileRef" default:"HEAD"` }
EditableCluster @description The subset of Cluster fields that can be edited after creation
type EditableEnvironment ¶
type EditableEnvironment struct { DefaultCluster *string `json:"defaultCluster" form:"defaultCluster"` DefaultFirecloudDevelopRef *string `json:"defaultFirecloudDevelopRef" form:"defaultFirecloudDevelopRef" default:"dev"` // should be the environment branch for live envs. Is usually dev for template/dynamic but not necessarily Owner *string `json:"owner" form:"owner"` // When creating, will be set to your email RequiresSuitability *bool `json:"requiresSuitability" form:"requiresSuitability" default:"false"` BaseDomain *string `json:"baseDomain" form:"baseDomain" default:"bee.envs-terra.bio"` NamePrefixesDomain *bool `json:"namePrefixesDomain" form:"namePrefixesDomain" default:"true"` HelmfileRef *string `json:"helmfileRef" form:"helmfileRef" default:"HEAD"` PreventDeletion *bool `json:"preventDeletion" form:"preventDeletion" default:"false"` // Used to protect specific BEEs from deletion (thelma checks this field) AutoDelete *environment.AutoDelete `json:"autoDelete" form:"autoDelete"` // Used to schedule automatic deletion of BEEs }
type Environment ¶
type Environment struct { ReadableBaseType TemplateEnvironmentInfo *Environment `json:"templateEnvironmentInfo,omitempty" swaggertype:"object" form:"-"` // Single-layer recursive; provides info of the template environment if this environment has one DefaultClusterInfo *Cluster `json:"defaultClusterInfo,omitempty" form:"-"` ValuesName string `json:"valuesName" form:"valuesName"` CreatableEnvironment }
type EnvironmentController ¶
type EnvironmentController = ModelController[v2models.Environment, Environment, CreatableEnvironment, EditableEnvironment]
type ModelController ¶
type ModelController[M v2models.Model, R Readable, C Creatable[R], E Editable[R, C]] struct { // contains filtered or unexported fields }
ModelController exposes the same "verbs" exposed by a v2models.internalStore, but it adds the user-type to database-type mapping that provides type safety for what fields can be read/queried, created, and edited. ModelController also handles setting defaults--even complex ones, like from template Environment entries.
Implementation note: this mapping behavior exists at the controller level (rather than in serializers, etc. written elsewhere) because going from a user-type to a database-type actually itself requires a database connection, so it can resolve associations. For example, a user-type would allow an association to be referenced by name, ID, or any other selector, but a database-type would specifically use the ID as the foreign key. ModelController is responsible for doing that translation. A bonus of defining the controller in terms of user-types is that defaults can be handled in terms of the user-type, making for simpler documentation and more obvious behavior.
func (ModelController[M, R, C, E]) Create ¶
func (c ModelController[M, R, C, E]) Create(creatable C, user *auth.User) (R, bool, error)
func (ModelController[M, R, C, E]) Delete ¶
func (c ModelController[M, R, C, E]) Delete(selector string, user *auth.User) (R, error)
func (ModelController[M, R, C, E]) Edit ¶
func (c ModelController[M, R, C, E]) Edit(selector string, editable E, user *auth.User) (R, error)
func (ModelController[M, R, C, E]) Get ¶
func (c ModelController[M, R, C, E]) Get(selector string) (R, error)
func (ModelController[M, R, C, E]) GetOtherValidSelectors ¶
func (c ModelController[M, R, C, E]) GetOtherValidSelectors(selector string) ([]string, error)
func (ModelController[M, R, C, E]) ListAllMatching ¶
func (c ModelController[M, R, C, E]) ListAllMatching(filter R, limit int) ([]R, error)
type Readable ¶
type Readable interface{}
Readable represents the full set of fields that can be read (or queried for) by a user. Generally, a Readable will at east embed a ReadableBaseType and a Creatable inside it, but it can have additional read-only fields. A Readable should map to some database v2models.Model type; see ModelController for more context.