This is an automated email from the ASF dual-hosted git repository. zhangjintao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
The following commit(s) were added to refs/heads/master by this push: new 0c6de2d feat: update Ingress LB status (#740) 0c6de2d is described below commit 0c6de2deb92c72b8d609490283c930a068df7d23 Author: Jintao Zhang <zhangjintao9...@gmail.com> AuthorDate: Thu Dec 2 16:53:12 2021 +0800 feat: update Ingress LB status (#740) --- cmd/ingress/ingress.go | 8 +++ conf/config-default.yaml | 10 +++ pkg/config/config.go | 36 +++++----- pkg/config/config_test.go | 38 +++++++---- pkg/ingress/apisix_route.go | 2 +- pkg/ingress/ingress.go | 51 +++++++++++++++ pkg/ingress/status.go | 148 +++++++++++++++++++++++++++++++++++++++++- test/e2e/ingress/status.go | 50 ++++++++++++++ test/e2e/scaffold/ingress.go | 10 +-- test/e2e/scaffold/scaffold.go | 3 + 10 files changed, 319 insertions(+), 37 deletions(-) diff --git a/cmd/ingress/ingress.go b/cmd/ingress/ingress.go index e36fbcc..2729738 100644 --- a/cmd/ingress/ingress.go +++ b/cmd/ingress/ingress.go @@ -140,6 +140,14 @@ the apisix cluster and others are created`, cmd.PersistentFlags().StringVar(&cfg.LogOutput, "log-output", "stderr", "error log output file") cmd.PersistentFlags().StringVar(&cfg.HTTPListen, "http-listen", ":8080", "the HTTP Server listen address") cmd.PersistentFlags().StringVar(&cfg.HTTPSListen, "https-listen", ":8443", "the HTTPS Server listen address") + cmd.PersistentFlags().StringVar(&cfg.IngressPublishService, "ingress-publish-service", "", + `the controller will use the Endpoint of this Service to update the status information of the Ingress resource. +The format is "namespace/svc-name" to solve the situation that the data plane and the controller are not deployed in the same namespace.`) + cmd.PersistentFlags().StringSliceVar(&cfg.IngressStatusAddress, "ingress-status-address", []string{}, + `when there is no available information on the Service used for publishing on the data plane, +the static address provided here will be used to update the status information of Ingress. +When ingress-publish-service is specified at the same time, ingress-status-address is preferred. +For example, no available LB exists in the bare metal environment.`) cmd.PersistentFlags().BoolVar(&cfg.EnableProfiling, "enable-profiling", true, "enable profiling via web interface host:port/debug/pprof") cmd.PersistentFlags().StringVar(&cfg.Kubernetes.Kubeconfig, "kubeconfig", "", "Kubernetes configuration file (by default in-cluster configuration will be used)") cmd.PersistentFlags().DurationVar(&cfg.Kubernetes.ResyncInterval.Duration, "resync-interval", time.Minute, "the controller resync (with Kubernetes) interval, the minimum resync interval is 30s") diff --git a/conf/config-default.yaml b/conf/config-default.yaml index c724212..afc521f 100644 --- a/conf/config-default.yaml +++ b/conf/config-default.yaml @@ -32,6 +32,16 @@ key_file: "/etc/webhook/certs/key.pem" # the TLS key file path. http_listen: ":8080" # the HTTP Server listen address, default is ":8080" https_listen: ":8443" # the HTTPS Server listen address, default is ":8443" +ingress_publish_service: "" # the controller will use the Endpoint of this Service to + # update the status information of the Ingress resource. + # The format is "namespace/svc-name" to solve the situation that + # the data plane and the controller are not deployed in the same namespace. +ingress_status_address: [] # when there is no available information on the Service + # used for publishing on the data plane, + # the static address provided here will be + # used to update the status information of Ingress. + # When ingress-publish-service is specified at the same time, ingress-status-address is preferred. + # 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. diff --git a/pkg/config/config.go b/pkg/config/config.go index 1f8a3dd..15f7bd3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -66,15 +66,17 @@ const ( // Config contains all config items which are necessary for // apisix-ingress-controller's running. type Config struct { - CertFilePath string `json:"cert_file" yaml:"cert_file"` - KeyFilePath string `json:"key_file" yaml:"key_file"` - LogLevel string `json:"log_level" yaml:"log_level"` - LogOutput string `json:"log_output" yaml:"log_output"` - HTTPListen string `json:"http_listen" yaml:"http_listen"` - HTTPSListen string `json:"https_listen" yaml:"https_listen"` - EnableProfiling bool `json:"enable_profiling" yaml:"enable_profiling"` - Kubernetes KubernetesConfig `json:"kubernetes" yaml:"kubernetes"` - APISIX APISIXConfig `json:"apisix" yaml:"apisix"` + CertFilePath string `json:"cert_file" yaml:"cert_file"` + KeyFilePath string `json:"key_file" yaml:"key_file"` + LogLevel string `json:"log_level" yaml:"log_level"` + LogOutput string `json:"log_output" yaml:"log_output"` + HTTPListen string `json:"http_listen" yaml:"http_listen"` + HTTPSListen string `json:"https_listen" yaml:"https_listen"` + IngressPublishService string `json:"ingress_publish_service" yaml:"ingress_publish_service"` + IngressStatusAddress []string `json:"ingress_status_address" yaml:"ingress_status_address"` + EnableProfiling bool `json:"enable_profiling" yaml:"enable_profiling"` + Kubernetes KubernetesConfig `json:"kubernetes" yaml:"kubernetes"` + APISIX APISIXConfig `json:"apisix" yaml:"apisix"` } // KubernetesConfig contains all Kubernetes related config items. @@ -113,13 +115,15 @@ type APISIXConfig struct { // default value. func NewDefaultConfig() *Config { return &Config{ - LogLevel: "warn", - LogOutput: "stderr", - HTTPListen: ":8080", - HTTPSListen: ":8443", - CertFilePath: "/etc/webhook/certs/cert.pem", - KeyFilePath: "/etc/webhook/certs/key.pem", - EnableProfiling: true, + LogLevel: "warn", + LogOutput: "stderr", + HTTPListen: ":8080", + HTTPSListen: ":8443", + IngressPublishService: "", + IngressStatusAddress: []string{}, + CertFilePath: "/etc/webhook/certs/cert.pem", + KeyFilePath: "/etc/webhook/certs/key.pem", + EnableProfiling: true, Kubernetes: KubernetesConfig{ Kubeconfig: "", // Use in-cluster configurations. ResyncInterval: types.TimeDuration{Duration: 6 * time.Hour}, diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 8877c7a..e7e3862 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -28,13 +28,15 @@ import ( func TestNewConfigFromFile(t *testing.T) { cfg := &Config{ - LogLevel: "warn", - LogOutput: "stdout", - HTTPListen: ":9090", - HTTPSListen: ":9443", - CertFilePath: "/etc/webhook/certs/cert.pem", - KeyFilePath: "/etc/webhook/certs/key.pem", - EnableProfiling: true, + LogLevel: "warn", + LogOutput: "stdout", + HTTPListen: ":9090", + HTTPSListen: ":9443", + IngressPublishService: "", + IngressStatusAddress: []string{}, + CertFilePath: "/etc/webhook/certs/cert.pem", + KeyFilePath: "/etc/webhook/certs/key.pem", + EnableProfiling: true, Kubernetes: KubernetesConfig{ ResyncInterval: types.TimeDuration{Duration: time.Hour}, Kubeconfig: "/path/to/foo/baz", @@ -77,6 +79,8 @@ log_level: warn log_output: stdout http_listen: :9090 https_listen: :9443 +ingress_publish_service: "" +ingress_status_address: [] enable_profiling: true kubernetes: kubeconfig: /path/to/foo/baz @@ -105,13 +109,15 @@ apisix: func TestConfigWithEnvVar(t *testing.T) { cfg := &Config{ - LogLevel: "warn", - LogOutput: "stdout", - HTTPListen: ":9090", - HTTPSListen: ":9443", - CertFilePath: "/etc/webhook/certs/cert.pem", - KeyFilePath: "/etc/webhook/certs/key.pem", - EnableProfiling: true, + LogLevel: "warn", + LogOutput: "stdout", + HTTPListen: ":9090", + HTTPSListen: ":9443", + IngressPublishService: "", + IngressStatusAddress: []string{}, + CertFilePath: "/etc/webhook/certs/cert.pem", + KeyFilePath: "/etc/webhook/certs/key.pem", + EnableProfiling: true, Kubernetes: KubernetesConfig{ ResyncInterval: types.TimeDuration{Duration: time.Hour}, Kubeconfig: "", @@ -143,6 +149,8 @@ func TestConfigWithEnvVar(t *testing.T) { "log_output": "stdout", "http_listen": ":9090", "https_listen": ":9443", + "ingress_publish_service": "", + "ingress_status_address": [], "enable_profiling": true, "kubernetes": { "kubeconfig": "{{.KUBECONFIG}}", @@ -176,6 +184,8 @@ log_level: warn log_output: stdout http_listen: :9090 https_listen: :9443 +ingress_publish_service: "" +ingress_status_address: [] enable_profiling: true kubernetes: resync_interval: 1h0m0s diff --git a/pkg/ingress/apisix_route.go b/pkg/ingress/apisix_route.go index 50c5df0..a4b8e9d 100644 --- a/pkg/ingress/apisix_route.go +++ b/pkg/ingress/apisix_route.go @@ -133,7 +133,7 @@ func (c *apisixRouteController) sync(ctx context.Context, ev *types.Event) error } ar = ev.Tombstone.(kube.ApisixRoute) } - // + switch obj.GroupVersion { case kube.ApisixRouteV1: tctx, err = c.controller.translator.TranslateRouteV1(ar.V1()) diff --git a/pkg/ingress/ingress.go b/pkg/ingress/ingress.go index cd42bf3..da136c2 100644 --- a/pkg/ingress/ingress.go +++ b/pkg/ingress/ingress.go @@ -21,6 +21,7 @@ import ( "go.uber.org/zap" k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" @@ -184,7 +185,42 @@ func (c *ingressController) sync(ctx context.Context, ev *types.Event) error { } func (c *ingressController) handleSyncErr(obj interface{}, err error) { + ev := obj.(*types.Event) + event := ev.Object.(kube.IngressEvent) + namespace, name, errLocal := cache.SplitMetaNamespaceKey(event.Key) + if errLocal != nil { + log.Errorf("invalid resource key: %s", event.Key) + return + } + + var ing kube.Ingress + switch event.GroupVersion { + case kube.IngressV1: + ing, err = c.controller.ingressLister.V1(namespace, name) + case kube.IngressV1beta1: + ing, err = c.controller.ingressLister.V1beta1(namespace, name) + case kube.IngressExtensionsV1beta1: + ing, err = c.controller.ingressLister.ExtensionsV1beta1(namespace, name) + } + if err == nil { + // add status + if ev.Type != types.EventDelete { + if errLocal == nil { + switch ing.GroupVersion() { + case kube.IngressV1: + c.controller.recordStatus(ing.V1(), _resourceSynced, nil, metav1.ConditionTrue, ing.V1().GetGeneration()) + case kube.IngressV1beta1: + c.controller.recordStatus(ing.V1beta1(), _resourceSynced, nil, metav1.ConditionTrue, ing.V1beta1().GetGeneration()) + case kube.IngressExtensionsV1beta1: + c.controller.recordStatus(ing.ExtensionsV1beta1(), _resourceSynced, nil, metav1.ConditionTrue, ing.ExtensionsV1beta1().GetGeneration()) + } + } else { + log.Errorw("failed split namespace/name", + zap.Error(errLocal), + ) + } + } c.workqueue.Forget(obj) c.controller.MetricsCollector.IncrSyncOperation("ingress", "success") return @@ -193,6 +229,21 @@ func (c *ingressController) handleSyncErr(obj interface{}, err error) { zap.Any("object", obj), zap.Error(err), ) + + if errLocal == nil { + switch ing.GroupVersion() { + case kube.IngressV1: + c.controller.recordStatus(ing.V1(), _resourceSyncAborted, err, metav1.ConditionTrue, ing.V1().GetGeneration()) + case kube.IngressV1beta1: + c.controller.recordStatus(ing.V1beta1(), _resourceSyncAborted, err, metav1.ConditionTrue, ing.V1beta1().GetGeneration()) + case kube.IngressExtensionsV1beta1: + c.controller.recordStatus(ing.ExtensionsV1beta1(), _resourceSyncAborted, err, metav1.ConditionTrue, ing.ExtensionsV1beta1().GetGeneration()) + } + } else { + log.Errorw("failed split namespace/name", + zap.Error(errLocal), + ) + } c.workqueue.AddRateLimited(obj) c.controller.MetricsCollector.IncrSyncOperation("ingress", "failure") } diff --git a/pkg/ingress/status.go b/pkg/ingress/status.go index f19873e..882595e 100644 --- a/pkg/ingress/status.go +++ b/pkg/ingress/status.go @@ -17,11 +17,19 @@ package ingress import ( "context" + "fmt" + "net" + "time" "go.uber.org/zap" + apiv1 "k8s.io/api/core/v1" + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + networkingv1 "k8s.io/api/networking/v1" + networkingv1beta1 "k8s.io/api/networking/v1beta1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" configv1 "github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v1" configv2alpha1 "github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2alpha1" @@ -31,8 +39,9 @@ import ( ) const ( - _conditionType = "ResourcesAvailable" - _commonSuccessMessage = "Sync Successfully" + _conditionType = "ResourcesAvailable" + _commonSuccessMessage = "Sync Successfully" + _gatewayLBNotReadyMessage = "The LoadBalancer used by the APISIX gateway is not yet ready" ) // verifyGeneration verify generation to decide whether to update status @@ -59,6 +68,7 @@ func (c *Controller) recordStatus(at interface{}, reason string, err error, stat ObservedGeneration: generation, } client := c.kubeClient.APISIXClient + kubeClient := c.kubeClient.Client switch v := at.(type) { case *configv1.ApisixTls: @@ -163,8 +173,142 @@ func (c *Controller) recordStatus(at interface{}, reason string, err error, stat ) } } + case *networkingv1.Ingress: + // set to status + lbips, err := c.ingressLBStatusIPs() + if err != nil { + log.Errorw("failed to get APISIX gateway external IPs", + zap.Error(err), + ) + + } + + v.Status.LoadBalancer.Ingress = lbips + if _, errRecord := kubeClient.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: + // set to status + lbips, err := c.ingressLBStatusIPs() + if err != nil { + log.Errorw("failed to get APISIX gateway external IPs", + zap.Error(err), + ) + + } + + v.Status.LoadBalancer.Ingress = lbips + if _, errRecord := kubeClient.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), + ) + } + case *extensionsv1beta1.Ingress: + // set to status + lbips, err := c.ingressLBStatusIPs() + if err != nil { + log.Errorw("failed to get APISIX gateway external IPs", + zap.Error(err), + ) + + } + + v.Status.LoadBalancer.Ingress = lbips + if _, errRecord := kubeClient.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), + ) + } default: // This should not be executed log.Errorf("unsupported resource record: %s", v) } } + +// ingressPublishAddresses get addressed used to expose Ingress +func (c *Controller) ingressPublishAddresses() ([]string, error) { + ingressPublishService := c.cfg.IngressPublishService + ingressStatusAddress := c.cfg.IngressStatusAddress + addrs := []string{} + + // if ingressStatusAddress is specified, it will be used first + if len(ingressStatusAddress) > 0 { + addrs = append(addrs, ingressStatusAddress...) + return addrs, nil + } + + namespace, name, err := cache.SplitMetaNamespaceKey(ingressPublishService) + if err != nil { + log.Errorf("invalid ingressPublishService %s: %s", ingressPublishService, err) + return nil, err + } + + kubeClient := c.kubeClient.Client + svc, err := kubeClient.CoreV1().Services(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + switch svc.Spec.Type { + case apiv1.ServiceTypeLoadBalancer: + if len(svc.Status.LoadBalancer.Ingress) < 1 { + return addrs, fmt.Errorf(_gatewayLBNotReadyMessage) + } + + for _, ip := range svc.Status.LoadBalancer.Ingress { + if ip.IP == "" { + // typically AWS load-balancers + addrs = append(addrs, ip.Hostname) + } else { + addrs = append(addrs, ip.IP) + } + } + + addrs = append(addrs, svc.Spec.ExternalIPs...) + return addrs, nil + default: + return addrs, nil + } + +} + +// ingressLBStatusIPs organizes the available addresses +func (c *Controller) ingressLBStatusIPs() ([]apiv1.LoadBalancerIngress, error) { + lbips := []apiv1.LoadBalancerIngress{} + var ips []string + + for { + var err error + ips, err = c.ingressPublishAddresses() + if err != nil { + if err.Error() == _gatewayLBNotReadyMessage { + log.Warnf("%s. Provided service: %s", _gatewayLBNotReadyMessage, c.cfg.IngressPublishService) + time.Sleep(time.Second) + continue + } + + return nil, err + } + break + } + + for _, ip := range ips { + if net.ParseIP(ip) == nil { + lbips = append(lbips, apiv1.LoadBalancerIngress{Hostname: ip}) + } else { + lbips = append(lbips, apiv1.LoadBalancerIngress{IP: ip}) + } + + } + + return lbips, nil +} diff --git a/test/e2e/ingress/status.go b/test/e2e/ingress/status.go index fcf9060..8643266 100644 --- a/test/e2e/ingress/status.go +++ b/test/e2e/ingress/status.go @@ -17,7 +17,9 @@ package ingress import ( "fmt" + "net/http" "strings" + "time" "github.com/onsi/ginkgo" "github.com/stretchr/testify/assert" @@ -69,3 +71,51 @@ spec: assert.True(ginkgo.GinkgoT(), hasMsg, "Status is recorded") }) }) + +var _ = ginkgo.Describe("Ingress LB Status Testing", func() { + opts := &scaffold.Options{ + Name: "default", + Kubeconfig: scaffold.GetKubeconfig(), + APISIXConfigPath: "testdata/apisix-gw-config.yaml", + IngressAPISIXReplicas: 1, + HTTPBinServicePort: 80, + APISIXRouteVersion: "apisix.apache.org/v2beta2", + APISIXPublishAddress: "10.6.6.6", + EnableWebhooks: false, + } + s := scaffold.NewScaffold(opts) + ginkgo.It("check the ingress lb status is updated", func() { + backendSvc, backendPort := s.DefaultHTTPBackend() + ing := fmt.Sprintf(` +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: apisix + name: ingress-v1-lb +spec: + rules: + - host: httpbin.org + http: + paths: + - path: /ip + pathType: Exact + backend: + service: + name: %s + port: + number: %d +`, backendSvc, backendPort[0]) + err := s.CreateResourceFromString(ing) + assert.Nil(ginkgo.GinkgoT(), err, "creating ingress") + time.Sleep(5 * time.Second) + + _ = s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect().Status(http.StatusOK) + + output, err := s.GetOutputFromString("ingress", "ingress-v1-lb", "-o", "jsonpath='{ .status.loadBalancer.ingress[0].ip }'") + assert.Nil(ginkgo.GinkgoT(), err, "Get output of ingress status") + + hasIP := strings.Contains(output, "10.6.6.6") + assert.True(ginkgo.GinkgoT(), hasIP, "LB Status is recorded") + }) +}) diff --git a/test/e2e/scaffold/ingress.go b/test/e2e/scaffold/ingress.go index bd6ddbd..99b9ec3 100644 --- a/test/e2e/scaffold/ingress.go +++ b/test/e2e/scaffold/ingress.go @@ -283,6 +283,8 @@ spec: - %s - --apisix-route-version - %s + - --ingress-status-address + - "%s" - --watch-endpointslices %s volumes: @@ -405,9 +407,9 @@ func (s *Scaffold) newIngressAPISIXController() error { var ingressAPISIXDeployment string label := fmt.Sprintf("apisix.ingress.watch=%s", s.namespace) if s.opts.EnableWebhooks { - ingressAPISIXDeployment = fmt.Sprintf(_ingressAPISIXDeploymentTemplate, s.opts.IngressAPISIXReplicas, s.namespace, label, s.opts.APISIXRouteVersion, _volumeMounts, _webhookCertSecret) + ingressAPISIXDeployment = fmt.Sprintf(_ingressAPISIXDeploymentTemplate, s.opts.IngressAPISIXReplicas, s.namespace, label, s.opts.APISIXRouteVersion, s.opts.APISIXPublishAddress, _volumeMounts, _webhookCertSecret) } else { - ingressAPISIXDeployment = fmt.Sprintf(_ingressAPISIXDeploymentTemplate, s.opts.IngressAPISIXReplicas, s.namespace, label, s.opts.APISIXRouteVersion, "", _webhookCertSecret) + ingressAPISIXDeployment = fmt.Sprintf(_ingressAPISIXDeploymentTemplate, s.opts.IngressAPISIXReplicas, s.namespace, label, s.opts.APISIXRouteVersion, s.opts.APISIXPublishAddress, "", _webhookCertSecret) } err = k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, ingressAPISIXDeployment) @@ -513,9 +515,9 @@ func (s *Scaffold) ScaleIngressController(desired int) error { var ingressDeployment string label := fmt.Sprintf("apisix.ingress.watch=%s", s.namespace) if s.opts.EnableWebhooks { - ingressDeployment = fmt.Sprintf(_ingressAPISIXDeploymentTemplate, desired, s.namespace, label, s.opts.APISIXRouteVersion, _volumeMounts, _webhookCertSecret) + ingressDeployment = fmt.Sprintf(_ingressAPISIXDeploymentTemplate, desired, s.namespace, label, s.opts.APISIXRouteVersion, s.opts.APISIXPublishAddress, _volumeMounts, _webhookCertSecret) } else { - ingressDeployment = fmt.Sprintf(_ingressAPISIXDeploymentTemplate, desired, s.namespace, label, s.opts.APISIXRouteVersion, "", _webhookCertSecret) + ingressDeployment = fmt.Sprintf(_ingressAPISIXDeploymentTemplate, desired, s.namespace, label, s.opts.APISIXRouteVersion, s.opts.APISIXPublishAddress, "", _webhookCertSecret) } if err := k8s.KubectlApplyFromStringE(s.t, s.kubectlOptions, ingressDeployment); err != nil { return err diff --git a/test/e2e/scaffold/scaffold.go b/test/e2e/scaffold/scaffold.go index 73173f6..b19d806 100644 --- a/test/e2e/scaffold/scaffold.go +++ b/test/e2e/scaffold/scaffold.go @@ -53,6 +53,7 @@ type Options struct { APISIXRouteVersion string APISIXAdminAPIKey string EnableWebhooks bool + APISIXPublishAddress string } type Scaffold struct { @@ -130,6 +131,7 @@ func NewDefaultScaffold() *Scaffold { HTTPBinServicePort: 80, APISIXRouteVersion: kube.ApisixRouteV1, EnableWebhooks: false, + APISIXPublishAddress: "", } return NewScaffold(opts) } @@ -144,6 +146,7 @@ func NewDefaultV2Scaffold() *Scaffold { HTTPBinServicePort: 80, APISIXRouteVersion: kube.ApisixRouteV2alpha1, EnableWebhooks: false, + APISIXPublishAddress: "", } return NewScaffold(opts) }