Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: apisix http client #147

Merged
merged 15 commits into from
Jan 8, 2021
16 changes: 11 additions & 5 deletions cmd/ingress/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (

"github.com/api7/ingress-controller/pkg/config"
"github.com/api7/ingress-controller/pkg/log"
"github.com/api7/ingress-controller/pkg/seven/conf"
"github.com/api7/ingress-controller/pkg/types"
)

Expand Down Expand Up @@ -61,9 +60,19 @@ func (fws *fakeWriteSyncer) bytes() (p []byte) {

func TestSignalHandler(t *testing.T) {
cmd := NewIngressCommand()
cmd.SetArgs([]string{
"--log-level", "debug",
"--log-output", "./test.log",
"--http-listen", "127.0.0.1:16780",
"--enable-profiling",
"--kubeconfig", "/foo/bar/baz",
"--resync-interval", "24h",
"--apisix-base-url", "http://apisixgw.default.cluster.local/apisix",
"--apisix-admin-key", "0x123",
})
waitCh := make(chan struct{})
go func() {
cmd.Run(cmd, nil)
cmd.Execute()
close(waitCh)
}()

Expand Down Expand Up @@ -131,9 +140,6 @@ func TestNewIngressCommandEffectiveLog(t *testing.T) {
assert.Equal(t, cfg.Kubernetes.ResyncInterval, types.TimeDuration{24 * time.Hour})
assert.Equal(t, cfg.APISIX.AdminKey, "0x123")
assert.Equal(t, cfg.APISIX.BaseURL, "http://apisixgw.default.cluster.local/apisix")

// Test the conf.BaseUrl is really set.
assert.Equal(t, cfg.APISIX.BaseURL, conf.BaseUrl)
}

func parseLog(t *testing.T, r *bufio.Reader) *fields {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
github.com/yudai/pp v2.0.1+incompatible // indirect
go.uber.org/zap v1.13.0
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
gopkg.in/resty.v1 v1.12.0
gopkg.in/yaml.v2 v2.2.8
k8s.io/api v0.0.0-20190819141258-3544db3b9e44
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -346,11 +348,16 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
Expand Down
144 changes: 144 additions & 0 deletions pkg/apisix/apisix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// 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 apisix

import (
"context"

v1 "github.com/api7/ingress-controller/pkg/types/apisix/v1"
)

// APISIX is the unified client tool to communicate with APISIX.
type APISIX interface {
// Cluster specifies the target cluster to talk.
Cluster(string) Cluster
// AddCluster adds a new cluster.
AddCluster(*ClusterOptions) error
// ListClusters lists all APISIX clusters.
ListClusters() []Cluster
}

// Cluster defines specific operations that can be applied in an APISIX
// cluster.
type Cluster interface {
// Route returns a Route interface that can operate Route resources.
Route() Route
// Upstream returns a Upstream interface that can operate Upstream resources.
Upstream() Upstream
// Service returns a Service interface that can operate Service resources.
Service() Service
// SSL returns a SSL interface that can operate SSL resources.
SSL() SSL
}

// Route is the specific client interface to take over the create, update,
// list and delete for APISIX's Route resource.
type Route interface {
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)
}

// SSL is the specific client interface to take over the create, update,
// list and delete for APISIX's SSL resource.
type SSL interface {
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)
}

// Upstream is the specific client interface to take over the create, update,
// list and delete for APISIX's Upstream resource.
type Upstream interface {
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)
}

// Service is the specific client interface to take over the create, update,
// list and delete for APISIX's Service resource.
type Service interface {
List(context.Context) ([]*v1.Service, error)
Create(context.Context, *v1.Service) (*v1.Service, error)
Delete(context.Context, *v1.Service) error
Update(context.Context, *v1.Service) (*v1.Service, error)
}

type apisix struct {
defaultCluster Cluster
nonExistentCluster Cluster
defaultClusterName string
clusters map[string]Cluster
}

// NewForOptions creates an APISIX client to perform resources change pushing.
// Users should carry a ClusterOptions to configure the default APISIX cluster.
func NewForOptions(co *ClusterOptions) (APISIX, error) {
defaultCluster, err := newCluster(co)
if err != nil {
return nil, err
}
cli := &apisix{
defaultCluster: defaultCluster,
defaultClusterName: co.Name,
nonExistentCluster: newNonExistentCluster(),
}
return cli, nil
}

// Cluster implements APISIX.Cluster method.
func (c *apisix) Cluster(name string) Cluster {
if name == c.defaultClusterName {
return c.defaultCluster
}
cluster, ok := c.clusters[name]
if !ok {
return c.nonExistentCluster
}
return cluster
}

// ListClusters implements APISIX.ListClusters method.
func (c *apisix) ListClusters() []Cluster {
clusters := make([]Cluster, 0, len(c.clusters)+1)
clusters = append(clusters, c.defaultCluster)
for _, cluster := range c.clusters {
clusters = append(clusters, cluster)
}
return clusters
}

// AddCluster implements APISIX.AddCluster method.
func (c *apisix) AddCluster(co *ClusterOptions) error {
if co.Name == c.defaultClusterName {
return ErrDuplicatedCluster
}
_, ok := c.clusters[co.Name]
if ok {
return ErrDuplicatedCluster
}
cluster, err := newCluster(co)
if err != nil {
return err
}
if c.clusters == nil {
c.clusters = make(map[string]Cluster)
}
c.clusters[co.Name] = cluster
return nil
}
Loading