Description
When ApisixRoute
, ApisixUpstream
and other CRDs are watched by ingress controller, it converts these objects to the format of APISIX Resources, like Route, Upstream and etc.
Currently, one rule in ApisixRoute
object may generate a Route, Service, Upstream object; an APISIXService
may generate
a Service and Upstream object; an ApisixUpstream
will generate an Upstream object. What's more, the order to push them (to APISIX) is important, we must push Upstream before Service, push Service before Route.
Some drawbacks in current implementation:
- the Service object generated by
ApisixRoute
is useless since all configurations in it are also in the Route, we can remove it; - also, logics for Route, Service, Upstream are highly duplicated, so we can abstract them to reduce the code complexity;
- Resource cascading update are implemented in several different places with the channel to communicate and keep the order, which is complex, we can simplify it by writing sequential codes.
Operations for resources like Route, Service, Upstream and others can be abstracted as a ResourceOperator
interface.
// pseudo code
// ResourceOperator abstracts all necessary operations for operating an APISIX resource like Route, Upstream.
type ResourceOperator interface {
Get() ([]interface{}, error)
Add(obj interface{}) error
Update(obj interface{}) error
Delete(id string) error
DiffFrom(t interface{}) (bool, error)
.......
}
func NewRouteOperator() ResourceOperator {}
func NewServiceOperator() ResourceOperator {}
func NewUpstreamOperator() ResourceOperator {}
For each resource change, we have a struct ResourceChange
type ResourceChange struct {
operator ResourceOperator
changeReason string // for logging
}
func ApplyResourceChange(rc *ResourceChange) error {}
On a higher land, we can orchestrate the resource change to ResourcesChange
type ResourcesChange [][]ResourceChange
func (rsc *ResourceChange) Apply() error {}
We put Upstream in ResourcesChange[0] which means it has the first priority to apply, ResourcesChange[1] for Service and so on.
Note the whole apply process can not be atomic, we relay on the user to delete the broken CRD object if the apply process is aborted.