@@ -30,6 +30,7 @@ import (
|
|||||||
"kubesphere.io/kubesphere/pkg/apiserver/filters"
|
"kubesphere.io/kubesphere/pkg/apiserver/filters"
|
||||||
"kubesphere.io/kubesphere/pkg/apiserver/request"
|
"kubesphere.io/kubesphere/pkg/apiserver/request"
|
||||||
"kubesphere.io/kubesphere/pkg/informers"
|
"kubesphere.io/kubesphere/pkg/informers"
|
||||||
|
alertingv1 "kubesphere.io/kubesphere/pkg/kapis/alerting/v1"
|
||||||
clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1"
|
clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1"
|
||||||
configv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/config/v1alpha2"
|
configv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/config/v1alpha2"
|
||||||
devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2"
|
devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2"
|
||||||
@@ -37,6 +38,7 @@ import (
|
|||||||
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/logging/v1alpha2"
|
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/logging/v1alpha2"
|
||||||
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
|
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
|
||||||
networkv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/network/v1alpha2"
|
networkv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/network/v1alpha2"
|
||||||
|
notificationv1 "kubesphere.io/kubesphere/pkg/kapis/notification/v1"
|
||||||
"kubesphere.io/kubesphere/pkg/kapis/oauth"
|
"kubesphere.io/kubesphere/pkg/kapis/oauth"
|
||||||
openpitrixv1 "kubesphere.io/kubesphere/pkg/kapis/openpitrix/v1"
|
openpitrixv1 "kubesphere.io/kubesphere/pkg/kapis/openpitrix/v1"
|
||||||
operationsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/operations/v1alpha2"
|
operationsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/operations/v1alpha2"
|
||||||
@@ -174,6 +176,8 @@ func (s *APIServer) installKubeSphereAPIs() {
|
|||||||
s.SonarClient,
|
s.SonarClient,
|
||||||
s.KubernetesClient.KubeSphere(),
|
s.KubernetesClient.KubeSphere(),
|
||||||
s.S3Client))
|
s.S3Client))
|
||||||
|
urlruntime.Must(notificationv1.AddToContainer(s.container, s.Config.NotificationOptions.Endpoint))
|
||||||
|
urlruntime.Must(alertingv1.AddToContainer(s.container, s.Config.AlertingOptions.Endpoint))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIServer) Run(stopCh <-chan struct{}) (err error) {
|
func (s *APIServer) Run(stopCh <-chan struct{}) (err error) {
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ func newTestConfig() (*Config, error) {
|
|||||||
Version: "6",
|
Version: "6",
|
||||||
},
|
},
|
||||||
AlertingOptions: &alerting.Options{
|
AlertingOptions: &alerting.Options{
|
||||||
Endpoint: "http://alerting.kubesphere-alerting-system.svc:9200",
|
Endpoint: "http://alerting-client-server.kubesphere-alerting-system.svc:9200/api",
|
||||||
},
|
},
|
||||||
NotificationOptions: ¬ification.Options{
|
NotificationOptions: ¬ification.Options{
|
||||||
Endpoint: "http://notification.kubesphere-alerting-system.svc:9200",
|
Endpoint: "http://notification.kubesphere-alerting-system.svc:9200",
|
||||||
|
|||||||
18
pkg/kapis/alerting/v1/register.go
Normal file
18
pkg/kapis/alerting/v1/register.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/emicklei/go-restful"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"kubesphere.io/kubesphere/pkg/kapis/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
var GroupVersion = schema.GroupVersion{Group: "alerting.kubesphere.io", Version: "v1"}
|
||||||
|
|
||||||
|
func AddToContainer(container *restful.Container, endpoint string) error {
|
||||||
|
proxy, err := generic.NewGenericProxy(endpoint, GroupVersion.Group, GroupVersion.Version)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxy.AddToContainer(container)
|
||||||
|
}
|
||||||
96
pkg/kapis/generic/generic.go
Normal file
96
pkg/kapis/generic/generic.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package generic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/emicklei/go-restful"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/proxy"
|
||||||
|
"k8s.io/klog"
|
||||||
|
"kubesphere.io/kubesphere/pkg/api"
|
||||||
|
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// genericProxy is a simple proxy for external service.
|
||||||
|
type genericProxy struct {
|
||||||
|
// proxy service endpoint
|
||||||
|
Endpoint *url.URL
|
||||||
|
|
||||||
|
// api group name exposed to clients
|
||||||
|
GroupName string
|
||||||
|
|
||||||
|
// api version
|
||||||
|
Version string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGenericProxy(endpoint string, groupName string, version string) (*genericProxy, error) {
|
||||||
|
parse, err := url.Parse(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim path suffix slash
|
||||||
|
parse.Path = strings.Trim(parse.Path, "/")
|
||||||
|
|
||||||
|
return &genericProxy{
|
||||||
|
Endpoint: parse,
|
||||||
|
GroupName: groupName,
|
||||||
|
Version: version,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *genericProxy) AddToContainer(container *restful.Container) error {
|
||||||
|
webservice := runtime.NewWebService(schema.GroupVersion{
|
||||||
|
Group: g.GroupName,
|
||||||
|
Version: g.Version,
|
||||||
|
})
|
||||||
|
|
||||||
|
webservice.Route(webservice.GET("/{path:*}").
|
||||||
|
To(g.handler).
|
||||||
|
Returns(http.StatusOK, api.StatusOK, nil))
|
||||||
|
|
||||||
|
webservice.Route(webservice.PUT("/{path:*}").
|
||||||
|
To(g.handler).
|
||||||
|
Returns(http.StatusOK, api.StatusOK, nil))
|
||||||
|
|
||||||
|
webservice.Route(webservice.POST("/{path:*}").
|
||||||
|
To(g.handler).
|
||||||
|
Returns(http.StatusOK, api.StatusOK, nil))
|
||||||
|
|
||||||
|
webservice.Route(webservice.DELETE("/{path:*}").
|
||||||
|
To(g.handler).
|
||||||
|
Returns(http.StatusOK, api.StatusOK, nil))
|
||||||
|
|
||||||
|
container.Add(webservice)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *genericProxy) handler(request *restful.Request, response *restful.Response) {
|
||||||
|
u := g.makeURL(request)
|
||||||
|
|
||||||
|
httpProxy := proxy.NewUpgradeAwareHandler(u, http.DefaultTransport, false, false, &errorResponder{})
|
||||||
|
httpProxy.ServeHTTP(response, request.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *genericProxy) makeURL(request *restful.Request) *url.URL {
|
||||||
|
u := *(request.Request.URL)
|
||||||
|
u.Host = g.Endpoint.Host
|
||||||
|
u.Scheme = g.Endpoint.Scheme
|
||||||
|
u.Path = strings.Replace(request.Request.URL.Path, fmt.Sprintf("/kapis/%s", g.GroupName), "", 1)
|
||||||
|
|
||||||
|
// prepend path from endpoint
|
||||||
|
if len(g.Endpoint.Path) != 0 {
|
||||||
|
u.Path = fmt.Sprintf("/%s%s", g.Endpoint.Path, u.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &u
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorResponder struct{}
|
||||||
|
|
||||||
|
func (e *errorResponder) Error(w http.ResponseWriter, req *http.Request, err error) {
|
||||||
|
klog.Error(err)
|
||||||
|
}
|
||||||
60
pkg/kapis/generic/generic_test.go
Normal file
60
pkg/kapis/generic/generic_test.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package generic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/emicklei/go-restful"
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var group = "test.kubesphere.io"
|
||||||
|
var version = "v1"
|
||||||
|
var scheme = "http"
|
||||||
|
|
||||||
|
func TestNewGenericProxy(t *testing.T) {
|
||||||
|
var testCases = []struct {
|
||||||
|
description string
|
||||||
|
endpoint string
|
||||||
|
query string
|
||||||
|
expected *url.URL
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "Endpoint with path",
|
||||||
|
endpoint: "http://awesome.kubesphere-system.svc:8080/api",
|
||||||
|
query: "/kapis/test.kubesphere.io/v1/foo/bar?id=1&time=whatever",
|
||||||
|
expected: &url.URL{
|
||||||
|
Scheme: scheme,
|
||||||
|
Host: "awesome.kubesphere-system.svc:8080",
|
||||||
|
Path: "/api/v1/foo/bar",
|
||||||
|
RawQuery: "id=1&time=whatever",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Endpoint without path",
|
||||||
|
endpoint: "http://awesome.kubesphere-system.svc:8080",
|
||||||
|
query: "/kapis/test.kubesphere.io/v1/foo/bar?id=1&time=whatever",
|
||||||
|
expected: &url.URL{
|
||||||
|
Scheme: scheme,
|
||||||
|
Host: "awesome.kubesphere-system.svc:8080",
|
||||||
|
Path: "/v1/foo/bar",
|
||||||
|
RawQuery: "id=1&time=whatever",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
proxy, err := NewGenericProxy(testCase.endpoint, group, version)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(testCase.description, func(t *testing.T) {
|
||||||
|
request := httptest.NewRequest("GET", testCase.query, nil)
|
||||||
|
u := proxy.makeURL(restful.NewRequest(request))
|
||||||
|
if diff := cmp.Diff(u, testCase.expected); len(diff) != 0 {
|
||||||
|
t.Errorf("%T differ (-got, +want): %s", testCase.expected, diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
19
pkg/kapis/notification/v1/register.go
Normal file
19
pkg/kapis/notification/v1/register.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/emicklei/go-restful"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"kubesphere.io/kubesphere/pkg/kapis/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
var GroupVersion = schema.GroupVersion{Group: "notification.kubesphere.io", Version: "v1"}
|
||||||
|
|
||||||
|
func AddToContainer(container *restful.Container, endpoint string) error {
|
||||||
|
|
||||||
|
proxy, err := generic.NewGenericProxy(endpoint, GroupVersion.Group, GroupVersion.Version)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxy.AddToContainer(container)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user