Skip to content

Commit

Permalink
feat: support comparison in resource sync (#1742)
Browse files Browse the repository at this point in the history
  • Loading branch information
lingsamuel committed Apr 3, 2023
1 parent 0602314 commit 2cb99b8
Show file tree
Hide file tree
Showing 63 changed files with 2,095 additions and 687 deletions.
3 changes: 2 additions & 1 deletion cmd/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ For example, no available LB exists in the bare metal environment.`)
cmd.PersistentFlags().StringVar(&cfg.APISIX.DefaultClusterBaseURL, "default-apisix-cluster-base-url", "", "the base URL of admin api / manager api for the default APISIX cluster")
cmd.PersistentFlags().StringVar(&cfg.APISIX.DefaultClusterAdminKey, "default-apisix-cluster-admin-key", "", "admin key used for the authorization of admin api / manager api for the default APISIX cluster")
cmd.PersistentFlags().StringVar(&cfg.APISIX.DefaultClusterName, "default-apisix-cluster-name", "default", "name of the default apisix cluster")
cmd.PersistentFlags().DurationVar(&cfg.ApisixResourceSyncInterval.Duration, "apisix-resource-sync-interval", 1*time.Hour, "interval between syncs in seconds. Default value is 1h. Set to 0 to disable.")
cmd.PersistentFlags().DurationVar(&cfg.ApisixResourceSyncInterval.Duration, "apisix-resource-sync-interval", 1*time.Hour, "interval of periodic sync in seconds. Default value is 1h. Set to 0 to disable. Min is 60s.")
cmd.PersistentFlags().BoolVar(&cfg.ApisixResourceSyncComparison, "apisix-resource-sync-comparison", true, "enable comparison in periodic sync")
cmd.PersistentFlags().StringVar(&cfg.PluginMetadataConfigMap, "plugin-metadata-cm", "plugin-metadata-config-map", "ConfigMap name of plugin metadata.")

return cmd
Expand Down
2 changes: 1 addition & 1 deletion conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ingress_status_address: [] # when there is no available information on the Ser
# For example, no available LB exists in the bare metal environment.
enable_profiling: true # enable profiling via web interfaces
# host:port/debug/pprof, default is true.
apisix-resource-sync-interval: "300s" # Default interval for synchronizing Kubernetes resources to APISIX
apisix_resource_sync_interval: "1h" # Default interval for synchronizing Kubernetes resources to APISIX

# Kubernetes related configurations.
kubernetes:
Expand Down
103 changes: 52 additions & 51 deletions pkg/apisix/apisix.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ import (
// APISIX is the unified client tool to communicate with APISIX.
type APISIX interface {
// Cluster specifies the target cluster to talk.
Cluster(string) Cluster
Cluster(name string) Cluster
// AddCluster adds a new cluster.
AddCluster(context.Context, *ClusterOptions) error
// UpdateCluster updates an existing cluster.
UpdateCluster(context.Context, *ClusterOptions) error
// ListClusters lists all APISIX clusters.
ListClusters() []Cluster
// DeleteCluster deletes the target APISIX cluster by its name.
DeleteCluster(string)
DeleteCluster(name string)
}

// Cluster defines specific operations that can be applied in an APISIX
Expand Down Expand Up @@ -72,103 +72,104 @@ type Cluster interface {
// Route is the specific client interface to take over the create, update,
// list and delete for APISIX Route resource.
type Route interface {
Get(context.Context, string) (*v1.Route, error)
List(context.Context) ([]*v1.Route, error)
Create(context.Context, *v1.Route) (*v1.Route, error)
Delete(context.Context, *v1.Route) error
Update(context.Context, *v1.Route) (*v1.Route, error)
Get(ctx context.Context, name string) (*v1.Route, error)
List(ctx context.Context) ([]*v1.Route, error)
Create(ctx context.Context, route *v1.Route, shouldCompare bool) (*v1.Route, error)
Delete(ctx context.Context, route *v1.Route) error
Update(ctx context.Context, route *v1.Route, shouldCompare bool) (*v1.Route, error)
}

// SSL is the specific client interface to take over the create, update,
// list and delete for APISIX SSL resource.
type SSL interface {
Get(context.Context, string) (*v1.Ssl, error)
List(context.Context) ([]*v1.Ssl, error)
Create(context.Context, *v1.Ssl) (*v1.Ssl, error)
Delete(context.Context, *v1.Ssl) error
Update(context.Context, *v1.Ssl) (*v1.Ssl, error)
// name is namespace_sslname
Get(ctx context.Context, name string) (*v1.Ssl, error)
List(ctx context.Context) ([]*v1.Ssl, error)
Create(ctx context.Context, ssl *v1.Ssl, shouldCompare bool) (*v1.Ssl, error)
Delete(ctx context.Context, ssl *v1.Ssl) error
Update(ctx context.Context, ssl *v1.Ssl, shouldCompare bool) (*v1.Ssl, error)
}

// Upstream is the specific client interface to take over the create, update,
// list and delete for APISIX Upstream resource.
type Upstream interface {
Get(context.Context, string) (*v1.Upstream, error)
List(context.Context) ([]*v1.Upstream, error)
Create(context.Context, *v1.Upstream) (*v1.Upstream, error)
Delete(context.Context, *v1.Upstream) error
Update(context.Context, *v1.Upstream) (*v1.Upstream, error)
Get(ctx context.Context, name string) (*v1.Upstream, error)
List(ctx context.Context) ([]*v1.Upstream, error)
Create(ctx context.Context, ups *v1.Upstream, shouldCompare bool) (*v1.Upstream, error)
Delete(ctx context.Context, ups *v1.Upstream) error
Update(ctx context.Context, ups *v1.Upstream, shouldCompare bool) (*v1.Upstream, error)
}

// StreamRoute is the specific client interface to take over the create, update,
// list and delete for APISIX Stream Route resource.
type StreamRoute interface {
Get(context.Context, string) (*v1.StreamRoute, error)
List(context.Context) ([]*v1.StreamRoute, error)
Create(context.Context, *v1.StreamRoute) (*v1.StreamRoute, error)
Delete(context.Context, *v1.StreamRoute) error
Update(context.Context, *v1.StreamRoute) (*v1.StreamRoute, error)
Get(ctx context.Context, name string) (*v1.StreamRoute, error)
List(ctx context.Context) ([]*v1.StreamRoute, error)
Create(ctx context.Context, route *v1.StreamRoute, shouldCompare bool) (*v1.StreamRoute, error)
Delete(ctx context.Context, route *v1.StreamRoute) error
Update(ctx context.Context, route *v1.StreamRoute, shouldCompare bool) (*v1.StreamRoute, error)
}

// GlobalRule is the specific client interface to take over the create, update,
// list and delete for APISIX Global Rule resource.
type GlobalRule interface {
Get(context.Context, string) (*v1.GlobalRule, error)
List(context.Context) ([]*v1.GlobalRule, error)
Create(context.Context, *v1.GlobalRule) (*v1.GlobalRule, error)
Delete(context.Context, *v1.GlobalRule) error
Update(context.Context, *v1.GlobalRule) (*v1.GlobalRule, error)
Get(ctx context.Context, id string) (*v1.GlobalRule, error)
List(ctx context.Context) ([]*v1.GlobalRule, error)
Create(ctx context.Context, rule *v1.GlobalRule, shouldCompare bool) (*v1.GlobalRule, error)
Delete(ctx context.Context, rule *v1.GlobalRule) error
Update(ctx context.Context, rule *v1.GlobalRule, shouldCompare bool) (*v1.GlobalRule, error)
}

// Consumer is the specific client interface to take over the create, update,
// list and delete for APISIX Consumer resource.
type Consumer interface {
Get(context.Context, string) (*v1.Consumer, error)
List(context.Context) ([]*v1.Consumer, error)
Create(context.Context, *v1.Consumer) (*v1.Consumer, error)
Delete(context.Context, *v1.Consumer) error
Update(context.Context, *v1.Consumer) (*v1.Consumer, error)
Get(ctx context.Context, name string) (*v1.Consumer, error)
List(ctx context.Context) ([]*v1.Consumer, error)
Create(ctx context.Context, consumer *v1.Consumer, shouldCompare bool) (*v1.Consumer, error)
Delete(ctx context.Context, consumer *v1.Consumer) error
Update(ctx context.Context, consumer *v1.Consumer, shouldCompare bool) (*v1.Consumer, error)
}

// Plugin is the specific client interface to fetch APISIX Plugin resource.
type Plugin interface {
List(context.Context) ([]string, error)
List(ctx context.Context) ([]string, error)
}

// Schema is the specific client interface to fetch the schema of APISIX objects.
type Schema interface {
GetPluginSchema(context.Context, string) (*v1.Schema, error)
GetRouteSchema(context.Context) (*v1.Schema, error)
GetUpstreamSchema(context.Context) (*v1.Schema, error)
GetConsumerSchema(context.Context) (*v1.Schema, error)
GetSslSchema(context.Context) (*v1.Schema, error)
GetPluginSchema(ctx context.Context, pluginName string) (*v1.Schema, error)
GetRouteSchema(ctx context.Context) (*v1.Schema, error)
GetUpstreamSchema(ctx context.Context) (*v1.Schema, error)
GetConsumerSchema(ctx context.Context) (*v1.Schema, error)
GetSslSchema(ctx context.Context) (*v1.Schema, error)
GetPluginConfigSchema(ctx context.Context) (*v1.Schema, error)
}

// PluginConfig is the specific client interface to take over the create, update,
// list and delete for APISIX PluginConfig resource.
type PluginConfig interface {
Get(context.Context, string) (*v1.PluginConfig, error)
List(context.Context) ([]*v1.PluginConfig, error)
Create(context.Context, *v1.PluginConfig) (*v1.PluginConfig, error)
Delete(context.Context, *v1.PluginConfig) error
Update(context.Context, *v1.PluginConfig) (*v1.PluginConfig, error)
Get(ctx context.Context, name string) (*v1.PluginConfig, error)
List(ctx context.Context) ([]*v1.PluginConfig, error)
Create(ctx context.Context, plugin *v1.PluginConfig, shouldCompare bool) (*v1.PluginConfig, error)
Delete(ctx context.Context, plugin *v1.PluginConfig) error
Update(ctx context.Context, plugin *v1.PluginConfig, shouldCompare bool) (*v1.PluginConfig, error)
}

type PluginMetadata interface {
Get(context.Context, string) (*v1.PluginMetadata, error)
List(context.Context) ([]*v1.PluginMetadata, error)
Delete(context.Context, *v1.PluginMetadata) error
Update(context.Context, *v1.PluginMetadata) (*v1.PluginMetadata, error)
Get(ctx context.Context, name string) (*v1.PluginMetadata, error)
List(ctx context.Context) ([]*v1.PluginMetadata, error)
Delete(ctx context.Context, metadata *v1.PluginMetadata) error
Update(ctx context.Context, metadata *v1.PluginMetadata, shouldCompare bool) (*v1.PluginMetadata, error)
}

type UpstreamServiceRelation interface {
// Get relation based on namespace+"_"+service.name
Get(context.Context, string) (*v1.UpstreamServiceRelation, error)
List(context.Context) ([]*v1.UpstreamServiceRelation, error)
Get(ctx context.Context, svcName string) (*v1.UpstreamServiceRelation, error)
List(ctx context.Context) ([]*v1.UpstreamServiceRelation, error)
// Delete relation based on namespace+"_"+service.name
Delete(context.Context, string) error
Delete(ctx context.Context, svcName string) error
// Build relation based on upstream.name
Create(context.Context, string) error
Create(ctx context.Context, svcName string) error
}

type apisix struct {
Expand Down
6 changes: 3 additions & 3 deletions pkg/apisix/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ type Cache interface {
GetStreamRoute(string) (*v1.StreamRoute, error)
// GetGlobalRule finds the global_rule from cache according to the primary index (id).
GetGlobalRule(string) (*v1.GlobalRule, error)
// GetConsumer finds the consumer from cache according to the primary index (id).
// GetConsumer finds the consumer from cache according to the primary index (username).
GetConsumer(string) (*v1.Consumer, error)
// GetSchema finds the scheme from cache according to the primary index (id).
// GetSchema finds the scheme from cache according to the primary index (name).
GetSchema(string) (*v1.Schema, error)
// GetPluginConfig finds the plugin_config from cache according to the primary index (id).
GetPluginConfig(string) (*v1.PluginConfig, error)

// GetUpstreamServiceRelation finds the upstream_service from cache according to the primary index (service name).
GetUpstreamServiceRelation(string) (*v1.UpstreamServiceRelation, error)

// ListRoutes lists all routes in cache.
Expand Down
174 changes: 174 additions & 0 deletions pkg/apisix/cache/noop_db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package cache

import (
v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
)

type noopCache struct {
}

// NewMemDBCache creates a Cache object backs with a memory DB.
func NewNoopDBCache() (Cache, error) {
return &noopCache{}, nil
}

func (c *noopCache) InsertRoute(r *v1.Route) error {
return nil
}

func (c *noopCache) InsertSSL(ssl *v1.Ssl) error {
return nil
}

func (c *noopCache) InsertUpstream(u *v1.Upstream) error {
return nil
}

func (c *noopCache) InsertStreamRoute(sr *v1.StreamRoute) error {
return nil
}

func (c *noopCache) InsertGlobalRule(gr *v1.GlobalRule) error {
return nil
}

func (c *noopCache) InsertConsumer(consumer *v1.Consumer) error {
return nil
}

func (c *noopCache) InsertSchema(schema *v1.Schema) error {
return nil
}

func (c *noopCache) InsertPluginConfig(pc *v1.PluginConfig) error {
return nil
}

func (c *noopCache) InsertUpstreamServiceRelation(us *v1.UpstreamServiceRelation) error {
return nil
}

func (c *noopCache) GetRoute(id string) (*v1.Route, error) {
return nil, nil
}

func (c *noopCache) GetSSL(id string) (*v1.Ssl, error) {
return nil, nil
}

func (c *noopCache) GetUpstream(id string) (*v1.Upstream, error) {
return nil, nil
}

func (c *noopCache) GetStreamRoute(id string) (*v1.StreamRoute, error) {
return nil, nil
}

func (c *noopCache) GetGlobalRule(id string) (*v1.GlobalRule, error) {
return nil, nil
}

func (c *noopCache) GetConsumer(username string) (*v1.Consumer, error) {
return nil, nil
}

func (c *noopCache) GetSchema(name string) (*v1.Schema, error) {
return nil, nil
}

func (c *noopCache) GetPluginConfig(name string) (*v1.PluginConfig, error) {
return nil, nil
}

func (c *noopCache) GetUpstreamServiceRelation(serviceName string) (*v1.UpstreamServiceRelation, error) {
return nil, nil
}

func (c *noopCache) ListRoutes() ([]*v1.Route, error) {
return nil, nil
}

func (c *noopCache) ListSSL() ([]*v1.Ssl, error) {
return nil, nil
}

func (c *noopCache) ListUpstreams() ([]*v1.Upstream, error) {
return nil, nil
}

func (c *noopCache) ListStreamRoutes() ([]*v1.StreamRoute, error) {
return nil, nil
}

func (c *noopCache) ListGlobalRules() ([]*v1.GlobalRule, error) {
return nil, nil
}

func (c *noopCache) ListConsumers() ([]*v1.Consumer, error) {
return nil, nil
}

func (c *noopCache) ListSchema() ([]*v1.Schema, error) {
return nil, nil
}

func (c *noopCache) ListPluginConfigs() ([]*v1.PluginConfig, error) {
return nil, nil
}

func (c *noopCache) ListUpstreamServiceRelation() ([]*v1.UpstreamServiceRelation, error) {
return nil, nil
}

func (c *noopCache) DeleteRoute(r *v1.Route) error {
return nil
}

func (c *noopCache) DeleteSSL(ssl *v1.Ssl) error {
return nil
}

func (c *noopCache) DeleteUpstream(u *v1.Upstream) error {
return nil
}

func (c *noopCache) DeleteStreamRoute(sr *v1.StreamRoute) error {
return nil
}

func (c *noopCache) DeleteGlobalRule(gr *v1.GlobalRule) error {
return nil
}

func (c *noopCache) DeleteConsumer(consumer *v1.Consumer) error {
return nil
}

func (c *noopCache) DeleteSchema(schema *v1.Schema) error {
return nil
}

func (c *noopCache) DeletePluginConfig(pc *v1.PluginConfig) error {
return nil
}

func (c *noopCache) DeleteUpstreamServiceRelation(us *v1.UpstreamServiceRelation) error {
return nil
}
Loading

0 comments on commit 2cb99b8

Please sign in to comment.