Skip to content

Commit

Permalink
feat: support disable status (#1595)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlinsRan authored Feb 14, 2023
1 parent 88d04f2 commit 199dcff
Show file tree
Hide file tree
Showing 21 changed files with 690 additions and 84 deletions.
1 change: 1 addition & 0 deletions cmd/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ For example, no available LB exists in the bare metal environment.`)
cmd.PersistentFlags().StringVar(&cfg.Kubernetes.APIVersion, "api-version", config.DefaultAPIVersion, config.APIVersionDescribe)
cmd.PersistentFlags().BoolVar(&cfg.Kubernetes.WatchEndpointSlices, "watch-endpointslices", false, "whether to watch endpointslices rather than endpoints")
cmd.PersistentFlags().BoolVar(&cfg.Kubernetes.EnableGatewayAPI, "enable-gateway-api", false, "whether to enable support for Gateway API")
cmd.PersistentFlags().BoolVar(&cfg.Kubernetes.DisableStatusUpdates, "disable-status-updates", false, "Disable resource status updates")
cmd.PersistentFlags().StringVar(&cfg.APISIX.AdminAPIVersion, "apisix-admin-api-version", "v2", `the APISIX admin API version. can be "v2" or "v3". Default value is v2.`)
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")
Expand Down
6 changes: 5 additions & 1 deletion conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ ingress_status_address: [] # when there is no available information on the Ser
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

# Kubernetes related configurations.
kubernetes:
kubeconfig: "" # the Kubernetes configuration file path, default is
Expand Down Expand Up @@ -82,11 +83,14 @@ kubernetes:
api_version: apisix.apache.org/v2 # the default value of API version is "apisix.apache.org/v2", support "apisix.apache.org/v2beta3" and "apisix.apache.org/v2".

plugin_metadata_cm: plugin-metadata-config-map

disable_status_updates: false # In the case of a large number of resources and the status of resources is not concerned
# you can consider disabling status to speed up the synchronization cycle of resources.
# APISIX related configurations.
apisix:
admin_api_version: v3 # the APISIX admin API version. can be "v2" or "v3"

default_cluster_base_url: "http://127.0.0.1:9080/apisix/admin" # The base url of admin api / manager api
default_cluster_base_url: "http://127.0.0.1:9180/apisix/admin" # The base url of admin api / manager api
# of the default APISIX cluster

default_cluster_admin_key: "" # the admin key used for the authentication of admin api / manager api in the
Expand Down
36 changes: 19 additions & 17 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,16 @@ type Config struct {

// KubernetesConfig contains all Kubernetes related config items.
type KubernetesConfig struct {
Kubeconfig string `json:"kubeconfig" yaml:"kubeconfig"`
ResyncInterval types.TimeDuration `json:"resync_interval" yaml:"resync_interval"`
NamespaceSelector []string `json:"namespace_selector" yaml:"namespace_selector"`
ElectionID string `json:"election_id" yaml:"election_id"`
IngressClass string `json:"ingress_class" yaml:"ingress_class"`
IngressVersion string `json:"ingress_version" yaml:"ingress_version"`
WatchEndpointSlices bool `json:"watch_endpoint_slices" yaml:"watch_endpoint_slices"`
APIVersion string `json:"api_version" yaml:"api_version"`
EnableGatewayAPI bool `json:"enable_gateway_api" yaml:"enable_gateway_api"`
Kubeconfig string `json:"kubeconfig" yaml:"kubeconfig"`
ResyncInterval types.TimeDuration `json:"resync_interval" yaml:"resync_interval"`
NamespaceSelector []string `json:"namespace_selector" yaml:"namespace_selector"`
ElectionID string `json:"election_id" yaml:"election_id"`
IngressClass string `json:"ingress_class" yaml:"ingress_class"`
IngressVersion string `json:"ingress_version" yaml:"ingress_version"`
WatchEndpointSlices bool `json:"watch_endpoint_slices" yaml:"watch_endpoint_slices"`
APIVersion string `json:"api_version" yaml:"api_version"`
EnableGatewayAPI bool `json:"enable_gateway_api" yaml:"enable_gateway_api"`
DisableStatusUpdates bool `json:"disable_status_updates" yaml:"disable_status_updates"`
}

// APISIXConfig contains all APISIX related config items.
Expand Down Expand Up @@ -133,14 +134,15 @@ func NewDefaultConfig() *Config {
EnableProfiling: true,
ApisixResourceSyncInterval: types.TimeDuration{Duration: 300 * time.Second},
Kubernetes: KubernetesConfig{
Kubeconfig: "", // Use in-cluster configurations.
ResyncInterval: types.TimeDuration{Duration: 6 * time.Hour},
ElectionID: IngressAPISIXLeader,
IngressClass: IngressClass,
IngressVersion: IngressNetworkingV1,
APIVersion: DefaultAPIVersion,
WatchEndpointSlices: false,
EnableGatewayAPI: false,
Kubeconfig: "", // Use in-cluster configurations.
ResyncInterval: types.TimeDuration{Duration: 6 * time.Hour},
ElectionID: IngressAPISIXLeader,
IngressClass: IngressClass,
IngressVersion: IngressNetworkingV1,
APIVersion: DefaultAPIVersion,
WatchEndpointSlices: false,
EnableGatewayAPI: false,
DisableStatusUpdates: false,
},
APISIX: APISIXConfig{
AdminAPIVersion: "v2",
Expand Down
31 changes: 18 additions & 13 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ func TestNewConfigFromFile(t *testing.T) {
EnableProfiling: true,
ApisixResourceSyncInterval: types.TimeDuration{Duration: 200 * time.Second},
Kubernetes: KubernetesConfig{
ResyncInterval: types.TimeDuration{Duration: time.Hour},
Kubeconfig: "/path/to/foo/baz",
ElectionID: "my-election-id",
IngressClass: IngressClass,
IngressVersion: IngressNetworkingV1,
APIVersion: DefaultAPIVersion,
ResyncInterval: types.TimeDuration{Duration: time.Hour},
Kubeconfig: "/path/to/foo/baz",
ElectionID: "my-election-id",
IngressClass: IngressClass,
IngressVersion: IngressNetworkingV1,
APIVersion: DefaultAPIVersion,
DisableStatusUpdates: true,
},
APISIX: APISIXConfig{
AdminAPIVersion: "v2",
Expand Down Expand Up @@ -94,6 +95,7 @@ kubernetes:
ingress_class: apisix
ingress_version: networking/v1
api_version: apisix.apache.org/v2
disable_status_updates: true
apisix:
admin_api_version: v2
default_cluster_base_url: http://127.0.0.1:8080/apisix
Expand Down Expand Up @@ -132,12 +134,13 @@ func TestConfigWithEnvVar(t *testing.T) {
EnableProfiling: true,
ApisixResourceSyncInterval: types.TimeDuration{Duration: 200 * time.Second},
Kubernetes: KubernetesConfig{
ResyncInterval: types.TimeDuration{Duration: time.Hour},
Kubeconfig: "",
ElectionID: "my-election-id",
IngressClass: IngressClass,
IngressVersion: IngressNetworkingV1,
APIVersion: DefaultAPIVersion,
ResyncInterval: types.TimeDuration{Duration: time.Hour},
Kubeconfig: "",
ElectionID: "my-election-id",
IngressClass: IngressClass,
IngressVersion: IngressNetworkingV1,
APIVersion: DefaultAPIVersion,
DisableStatusUpdates: true,
},
APISIX: APISIXConfig{
AdminAPIVersion: "v2",
Expand Down Expand Up @@ -173,7 +176,8 @@ func TestConfigWithEnvVar(t *testing.T) {
"resync_interval": "1h0m0s",
"election_id": "my-election-id",
"ingress_class": "apisix",
"ingress_version": "networking/v1"
"ingress_version": "networking/v1",
"disable_status_updates": true
},
"apisix": {
"admin_api_version": "v2",
Expand Down Expand Up @@ -212,6 +216,7 @@ kubernetes:
election_id: my-election-id
ingress_class: apisix
ingress_version: networking/v1
disable_status_updates: true
apisix:
admin_api_version: v2
default_cluster_base_url: {{.DEFAULT_CLUSTER_BASE_URL}}
Expand Down
5 changes: 4 additions & 1 deletion pkg/providers/apisix/apisix_cluster_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,9 @@ func (c *apisixClusterConfigController) ResourceSync() {

// recordStatus record resources status
func (c *apisixClusterConfigController) recordStatus(at interface{}, reason string, err error, status metav1.ConditionStatus, generation int64) {
if c.Kubernetes.DisableStatusUpdates {
return
}
// build condition
message := utils.CommonSuccessMessage
if err != nil {
Expand Down Expand Up @@ -475,7 +478,7 @@ func (c *apisixClusterConfigController) recordStatus(at interface{}, reason stri
conditions := make([]metav1.Condition, 0)
v.Status.Conditions = conditions
}
if utils.VerifyGeneration(&v.Status.Conditions, condition) {
if utils.VerifyConditions(&v.Status.Conditions, condition) {
meta.SetStatusCondition(&v.Status.Conditions, condition)
if _, errRecord := apisixClient.ApisixV2().ApisixClusterConfigs().
UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
Expand Down
3 changes: 3 additions & 0 deletions pkg/providers/apisix/apisix_consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,9 @@ func (c *apisixConsumerController) ResourceSync() {

// recordStatus record resources status
func (c *apisixConsumerController) recordStatus(at interface{}, reason string, err error, status metav1.ConditionStatus, generation int64) {
if c.Kubernetes.DisableStatusUpdates {
return
}
// build condition
message := utils.CommonSuccessMessage
if err != nil {
Expand Down
5 changes: 4 additions & 1 deletion pkg/providers/apisix/apisix_plugin_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,9 @@ func (c *apisixPluginConfigController) ResourceSync() {

// recordStatus record resources status
func (c *apisixPluginConfigController) recordStatus(at interface{}, reason string, err error, status metav1.ConditionStatus, generation int64) {
if c.Kubernetes.DisableStatusUpdates {
return
}
// build condition
message := utils.CommonSuccessMessage
if err != nil {
Expand Down Expand Up @@ -434,7 +437,7 @@ func (c *apisixPluginConfigController) recordStatus(at interface{}, reason strin
conditions := make([]metav1.Condition, 0)
v.Status.Conditions = conditions
}
if utils.VerifyGeneration(&v.Status.Conditions, condition) {
if utils.VerifyConditions(&v.Status.Conditions, condition) {
meta.SetStatusCondition(&v.Status.Conditions, condition)
if _, errRecord := apisixClient.ApisixV2().ApisixPluginConfigs(v.Namespace).
UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
Expand Down
16 changes: 14 additions & 2 deletions pkg/providers/apisix/apisix_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,8 +843,20 @@ func (c *apisixRouteController) handleApisixUpstreamErr(ev *routeEvent, errOrigi
c.workqueue.AddRateLimited(ev)
}

// recordStatus record resources status
/*
recordStatus record resources status
TODO: The resouceVersion of the sync phase and the recordStatus phase may be different. There is consistency
problem here, and incorrect status may be recorded.(It will only be triggered when it is updated multiple times in a short time)
IsUpdateStatus(currentObject, latestObject) bool {
return currentObject.resourceVersion >= latestObject.resourceVersion && !Equal(currentObject.status, latestObject.status)
}
*/
func (c *apisixRouteController) recordStatus(at interface{}, reason string, err error, status metav1.ConditionStatus, generation int64) {
if c.Kubernetes.DisableStatusUpdates {
return
}
// build condition
message := utils.CommonSuccessMessage
if err != nil {
Expand Down Expand Up @@ -887,7 +899,7 @@ func (c *apisixRouteController) recordStatus(at interface{}, reason string, err
conditions := make([]metav1.Condition, 0)
v.Status.Conditions = conditions
}
if utils.VerifyGeneration(&v.Status.Conditions, condition) {
if utils.VerifyConditions(&v.Status.Conditions, condition) && !meta.IsStatusConditionPresentAndEqual(v.Status.Conditions, condition.Type, condition.Status) {
meta.SetStatusCondition(&v.Status.Conditions, condition)
if _, errRecord := apisixClient.ApisixV2().ApisixRoutes(v.Namespace).
UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
Expand Down
5 changes: 4 additions & 1 deletion pkg/providers/apisix/apisix_tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ func (c *apisixTlsController) ResourceSync() {

// recordStatus record resources status
func (c *apisixTlsController) recordStatus(at interface{}, reason string, err error, status metav1.ConditionStatus, generation int64) {
if c.Kubernetes.DisableStatusUpdates {
return
}
// build condition
message := utils.CommonSuccessMessage
if err != nil {
Expand Down Expand Up @@ -442,7 +445,7 @@ func (c *apisixTlsController) recordStatus(at interface{}, reason string, err er
conditions := make([]metav1.Condition, 0)
v.Status.Conditions = conditions
}
if utils.VerifyGeneration(&v.Status.Conditions, condition) {
if utils.VerifyConditions(&v.Status.Conditions, condition) {
meta.SetStatusCondition(&v.Status.Conditions, condition)
if _, errRecord := apisixClient.ApisixV2().ApisixTlses(v.Namespace).
UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
Expand Down
5 changes: 4 additions & 1 deletion pkg/providers/apisix/apisix_upstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,9 @@ func (c *apisixUpstreamController) handleSvcErr(key string, errOrigin error) {

// recordStatus record resources status
func (c *apisixUpstreamController) recordStatus(at interface{}, reason string, err error, status metav1.ConditionStatus, generation int64) {
if c.Kubernetes.DisableStatusUpdates {
return
}
// build condition
message := utils.CommonSuccessMessage
if err != nil {
Expand Down Expand Up @@ -847,7 +850,7 @@ func (c *apisixUpstreamController) recordStatus(at interface{}, reason string, e
conditions := make([]metav1.Condition, 0)
v.Status.Conditions = conditions
}
if utils.VerifyGeneration(&v.Status.Conditions, condition) {
if utils.VerifyConditions(&v.Status.Conditions, condition) {
meta.SetStatusCondition(&v.Status.Conditions, condition)
if _, errRecord := apisixClient.ApisixV2().ApisixUpstreams(v.Namespace).
UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/providers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ func (c *Controller) run(ctx context.Context) {
KubeClient: c.kubeClient.Client,
MetricsCollector: c.MetricsCollector,
NamespaceProvider: c.namespaceProvider,
ListerInformer: common.ListerInformer,
})
if err != nil {
ctx.Done()
Expand Down
2 changes: 1 addition & 1 deletion pkg/providers/gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func (c *gatewayController) recordStatus(v *gatewayv1beta1.Gateway, reason strin
meta.SetStatusCondition(&v.Status.Conditions, gatewayCondition)
}

lbips, err := utils.IngressLBStatusIPs(c.controller.Cfg.IngressPublishService, c.controller.Cfg.IngressStatusAddress, c.controller.KubeClient)
lbips, err := utils.IngressLBStatusIPs(c.controller.Cfg.IngressPublishService, c.controller.Cfg.IngressStatusAddress, c.controller.ListerInformer.SvcLister)
if err != nil {
log.Errorw("failed to get APISIX gateway external IPs",
zap.Error(err),
Expand Down
2 changes: 2 additions & 0 deletions pkg/providers/gateway/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"github.com/apache/apisix-ingress-controller/pkg/providers/gateway/types"
"github.com/apache/apisix-ingress-controller/pkg/providers/k8s/namespace"
"github.com/apache/apisix-ingress-controller/pkg/providers/translation"
providertypes "github.com/apache/apisix-ingress-controller/pkg/providers/types"
"github.com/apache/apisix-ingress-controller/pkg/providers/utils"
)

Expand Down Expand Up @@ -96,6 +97,7 @@ type ProviderOptions struct {
KubeClient kubernetes.Interface
MetricsCollector metrics.Collector
NamespaceProvider namespace.WatchingNamespaceProvider
ListerInformer *providertypes.ListerInformer
}

func NewGatewayProvider(opts *ProviderOptions) (*Provider, error) {
Expand Down
61 changes: 34 additions & 27 deletions pkg/providers/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ func (c *ingressController) ResourceSync() {

// recordStatus record resources status
func (c *ingressController) recordStatus(at runtime.Object, reason string, err error, status metav1.ConditionStatus, generation int64) {
if c.Kubernetes.DisableStatusUpdates {
return
}
client := c.KubeClient.Client

at = at.DeepCopyObject()
Expand All @@ -479,15 +482,16 @@ func (c *ingressController) recordStatus(at runtime.Object, reason string, err e
)

}

v.ObjectMeta.Generation = generation
v.Status.LoadBalancer.Ingress = utils.CoreV1ToNetworkV1LB(lbips)
if _, errRecord := client.NetworkingV1().Ingresses(v.Namespace).UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
log.Errorw("failed to record status change for IngressV1",
zap.Error(errRecord),
zap.String("name", v.Name),
zap.String("namespace", v.Namespace),
)
ingressLB := utils.CoreV1ToNetworkV1LB(lbips)
if !utils.CompareNetworkingV1LBEqual(v.Status.LoadBalancer.Ingress, ingressLB) {
v.Status.LoadBalancer.Ingress = ingressLB
if _, errRecord := client.NetworkingV1().Ingresses(v.Namespace).UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
log.Errorw("failed to record status change for IngressV1",
zap.Error(errRecord),
zap.String("name", v.Name),
zap.String("namespace", v.Namespace),
)
}
}

case *networkingv1beta1.Ingress:
Expand All @@ -497,17 +501,18 @@ func (c *ingressController) recordStatus(at runtime.Object, reason string, err e
log.Errorw("failed to get APISIX gateway external IPs",
zap.Error(err),
)

}

v.ObjectMeta.Generation = generation
v.Status.LoadBalancer.Ingress = utils.CoreV1ToNetworkV1beta1LB(lbips)
if _, errRecord := client.NetworkingV1beta1().Ingresses(v.Namespace).UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
log.Errorw("failed to record status change for IngressV1",
zap.Error(errRecord),
zap.String("name", v.Name),
zap.String("namespace", v.Namespace),
)
ingressLB := utils.CoreV1ToNetworkV1beta1LB(lbips)
if !utils.CompareNetworkingV1beta1LBEqual(v.Status.LoadBalancer.Ingress, ingressLB) {
v.Status.LoadBalancer.Ingress = ingressLB
if _, errRecord := client.NetworkingV1beta1().Ingresses(v.Namespace).UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
log.Errorw("failed to record status change for IngressV1beta1",
zap.Error(errRecord),
zap.String("name", v.Name),
zap.String("namespace", v.Namespace),
)
}
}
case *extensionsv1beta1.Ingress:
// set to status
Expand All @@ -519,14 +524,16 @@ func (c *ingressController) recordStatus(at runtime.Object, reason string, err e

}

v.ObjectMeta.Generation = generation
v.Status.LoadBalancer.Ingress = utils.CoreV1ToExtensionsV1beta1LB(lbips)
if _, errRecord := client.ExtensionsV1beta1().Ingresses(v.Namespace).UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
log.Errorw("failed to record status change for IngressV1",
zap.Error(errRecord),
zap.String("name", v.Name),
zap.String("namespace", v.Namespace),
)
ingressLB := utils.CoreV1ToExtensionsV1beta1LB(lbips)
if !utils.CompareExtensionsV1beta1LBEqual(v.Status.LoadBalancer.Ingress, ingressLB) {
v.Status.LoadBalancer.Ingress = ingressLB
if _, errRecord := client.ExtensionsV1beta1().Ingresses(v.Namespace).UpdateStatus(context.TODO(), v, metav1.UpdateOptions{}); errRecord != nil {
log.Errorw("failed to record status change for IngressExtensionsv1beta1",
zap.Error(errRecord),
zap.String("name", v.Name),
zap.String("namespace", v.Namespace),
)
}
}
default:
// This should not be executed
Expand All @@ -536,7 +543,7 @@ func (c *ingressController) recordStatus(at runtime.Object, reason string, err e

// ingressLBStatusIPs organizes the available addresses
func (c *ingressController) ingressLBStatusIPs() ([]corev1.LoadBalancerIngress, error) {
return utils.IngressLBStatusIPs(c.IngressPublishService, c.IngressStatusAddress, c.KubeClient.Client)
return utils.IngressLBStatusIPs(c.IngressPublishService, c.IngressStatusAddress, c.SvcLister)
}

func (c *ingressController) storeSecretReference(secretKey string, ingressKey string, evType types.EventType, ssl *v1.Ssl) {
Expand Down
Loading

0 comments on commit 199dcff

Please sign in to comment.