Proxy DevOps APIs with version v1alpha1

Signed-off-by: johnniang <johnniang@fastmail.com>
This commit is contained in:
johnniang
2022-02-23 16:03:16 +08:00
parent f50de9af65
commit ef1d0fdf1d
7 changed files with 130 additions and 91 deletions

View File

@@ -65,8 +65,7 @@ import (
clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1"
configv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/config/v1alpha2"
crd "kubesphere.io/kubesphere/pkg/kapis/crd"
devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2"
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha3"
kapisdevops "kubesphere.io/kubesphere/pkg/kapis/devops"
edgeruntimev1alpha1 "kubesphere.io/kubesphere/pkg/kapis/edgeruntime/v1alpha1"
gatewayv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/gateway/v1alpha1"
iamapi "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
@@ -244,8 +243,7 @@ func (s *APIServer) installKubeSphereAPIs() {
s.Config.AuthenticationOptions))
urlruntime.Must(servicemeshv1alpha2.AddToContainer(s.Config.ServiceMeshOptions, s.container, s.KubernetesClient.Kubernetes(), s.CacheClient))
urlruntime.Must(networkv1alpha2.AddToContainer(s.container, s.Config.NetworkOptions.WeaveScopeHost))
urlruntime.Must(devopsv1alpha2.AddToContainer(s.container, s.Config.DevopsOptions.Endpoint))
urlruntime.Must(devopsv1alpha3.AddToContainer(s.container, s.Config.DevopsOptions.Endpoint))
urlruntime.Must(kapisdevops.AddToContainer(s.container, s.Config.DevopsOptions.Endpoint))
urlruntime.Must(notificationv1.AddToContainer(s.container, s.Config.NotificationOptions.Endpoint))
urlruntime.Must(alertingv1.AddToContainer(s.container, s.Config.AlertingOptions.Endpoint))
urlruntime.Must(alertingv2alpha1.AddToContainer(s.container, s.InformerFactory,

View File

@@ -1,17 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed 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 devops

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 The KubeSphere Authors.
Copyright 2022 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,26 +14,27 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha2
package devops
import (
"github.com/emicklei/go-restful"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/kapis/generic"
)
const (
GroupName = "devops.kubesphere.io"
)
const groupName = "devops.kubesphere.io"
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
var versions = []string{"v1alpha1", "v1alpha2", "v1alpha3"}
// AddToContainer registers DevOps proxies to the container.
func AddToContainer(container *restful.Container, endpoint string) error {
proxy, err := generic.NewGenericProxy(endpoint, GroupVersion.Group, GroupVersion.Version)
for _, version := range versions {
proxy, err := generic.NewGenericProxy(endpoint, groupName, version)
if err != nil {
return err
}
return proxy.AddToContainer(container)
if err = proxy.AddToContainer(container); err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,112 @@
/*
Copyright 2022 The KubeSphere Authors.
Licensed 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 devops
import (
"github.com/emicklei/go-restful"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)
func TestAddToContainer(t *testing.T) {
fakeResponse := "fake DevOps APIServer response"
type args struct {
target string
mockAPIPattern string
mockResponse string
}
tests := []struct {
name string
args args
wantErr bool
wantResponse string
}{{
name: "Should proxy v1alpha1 API properly",
args: args{
target: "/kapis/devops.kubesphere.io/v1alpha1/resources",
mockAPIPattern: "/v1alpha1/resources",
},
wantResponse: fakeResponse,
}, {
name: "Should proxy v1alpha2 API properly",
args: args{
target: "/kapis/devops.kubesphere.io/v1alpha2/resources",
mockAPIPattern: "/v1alpha2/resources",
},
wantResponse: fakeResponse,
}, {
name: "Should proxy v1alpha3 API properly",
args: args{
target: "/kapis/devops.kubesphere.io/v1alpha3/resources",
mockAPIPattern: "/v1alpha3/resources",
},
wantResponse: fakeResponse,
}, {
name: "Should return 404 if no pattern matches",
args: args{
target: "/kapis/devops.kubesphere.io/v1alpha3/resources",
mockAPIPattern: "/v1alpha4/resources",
},
wantResponse: "404 page not found\n",
}, {
name: "Should not proxy v1alpha123 API properly event if pattern matched",
args: args{
target: "/kapis/devops.kubesphere.io/v1alpha123/resources",
mockAPIPattern: "/v1alpha123/resources",
},
wantResponse: "404 page not found\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// create a fresh mock DevOps APIServer.
server := mockDevOpsAPIServer(tt.args.mockAPIPattern, 200, tt.args.mockResponse)
defer server.Close()
// mock to request DevOps API from KubeSphere APIServer
container := restful.NewContainer()
if err := AddToContainer(container, server.URL); (err != nil) != tt.wantErr {
t.Errorf("AddToContainer() error = %v, wantErr %v", err, tt.wantErr)
}
request := httptest.NewRequest(http.MethodGet, tt.args.target, nil)
recorder := &responseRecorder{*httptest.NewRecorder()}
container.ServeHTTP(restful.NewResponse(recorder), request)
assert.Equal(t, tt.wantResponse, recorder.Body.String())
})
}
}
func mockDevOpsAPIServer(pattern string, fakeCode int, fakeResp string) *httptest.Server {
mux := http.NewServeMux()
mux.HandleFunc(pattern, func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(fakeCode)
_, _ = writer.Write([]byte(fakeResp))
})
return httptest.NewServer(mux)
}
// responseRecorder extends httptest.ResponseRecorder and implements CloseNotifier interface for generic proxy.
type responseRecorder struct {
httptest.ResponseRecorder
}
func (*responseRecorder) CloseNotify() <-chan bool {
return nil
}

View File

@@ -1,12 +0,0 @@
approvers:
- shaowenchen
- linuxsuren
reviewers:
- runzexia
- soulseen
- shaowenchen
- linuxsuren
labels:
- area/devops

View File

@@ -1,41 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed 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 v1alpha3
import (
"github.com/emicklei/go-restful"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/kapis/generic"
)
const (
GroupName = "devops.kubesphere.io"
)
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha3"}
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)
}

View File

@@ -22,6 +22,7 @@ import (
"flag"
"fmt"
"io/ioutil"
kapisdevops "kubesphere.io/kubesphere/pkg/kapis/devops"
"log"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
@@ -43,8 +44,6 @@ import (
"kubesphere.io/kubesphere/pkg/informers"
alertingv2alpha1 "kubesphere.io/kubesphere/pkg/kapis/alerting/v2alpha1"
clusterkapisv1alpha1 "kubesphere.io/kubesphere/pkg/kapis/cluster/v1alpha1"
devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2"
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha3"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
networkv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/network/v1alpha2"
@@ -120,8 +119,7 @@ func generateSwaggerJson() []byte {
urlruntime.Must(oauth.AddToContainer(container, nil, nil, nil, nil, nil, nil))
urlruntime.Must(clusterkapisv1alpha1.AddToContainer(container, clientsets.KubeSphere(), informerFactory.KubernetesSharedInformerFactory(),
informerFactory.KubeSphereSharedInformerFactory(), "", "", ""))
urlruntime.Must(devopsv1alpha2.AddToContainer(container, ""))
urlruntime.Must(devopsv1alpha3.AddToContainer(container, ""))
urlruntime.Must(kapisdevops.AddToContainer(container, ""))
urlruntime.Must(iamv1alpha2.AddToContainer(container, nil, nil, group.New(informerFactory, clientsets.KubeSphere(), clientsets.Kubernetes()), nil))
urlruntime.Must(monitoringv1alpha3.AddToContainer(container, clientsets.Kubernetes(), nil, nil, informerFactory, nil, nil, nil))
urlruntime.Must(openpitrixv1.AddToContainer(container, informerFactory, fake.NewSimpleClientset(), nil))