Documentation
¶
Index ¶
- Constants
- func ZeroPrivateFields(r Model)
- func ZeroReadonlyFields(r Model)
- type AWSKubeConfig
- type ActionStatus
- type Addresses
- type App
- type BaseModel
- type BelongsToField
- type BytesValue
- type CloudAccount
- type Component
- type ComponentConfig
- type ComponentPrivateImageKey
- type ContainerBlueprint
- type CoresValue
- type CustomDeployScript
- type Entrypoint
- type EnvVar
- type Error
- type IndexedModelField
- type Instance
- type Kube
- type Model
- type Mount
- type Node
- type Port
- type PortAddress
- type PrivateImageKey
- type Release
- type ResourceMetrics
- type Session
- type TaggedModelField
- type User
- type Volume
- type VolumeBlueprint
Constants ¶
View Source
const ( UserRoleAdmin = "admin" UserRoleUser = "user" )
Variables ¶
This section is empty.
Functions ¶
func ZeroPrivateFields ¶
func ZeroPrivateFields(r Model)
ZeroPrivateFields takes a Model with pointer, and zeroes any fields with the tag sg:"private".
func ZeroReadonlyFields ¶
func ZeroReadonlyFields(r Model)
ZeroReadonlyFields takes a Model with pointer, and zeroes any fields with the tag sg:"readonly".
Types ¶
type AWSKubeConfig ¶
type AWSKubeConfig struct {
Region string `json:"region" validate:"nonzero,regexp=^[a-z]{2}-[a-z]+-[0-9]$"`
AvailabilityZone string `json:"availability_zone" validate:"nonzero,regexp=^[a-z]{2}-[a-z]+-[0-9][a-z]$"`
VPCIPRange string `json:"vpc_ip_range" validate:"nonzero" sg:"default=172.20.0.0/16"`
PublicSubnetIPRange string `json:"public_subnet_ip_range" validate:"nonzero" sg:"default=172.20.0.0/24"`
MasterPrivateIP string `json:"master_private_ip" validate:"nonzero" sg:"default=172.20.0.9"`
PrivateKey string `json:"private_key,omitempty" sg:"readonly,private"`
VPCID string `json:"vpc_id" sg:"readonly"`
InternetGatewayID string `json:"internet_gateway_id" sg:"readonly"`
PublicSubnetID string `json:"public_subnet_id" sg:"readonly"`
RouteTableID string `json:"route_table_id" sg:"readonly"`
RouteTableSubnetAssociationID string `json:"route_table_subnet_association_id" sg:"readonly"`
ELBSecurityGroupID string `json:"elb_security_group_id" sg:"readonly"`
NodeSecurityGroupID string `json:"node_security_group_id" sg:"readonly"`
MasterID string `json:"master_id" sg:"readonly"`
}
type ActionStatus ¶
type Addresses ¶
type Addresses struct {
External []*PortAddress `json:"external"`
Internal []*PortAddress `json:"internal"`
}
type App ¶
type App struct {
BaseModel
Name string `json:"name" validate:"nonzero,max=24,regexp=^[a-z]([-a-z0-9]*[a-z0-9])?$" gorm:"not null;unique_index:name_within_kube"`
// belongs_to Kube
Kube *Kube `json:"kube,omitempty"`
KubeID *int64 `json:"kube_id" gorm:"not null;index;unique_index:name_within_kube"`
// has_many Components
Components []*Component `json:"components,omitempty"`
}
type BaseModel ¶
type BaseModel struct {
ID *int64 `gorm:"primary_key" json:"id,omitempty" sg:"readonly"`
UUID string `json:"uuid,omitempty" sg:"readonly"`
CreatedAt time.Time `json:"created_at,omitempty" sg:"readonly"` // TODO won't be omitted cuz not *time.Time
UpdatedAt time.Time `json:"updated_at,omitempty" sg:"readonly"`
Status *ActionStatus `gorm:"-" json:"status,omitempty"`
}
func (*BaseModel) SetActionStatus ¶
func (m *BaseModel) SetActionStatus(status *ActionStatus)
type BelongsToField ¶
type BelongsToField struct {
Field reflect.StructField
Value reflect.Value
}
type BytesValue ¶
type BytesValue struct {
Bytes int64
}
func BytesFromString ¶
func BytesFromString(str string) *BytesValue
func (*BytesValue) Gibibytes ¶
func (v *BytesValue) Gibibytes() float64
func (*BytesValue) MarshalJSON ¶
func (b *BytesValue) MarshalJSON() ([]byte, error)
func (*BytesValue) Mebibytes ¶
func (v *BytesValue) Mebibytes() float64
func (*BytesValue) ToKubeMebibytes ¶
func (v *BytesValue) ToKubeMebibytes() string
func (*BytesValue) UnmarshalJSON ¶
func (b *BytesValue) UnmarshalJSON(raw []byte) error
type CloudAccount ¶
type CloudAccount struct {
BaseModel
// has_many Kubes
Kubes []*Kube `json:"kubes,omitempty"`
Name string `json:"name" validate:"nonzero" gorm:"not null;unique_index"`
Provider string `json:"provider" validate:"regexp=^(aws)$" gorm:"not null"`
// NOTE this is loose map to allow for multiple clouds (eventually)
Credentials map[string]string `json:"credentials,omitempty" gorm:"-" sg:"store_as_json_in=CredentialsJSON,private"`
CredentialsJSON []byte `json:"-" gorm:"not null"`
}
type Component ¶
type Component struct {
BaseModel
// belongs_to App
App *App `json:"app,omitempty"`
AppID *int64 `json:"app_id" gorm:"not null;index;unique_index:name_within_app"`
Name string `json:"name" validate:"nonzero,max=17,regexp=^[a-z]([-a-z0-9]*[a-z0-9])?$" gorm:"not null;unique_index:name_within_app"`
// CustomDeployScript is stored as JSON (like an embed in Mongo)
CustomDeployScript *CustomDeployScript `json:"custom_deploy_script,omitempty" gorm:"-" sg:"store_as_json_in=CustomDeployScriptJSON"`
CustomDeployScriptJSON []byte `json:"-"`
// has_many Releases (for preloading)
Releases []*Release `json:"releases,omitempty"`
// has_many Instances (for preloading)
Instances []*Instance `json:"instances,omitempty"`
// has_one CurrentRelease
CurrentRelease *Release `json:"current_release,omitempty" gorm:"ForeignKey:CurrentReleaseID"`
CurrentReleaseID *int64 `json:"current_release_id" sg:"readonly"`
// has_one TargetRelease
TargetRelease *Release `json:"target_release,omitempty" gorm:"ForeignKey:TargetReleaseID"`
TargetReleaseID *int64 `json:"target_release_id" sg:"readonly"`
Addresses *Addresses `json:"addresses,omitempty" gorm:"-" sg:"store_as_json_in=AddressesJSON"`
AddressesJSON []byte `json:"-"`
// has_many ComponentPrivateImageKeys (really a many2many with PrivateImageKeys)
PrivateImageKeys []*ComponentPrivateImageKey `json:"private_image_keys"`
}
func (*Component) InstanceByNum ¶
func (*Component) InstanceCount ¶
returns max of the 2 releases
type ComponentConfig ¶
type ComponentConfig struct {
// These attributes, when changed from last Release, indicate a restart is
// needed (or just new instances through other means).
Volumes []*VolumeBlueprint `json:"volumes"`
Containers []*ContainerBlueprint `json:"containers" validate:"min=1"`
TerminationGracePeriod int `json:"termination_grace_period" validate:"min=0" sg:"default=10"`
}
type ComponentPrivateImageKey ¶
type ComponentPrivateImageKey struct {
BaseModel
// belongs_to Component
Component *Component `json:"component,omitempty"`
ComponentID *int64 `json:"component_id" gorm:"not null;index"`
// belongs_to PrivateImageKey
Key *PrivateImageKey `json:"key,omitempty" gorm:"ForeignKey:KeyID"`
KeyID *int64 `json:"key_id" gorm:"not null;index"`
}
Join model
type ContainerBlueprint ¶
type ContainerBlueprint struct {
Image string `json:"image" validate:"nonzero,regexp=^[-\\w\\.\\/]+(:[-\\w\\.]+)?$"`
Name string `json:"name,omitempty" validate:"regexp=^[-\\w\\.\\/]+(:[-\\w\\.]+)?$"`
Command []string `json:"command,omitempty"`
Ports []*Port `json:"ports,omitempty"`
Env []*EnvVar `json:"env,omitempty"`
CPURequest *CoresValue `json:"cpu_request"`
CPULimit *CoresValue `json:"cpu_limit"`
RAMRequest *BytesValue `json:"ram_request"`
RAMLimit *BytesValue `json:"ram_limit"`
Mounts []*Mount `json:"mounts,omitempty"`
}
func (*ContainerBlueprint) NameOrDefault ¶
func (c *ContainerBlueprint) NameOrDefault() string
type CoresValue ¶
type CoresValue struct {
Millicores int
}
func CoresFromString ¶
func CoresFromString(str string) *CoresValue
func (*CoresValue) Cores ¶
func (v *CoresValue) Cores() float64
func (*CoresValue) MarshalJSON ¶
func (c *CoresValue) MarshalJSON() ([]byte, error)
func (*CoresValue) ToKubeMillicores ¶
func (v *CoresValue) ToKubeMillicores() string
func (*CoresValue) UnmarshalJSON ¶
func (c *CoresValue) UnmarshalJSON(raw []byte) error
type CustomDeployScript ¶
type Entrypoint ¶
type Entrypoint struct {
BaseModel
// belongs_to Kube
Kube *Kube `json:"kube,omitempty"`
KubeID *int64 `json:"kube_id" gorm:"not null;index"`
Name string `json:"name" validate:"nonzero,max=21,regexp=^[\\w-]+$" gorm:"not null;unique_index"`
ProviderID string `json:"provider_id" sg:"readonly"`
// the ELB address
Address string `json:"address,omitempty" sg:"readonly"`
}
func (*Entrypoint) BeforeCreate ¶
func (m *Entrypoint) BeforeCreate() error
type IndexedModelField ¶
func IndexedFields ¶
func IndexedFields(m Model) (fields []*IndexedModelField)
type Instance ¶
type Instance struct {
BaseModel
// belongs_to Component (we could simply get by current or target ID off of Component, but this makes it simpler for Component-based lookup)
Component *Component `json:"component,omitempty"`
ComponentID *int64 `json:"component_id" gorm:"not null;index"`
// belongs_to Release (this can be changed)
Release *Release `json:"release,omitempty"`
ReleaseID *int64 `json:"release_id" gorm:"not null;index"`
// has_many Volumes (for preloading)
Volumes []*Volume `json:"volumes,omitempty"`
Num int `json:"num"`
Name string `json:"name"`
Started bool `json:"started" gorm:"index"`
ResourceMetrics
Addresses *Addresses `json:"addresses,omitempty" gorm:"-" sg:"store_as_json_in=AddressesJSON"`
AddressesJSON []byte `json:"-"`
}
type Kube ¶
type Kube struct {
BaseModel
// belongs_to CloudAccount
CloudAccount *CloudAccount `json:"cloud_account,omitempty"`
CloudAccountID *int64 `json:"cloud_account_id" gorm:"not null;index"`
// has_many Nodes
Nodes []*Node `json:"nodes,omitempty"`
// has_many Apps
Apps []*App `json:"apps,omitempty"`
// has_many Entrypoints
Entrypoints []*Entrypoint `json:"entrypoints,omitempty"`
// has_many Volumes
Volumes []*Volume `json:"volumes,omitempty"`
Name string `json:"name" validate:"nonzero,max=12,regexp=^[a-z]([-a-z0-9]*[a-z0-9])?$" gorm:"not null;unique_index"`
MasterNodeSize string `json:"master_node_size" validate:"nonzero"`
NodeSizes []string `json:"node_sizes" gorm:"-" validate:"min=1" sg:"store_as_json_in=NodeSizesJSON"`
NodeSizesJSON []byte `json:"-" gorm:"not null"`
Username string `json:"username" validate:"nonzero"`
Password string `json:"password" validate:"nonzero"`
// NOTE due to how we marshal this as JSON, it's difficult to have this stored
// as an interface, because unmarshalling causes us to lose the underlying
// type. So, this is kindof like a whacky form of single-table inheritance.
AWSConfig *AWSKubeConfig `json:"aws_config,omitempty" gorm:"-" sg:"store_as_json_in=AWSConfigJSON"`
AWSConfigJSON []byte `json:"-"`
MasterPublicIP string `json:"master_public_ip" sg:"readonly"`
Ready bool `json:"ready" sg:"readonly" gorm:"index"`
}
type Model ¶
type Model interface {
GetID() interface{}
GetUUID() string
SetUUID()
SetActionStatus(*ActionStatus)
}
type Node ¶
type Node struct {
BaseModel
// belongs_to Kube
Kube *Kube `json:"kube,omitempty"`
KubeID *int64 `json:"kube_id" gorm:"not null;index"`
// This is the only input for Node
Size string `json:"size" validate:"nonzero"`
ProviderID string `json:"provider_id" sg:"readonly" gorm:"index"`
Name string `json:"name" sg:"readonly" gorm:"index"`
ExternalIP string `json:"external_ip" sg:"readonly"`
ProviderCreationTimestamp time.Time `json:"provider_creation_timestamp" sg:"readonly"`
OutOfDisk bool `json:"out_of_disk" sg:"readonly"`
Ready bool `json:"ready" sg:"readonly"`
ResourceMetrics
}
type Port ¶
type Port struct {
// TODO Kube only accepts TCP|UDP for protocol values, but we accept values
// like HTTP, which are used to display component addresses. We should either
// build a map defining the accepted application protocols on top of TCP|UDP,
// or make a sep. field.
Protocol string `json:"protocol" validate:"nonzero" sg:"default=TCP"`
// Number is the port number used by the container. If your application runs
// on port 80, for example, use that.
Number int `json:"number" validate:"nonzero,max=40000"`
// Public determines whether the port can be accessed ONLY from other
// Components within Supergiant (false), or from BOTH inside and outside of
// Supergiant (true). When true, the port can be accessed from external Node
// IPs. When true, and with an EntrypointDomain provided, the port will be
// exposed on an external load balancer.
Public bool `json:"public"`
// PerInstance, when true, provides each Instance of a Component with its own
// addressable endpoint (in addition to the normal Component-wide endpoints).
// When false, Instances can not be reached directly, as traffic to the port
// is load balanced randomly across all Instances.
PerInstance bool `json:"per_instance"`
// EntrypointDomain specifies which Entrypoint this Port is added to. Does not
// apply when Public is false.
EntrypointID *int64 `json:"entrypoint_id,omitempty"`
// ExternalNumber instructs the Entrypoint to set the actual Port number
// specified as the external load balancer port.
//
// TODO validation needed just like on Number, but it can't be nonzero since
// the value provided can be 0.
//
// NOTE Does not apply when EntrypointDomain is nil.
// Does not apply to PerInstance ports.
ExternalNumber int `json:"external_number"`
}
type PortAddress ¶
type PrivateImageKey ¶
type PrivateImageKey struct {
BaseModel
// SSL bool `json:"ssl"`
Host string `json:"host" validate:"nonzero,regexp=^[^/]+$"`
Username string `json:"username" validate:"nonzero" gorm:"not null;index"` // Not unique, because maybe multiple registries
// NOTE these are not stored in database
Email string `json:"email" validate:"nonzero" sg:"private" gorm:"-"`
Password string `json:"password" validate:"nonzero" sg:"private" gorm:"-"`
// Used for K8S Secret
Key string `json:"key" validate:"nonzero" sg:"private,readonly"`
}
func (*PrivateImageKey) MakeKey ¶
func (m *PrivateImageKey) MakeKey()
func (*PrivateImageKey) RegistryURL ¶
func (m *PrivateImageKey) RegistryURL() string
type Release ¶
type Release struct {
BaseModel
// belongs_to Component
Component *Component `json:"component,omitempty"`
ComponentID *int64 `json:"component_id" gorm:"not null;index"`
// TODO
// InstanceGroup is used as a labeling mechanism for instances. If nil,
// InstanceGroup is set equal to the release's Timestamp. If a value is
// supplied by the user, it MUST be the current (previous) Release's
// Timestamp.
//
// The purpose of InstanceGroup is to prevent restarting between Releases.
// I'm pretty sure the ONLY scenario in which this value makes sense is when
// changing InstanceCount, and the value supplied in such a scenario must be
// the previous Release's timestamp.
//
// It seems as though we need to break deploys up into:
// - config changes
// - adding/removing instances
//
// It might still makes sense to have Release as a grouping mechanism, though,
// because it could allow for grouping metrics recorded per-Release. However,
// you may be able to separate the operations, but have every operation create
// a new record that records the config / instance count at that time.
InstanceGroup *int64 `json:"instance_group,omitempty"`
InstanceCount int `json:"instance_count" validate:"min=1" sg:"default=1"`
// Config is stored as JSON (like an embed in Mongo)
Config *ComponentConfig `json:"config" gorm:"-" sg:"store_as_json_in=ConfigJSON"`
ConfigJSON []byte `json:"-" gorm:"not null"`
InUse bool `json:"in_use" sg:"readonly"`
}
NOTE the word Blueprint is used for Volumes and Containers, since they are both "definitions" that create "instances" of the real thing
type ResourceMetrics ¶
type ResourceMetrics struct {
CPUUsage int64 `json:"cpu_usage" sg:"readonly"`
CPULimit int64 `json:"cpu_limit" sg:"readonly"`
RAMUsage int64 `json:"ram_usage" sg:"readonly"`
RAMLimit int64 `json:"ram_limit" sg:"readonly"`
}
NOTE this is not to be confused with our concept of Resources like Apps and Components -- this is for CPU / RAM / disk.
type Session ¶
type Session struct {
ID string `json:"id"`
UserID *int64 `json:"user_id"`
CreatedAt time.Time `json:"created_at"`
User *User `json:"user"`
}
func (*Session) Description ¶
func (*Session) SetActionStatus ¶
func (m *Session) SetActionStatus(status *ActionStatus)
type TaggedModelField ¶
type TaggedModelField struct {
Field reflect.Value
Readonly bool
Private bool
Default interface{}
StoreAsJsonIn *reflect.Value
ForeignKeyOf *BelongsToField
}
func TaggedModelFieldsOf ¶
func TaggedModelFieldsOf(r Model) (taggedFields []*TaggedModelField)
type User ¶
type User struct {
BaseModel
Username string `json:"username" validate:"nonzero,max=24,regexp=^[A-Za-z0-9_-]+$" gorm:"not null;unique_index"`
Password string `json:"password,omitempty" validate:"nonzero,min=8,max=32" gorm:"-" sg:"private"`
Role string `json:"role" validate:"nonzero" gorm:"not null" sg:"default=user"`
EncryptedPassword []byte `json:"-" gorm:"not null"`
APIToken string `json:"api_token" gorm:"not null;index" sg:"readonly"`
}
func (*User) BeforeCreate ¶
func (*User) BeforeSave ¶
func (*User) GenerateAPIToken ¶
func (m *User) GenerateAPIToken()
type Volume ¶
type Volume struct {
BaseModel
// belongs_to Instance
Instance *Instance `json:"instance"`
InstanceID *int64 `json:"instance_id" gorm:"not null;index"`
// belongs_to Kube
Kube *Kube `json:"kube"`
KubeID *int64 `json:"kube_id" gorm:"not null;index"`
// NOTE these are the same as VolumeBlueprint (we may want to repeat valiations)
Name string `json:"name"`
Type string `json:"type"`
Size int `json:"size"`
ProviderID string `json:"provider_id" sg:"readonly"`
}
type VolumeBlueprint ¶
Click to show internal directories.
Click to hide internal directories.