Skip to content

Commit

Permalink
feature: add ingress controller http server (#1940)
Browse files Browse the repository at this point in the history
  • Loading branch information
yaoxinwang-git authored Nov 29, 2022
1 parent f940db0 commit 3fecabd
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Tencent is pleased to support the open source community by making Blueking Container Service available.
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* 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 httpsvr

import (
"github.com/emicklei/go-restful"
"sigs.k8s.io/controller-runtime/pkg/manager"
)

// HttpServerClient http server client
type HttpServerClient struct {
Mgr manager.Manager
}

func InitRouters(ws *restful.WebService, httpServerClient *HttpServerClient) {
ws.Route(ws.GET("/api/v1/ingresss").To(httpServerClient.listIngress))
ws.Route(ws.GET("/api/v1/portpools").To(httpServerClient.listPortPool))
ws.Route(ws.GET("/api/v1/listeners/{condition}/{namespace}/{name}").To(httpServerClient.listListener))

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Tencent is pleased to support the open source community by making Blueking Container Service available.
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* 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 httpsvr

import (
"context"

"github.com/emicklei/go-restful"

"github.com/Tencent/bk-bcs/bcs-common/common/blog"
networkextensionv1 "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/kubernetes/apis/networkextension/v1"
)

func (h *HttpServerClient) listIngress(request *restful.Request, response *restful.Response) {
ingressList := &networkextensionv1.IngressList{}
if err := h.Mgr.GetClient().List(context.Background(), ingressList); err != nil {
blog.Errorf("list ext ingresses failed when collect metrics, err %s", err.Error())
return
}
data := CreateResponseData(nil, "success", ingressList)
_, _ = response.Write([]byte(data))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Tencent is pleased to support the open source community by making Blueking Container Service available.
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* 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 httpsvr

import (
"context"
"github.com/Tencent/bk-bcs/bcs-common/common/blog"
networkextensionv1 "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/kubernetes/apis/networkextension/v1"
"github.com/emicklei/go-restful"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8slabels "k8s.io/apimachinery/pkg/labels"
k8sapitypes "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func (h *HttpServerClient) listListener(request *restful.Request, response *restful.Response) {

var data string
switch request.PathParameter("condition") {
case "ingress":
ingress := &networkextensionv1.Ingress{}
if err := h.Mgr.GetClient().Get(context.Background(), k8sapitypes.NamespacedName{
Name: request.PathParameter("name"),
Namespace: request.PathParameter("namespace"),
}, ingress); err != nil {
if k8serrors.IsNotFound(err) {
blog.Infof("ingress %s/%s not found", request.PathParameter("namespace"), request.PathParameter("name"))
data = CreateResponseData(err, "failed", nil)
break
}
}
existedListenerList := &networkextensionv1.ListenerList{}
selector, err := k8smetav1.LabelSelectorAsSelector(k8smetav1.SetAsLabelSelector(k8slabels.Set(map[string]string{
ingress.Name: networkextensionv1.LabelValueForIngressName,
networkextensionv1.LabelKeyForIsSegmentListener: networkextensionv1.LabelValueFalse,
})))
err = h.Mgr.GetClient().List(context.TODO(), existedListenerList, &client.ListOptions{
Namespace: ingress.Namespace,
LabelSelector: selector})
if err != nil {
blog.Errorf("list listeners filter by ingress %s failed, err %s",
request.PathParameter("name"), err.Error())
data = CreateResponseData(err, "failed", nil)
break
}
data = CreateResponseData(nil, "success", existedListenerList)
case "portpool":
portPool := &networkextensionv1.PortPool{}
if err := h.Mgr.GetClient().Get(context.Background(), k8sapitypes.NamespacedName{
Name: request.PathParameter("name"),
Namespace: request.PathParameter("namespace"),
}, portPool); err != nil {
if k8serrors.IsNotFound(err) {
blog.Infof("portpool %s/%s not found", request.PathParameter("namespace"), request.PathParameter("name"))
data = CreateResponseData(err, "failed", nil)
break
}
}
result := make(map[string]*networkextensionv1.ListenerList, 0)
for i := range portPool.Spec.PoolItems {
existedListenerList := &networkextensionv1.ListenerList{}
selector, err := k8smetav1.LabelSelectorAsSelector(k8smetav1.SetAsLabelSelector(k8slabels.Set(map[string]string{
portPool.Spec.PoolItems[i].ItemName: networkextensionv1.LabelValueForPortPoolItemName,
networkextensionv1.LabelKeyForIsSegmentListener: networkextensionv1.LabelValueFalse,
})))
err = h.Mgr.GetClient().List(context.TODO(), existedListenerList, &client.ListOptions{
Namespace: request.PathParameter("namespace"),
LabelSelector: selector})
if err != nil {
blog.Errorf("list listeners filter by port pool item %s failed, err %s",
portPool.Spec.PoolItems[i].ItemName, err.Error())
data = CreateResponseData(err, "failed", nil)
break
}
result[portPool.Spec.PoolItems[i].ItemName] = existedListenerList
}
data = CreateResponseData(nil, "success", result)
}

_, _ = response.Write([]byte(data))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Tencent is pleased to support the open source community by making Blueking Container Service available.
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* 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 httpsvr

import (
"context"

"github.com/emicklei/go-restful"

"github.com/Tencent/bk-bcs/bcs-common/common/blog"
networkextensionv1 "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/kubernetes/apis/networkextension/v1"
)

func (h *HttpServerClient) listPortPool(request *restful.Request, response *restful.Response) {
poolList := &networkextensionv1.PortPoolList{}
if err := h.Mgr.GetClient().List(context.Background(), poolList); err != nil {
blog.Errorf("list port pool failed when collect metrics, err %s", err.Error())
}
data := CreateResponseData(nil, "success", poolList)
_, _ = response.Write([]byte(data))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Tencent is pleased to support the open source community by making Blueking Container Service available.
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* 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 httpsvr

import (
"errors"

"github.com/Tencent/bk-bcs/bcs-common/common"
bhttp "github.com/Tencent/bk-bcs/bcs-common/common/http"
)

// CreateResponseData common response
func CreateResponseData(err error, msg string, data interface{}) string {
var rpyErr error
if err != nil {
rpyErr = bhttp.InternalError(common.BcsErrMesosSchedCommon, msg)
} else {
rpyErr = errors.New(bhttp.GetRespone(common.BcsSuccess, common.BcsSuccessStr, data))
}

// blog.V(3).Infof("createRespone: %s", rpyErr.Error())

return rpyErr.Error()
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,23 @@ type ControllerOption struct {

// ConflictCheckOpen if false, skip all conflict checking about ingress and port pool
ConflictCheckOpen bool

HttpServerPort uint

Conf Conf

ServCert ServCert
}
type Conf struct {
ServCert ServCert
InsecureAddress string
InsecurePort uint
VerifyClientTLS bool
}
type ServCert struct {
CAFile string
CertFile string
KeyFile string
CertPasswd string
IsSSL bool
}
40 changes: 39 additions & 1 deletion bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import (
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"

"github.com/Tencent/bk-bcs/bcs-common/common/blog"
"github.com/Tencent/bk-bcs/bcs-common/common/http/httpserver"
"github.com/Tencent/bk-bcs/bcs-common/common/http/ipv6server"
clbv1 "github.com/Tencent/bk-bcs/bcs-k8s/kubedeprecated/apis/clb/v1"
ingressctrl "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/ingresscontroller"
Expand All @@ -44,6 +46,7 @@ import (
"github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/internal/constant"
"github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/internal/eventer"
"github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/internal/generator"
"github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/internal/httpsvr"
"github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/internal/option"
"github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/internal/portpoolcache"
"github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-network/bcs-ingress-controller/internal/webhookserver"
Expand Down Expand Up @@ -106,6 +109,8 @@ func main() {
flag.BoolVar(&opts.ConflictCheckOpen, "conflict_check_open", true, "if false, "+
"skip all conflict checking about ingress and port pool")

flag.UintVar(&opts.HttpServerPort, "port", 8082, "port for ingress controller http server")

flag.Parse()

opts.Verbosity = int32(verbosity)
Expand Down Expand Up @@ -334,7 +339,15 @@ func main() {
metrics.Registry.MustRegister(collector)

blog.Infof("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {

err = initHttpServer(opts, mgr)
if err != nil {
blog.Errorf("init http server failed: %v", err.Error())
os.Exit(1)
}

blog.Infof("starting http server")
if err = mgr.Start(ctrl.SetupSignalHandler()); err != nil {
blog.Errorf("problem running manager, err %s", err.Error())
os.Exit(1)
}
Expand Down Expand Up @@ -364,3 +377,28 @@ func runPrometheusMetrics(op *option.ControllerOption) {
}
}()
}

//initHttpServer init ingress controller http server
func initHttpServer(op *option.ControllerOption, mgr manager.Manager) error {
server := httpserver.NewHttpServer(op.HttpServerPort, op.Address, "")
if op.Conf.ServCert.IsSSL {
server.SetSsl(op.Conf.ServCert.CAFile, op.Conf.ServCert.CertFile, op.Conf.ServCert.KeyFile,
op.Conf.ServCert.CertPasswd)
}

server.SetInsecureServer(op.Conf.InsecureAddress, op.Conf.InsecurePort)
ws := server.NewWebService("/ingresscontroller", nil)
httpServerClient := &httpsvr.HttpServerClient{
mgr,
}
httpsvr.InitRouters(ws, httpServerClient)

router := server.GetRouter()
webContainer := server.GetWebContainer()
router.Handle("/ingresscontroller/{sub_path:.*}", webContainer)
if err := server.ListenAndServeMux(op.Conf.VerifyClientTLS); err != nil {
return fmt.Errorf("http ListenAndServe error %s", err.Error())
}
return nil

}

0 comments on commit 3fecabd

Please sign in to comment.