Documentation ¶
Overview ¶
Package resolve is a heart of Aptomi that performs policy resolution, taking policy and service consumption intents as input, producing a set of components to be instantiated in the cloud (desired state) as output, along with their discovery parameters, code parameters, and component instance graph.
Index ¶
- Constants
- Variables
- func KeyForComponentKey(componentKey string) string
- type ComponentInstance
- func (instance *ComponentInstance) GetDeployName() string
- func (instance *ComponentInstance) GetKey() string
- func (instance *ComponentInstance) GetName() string
- func (instance *ComponentInstance) GetNamespace() string
- func (instance *ComponentInstance) GetRunningTime() time.Duration
- func (instance *ComponentInstance) UpdateTimes(createdAt time.Time, updatedAt time.Time)
- type ComponentInstanceKey
- func (cik ComponentInstanceKey) GetDeployName() string
- func (cik ComponentInstanceKey) GetKey() string
- func (cik *ComponentInstanceKey) GetParentServiceKey() *ComponentInstanceKey
- func (cik *ComponentInstanceKey) IsComponent() bool
- func (cik *ComponentInstanceKey) IsService() bool
- func (cik *ComponentInstanceKey) MakeCopy() *ComponentInstanceKey
- type ComponentInstanceMetadata
- type CriticalError
- type PolicyResolution
- func (resolution *PolicyResolution) AppendData(ops *PolicyResolution) error
- func (resolution *PolicyResolution) GetComponentInstanceEntry(cik *ComponentInstanceKey) *ComponentInstance
- func (resolution *PolicyResolution) RecordCodeParams(cik *ComponentInstanceKey, codeParams util.NestedParameterMap) error
- func (resolution *PolicyResolution) RecordDiscoveryParams(cik *ComponentInstanceKey, discoveryParams util.NestedParameterMap) error
- func (resolution *PolicyResolution) RecordLabels(cik *ComponentInstanceKey, labels *lang.LabelSet)
- func (resolution *PolicyResolution) RecordResolved(cik *ComponentInstanceKey, dependency *lang.Dependency, ...)
- func (resolution *PolicyResolution) StoreEdge(src *ComponentInstanceKey, dst *ComponentInstanceKey)
- type PolicyResolver
Constants ¶
const AllowIngres = "allow_ingress"
AllowIngres is an special key, which is used in DataForPlugins to indicate whether ingress traffic should be allowed for a given component instance
Variables ¶
var ComponentInstanceObject = &runtime.Info{ Kind: "component-instance", Storable: true, Versioned: false, Constructor: func() runtime.Object { return &ComponentInstance{} }, }
ComponentInstanceObject is an informational data structure with Kind and Constructor for component instance object
var MaxConcurrentGoRoutines = sysruntime.NumCPU()
MaxConcurrentGoRoutines is the number of concurrently running goroutines for policy evaluation and processing. We don't necessarily want to run a lot of them due to CPU/memory constraints and due to the fact that there is minimal io wait time in policy processing (goroutines are mostly busy doing calculations as opposed to waiting).
Functions ¶
func KeyForComponentKey ¶
KeyForComponentKey returns object key by provided component instance key
Types ¶
type ComponentInstance ¶
type ComponentInstance struct { runtime.TypeKind `yaml:",inline"` // Metadata is an object metadata for component instance Metadata *ComponentInstanceMetadata // DependencyKeys is a list of dependency keys which are keeping this component instantiated DependencyKeys map[string]bool // CalculatedLabels is a set of calculated labels for the component, aggregated over all uses CalculatedLabels *lang.LabelSet // CalculatedDiscovery is a set of calculated discovery parameters for the component (non-conflicting over all uses of this component) CalculatedDiscovery util.NestedParameterMap // CalculatedCodeParams is a set of calculated code parameters for the component (non-conflicting over all uses of this component) CalculatedCodeParams util.NestedParameterMap // EdgesIn is a set of incoming graph edges ('key' -> true) into this component instance. Storing for observability and reporting, so we can reconstruct the graph EdgesIn map[string]bool // EdgesOut is a set of outgoing graph edges ('key' -> true) into this component instance. Storing for observability and reporting, so we can reconstruct the graph EdgesOut map[string]bool // DataForPlugins is an additional data recorded for use in plugins DataForPlugins map[string]string // CreatedAt is when this component instance was created CreatedAt time.Time // UpdatedAt is the last time when this component instance was updated UpdatedAt time.Time // Endpoints represents all URLs that could be used to access deployed service Endpoints map[string]string }
ComponentInstance is an instance of a particular code component within a service, which indicate that this component has to be instantiated and configured in a certain cluster. Policy resolver produces a map of component instances and their parameters in desired state (PolicyResolution) as result of policy resolution.
When a service gets instantiated, a special "root" component instance gets created with component name set to Metadata.Key.ComponentName == componentRootName. Then all "child" component instances get created, one per service component with type code.
Every ComponentInstance contains full information about for a given component instance - who is consuming this instance, labels, code params, discovery params, in & out graph edges (what component instances we depend on, what component instances depend on us), creation/update times, and endpoints retrieved from the underlying cloud.
func (*ComponentInstance) GetDeployName ¶
func (instance *ComponentInstance) GetDeployName() string
GetDeployName returns a string that could be used as name for deployment inside the cluster
func (*ComponentInstance) GetKey ¶
func (instance *ComponentInstance) GetKey() string
GetKey returns an object key. It's a component instance key, as generated by the engine
func (*ComponentInstance) GetName ¶
func (instance *ComponentInstance) GetName() string
GetName returns object name
func (*ComponentInstance) GetNamespace ¶
func (instance *ComponentInstance) GetNamespace() string
GetNamespace returns an object namespace. It's a system namespace for all component instances
func (*ComponentInstance) GetRunningTime ¶
func (instance *ComponentInstance) GetRunningTime() time.Duration
GetRunningTime returns the total lifetime of a component instance (since it was launched till now)
func (*ComponentInstance) UpdateTimes ¶
func (instance *ComponentInstance) UpdateTimes(createdAt time.Time, updatedAt time.Time)
UpdateTimes updates component creation and update times
type ComponentInstanceKey ¶
type ComponentInstanceKey struct { // required fields ClusterName string // mandatory Namespace string // determined from the contract ContractName string // mandatory ContextName string // mandatory ContextNameWithKeys string // calculated ServiceName string // determined from the context (included into key for readability) ComponentName string // component name // contains filtered or unexported fields }
ComponentInstanceKey is a key for component instance. During policy resolution every component instance gets assigned a unique string key. It's important to form those keys correctly, so that we can make actual comparison of actual state (components with their keys) and desired state (components with their keys).
Currently, component keys are formed from multiple parameters as follows. Cluster gets included as a part of the key (components running on different clusters must have different keys). Namespace gets included as a part of the key (components from different namespaces must have different keys). Contract, Context (with allocation keys), Service get included as a part of the key (Service must be within the same namespace as Contract). ComponentName gets included as a part of the key. For service-level component instances, ComponentName is set to componentRootName, while for all component instances within a service an actual Component.Name is used.
func NewComponentInstanceKey ¶
func NewComponentInstanceKey(cluster *lang.Cluster, contract *lang.Contract, context *lang.Context, allocationsKeysResolved []string, service *lang.Service, component *lang.ServiceComponent) *ComponentInstanceKey
NewComponentInstanceKey creates a new ComponentInstanceKey
func (ComponentInstanceKey) GetDeployName ¶
func (cik ComponentInstanceKey) GetDeployName() string
GetDeployName returns a string that could be used as name for deployment inside the cluster
func (ComponentInstanceKey) GetKey ¶
func (cik ComponentInstanceKey) GetKey() string
GetKey returns a string key
func (*ComponentInstanceKey) GetParentServiceKey ¶
func (cik *ComponentInstanceKey) GetParentServiceKey() *ComponentInstanceKey
GetParentServiceKey returns a key for the parent service, replacing componentName with componentRootName
func (*ComponentInstanceKey) IsComponent ¶
func (cik *ComponentInstanceKey) IsComponent() bool
IsComponent returns 'true' if it's a component instance key and we can go up to the corresponding service. And it will return 'false' if it's a service instance key
func (*ComponentInstanceKey) IsService ¶
func (cik *ComponentInstanceKey) IsService() bool
IsService returns 'true' if it's a contract instance key and we can't go up anymore. And it will return 'false' if it's a component instance key
func (*ComponentInstanceKey) MakeCopy ¶
func (cik *ComponentInstanceKey) MakeCopy() *ComponentInstanceKey
MakeCopy creates a copy of ComponentInstanceKey
type ComponentInstanceMetadata ¶
type ComponentInstanceMetadata struct {
Key *ComponentInstanceKey
}
ComponentInstanceMetadata is object metadata for ComponentInstance
type CriticalError ¶
type CriticalError struct { *errors.ErrorWithDetails // contains filtered or unexported fields }
CriticalError represents a critical error inside the engine. If a critical error occurs, it signals the engine to stop policy processing and fail policy resolution with an error. If a non-critical error occurs, then the engine will skip the current declaration of service consumption (the one that is currently being processed) and proceed with policy resolution, moving on to the remaining declarations of service consumption
func NewCriticalError ¶
func NewCriticalError(err *errors.ErrorWithDetails) *CriticalError
NewCriticalError creates a new critical error
func (*CriticalError) IsLogged ¶
func (err *CriticalError) IsLogged() bool
IsLogged returns if an error has been already processed and logged
func (*CriticalError) SetLoggedFlag ¶
func (err *CriticalError) SetLoggedFlag()
SetLoggedFlag sets a flag that an error has been logged. So that when we go up the recursion stack in the engine, it doesn't get logged multiple times
type PolicyResolution ¶
type PolicyResolution struct { // Resolved component instances: componentKey -> componentInstance ComponentInstanceMap map[string]*ComponentInstance // Resolved dependencies: dependencyID -> serviceKey DependencyInstanceMap map[string]string ComponentProcessingOrder []string // contains filtered or unexported fields }
PolicyResolution contains resolution data for the policy. It essentially represents the desired state calculated by policy resolver. It contains a calculated map of component instances with their data, information about resolved service consumption declarations, as well as processing order to components in which they have to be instantiated/updated/deleted.
func NewPolicyResolution ¶
func NewPolicyResolution() *PolicyResolution
NewPolicyResolution creates new empty PolicyResolution
func (*PolicyResolution) AppendData ¶
func (resolution *PolicyResolution) AppendData(ops *PolicyResolution) error
AppendData appends data to the current PolicyResolution record by aggregating data over component instances
func (*PolicyResolution) GetComponentInstanceEntry ¶
func (resolution *PolicyResolution) GetComponentInstanceEntry(cik *ComponentInstanceKey) *ComponentInstance
GetComponentInstanceEntry retrieves a component instance entry by key, or creates an new entry if it doesn't exist
func (*PolicyResolution) RecordCodeParams ¶
func (resolution *PolicyResolution) RecordCodeParams(cik *ComponentInstanceKey, codeParams util.NestedParameterMap) error
RecordCodeParams stores calculated code params for component instance
func (*PolicyResolution) RecordDiscoveryParams ¶
func (resolution *PolicyResolution) RecordDiscoveryParams(cik *ComponentInstanceKey, discoveryParams util.NestedParameterMap) error
RecordDiscoveryParams stores calculated discovery params for component instance
func (*PolicyResolution) RecordLabels ¶
func (resolution *PolicyResolution) RecordLabels(cik *ComponentInstanceKey, labels *lang.LabelSet)
RecordLabels stores calculated labels for component instance
func (*PolicyResolution) RecordResolved ¶
func (resolution *PolicyResolution) RecordResolved(cik *ComponentInstanceKey, dependency *lang.Dependency, ruleResult *lang.RuleActionResult)
RecordResolved takes a component instance and adds a new dependency record into it
func (*PolicyResolution) StoreEdge ¶
func (resolution *PolicyResolution) StoreEdge(src *ComponentInstanceKey, dst *ComponentInstanceKey)
StoreEdge stores incoming/outgoing graph edges for component instance for observability and reporting
type PolicyResolver ¶
type PolicyResolver struct {
// contains filtered or unexported fields
}
PolicyResolver is a core of Aptomi for policy resolution and translating all service consumption declarations into a single PolicyResolution object which represents desired state of components running in a cloud.
func NewPolicyResolver ¶
func NewPolicyResolver(policy *lang.Policy, externalData *external.Data, eventLog *event.Log) *PolicyResolver
NewPolicyResolver creates a new policy resolver
func (*PolicyResolver) ResolveAllDependencies ¶
func (resolver *PolicyResolver) ResolveAllDependencies() (*PolicyResolution, error)
ResolveAllDependencies takes policy as input and calculates PolicyResolution (desired state) as output.
It resolves all recorded service consumption declarations ("<user> needs <contract> with <labels>"), calculating which component have to be allocated and with which parameters. Once PolicyResolution (desired state) is calculated, it can be rendered by the engine diff/apply by deploying/configuring required components/containers in the cloud.