Compare commits

...

20 Commits

Author SHA1 Message Date
KubeSphere CI Bot
2758e35a4e Merge pull request #4881 from suwliang3/master
feature:test functions in package resources/v1alpha3 by building restful's re…
2022-05-29 23:23:40 +08:00
KubeSphere CI Bot
305da3c0c5 Merge pull request #4918 from anhoder/master
fix:goroutine leak when open terminal
2022-05-29 23:18:51 +08:00
KubeSphere CI Bot
e5ac3608f6 Merge pull request #4916 from ONE7live/dev_test
add some unit test for models
2022-05-29 23:17:50 +08:00
anhoder
d0933055cb fix:goroutine leak when open terminal 2022-05-27 18:25:43 +08:00
KubeSphere CI Bot
fc7cdd7300 Merge pull request #4915 from wansir/master
chore: update vendor
2022-05-27 17:47:25 +08:00
hongming
52b7fb71b2 chore: update vendor 2022-05-27 16:42:26 +08:00
ONE7live
4247387144 add some unit test for models
Signed-off-by: ONE7live <wangqi_yewu@cmss.chinamobile.com>
2022-05-27 16:10:01 +08:00
KubeSphere CI Bot
da5e4cc247 Merge pull request #4904 from xyz-li/master
add workspace to review list
2022-05-25 14:34:31 +08:00
LiHui
73852a8a4b add workspace to review list 2022-05-25 11:58:21 +08:00
suwanliang
b2be653639 run make fmt and make goimports 2022-05-24 18:37:16 +08:00
KubeSphere CI Bot
0418277b57 Merge pull request #4896 from wansir/fix-4890
fix: cluster list granted to users is incorrect
2022-05-23 17:59:52 +08:00
hongming
382be8b16b fix: cluster list granted to users is incorrect 2022-05-23 17:06:19 +08:00
KubeSphere CI Bot
32ac94a7e5 Merge pull request #4889 from xyz-li/sync
cluster not found and repo not found
2022-05-23 15:48:13 +08:00
KubeSphere CI Bot
3e381c9ad5 Merge pull request #4879 from xiaoping378/patch-1
fix unformatted log
2022-05-23 11:56:51 +08:00
LiHui
35027a346b add openpitrix Client to apiserver 2022-05-20 17:37:52 +08:00
LiHui
32b85cd625 cluster clusters 2022-05-20 11:53:51 +08:00
KubeSphere CI Bot
559539275e Merge pull request #4888 from wansir/master
refactor: remove the useless CRD
2022-05-19 15:58:58 +08:00
hongming
211fb293e0 refactor: remove the useless CRD 2022-05-19 15:43:37 +08:00
suwanliang
530b358c94 test functions in package resources/v1alpha3 by building restful's res and res 2022-05-16 18:27:06 +08:00
xiaoping
aa78e3215c fix unformatted log 2022-05-15 21:05:58 +08:00
51 changed files with 889 additions and 997 deletions

View File

@@ -488,9 +488,10 @@ func addAllControllers(mgr manager.Manager, client k8s.Client, informerFactory i
if cmOptions.MultiClusterOptions.Enable {
clusterController := cluster.NewClusterController(
client.Kubernetes(),
client.KubeSphere(),
client.Config(),
kubesphereInformer.Cluster().V1alpha1().Clusters(),
client.KubeSphere().ClusterV1alpha1().Clusters(),
kubesphereInformer.Iam().V1alpha2().Users().Lister(),
cmOptions.MultiClusterOptions.ClusterControllerResyncPeriod,
cmOptions.MultiClusterOptions.HostClusterName,
)

View File

@@ -21,6 +21,9 @@ import (
"flag"
"fmt"
openpitrixv1 "kubesphere.io/kubesphere/pkg/kapis/openpitrix/v1"
"kubesphere.io/kubesphere/pkg/utils/clusterclient"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/token"
"k8s.io/client-go/kubernetes/scheme"
@@ -209,6 +212,13 @@ func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIS
apiServer.AlertingClient = alertingClient
}
if s.Config.MultiClusterOptions.Enable {
cc := clusterclient.NewClusterClient(informerFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters())
apiServer.ClusterClient = cc
}
apiServer.OpenpitrixClient = openpitrixv1.NewOpenpitrixClient(informerFactory, apiServer.KubernetesClient.KubeSphere(), s.OpenPitrixOptions, apiServer.ClusterClient, stopCh)
server := &http.Server{
Addr: fmt.Sprintf(":%d", s.GenericServerRunOptions.InsecurePort),
}

5
go.mod
View File

@@ -258,6 +258,7 @@ replace (
github.com/coreos/pkg => github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f
github.com/cortexproject/cortex => github.com/cortexproject/cortex v1.3.1-0.20200901115931-255ff3306960
github.com/cpuguy83/go-md2man => github.com/cpuguy83/go-md2man v1.0.10
github.com/cpuguy83/go-md2man/v2 => github.com/cpuguy83/go-md2man/v2 v2.0.0
github.com/creack/pty => github.com/creack/pty v1.1.7
github.com/cyphar/filepath-securejoin => github.com/cyphar/filepath-securejoin v0.2.2
github.com/cznic/b => github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07
@@ -375,7 +376,6 @@ replace (
github.com/gobwas/pool => github.com/gobwas/pool v0.2.0
github.com/gobwas/ws => github.com/gobwas/ws v1.0.2
github.com/gocql/gocql => github.com/gocql/gocql v0.0.0-20200526081602-cd04bd7f22a7
github.com/gocraft/dbr => github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6
github.com/godbus/dbus => github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968
github.com/godror/godror => github.com/godror/godror v0.13.3
github.com/gofrs/flock => github.com/gofrs/flock v0.7.1
@@ -501,10 +501,10 @@ replace (
github.com/kr/pty => github.com/kr/pty v1.1.5
github.com/kr/text => github.com/kr/text v0.1.0
github.com/kshvakov/clickhouse => github.com/kshvakov/clickhouse v1.3.5
github.com/kubernetes-csi/external-snapshotter/client/v3 => github.com/kubernetes-csi/external-snapshotter/client/v3 v3.0.0
github.com/kubernetes-csi/external-snapshotter/client/v4 => github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0
github.com/kubesphere/pvc-autoresizer => github.com/kubesphere/pvc-autoresizer v0.1.1
github.com/kubesphere/sonargo => github.com/kubesphere/sonargo v0.0.2
github.com/kubesphere/storageclass-accessor => github.com/kubesphere/storageclass-accessor v0.2.0
github.com/kylelemons/go-gypsy => github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28
github.com/kylelemons/godebug => github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb
github.com/lann/builder => github.com/lann/builder v0.0.0-20180802200727-47ae307949d0
@@ -653,6 +653,7 @@ replace (
github.com/sergi/go-diff => github.com/sergi/go-diff v1.0.0
github.com/shopspring/decimal => github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24
github.com/shurcooL/httpfs => github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
github.com/shurcooL/sanitized_anchor_name => github.com/shurcooL/sanitized_anchor_name v1.0.0
github.com/shurcooL/vfsgen => github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
github.com/siebenmann/go-kstat => github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745
github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.4.2

View File

@@ -26,28 +26,25 @@ import (
"sync"
"time"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/discovery"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/util/retry"
"github.com/emicklei/go-restful"
extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
urlruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets"
unionauth "k8s.io/apiserver/pkg/authentication/request/union"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
"k8s.io/client-go/discovery"
"k8s.io/client-go/util/retry"
"k8s.io/klog"
runtimecache "sigs.k8s.io/controller-runtime/pkg/cache"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
notificationv2beta1 "kubesphere.io/api/notification/v2beta1"
tenantv1alpha1 "kubesphere.io/api/tenant/v1alpha1"
typesv1beta1 "kubesphere.io/api/types/v1beta1"
runtimecache "sigs.k8s.io/controller-runtime/pkg/cache"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
audit "kubesphere.io/kubesphere/pkg/apiserver/auditing"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/authenticators/basic"
@@ -98,6 +95,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/group"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/loginrecord"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/user"
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
@@ -110,6 +108,7 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/monitoring"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
"kubesphere.io/kubesphere/pkg/utils/clusterclient"
"kubesphere.io/kubesphere/pkg/utils/iputil"
"kubesphere.io/kubesphere/pkg/utils/metrics"
)
@@ -164,6 +163,10 @@ type APIServer struct {
// controller-runtime client
RuntimeClient runtimeclient.Client
ClusterClient clusterclient.ClusterClients
OpenpitrixClient openpitrix.Interface
}
func (s *APIServer) PrepareRun(stopCh <-chan struct{}) error {
@@ -223,17 +226,17 @@ func (s *APIServer) installKubeSphereAPIs(stopCh <-chan struct{}) {
urlruntime.Must(configv1alpha2.AddToContainer(s.container, s.Config))
urlruntime.Must(resourcev1alpha3.AddToContainer(s.container, s.InformerFactory, s.RuntimeCache))
urlruntime.Must(monitoringv1alpha3.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.MetricsClient, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions, s.RuntimeClient, stopCh))
urlruntime.Must(meteringv1alpha1.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.RuntimeCache, s.Config.MeteringOptions, nil, s.RuntimeClient, stopCh))
urlruntime.Must(openpitrixv1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions, stopCh))
urlruntime.Must(monitoringv1alpha3.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.MetricsClient, s.InformerFactory, s.OpenpitrixClient, s.RuntimeClient))
urlruntime.Must(meteringv1alpha1.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.InformerFactory, s.RuntimeCache, s.Config.MeteringOptions, s.OpenpitrixClient, s.RuntimeClient))
urlruntime.Must(openpitrixv1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions, s.OpenpitrixClient))
urlruntime.Must(openpitrixv2alpha1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions))
urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes()))
urlruntime.Must(resourcesv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.InformerFactory,
s.KubernetesClient.Master()))
urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.Kubernetes(),
s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache, s.Config.MeteringOptions, stopCh))
s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, imOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache, s.Config.MeteringOptions, s.OpenpitrixClient))
urlruntime.Must(tenantv1alpha3.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.Kubernetes(),
s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache, s.Config.MeteringOptions, stopCh))
s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, imOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache, s.Config.MeteringOptions, s.OpenpitrixClient))
urlruntime.Must(terminalv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), rbacAuthorizer, s.KubernetesClient.Config(), s.Config.TerminalOptions))
urlruntime.Must(clusterkapisv1alpha1.AddToContainer(s.container,
s.KubernetesClient.KubeSphere(),
@@ -346,7 +349,7 @@ func (s *APIServer) buildHandlerChain(stopCh <-chan struct{}) {
handler = filters.WithAuthorization(handler, authorizers)
if s.Config.MultiClusterOptions.Enable {
clusterDispatcher := dispatch.NewClusterDispatch(s.InformerFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters())
clusterDispatcher := dispatch.NewClusterDispatch(s.ClusterClient)
handler = filters.WithMultipleClusterDispatcher(handler, clusterDispatcher)
}
@@ -531,7 +534,6 @@ func (s *APIServer) waitForResourceSync(ctx context.Context) error {
typesv1beta1.ResourcePluralFederatedConfigmap,
typesv1beta1.ResourcePluralFederatedStatefulSet,
typesv1beta1.ResourcePluralFederatedIngress,
typesv1beta1.ResourcePluralFederatedResourceQuota,
typesv1beta1.ResourcePluralFederatedPersistentVolumeClaim,
typesv1beta1.ResourcePluralFederatedApplication,
}

View File

@@ -30,7 +30,6 @@ import (
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
"kubesphere.io/kubesphere/pkg/apiserver/request"
clusterinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/cluster/v1alpha1"
"kubesphere.io/kubesphere/pkg/utils/clusterclient"
)
@@ -47,8 +46,8 @@ type clusterDispatch struct {
clusterclient.ClusterClients
}
func NewClusterDispatch(clusterInformer clusterinformer.ClusterInformer) Dispatcher {
return &clusterDispatch{clusterclient.NewClusterClient(clusterInformer)}
func NewClusterDispatch(cc clusterclient.ClusterClients) Dispatcher {
return &clusterDispatch{cc}
}
// Dispatch dispatch requests to designated cluster

View File

@@ -1,142 +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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1beta1 "kubesphere.io/api/types/v1beta1"
)
// FakeFederatedResourceQuotas implements FederatedResourceQuotaInterface
type FakeFederatedResourceQuotas struct {
Fake *FakeTypesV1beta1
ns string
}
var federatedresourcequotasResource = schema.GroupVersionResource{Group: "types.kubefed.io", Version: "v1beta1", Resource: "federatedresourcequotas"}
var federatedresourcequotasKind = schema.GroupVersionKind{Group: "types.kubefed.io", Version: "v1beta1", Kind: "FederatedResourceQuota"}
// Get takes name of the federatedResourceQuota, and returns the corresponding federatedResourceQuota object, and an error if there is any.
func (c *FakeFederatedResourceQuotas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.FederatedResourceQuota, err error) {
obj, err := c.Fake.
Invokes(testing.NewGetAction(federatedresourcequotasResource, c.ns, name), &v1beta1.FederatedResourceQuota{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.FederatedResourceQuota), err
}
// List takes label and field selectors, and returns the list of FederatedResourceQuotas that match those selectors.
func (c *FakeFederatedResourceQuotas) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.FederatedResourceQuotaList, err error) {
obj, err := c.Fake.
Invokes(testing.NewListAction(federatedresourcequotasResource, federatedresourcequotasKind, c.ns, opts), &v1beta1.FederatedResourceQuotaList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1beta1.FederatedResourceQuotaList{ListMeta: obj.(*v1beta1.FederatedResourceQuotaList).ListMeta}
for _, item := range obj.(*v1beta1.FederatedResourceQuotaList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested federatedResourceQuotas.
func (c *FakeFederatedResourceQuotas) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewWatchAction(federatedresourcequotasResource, c.ns, opts))
}
// Create takes the representation of a federatedResourceQuota and creates it. Returns the server's representation of the federatedResourceQuota, and an error, if there is any.
func (c *FakeFederatedResourceQuotas) Create(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.CreateOptions) (result *v1beta1.FederatedResourceQuota, err error) {
obj, err := c.Fake.
Invokes(testing.NewCreateAction(federatedresourcequotasResource, c.ns, federatedResourceQuota), &v1beta1.FederatedResourceQuota{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.FederatedResourceQuota), err
}
// Update takes the representation of a federatedResourceQuota and updates it. Returns the server's representation of the federatedResourceQuota, and an error, if there is any.
func (c *FakeFederatedResourceQuotas) Update(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.UpdateOptions) (result *v1beta1.FederatedResourceQuota, err error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(federatedresourcequotasResource, c.ns, federatedResourceQuota), &v1beta1.FederatedResourceQuota{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.FederatedResourceQuota), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeFederatedResourceQuotas) UpdateStatus(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.UpdateOptions) (*v1beta1.FederatedResourceQuota, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(federatedresourcequotasResource, "status", c.ns, federatedResourceQuota), &v1beta1.FederatedResourceQuota{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.FederatedResourceQuota), err
}
// Delete takes name of the federatedResourceQuota and deletes it. Returns an error if one occurs.
func (c *FakeFederatedResourceQuotas) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(federatedresourcequotasResource, c.ns, name), &v1beta1.FederatedResourceQuota{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeFederatedResourceQuotas) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(federatedresourcequotasResource, c.ns, listOpts)
_, err := c.Fake.Invokes(action, &v1beta1.FederatedResourceQuotaList{})
return err
}
// Patch applies the patch and returns the patched federatedResourceQuota.
func (c *FakeFederatedResourceQuotas) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.FederatedResourceQuota, err error) {
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(federatedresourcequotasResource, c.ns, name, pt, data, subresources...), &v1beta1.FederatedResourceQuota{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.FederatedResourceQuota), err
}

View File

@@ -76,10 +76,6 @@ func (c *FakeTypesV1beta1) FederatedPersistentVolumeClaims(namespace string) v1b
return &FakeFederatedPersistentVolumeClaims{c, namespace}
}
func (c *FakeTypesV1beta1) FederatedResourceQuotas(namespace string) v1beta1.FederatedResourceQuotaInterface {
return &FakeFederatedResourceQuotas{c, namespace}
}
func (c *FakeTypesV1beta1) FederatedSecrets(namespace string) v1beta1.FederatedSecretInterface {
return &FakeFederatedSecrets{c, namespace}
}

View File

@@ -1,195 +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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
"context"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1beta1 "kubesphere.io/api/types/v1beta1"
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
// FederatedResourceQuotasGetter has a method to return a FederatedResourceQuotaInterface.
// A group's client should implement this interface.
type FederatedResourceQuotasGetter interface {
FederatedResourceQuotas(namespace string) FederatedResourceQuotaInterface
}
// FederatedResourceQuotaInterface has methods to work with FederatedResourceQuota resources.
type FederatedResourceQuotaInterface interface {
Create(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.CreateOptions) (*v1beta1.FederatedResourceQuota, error)
Update(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.UpdateOptions) (*v1beta1.FederatedResourceQuota, error)
UpdateStatus(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.UpdateOptions) (*v1beta1.FederatedResourceQuota, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.FederatedResourceQuota, error)
List(ctx context.Context, opts v1.ListOptions) (*v1beta1.FederatedResourceQuotaList, error)
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.FederatedResourceQuota, err error)
FederatedResourceQuotaExpansion
}
// federatedResourceQuotas implements FederatedResourceQuotaInterface
type federatedResourceQuotas struct {
client rest.Interface
ns string
}
// newFederatedResourceQuotas returns a FederatedResourceQuotas
func newFederatedResourceQuotas(c *TypesV1beta1Client, namespace string) *federatedResourceQuotas {
return &federatedResourceQuotas{
client: c.RESTClient(),
ns: namespace,
}
}
// Get takes name of the federatedResourceQuota, and returns the corresponding federatedResourceQuota object, and an error if there is any.
func (c *federatedResourceQuotas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.FederatedResourceQuota, err error) {
result = &v1beta1.FederatedResourceQuota{}
err = c.client.Get().
Namespace(c.ns).
Resource("federatedresourcequotas").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of FederatedResourceQuotas that match those selectors.
func (c *federatedResourceQuotas) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.FederatedResourceQuotaList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1beta1.FederatedResourceQuotaList{}
err = c.client.Get().
Namespace(c.ns).
Resource("federatedresourcequotas").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested federatedResourceQuotas.
func (c *federatedResourceQuotas) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("federatedresourcequotas").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a federatedResourceQuota and creates it. Returns the server's representation of the federatedResourceQuota, and an error, if there is any.
func (c *federatedResourceQuotas) Create(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.CreateOptions) (result *v1beta1.FederatedResourceQuota, err error) {
result = &v1beta1.FederatedResourceQuota{}
err = c.client.Post().
Namespace(c.ns).
Resource("federatedresourcequotas").
VersionedParams(&opts, scheme.ParameterCodec).
Body(federatedResourceQuota).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a federatedResourceQuota and updates it. Returns the server's representation of the federatedResourceQuota, and an error, if there is any.
func (c *federatedResourceQuotas) Update(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.UpdateOptions) (result *v1beta1.FederatedResourceQuota, err error) {
result = &v1beta1.FederatedResourceQuota{}
err = c.client.Put().
Namespace(c.ns).
Resource("federatedresourcequotas").
Name(federatedResourceQuota.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(federatedResourceQuota).
Do(ctx).
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *federatedResourceQuotas) UpdateStatus(ctx context.Context, federatedResourceQuota *v1beta1.FederatedResourceQuota, opts v1.UpdateOptions) (result *v1beta1.FederatedResourceQuota, err error) {
result = &v1beta1.FederatedResourceQuota{}
err = c.client.Put().
Namespace(c.ns).
Resource("federatedresourcequotas").
Name(federatedResourceQuota.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(federatedResourceQuota).
Do(ctx).
Into(result)
return
}
// Delete takes name of the federatedResourceQuota and deletes it. Returns an error if one occurs.
func (c *federatedResourceQuotas) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("federatedresourcequotas").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *federatedResourceQuotas) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Namespace(c.ns).
Resource("federatedresourcequotas").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched federatedResourceQuota.
func (c *federatedResourceQuotas) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.FederatedResourceQuota, err error) {
result = &v1beta1.FederatedResourceQuota{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("federatedresourcequotas").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@@ -42,8 +42,6 @@ type FederatedNamespaceExpansion interface{}
type FederatedPersistentVolumeClaimExpansion interface{}
type FederatedResourceQuotaExpansion interface{}
type FederatedSecretExpansion interface{}
type FederatedServiceExpansion interface{}

View File

@@ -38,7 +38,6 @@ type TypesV1beta1Interface interface {
FederatedLimitRangesGetter
FederatedNamespacesGetter
FederatedPersistentVolumeClaimsGetter
FederatedResourceQuotasGetter
FederatedSecretsGetter
FederatedServicesGetter
FederatedStatefulSetsGetter
@@ -97,10 +96,6 @@ func (c *TypesV1beta1Client) FederatedPersistentVolumeClaims(namespace string) F
return newFederatedPersistentVolumeClaims(c, namespace)
}
func (c *TypesV1beta1Client) FederatedResourceQuotas(namespace string) FederatedResourceQuotaInterface {
return newFederatedResourceQuotas(c, namespace)
}
func (c *TypesV1beta1Client) FederatedSecrets(namespace string) FederatedSecretInterface {
return newFederatedSecrets(c, namespace)
}

View File

@@ -188,8 +188,6 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
return &genericInformer{resource: resource.GroupResource(), informer: f.Types().V1beta1().FederatedNamespaces().Informer()}, nil
case v1beta1.SchemeGroupVersion.WithResource("federatedpersistentvolumeclaims"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Types().V1beta1().FederatedPersistentVolumeClaims().Informer()}, nil
case v1beta1.SchemeGroupVersion.WithResource("federatedresourcequotas"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Types().V1beta1().FederatedResourceQuotas().Informer()}, nil
case v1beta1.SchemeGroupVersion.WithResource("federatedsecrets"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Types().V1beta1().FederatedSecrets().Informer()}, nil
case v1beta1.SchemeGroupVersion.WithResource("federatedservices"):

View File

@@ -1,90 +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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1beta1
import (
"context"
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
typesv1beta1 "kubesphere.io/api/types/v1beta1"
versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
v1beta1 "kubesphere.io/kubesphere/pkg/client/listers/types/v1beta1"
)
// FederatedResourceQuotaInformer provides access to a shared informer and lister for
// FederatedResourceQuotas.
type FederatedResourceQuotaInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1beta1.FederatedResourceQuotaLister
}
type federatedResourceQuotaInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}
// NewFederatedResourceQuotaInformer constructs a new informer for FederatedResourceQuota type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFederatedResourceQuotaInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredFederatedResourceQuotaInformer(client, namespace, resyncPeriod, indexers, nil)
}
// NewFilteredFederatedResourceQuotaInformer constructs a new informer for FederatedResourceQuota type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredFederatedResourceQuotaInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.TypesV1beta1().FederatedResourceQuotas(namespace).List(context.TODO(), options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.TypesV1beta1().FederatedResourceQuotas(namespace).Watch(context.TODO(), options)
},
},
&typesv1beta1.FederatedResourceQuota{},
resyncPeriod,
indexers,
)
}
func (f *federatedResourceQuotaInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredFederatedResourceQuotaInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *federatedResourceQuotaInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&typesv1beta1.FederatedResourceQuota{}, f.defaultInformer)
}
func (f *federatedResourceQuotaInformer) Lister() v1beta1.FederatedResourceQuotaLister {
return v1beta1.NewFederatedResourceQuotaLister(f.Informer().GetIndexer())
}

View File

@@ -48,8 +48,6 @@ type Interface interface {
FederatedNamespaces() FederatedNamespaceInformer
// FederatedPersistentVolumeClaims returns a FederatedPersistentVolumeClaimInformer.
FederatedPersistentVolumeClaims() FederatedPersistentVolumeClaimInformer
// FederatedResourceQuotas returns a FederatedResourceQuotaInformer.
FederatedResourceQuotas() FederatedResourceQuotaInformer
// FederatedSecrets returns a FederatedSecretInformer.
FederatedSecrets() FederatedSecretInformer
// FederatedServices returns a FederatedServiceInformer.
@@ -129,11 +127,6 @@ func (v *version) FederatedPersistentVolumeClaims() FederatedPersistentVolumeCla
return &federatedPersistentVolumeClaimInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
// FederatedResourceQuotas returns a FederatedResourceQuotaInformer.
func (v *version) FederatedResourceQuotas() FederatedResourceQuotaInformer {
return &federatedResourceQuotaInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
// FederatedSecrets returns a FederatedSecretInformer.
func (v *version) FederatedSecrets() FederatedSecretInformer {
return &federatedSecretInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}

View File

@@ -106,14 +106,6 @@ type FederatedPersistentVolumeClaimListerExpansion interface{}
// FederatedPersistentVolumeClaimNamespaceLister.
type FederatedPersistentVolumeClaimNamespaceListerExpansion interface{}
// FederatedResourceQuotaListerExpansion allows custom methods to be added to
// FederatedResourceQuotaLister.
type FederatedResourceQuotaListerExpansion interface{}
// FederatedResourceQuotaNamespaceListerExpansion allows custom methods to be added to
// FederatedResourceQuotaNamespaceLister.
type FederatedResourceQuotaNamespaceListerExpansion interface{}
// FederatedSecretListerExpansion allows custom methods to be added to
// FederatedSecretLister.
type FederatedSecretListerExpansion interface{}

View File

@@ -1,99 +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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1beta1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1beta1 "kubesphere.io/api/types/v1beta1"
)
// FederatedResourceQuotaLister helps list FederatedResourceQuotas.
// All objects returned here must be treated as read-only.
type FederatedResourceQuotaLister interface {
// List lists all FederatedResourceQuotas in the indexer.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1beta1.FederatedResourceQuota, err error)
// FederatedResourceQuotas returns an object that can list and get FederatedResourceQuotas.
FederatedResourceQuotas(namespace string) FederatedResourceQuotaNamespaceLister
FederatedResourceQuotaListerExpansion
}
// federatedResourceQuotaLister implements the FederatedResourceQuotaLister interface.
type federatedResourceQuotaLister struct {
indexer cache.Indexer
}
// NewFederatedResourceQuotaLister returns a new FederatedResourceQuotaLister.
func NewFederatedResourceQuotaLister(indexer cache.Indexer) FederatedResourceQuotaLister {
return &federatedResourceQuotaLister{indexer: indexer}
}
// List lists all FederatedResourceQuotas in the indexer.
func (s *federatedResourceQuotaLister) List(selector labels.Selector) (ret []*v1beta1.FederatedResourceQuota, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1beta1.FederatedResourceQuota))
})
return ret, err
}
// FederatedResourceQuotas returns an object that can list and get FederatedResourceQuotas.
func (s *federatedResourceQuotaLister) FederatedResourceQuotas(namespace string) FederatedResourceQuotaNamespaceLister {
return federatedResourceQuotaNamespaceLister{indexer: s.indexer, namespace: namespace}
}
// FederatedResourceQuotaNamespaceLister helps list and get FederatedResourceQuotas.
// All objects returned here must be treated as read-only.
type FederatedResourceQuotaNamespaceLister interface {
// List lists all FederatedResourceQuotas in the indexer for a given namespace.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1beta1.FederatedResourceQuota, err error)
// Get retrieves the FederatedResourceQuota from the indexer for a given namespace and name.
// Objects returned here must be treated as read-only.
Get(name string) (*v1beta1.FederatedResourceQuota, error)
FederatedResourceQuotaNamespaceListerExpansion
}
// federatedResourceQuotaNamespaceLister implements the FederatedResourceQuotaNamespaceLister
// interface.
type federatedResourceQuotaNamespaceLister struct {
indexer cache.Indexer
namespace string
}
// List lists all FederatedResourceQuotas in the indexer for a given namespace.
func (s federatedResourceQuotaNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.FederatedResourceQuota, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1beta1.FederatedResourceQuota))
})
return ret, err
}
// Get retrieves the FederatedResourceQuota from the indexer for a given namespace and name.
func (s federatedResourceQuotaNamespaceLister) Get(name string) (*v1beta1.FederatedResourceQuota, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1beta1.Resource("federatedresourcequota"), name)
}
return obj.(*v1beta1.FederatedResourceQuota), nil
}

View File

@@ -25,6 +25,7 @@ import (
"fmt"
"net/http"
"reflect"
"strings"
"time"
"gopkg.in/yaml.v2"
@@ -48,11 +49,13 @@ import (
fedv1b1 "sigs.k8s.io/kubefed/pkg/apis/core/v1beta1"
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/apiserver/config"
clusterclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/cluster/v1alpha1"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
clusterinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/cluster/v1alpha1"
clusterlister "kubesphere.io/kubesphere/pkg/client/listers/cluster/v1alpha1"
iamv1alpha2listers "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/simple/client/multicluster"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
@@ -126,12 +129,13 @@ type clusterController struct {
eventRecorder record.EventRecorder
// build this only for host cluster
client kubernetes.Interface
k8sClient kubernetes.Interface
hostConfig *rest.Config
clusterClient clusterclient.ClusterInterface
ksClient kubesphere.Interface
clusterLister clusterlister.ClusterLister
userLister iamv1alpha2listers.UserLister
clusterHasSynced cache.InformerSynced
queue workqueue.RateLimitingInterface
@@ -144,10 +148,11 @@ type clusterController struct {
}
func NewClusterController(
client kubernetes.Interface,
k8sClient kubernetes.Interface,
ksClient kubesphere.Interface,
config *rest.Config,
clusterInformer clusterinformer.ClusterInformer,
clusterClient clusterclient.ClusterInterface,
userLister iamv1alpha2listers.UserLister,
resyncPeriod time.Duration,
hostClusterName string,
) *clusterController {
@@ -156,19 +161,20 @@ func NewClusterController(
broadcaster.StartLogging(func(format string, args ...interface{}) {
klog.Info(fmt.Sprintf(format, args))
})
broadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: client.CoreV1().Events("")})
broadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: k8sClient.CoreV1().Events("")})
recorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cluster-controller"})
c := &clusterController{
eventBroadcaster: broadcaster,
eventRecorder: recorder,
client: client,
k8sClient: k8sClient,
ksClient: ksClient,
hostConfig: config,
clusterClient: clusterClient,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "cluster"),
workerLoopPeriod: time.Second,
resyncPeriod: resyncPeriod,
hostClusterName: hostClusterName,
userLister: userLister,
}
c.clusterLister = clusterInformer.Lister()
c.clusterHasSynced = clusterInformer.Informer().HasSynced
@@ -213,7 +219,7 @@ func (c *clusterController) Run(workers int, stopCh <-chan struct{}) error {
klog.Errorf("Error create host cluster, error %v", err)
}
if err := c.probeClusters(); err != nil {
if err := c.resyncClusters(); err != nil {
klog.Errorf("failed to reconcile cluster ready status, err: %v", err)
}
}, c.resyncPeriod, stopCh)
@@ -256,7 +262,7 @@ func (c *clusterController) reconcileHostCluster() error {
if len(clusters) == 0 {
hostCluster.Spec.Connection.KubeConfig = hostKubeConfig
hostCluster.Name = c.hostClusterName
_, err = c.clusterClient.Create(context.TODO(), hostCluster, metav1.CreateOptions{})
_, err = c.ksClient.ClusterV1alpha1().Clusters().Create(context.TODO(), hostCluster, metav1.CreateOptions{})
return err
} else if len(clusters) > 1 {
return fmt.Errorf("there MUST not be more than one host clusters, while there are %d", len(clusters))
@@ -280,18 +286,20 @@ func (c *clusterController) reconcileHostCluster() error {
}
// update host cluster config
_, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
_, err = c.ksClient.ClusterV1alpha1().Clusters().Update(context.TODO(), cluster, metav1.UpdateOptions{})
return err
}
func (c *clusterController) probeClusters() error {
func (c *clusterController) resyncClusters() error {
clusters, err := c.clusterLister.List(labels.Everything())
if err != nil {
return err
}
for _, cluster := range clusters {
c.syncCluster(cluster.Name)
if err = c.syncCluster(cluster.Name); err != nil {
klog.Warningf("failed to sync cluster %s: %s", cluster.Name, err)
}
}
return nil
}
@@ -328,7 +336,7 @@ func (c *clusterController) syncCluster(key string) error {
// registering our finalizer.
if !sets.NewString(cluster.ObjectMeta.Finalizers...).Has(clusterv1alpha1.Finalizer) {
cluster.ObjectMeta.Finalizers = append(cluster.ObjectMeta.Finalizers, clusterv1alpha1.Finalizer)
if cluster, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
if cluster, err = c.ksClient.ClusterV1alpha1().Clusters().Update(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
return err
}
}
@@ -338,17 +346,21 @@ func (c *clusterController) syncCluster(key string) error {
// need to unJoin federation first, before there are
// some cleanup work to do in member cluster which depends
// agent to proxy traffic
err = c.unJoinFederation(nil, name)
if err != nil {
if err = c.unJoinFederation(nil, name); err != nil {
klog.Errorf("Failed to unjoin federation for cluster %s, error %v", name, err)
return err
}
// cleanup after cluster has been deleted
if err := c.syncClusterMembers(nil, cluster); err != nil {
klog.Errorf("Failed to sync cluster members for %s: %v", name, err)
return err
}
// remove our cluster finalizer
finalizers := sets.NewString(cluster.ObjectMeta.Finalizers...)
finalizers.Delete(clusterv1alpha1.Finalizer)
cluster.ObjectMeta.Finalizers = finalizers.List()
if _, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
if _, err = c.ksClient.ClusterV1alpha1().Clusters().Update(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
return err
}
}
@@ -407,7 +419,7 @@ func (c *clusterController) syncCluster(key string) error {
}
c.updateClusterCondition(cluster, federationNotReadyCondition)
_, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
_, err = c.ksClient.ClusterV1alpha1().Clusters().Update(context.TODO(), cluster, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update cluster status, %#v", err)
}
@@ -496,8 +508,8 @@ func (c *clusterController) syncCluster(key string) error {
return err
}
if !reflect.DeepEqual(oldCluster, cluster) {
_, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
if !reflect.DeepEqual(oldCluster.Status, cluster.Status) {
_, err = c.ksClient.ClusterV1alpha1().Clusters().Update(context.TODO(), cluster, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update cluster status, %#v", err)
return err
@@ -508,6 +520,10 @@ func (c *clusterController) syncCluster(key string) error {
return err
}
if err = c.syncClusterMembers(clusterClient, cluster); err != nil {
return fmt.Errorf("failed to sync cluster membership for %s: %s", cluster.Name, err)
}
return nil
}
@@ -541,7 +557,7 @@ func (c *clusterController) setClusterNameInConfigMap(client kubernetes.Interfac
}
func (c *clusterController) checkIfClusterIsHostCluster(memberClusterNodes *v1.NodeList) bool {
hostNodes, err := c.client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
hostNodes, err := c.k8sClient.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
return false
}
@@ -786,3 +802,55 @@ func (c *clusterController) updateKubeConfigExpirationDateCondition(cluster *clu
})
return nil
}
// syncClusterMembers Sync granted clusters for users periodically
func (c *clusterController) syncClusterMembers(clusterClient *kubernetes.Clientset, cluster *clusterv1alpha1.Cluster) error {
users, err := c.userLister.List(labels.Everything())
if err != nil {
return fmt.Errorf("failed to list users: %s", err)
}
grantedUsers := sets.NewString()
clusterName := cluster.Name
if cluster.DeletionTimestamp.IsZero() {
list, err := clusterClient.RbacV1().ClusterRoleBindings().List(context.Background(),
metav1.ListOptions{LabelSelector: iamv1alpha2.UserReferenceLabel})
if err != nil {
return fmt.Errorf("failed to list clusterrolebindings: %s", err)
}
for _, clusterRoleBinding := range list.Items {
for _, sub := range clusterRoleBinding.Subjects {
if sub.Kind == iamv1alpha2.ResourceKindUser {
grantedUsers.Insert(sub.Name)
}
}
}
}
for _, user := range users {
user = user.DeepCopy()
grantedClustersAnnotation := user.Annotations[iamv1alpha2.GrantedClustersAnnotation]
var grantedClusters sets.String
if len(grantedClustersAnnotation) > 0 {
grantedClusters = sets.NewString(strings.Split(grantedClustersAnnotation, ",")...)
} else {
grantedClusters = sets.NewString()
}
if grantedUsers.Has(user.Name) && !grantedClusters.Has(clusterName) {
grantedClusters.Insert(clusterName)
} else if !grantedUsers.Has(user.Name) && grantedClusters.Has(clusterName) {
grantedClusters.Delete(clusterName)
}
grantedClustersAnnotation = strings.Join(grantedClusters.List(), ",")
if user.Annotations[iamv1alpha2.GrantedClustersAnnotation] != grantedClustersAnnotation {
if user.Annotations == nil {
user.Annotations = make(map[string]string, 0)
}
user.Annotations[iamv1alpha2.GrantedClustersAnnotation] = grantedClustersAnnotation
if _, err := c.ksClient.IamV1alpha2().Users().Update(context.Background(), user, metav1.UpdateOptions{}); err != nil {
return fmt.Errorf("failed to update user %s: %s", user.Name, err)
}
}
}
return nil
}

View File

@@ -73,7 +73,7 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
if err := r.SetupWithManager(mgr); err != nil {
return err
}
klog.Info("configured watch", "gvk", w.GroupVersionKind, "chartPath", w.ChartPath, "maxConcurrentReconciles", maxConcurrentReconciles, "reconcilePeriod", reconcilePeriod)
klog.Infoln("configured watch", "gvk", w.GroupVersionKind, "chartPath", w.ChartPath, "maxConcurrentReconciles", maxConcurrentReconciles, "reconcilePeriod", reconcilePeriod)
}
return nil
}

View File

@@ -1,3 +1,17 @@
// 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 webhooks
import (

View File

@@ -21,12 +21,10 @@ package v1alpha1
import (
"github.com/emicklei/go-restful"
"k8s.io/client-go/kubernetes"
openpitrixoptions "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
"kubesphere.io/kubesphere/pkg/informers"
monitorhle "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
@@ -47,6 +45,6 @@ type meterHandler interface {
HandlePVCMeterQuery(req *restful.Request, resp *restful.Response)
}
func newHandler(k kubernetes.Interface, m monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options, rtClient runtimeclient.Client, stopCh <-chan struct{}) meterHandler {
return monitorhle.NewHandler(k, m, nil, f, ksClient, resourceGetter, meteringOptions, opOptions, rtClient, stopCh)
func newHandler(k kubernetes.Interface, m monitoring.Interface, f informers.InformerFactory, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options, opClient openpitrix.Interface, rtClient runtimeclient.Client) meterHandler {
return monitorhle.NewHandler(k, m, nil, f, resourceGetter, meteringOptions, opClient, rtClient)
}

View File

@@ -20,9 +20,7 @@ package v1alpha1
import (
"net/http"
openpitrixoptions "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
"github.com/emicklei/go-restful"
restfulspec "github.com/emicklei/go-restful-openapi"
@@ -49,10 +47,10 @@ const (
var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha1"}
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, meteringClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface, cache cache.Cache, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options, rtClient runtimeclient.Client, stopCh <-chan struct{}) error {
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, meteringClient monitoring.Interface, factory informers.InformerFactory, cache cache.Cache, meteringOptions *meteringclient.Options, opClient openpitrix.Interface, rtClient runtimeclient.Client) error {
ws := runtime.NewWebService(GroupVersion)
h := newHandler(k8sClient, meteringClient, factory, ksClient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, opOptions, rtClient, stopCh)
h := newHandler(k8sClient, meteringClient, factory, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, opClient, rtClient)
ws.Route(ws.GET("/cluster").
To(h.HandleClusterMeterQuery).

View File

@@ -27,14 +27,8 @@ import (
"regexp"
"strings"
"k8s.io/klog"
converter "kubesphere.io/monitoring-dashboard/tools/converter"
openpitrixoptions "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
"github.com/emicklei/go-restful"
@@ -60,27 +54,16 @@ type handler struct {
rtClient runtimeclient.Client
}
func NewHandler(k kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options, rtClient runtimeclient.Client, stopCh <-chan struct{}) *handler {
var opRelease openpitrix.Interface
var s3Client s3.Interface
if opOptions != nil && opOptions.S3Options != nil && len(opOptions.S3Options.Endpoint) != 0 {
var err error
s3Client, err = s3.NewS3Client(opOptions.S3Options)
if err != nil {
klog.Errorf("failed to connect to storage, please check storage service status, error: %v", err)
}
}
if ksClient != nil {
opRelease = openpitrix.NewOpenpitrixOperator(f, ksClient, s3Client, stopCh)
}
func NewHandler(k kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, f informers.InformerFactory, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options, opClient openpitrix.Interface, rtClient runtimeclient.Client) *handler {
if meteringOptions == nil || meteringOptions.RetentionDay == "" {
meteringOptions = &meteringclient.DefaultMeteringOption
}
return &handler{
k: k,
mo: model.NewMonitoringOperator(monitoringClient, metricsClient, k, f, resourceGetter, opRelease),
opRelease: opRelease,
mo: model.NewMonitoringOperator(monitoringClient, metricsClient, k, f, resourceGetter, opClient),
opRelease: opClient,
meteringOptions: meteringOptions,
rtClient: rtClient,
}

View File

@@ -373,7 +373,7 @@ func TestParseRequestParams(t *testing.T) {
fakeInformerFactory.KubeSphereSharedInformerFactory()
handler := NewHandler(client, nil, nil, fakeInformerFactory, ksClient, nil, nil, nil, nil, nil)
handler := NewHandler(client, nil, nil, fakeInformerFactory, nil, nil, nil, nil)
result, err := handler.makeQueryOptions(tt.params, tt.lvl)
if err != nil {

View File

@@ -20,12 +20,10 @@ package v1alpha3
import (
"net/http"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
monitoringdashboardv1alpha2 "kubesphere.io/monitoring-dashboard/api/v1alpha2"
openpitrixoptions "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"github.com/emicklei/go-restful"
restfulspec "github.com/emicklei/go-restful-openapi"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -47,10 +45,10 @@ const (
var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha3"}
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface, opOptions *openpitrixoptions.Options, rtClient runtimeclient.Client, stopCh <-chan struct{}) error {
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, factory informers.InformerFactory, opClient openpitrix.Interface, rtClient runtimeclient.Client) error {
ws := runtime.NewWebService(GroupVersion)
h := NewHandler(k8sClient, monitoringClient, metricsClient, factory, ksClient, nil, nil, opOptions, rtClient, stopCh)
h := NewHandler(k8sClient, monitoringClient, metricsClient, factory, nil, nil, opClient, rtClient)
ws.Route(ws.GET("/kubesphere").
To(h.handleKubeSphereMetricsQuery).

View File

@@ -23,6 +23,8 @@ import (
"strings"
"time"
"kubesphere.io/kubesphere/pkg/utils/clusterclient"
restful "github.com/emicklei/go-restful"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -50,7 +52,7 @@ type openpitrixHandler struct {
openpitrix openpitrix.Interface
}
func newOpenpitrixHandler(ksInformers informers.InformerFactory, ksClient versioned.Interface, option *openpitrixoptions.Options, stopCh <-chan struct{}) *openpitrixHandler {
func NewOpenpitrixClient(ksInformers informers.InformerFactory, ksClient versioned.Interface, option *openpitrixoptions.Options, cc clusterclient.ClusterClients, stopCh <-chan struct{}) openpitrix.Interface {
var s3Client s3.Interface
if option != nil && option.S3Options != nil && len(option.S3Options.Endpoint) != 0 {
var err error
@@ -60,9 +62,7 @@ func newOpenpitrixHandler(ksInformers informers.InformerFactory, ksClient versio
}
}
return &openpitrixHandler{
openpitrix.NewOpenpitrixOperator(ksInformers, ksClient, s3Client, stopCh),
}
return openpitrix.NewOpenpitrixOperator(ksInformers, ksClient, s3Client, cc, stopCh)
}
func (h *openpitrixHandler) CreateRepo(req *restful.Request, resp *restful.Response) {

View File

@@ -38,11 +38,13 @@ const (
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
func AddToContainer(c *restful.Container, ksInfomrers informers.InformerFactory, ksClient versioned.Interface, options *openpitrixoptions.Options, stopCh <-chan struct{}) error {
func AddToContainer(c *restful.Container, ksInfomrers informers.InformerFactory, ksClient versioned.Interface, options *openpitrixoptions.Options, opClient openpitrix.Interface) error {
mimePatch := []string{restful.MIME_JSON, runtime.MimeJsonPatchJson, runtime.MimeMergePatchJson}
webservice := runtime.NewWebService(GroupVersion)
handler := newOpenpitrixHandler(ksInfomrers, ksClient, options, stopCh)
handler := &openpitrixHandler{
opClient,
}
webservice.Route(webservice.POST("/repos").
To(handler.CreateRepo).

View File

@@ -17,7 +17,16 @@ limitations under the License.
package v1alpha3
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"unsafe"
"github.com/emicklei/go-restful"
"k8s.io/klog"
"github.com/google/go-cmp/cmp"
fakesnapshot "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned/fake"
@@ -87,13 +96,11 @@ func TestResourceV1alpha2Fallback(t *testing.T) {
},
}
factory, err := prepare()
handler, err := prepare()
if err != nil {
t.Fatal(err)
}
handler := New(resourcev1alpha3.NewResourceGetter(factory, nil), resourcev1alpha2.NewResourceGetter(factory), components.NewComponentsGetter(factory.KubernetesSharedInformerFactory()))
for _, test := range tests {
got, err := listResources(test.namespace, test.resource, test.query, handler)
@@ -175,12 +182,31 @@ var (
ReadyReplicas: 0,
},
}
apiServerService = &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "ks-apiserver",
Namespace: "istio-system",
},
Spec: corev1.ServiceSpec{
Selector: map[string]string{"app": "ks-apiserver-app"},
},
}
ksControllerService = &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "ks-controller",
Namespace: "kubesphere-system",
},
Spec: corev1.ServiceSpec{
Selector: map[string]string{"app": "ks-controller-app"},
},
}
deployments = []interface{}{redisDeployment, nginxDeployment}
namespaces = []interface{}{defaultNamespace, kubesphereNamespace}
secrets = []interface{}{secretFoo1, secretFoo2}
services = []interface{}{apiServerService, ksControllerService}
)
func prepare() (informers.InformerFactory, error) {
func prepare() (*Handler, error) {
ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
@@ -210,6 +236,91 @@ func prepare() (informers.InformerFactory, error) {
return nil, err
}
}
for _, service := range services {
err := k8sInformerFactory.Core().V1().Services().Informer().GetIndexer().Add(service)
if err != nil {
return nil, err
}
}
return fakeInformerFactory, nil
handler := New(resourcev1alpha3.NewResourceGetter(fakeInformerFactory, nil), resourcev1alpha2.NewResourceGetter(fakeInformerFactory), components.NewComponentsGetter(fakeInformerFactory.KubernetesSharedInformerFactory()))
return handler, nil
}
func TestHandleGetComponentStatus(t *testing.T) {
param := map[string]string{
"component": "ks-controller",
}
request, response, err := buildReqAndRes("GET", "/kapis/resources.kubesphere.io/v1alpha3/components/{component}", param, nil)
if err != nil {
t.Fatal("build res or req failed ")
}
handler, err := prepare()
if err != nil {
t.Fatal("init handler failed")
}
handler.handleGetComponentStatus(request, response)
if status := response.StatusCode(); status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
}
func TestHandleGetComponents(t *testing.T) {
request, response, err := buildReqAndRes("GET", "/kapis/resources.kubesphere.io/v1alpha3/components", nil, nil)
if err != nil {
t.Fatal("build res or req failed ")
}
handler, err := prepare()
if err != nil {
t.Fatal("init handler failed")
}
handler.handleGetComponents(request, response)
if status := response.StatusCode(); status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
}
//build req and res in *restful
func buildReqAndRes(method, target string, param map[string]string, body io.Reader) (*restful.Request, *restful.Response, error) {
//build req
request := httptest.NewRequest(method, target, body)
newRequest := restful.NewRequest(request)
if param != nil {
err := setUnExportedFields(newRequest, "pathParameters", param)
if err != nil {
klog.Error("set pathParameters failed ")
return nil, nil, err
}
}
//build res
response := httptest.NewRecorder()
newResponse := restful.NewResponse(response)
// assign Key:routeProduces a value of "application/json"
err := setUnExportedFields(newResponse, "routeProduces", []string{"application/json"})
if err != nil {
klog.Error("set routeProduces failed ")
return nil, nil, err
}
return newRequest, newResponse, nil
}
//Setting unexported fields by using reflect
func setUnExportedFields(ptr interface{}, filedName string, newFiledValue interface{}) (err error) {
v := reflect.ValueOf(ptr).Elem().FieldByName(filedName)
v = reflect.NewAt(v.Type(), unsafe.Pointer(v.UnsafeAddr())).Elem()
nv := reflect.ValueOf(newFiledValue)
if v.Kind() != nv.Kind() {
return fmt.Errorf("kind error")
}
v.Set(nv)
return nil
}

View File

@@ -41,6 +41,8 @@ import (
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/models/tenant"
servererr "kubesphere.io/kubesphere/pkg/server/errors"
@@ -58,16 +60,16 @@ type tenantHandler struct {
func NewTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface,
evtsClient events.Client, loggingClient logging.Client, auditingclient auditing.Client,
am am.AccessManagementInterface, authorizer authorizer.Authorizer,
am am.AccessManagementInterface, im im.IdentityManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, resourceGetter *resourcev1alpha3.ResourceGetter,
meteringOptions *meteringclient.Options, stopCh <-chan struct{}) *tenantHandler {
meteringOptions *meteringclient.Options, opClient openpitrix.Interface) *tenantHandler {
if meteringOptions == nil || meteringOptions.RetentionDay == "" {
meteringOptions = &meteringclient.DefaultMeteringOption
}
return &tenantHandler{
tenant: tenant.New(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourceGetter, stopCh),
tenant: tenant.New(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, im, authorizer, monitoringclient, resourceGetter, opClient),
meteringOptions: meteringOptions,
}
}
@@ -555,8 +557,8 @@ func (h *tenantHandler) ListClusters(r *restful.Request, response *restful.Respo
return
}
result, err := h.tenant.ListClusters(user)
queryParam := query.ParseQueryParameter(r)
result, err := h.tenant.ListClusters(user, queryParam)
if err != nil {
klog.Error(err)
if errors.IsNotFound(err) {

View File

@@ -40,8 +40,10 @@ import (
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"kubesphere.io/kubesphere/pkg/models/metering"
"kubesphere.io/kubesphere/pkg/models/monitoring"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/simple/client/auditing"
@@ -63,12 +65,12 @@ func Resource(resource string) schema.GroupResource {
func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8sclient kubernetes.Interface,
ksclient kubesphere.Interface, evtsClient events.Client, loggingClient logging.Client,
auditingclient auditing.Client, am am.AccessManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, cache cache.Cache, meteringOptions *meteringclient.Options, stopCh <-chan struct{}) error {
auditingclient auditing.Client, am am.AccessManagementInterface, im im.IdentityManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, cache cache.Cache, meteringOptions *meteringclient.Options, opClient openpitrix.Interface) error {
mimePatch := []string{restful.MIME_JSON, runtime.MimeMergePatchJson, runtime.MimeJsonPatchJson}
ws := runtime.NewWebService(GroupVersion)
handler := NewTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, stopCh)
handler := NewTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, im, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, opClient)
ws.Route(ws.GET("/clusters").
To(handler.ListClusters).

View File

@@ -31,6 +31,8 @@ import (
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/models/tenant"
"kubesphere.io/kubesphere/pkg/simple/client/auditing"
@@ -47,16 +49,16 @@ type tenantHandler struct {
func newTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface,
evtsClient events.Client, loggingClient logging.Client, auditingclient auditing.Client,
am am.AccessManagementInterface, authorizer authorizer.Authorizer,
am am.AccessManagementInterface, im im.IdentityManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, resourceGetter *resourcev1alpha3.ResourceGetter,
meteringOptions *meteringclient.Options, stopCh <-chan struct{}) *tenantHandler {
meteringOptions *meteringclient.Options, opClient openpitrix.Interface) *tenantHandler {
if meteringOptions == nil || meteringOptions.RetentionDay == "" {
meteringOptions = &meteringclient.DefaultMeteringOption
}
return &tenantHandler{
tenant: tenant.New(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourceGetter, stopCh),
tenant: tenant.New(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, im, authorizer, monitoringclient, resourceGetter, opClient),
meteringOptions: meteringOptions,
}
}

View File

@@ -37,6 +37,8 @@ import (
"kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"kubesphere.io/kubesphere/pkg/models/openpitrix"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/simple/client/auditing"
@@ -58,13 +60,13 @@ func Resource(resource string) schema.GroupResource {
func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8sclient kubernetes.Interface,
ksclient kubesphere.Interface, evtsClient events.Client, loggingClient logging.Client,
auditingclient auditing.Client, am am.AccessManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, cache cache.Cache, meteringOptions *meteringclient.Options, stopCh <-chan struct{}) error {
auditingclient auditing.Client, am am.AccessManagementInterface, im im.IdentityManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, cache cache.Cache, meteringOptions *meteringclient.Options, opClient openpitrix.Interface) error {
mimePatch := []string{restful.MIME_JSON, runtime.MimeMergePatchJson, runtime.MimeJsonPatchJson}
ws := runtime.NewWebService(GroupVersion)
v1alpha2Handler := v1alpha2.NewTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, stopCh)
handler := newTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, stopCh)
v1alpha2Handler := v1alpha2.NewTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, im, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, opClient)
handler := newTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, im, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, opClient)
ws.Route(ws.POST("/workspacetemplates").
To(v1alpha2Handler.CreateWorkspaceTemplate).

View File

@@ -21,6 +21,8 @@ import (
"encoding/base64"
"testing"
"kubesphere.io/kubesphere/pkg/utils/reposcache"
"github.com/go-openapi/strfmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
@@ -172,5 +174,5 @@ func prepareAppOperator() ApplicationInterface {
k8sClient = fakek8s.NewSimpleClientset()
fakeInformerFactory = informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
return newApplicationOperator(cachedReposData, fakeInformerFactory.KubeSphereSharedInformerFactory(), ksClient, fake.NewFakeS3())
return newApplicationOperator(reposcache.NewReposCache(), fakeInformerFactory.KubeSphereSharedInformerFactory(), ksClient, fake.NewFakeS3())
}

View File

@@ -17,11 +17,11 @@ limitations under the License.
package openpitrix
import (
"sync"
"k8s.io/client-go/tools/cache"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/utils/clusterclient"
"kubesphere.io/api/application/v1alpha1"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
@@ -46,51 +46,42 @@ type openpitrixOperator struct {
CategoryInterface
}
var cachedReposData reposcache.ReposCache
var helmReposInformer cache.SharedIndexInformer
var once sync.Once
func init() {
cachedReposData = reposcache.NewReposCache()
}
func NewOpenpitrixOperator(ksInformers ks_informers.InformerFactory, ksClient versioned.Interface, s3Client s3.Interface, stopCh <-chan struct{}) Interface {
once.Do(func() {
klog.Infof("start helm repo informer")
helmReposInformer = ksInformers.KubeSphereSharedInformerFactory().Application().V1alpha1().HelmRepos().Informer()
helmReposInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
r := obj.(*v1alpha1.HelmRepo)
cachedReposData.AddRepo(r)
},
UpdateFunc: func(oldObj, newObj interface{}) {
oldRepo := oldObj.(*v1alpha1.HelmRepo)
newRepo := newObj.(*v1alpha1.HelmRepo)
cachedReposData.UpdateRepo(oldRepo, newRepo)
},
DeleteFunc: func(obj interface{}) {
r := obj.(*v1alpha1.HelmRepo)
cachedReposData.DeleteRepo(r)
},
})
ctgInformer := ksInformers.KubeSphereSharedInformerFactory().Application().V1alpha1().HelmCategories().Informer()
ctgInformer.AddIndexers(map[string]cache.IndexFunc{
reposcache.CategoryIndexer: func(obj interface{}) ([]string, error) {
ctg, _ := obj.(*v1alpha1.HelmCategory)
return []string{ctg.Spec.Name}, nil
},
})
indexer := ctgInformer.GetIndexer()
cachedReposData.SetCategoryIndexer(indexer)
func NewOpenpitrixOperator(ksInformers ks_informers.InformerFactory, ksClient versioned.Interface, s3Client s3.Interface, cc clusterclient.ClusterClients, stopCh <-chan struct{}) Interface {
klog.Infof("start helm repo informer")
cachedReposData := reposcache.NewReposCache()
helmReposInformer := ksInformers.KubeSphereSharedInformerFactory().Application().V1alpha1().HelmRepos().Informer()
helmReposInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
r := obj.(*v1alpha1.HelmRepo)
cachedReposData.AddRepo(r)
},
UpdateFunc: func(oldObj, newObj interface{}) {
oldRepo := oldObj.(*v1alpha1.HelmRepo)
newRepo := newObj.(*v1alpha1.HelmRepo)
cachedReposData.UpdateRepo(oldRepo, newRepo)
},
DeleteFunc: func(obj interface{}) {
r := obj.(*v1alpha1.HelmRepo)
cachedReposData.DeleteRepo(r)
},
})
ctgInformer := ksInformers.KubeSphereSharedInformerFactory().Application().V1alpha1().HelmCategories().Informer()
ctgInformer.AddIndexers(map[string]cache.IndexFunc{
reposcache.CategoryIndexer: func(obj interface{}) ([]string, error) {
ctg, _ := obj.(*v1alpha1.HelmCategory)
return []string{ctg.Spec.Name}, nil
},
})
indexer := ctgInformer.GetIndexer()
cachedReposData.SetCategoryIndexer(indexer)
return &openpitrixOperator{
AttachmentInterface: newAttachmentOperator(s3Client),
ApplicationInterface: newApplicationOperator(cachedReposData, ksInformers.KubeSphereSharedInformerFactory(), ksClient, s3Client),
RepoInterface: newRepoOperator(cachedReposData, ksInformers.KubeSphereSharedInformerFactory(), ksClient),
ReleaseInterface: newReleaseOperator(cachedReposData, ksInformers.KubernetesSharedInformerFactory(), ksInformers.KubeSphereSharedInformerFactory(), ksClient),
ReleaseInterface: newReleaseOperator(cachedReposData, ksInformers.KubernetesSharedInformerFactory(), ksInformers.KubeSphereSharedInformerFactory(), ksClient, cc),
CategoryInterface: newCategoryOperator(cachedReposData, ksInformers.KubeSphereSharedInformerFactory(), ksClient),
}
}

View File

@@ -70,13 +70,13 @@ type releaseOperator struct {
clusterClients clusterclient.ClusterClients
}
func newReleaseOperator(cached reposcache.ReposCache, k8sFactory informers.SharedInformerFactory, ksFactory externalversions.SharedInformerFactory, ksClient versioned.Interface) ReleaseInterface {
func newReleaseOperator(cached reposcache.ReposCache, k8sFactory informers.SharedInformerFactory, ksFactory externalversions.SharedInformerFactory, ksClient versioned.Interface, cc clusterclient.ClusterClients) ReleaseInterface {
c := &releaseOperator{
informers: k8sFactory,
rlsClient: ksClient.ApplicationV1alpha1().HelmReleases(),
rlsLister: ksFactory.Application().V1alpha1().HelmReleases().Lister(),
cachedRepos: cached,
clusterClients: clusterclient.NewClusterClient(ksFactory.Cluster().V1alpha1().Clusters()),
clusterClients: cc,
appVersionLister: ksFactory.Application().V1alpha1().HelmApplicationVersions().Lister(),
}

View File

@@ -21,6 +21,8 @@ import (
"encoding/base64"
"testing"
"kubesphere.io/kubesphere/pkg/utils/reposcache"
"github.com/go-openapi/strfmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog"
@@ -69,7 +71,7 @@ func TestOpenPitrixRelease(t *testing.T) {
}
}
rlsOperator := newReleaseOperator(cachedReposData, fakeInformerFactory.KubernetesSharedInformerFactory(), fakeInformerFactory.KubeSphereSharedInformerFactory(), ksClient)
rlsOperator := newReleaseOperator(reposcache.NewReposCache(), fakeInformerFactory.KubernetesSharedInformerFactory(), fakeInformerFactory.KubeSphereSharedInformerFactory(), ksClient, nil)
req := CreateClusterRequest{
Name: "test-rls",

View File

@@ -20,6 +20,8 @@ import (
"context"
"testing"
"kubesphere.io/kubesphere/pkg/utils/reposcache"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fakek8s "k8s.io/client-go/kubernetes/fake"
"k8s.io/klog"
@@ -111,5 +113,5 @@ func prepareRepoOperator() RepoInterface {
k8sClient = fakek8s.NewSimpleClientset()
fakeInformerFactory = informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
return newRepoOperator(cachedReposData, fakeInformerFactory.KubeSphereSharedInformerFactory(), ksClient)
return newRepoOperator(reposcache.NewReposCache(), fakeInformerFactory.KubeSphereSharedInformerFactory(), ksClient)
}

View File

@@ -280,6 +280,9 @@ type AppVersionReview struct {
// version type
VersionType string `json:"version_type,omitempty"`
// Workspace of the app version
Workspace string `json:"workspace,omitempty"`
}
type CreateAppRequest struct {

View File

@@ -817,6 +817,7 @@ func convertAppVersionReview(app *v1alpha1.HelmApplication, appVersion *v1alpha1
review.VersionID = appVersion.GetHelmApplicationVersionId()
review.Phase = AppVersionReviewPhaseOAIGen{}
review.VersionName = appVersion.GetVersionName()
review.Workspace = appVersion.GetWorkspace()
review.StatusTime = strfmt.DateTime(status.Audit[0].Time.Time)
review.AppName = app.GetTrueName()

View File

@@ -0,0 +1,240 @@
package persistentvolumeclaim
import (
"testing"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"github.com/google/go-cmp/cmp"
snapshot "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
snapshotefakeclient "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned/fake"
snapshotinformers "github.com/kubernetes-csi/external-snapshotter/client/v4/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/server/params"
)
var (
testStorageClassName = "sc1"
)
var (
pvc1 = &corev1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pvc-1",
Namespace: "default",
Annotations: map[string]string{
"kubesphere.io/in-use": "false",
"kubesphere.io/allow-snapshot": "false",
},
},
Spec: corev1.PersistentVolumeClaimSpec{
StorageClassName: &testStorageClassName,
},
Status: corev1.PersistentVolumeClaimStatus{
Phase: corev1.ClaimPending,
},
}
pvc2 = &corev1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pvc-2",
Namespace: "default",
Annotations: map[string]string{
"kubesphere.io/in-use": "false",
"kubesphere.io/allow-snapshot": "false",
},
},
Spec: corev1.PersistentVolumeClaimSpec{
StorageClassName: &testStorageClassName,
},
Status: corev1.PersistentVolumeClaimStatus{
Phase: corev1.ClaimLost,
},
}
pvc3 = &corev1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pvc-3",
Namespace: "default",
Annotations: map[string]string{
"kubesphere.io/in-use": "true",
"kubesphere.io/allow-snapshot": "false",
},
},
Spec: corev1.PersistentVolumeClaimSpec{
StorageClassName: &testStorageClassName,
},
Status: corev1.PersistentVolumeClaimStatus{
Phase: corev1.ClaimBound,
},
}
pod1 = &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-1",
Namespace: "default",
},
Spec: corev1.PodSpec{
Volumes: []corev1.Volume{
{
Name: "data",
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: pvc3.Name,
},
},
},
},
},
}
vsc1 = &snapshot.VolumeSnapshotClass{
ObjectMeta: metav1.ObjectMeta{
Name: "VolumeSnapshotClass-1",
Namespace: "default",
},
Driver: testStorageClassName,
}
persistentVolumeClaims = []interface{}{pvc1, pvc2, pvc3}
pods = []interface{}{pod1}
volumeSnapshotClasses = []interface{}{vsc1}
)
func prepare() (v1alpha2.Interface, error) {
client := fake.NewSimpleClientset()
informer := informers.NewSharedInformerFactory(client, 0)
snapshotClient := snapshotefakeclient.NewSimpleClientset()
snapshotInformers := snapshotinformers.NewSharedInformerFactory(snapshotClient, 0)
for _, persistentVolumeClaim := range persistentVolumeClaims {
err := informer.Core().V1().PersistentVolumeClaims().Informer().GetIndexer().Add(persistentVolumeClaim)
if err != nil {
return nil, err
}
}
for _, pod := range pods {
err := informer.Core().V1().Pods().Informer().GetIndexer().Add(pod)
if err != nil {
return nil, err
}
}
for _, volumeSnapshotClass := range volumeSnapshotClasses {
err := snapshotInformers.Snapshot().V1().VolumeSnapshotClasses().Informer().GetIndexer().Add(volumeSnapshotClass)
if err != nil {
return nil, err
}
}
return NewPersistentVolumeClaimSearcher(informer, snapshotInformers), nil
}
func TestGet(t *testing.T) {
tests := []struct {
Namespace string
Name string
Expected interface{}
ExpectedErr error
}{
{
"default",
"pvc-1",
pvc1,
nil,
},
}
getter, err := prepare()
if err != nil {
t.Fatal(err)
}
for _, test := range tests {
got, err := getter.Get(test.Namespace, test.Name)
if test.ExpectedErr != nil && err != test.ExpectedErr {
t.Errorf("expected error, got nothing")
} else if err != nil {
t.Fatal(err)
}
diff := cmp.Diff(got, test.Expected)
if diff != "" {
t.Errorf("%T differ (-got, +want): %s", test.Expected, diff)
}
}
}
func TestSearch(t *testing.T) {
tests := []struct {
Namespace string
Conditions *params.Conditions
OrderBy string
Reverse bool
Expected []interface{}
ExpectedErr error
}{
{
Namespace: "default",
Conditions: &params.Conditions{
Match: map[string]string{
v1alpha2.Status: v1alpha2.StatusPending,
},
Fuzzy: nil,
},
OrderBy: "name",
Reverse: false,
Expected: []interface{}{pvc1},
ExpectedErr: nil,
},
{
Namespace: "default",
Conditions: &params.Conditions{
Match: map[string]string{
v1alpha2.Status: v1alpha2.StatusLost,
},
Fuzzy: nil,
},
OrderBy: "name",
Reverse: false,
Expected: []interface{}{pvc2},
ExpectedErr: nil,
},
{
Namespace: "default",
Conditions: &params.Conditions{
Match: map[string]string{
v1alpha2.Status: v1alpha2.StatusBound,
},
Fuzzy: nil,
},
OrderBy: "name",
Reverse: false,
Expected: []interface{}{pvc3},
ExpectedErr: nil,
},
}
searcher, err := prepare()
if err != nil {
t.Fatal(err)
}
for _, test := range tests {
got, err := searcher.Search(test.Namespace, test.Conditions, test.OrderBy, test.Reverse)
if test.ExpectedErr != nil && err != test.ExpectedErr {
t.Errorf("expected error, got nothing")
} else if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(got, test.Expected); diff != "" {
t.Errorf("%T differ (-got, +want): %s", test.Expected, diff)
}
}
}

View File

@@ -0,0 +1,217 @@
package federatedpersistentvolumeclaim
import (
"testing"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"github.com/google/go-cmp/cmp"
fedv1beta1 "kubesphere.io/api/types/v1beta1"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
)
var (
testStorageClassName = "sc1"
)
var (
pvc1 = &fedv1beta1.FederatedPersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pvc-1",
Namespace: "default",
},
}
pvc2 = &fedv1beta1.FederatedPersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pvc-2",
Namespace: "default",
},
Spec: fedv1beta1.FederatedPersistentVolumeClaimSpec{
Template: fedv1beta1.PersistentVolumeClaimTemplate{
Spec: corev1.PersistentVolumeClaimSpec{
StorageClassName: &testStorageClassName,
},
},
},
}
pvc3 = &fedv1beta1.FederatedPersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pvc-3",
Namespace: "default",
Labels: map[string]string{
"kubesphere.io/in-use": "false",
},
},
Spec: fedv1beta1.FederatedPersistentVolumeClaimSpec{
Template: fedv1beta1.PersistentVolumeClaimTemplate{
Spec: corev1.PersistentVolumeClaimSpec{
StorageClassName: &testStorageClassName,
},
},
},
}
federatedPersistentVolumeClaims = []*fedv1beta1.FederatedPersistentVolumeClaim{pvc1, pvc2, pvc3}
)
func fedPVCsToInterface(federatedPersistentVolumeClaims ...*fedv1beta1.FederatedPersistentVolumeClaim) []interface{} {
items := make([]interface{}, 0)
for _, fedPVC := range federatedPersistentVolumeClaims {
items = append(items, fedPVC)
}
return items
}
func fedPVCsToRuntimeObject(federatedPersistentVolumeClaims ...*fedv1beta1.FederatedPersistentVolumeClaim) []runtime.Object {
items := make([]runtime.Object, 0)
for _, fedPVC := range federatedPersistentVolumeClaims {
items = append(items, fedPVC)
}
return items
}
func prepare() (v1alpha3.Interface, error) {
client := fake.NewSimpleClientset(fedPVCsToRuntimeObject(federatedPersistentVolumeClaims...)...)
informer := externalversions.NewSharedInformerFactory(client, 0)
for _, fedPVC := range federatedPersistentVolumeClaims {
err := informer.Types().V1beta1().FederatedPersistentVolumeClaims().Informer().GetIndexer().Add(fedPVC)
if err != nil {
return nil, err
}
}
return New(informer), nil
}
func TestGet(t *testing.T) {
tests := []struct {
namespace string
name string
expected runtime.Object
expectedErr error
}{
{
namespace: "default",
name: "pvc-1",
expected: fedPVCsToRuntimeObject(pvc1)[0],
expectedErr: nil,
},
}
getter, err := prepare()
if err != nil {
t.Fatal(err)
}
for _, test := range tests {
pvc, err := getter.Get(test.namespace, test.name)
if test.expectedErr != nil && err != test.expectedErr {
t.Errorf("expected error, got nothing")
} else if err != nil {
t.Fatal(err)
}
diff := cmp.Diff(pvc, test.expected)
if diff != "" {
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
}
}
}
func TestList(t *testing.T) {
tests := []struct {
description string
namespace string
query *query.Query
expected *api.ListResult
expectedErr error
}{
{
description: "test name filter",
namespace: "default",
query: &query.Query{
Pagination: &query.Pagination{
Limit: 10,
Offset: 0,
},
SortBy: query.FieldName,
Ascending: false,
Filters: map[query.Field]query.Value{query.FieldName: query.Value(pvc1.Name)},
},
expected: &api.ListResult{
Items: fedPVCsToInterface(federatedPersistentVolumeClaims[0]),
TotalItems: 1,
},
expectedErr: nil,
},
{
description: "test storageClass filter",
namespace: "default",
query: &query.Query{
Pagination: &query.Pagination{
Limit: 10,
Offset: 0,
},
SortBy: query.FieldName,
Ascending: false,
Filters: map[query.Field]query.Value{query.Field(storageClassName): query.Value(*pvc2.Spec.Template.Spec.StorageClassName)},
},
expected: &api.ListResult{
Items: fedPVCsToInterface(federatedPersistentVolumeClaims[2], federatedPersistentVolumeClaims[1]),
TotalItems: 2,
},
expectedErr: nil,
},
{
description: "test label filter",
namespace: "default",
query: &query.Query{
Pagination: &query.Pagination{
Limit: 10,
Offset: 0,
},
SortBy: query.FieldName,
Ascending: false,
LabelSelector: "kubesphere.io/in-use=false",
Filters: map[query.Field]query.Value{query.Field(storageClassName): query.Value(*pvc2.Spec.Template.Spec.StorageClassName)},
},
expected: &api.ListResult{
Items: fedPVCsToInterface(federatedPersistentVolumeClaims[2]),
TotalItems: 1,
},
expectedErr: nil,
},
}
lister, err := prepare()
if err != nil {
t.Fatal(err)
}
for _, test := range tests {
got, err := lister.List(test.namespace, test.query)
if test.expectedErr != nil && err != test.expectedErr {
t.Errorf("expected error, got nothing")
} else if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(got, test.expected); diff != "" {
t.Errorf("[%s] %T differ (-got, +want): %s", test.description, test.expected, diff)
}
}
}

View File

@@ -20,6 +20,9 @@ import (
"sort"
"strings"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/klog"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -150,33 +153,13 @@ func DefaultObjectMetaFilter(item metav1.ObjectMeta, filter query.Filter) bool {
}
}
func labelMatch(labels map[string]string, filter string) bool {
fields := strings.SplitN(filter, "=", 2)
var key, value string
var opposite bool
if len(fields) == 2 {
key = fields[0]
if strings.HasSuffix(key, "!") {
key = strings.TrimSuffix(key, "!")
opposite = true
}
value = fields[1]
} else {
key = fields[0]
value = "*"
func labelMatch(m map[string]string, filter string) bool {
labelSelector, err := labels.Parse(filter)
if err != nil {
klog.Warningf("invalid labelSelector %s: %s", filter, err)
return false
}
for k, v := range labels {
if opposite {
if (k == key) && v != value {
return true
}
} else {
if (k == key) && (value == "*" || v == value) {
return true
}
}
}
return false
return labelSelector.Matches(labels.Set(m))
}
func objectsToInterfaces(objs []runtime.Object) []interface{} {

View File

@@ -30,6 +30,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/kubernetes"
"k8s.io/klog"
@@ -40,6 +41,8 @@ import (
tenantv1alpha2 "kubesphere.io/api/tenant/v1alpha2"
typesv1beta1 "kubesphere.io/api/types/v1beta1"
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/api"
auditingv1alpha1 "kubesphere.io/kubesphere/pkg/api/auditing/v1alpha1"
eventsv1alpha1 "kubesphere.io/kubesphere/pkg/api/events/v1alpha1"
@@ -53,6 +56,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/auditing"
"kubesphere.io/kubesphere/pkg/models/events"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"kubesphere.io/kubesphere/pkg/models/logging"
"kubesphere.io/kubesphere/pkg/models/metering"
"kubesphere.io/kubesphere/pkg/models/monitoring"
@@ -92,7 +96,7 @@ type Interface interface {
DeleteNamespace(workspace, namespace string) error
UpdateNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error)
PatchNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error)
ListClusters(info user.Info) (*api.ListResult, error)
ListClusters(info user.Info, queryParam *query.Query) (*api.ListResult, error)
Metering(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (monitoring.Metrics, error)
MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (metering.ResourceStatistic, error)
CreateWorkspaceResourceQuota(workspace string, resourceQuota *quotav1alpha2.ResourceQuota) (*quotav1alpha2.ResourceQuota, error)
@@ -103,6 +107,7 @@ type Interface interface {
type tenantOperator struct {
am am.AccessManagementInterface
im im.IdentityManagementInterface
authorizer authorizer.Authorizer
k8sclient kubernetes.Interface
ksclient kubesphere.Interface
@@ -114,14 +119,10 @@ type tenantOperator struct {
opRelease openpitrix.ReleaseInterface
}
func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface, evtsClient eventsclient.Client, loggingClient loggingclient.Client, auditingclient auditingclient.Client, am am.AccessManagementInterface, authorizer authorizer.Authorizer, monitoringclient monitoringclient.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, stopCh <-chan struct{}) Interface {
var openpitrixRelease openpitrix.ReleaseInterface
if ksclient != nil {
openpitrixRelease = openpitrix.NewOpenpitrixOperator(informers, ksclient, nil, stopCh)
}
func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface, evtsClient eventsclient.Client, loggingClient loggingclient.Client, auditingclient auditingclient.Client, am am.AccessManagementInterface, im im.IdentityManagementInterface, authorizer authorizer.Authorizer, monitoringclient monitoringclient.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, opClient openpitrix.Interface) Interface {
return &tenantOperator{
am: am,
im: im,
authorizer: authorizer,
resourceGetter: resourcesv1alpha3.NewResourceGetter(informers, nil),
k8sclient: k8sclient,
@@ -130,7 +131,7 @@ func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ks
lo: logging.NewLoggingOperator(loggingClient),
auditing: auditing.NewEventsOperator(auditingclient),
mo: monitoring.NewMonitoringOperator(monitoringclient, nil, k8sclient, informers, resourceGetter, nil),
opRelease: openpitrixRelease,
opRelease: opClient,
}
}
@@ -503,7 +504,7 @@ func (t *tenantOperator) ListWorkspaceClusters(workspaceName string) (*api.ListR
for _, cluster := range workspace.Spec.Placement.Clusters {
obj, err := t.resourceGetter.Get(clusterv1alpha1.ResourcesPluralCluster, "", cluster.Name)
if err != nil {
klog.Error(err)
klog.Warning(err)
if errors.IsNotFound(err) {
continue
}
@@ -532,89 +533,69 @@ func (t *tenantOperator) ListWorkspaceClusters(workspaceName string) (*api.ListR
return &api.ListResult{Items: []interface{}{}, TotalItems: 0}, nil
}
func (t *tenantOperator) ListClusters(user user.Info) (*api.ListResult, error) {
func (t *tenantOperator) ListClusters(user user.Info, queryParam *query.Query) (*api.ListResult, error) {
listClustersInGlobalScope := authorizer.AttributesRecord{
User: user,
Verb: "list",
APIGroup: "cluster.kubesphere.io",
Resource: "clusters",
ResourceScope: request.GlobalScope,
ResourceRequest: true,
}
allowedListClustersInGlobalScope, _, err := t.authorizer.Authorize(listClustersInGlobalScope)
if err != nil {
klog.Error(err)
return nil, err
return nil, fmt.Errorf("failed to authorize: %s", err)
}
listWorkspacesInGlobalScope := authorizer.AttributesRecord{
User: user,
Verb: "list",
Resource: "workspaces",
ResourceScope: request.GlobalScope,
ResourceRequest: true,
if allowedListClustersInGlobalScope == authorizer.DecisionAllow {
return t.resourceGetter.List(clusterv1alpha1.ResourcesPluralCluster, "", queryParam)
}
allowedListWorkspacesInGlobalScope, _, err := t.authorizer.Authorize(listWorkspacesInGlobalScope)
userDetail, err := t.im.DescribeUser(user.GetName())
if err != nil {
klog.Error(err)
return nil, err
return nil, fmt.Errorf("failed to describe user: %s", err)
}
if allowedListClustersInGlobalScope == authorizer.DecisionAllow ||
allowedListWorkspacesInGlobalScope == authorizer.DecisionAllow {
result, err := t.resourceGetter.List(clusterv1alpha1.ResourcesPluralCluster, "", query.New())
grantedClustersAnnotation := userDetail.Annotations[iamv1alpha2.GrantedClustersAnnotation]
var grantedClusters sets.String
if len(grantedClustersAnnotation) > 0 {
grantedClusters = sets.NewString(strings.Split(grantedClustersAnnotation, ",")...)
} else {
grantedClusters = sets.NewString()
}
var clusters []*clusterv1alpha1.Cluster
for _, grantedCluster := range grantedClusters.List() {
obj, err := t.resourceGetter.Get(clusterv1alpha1.ResourcesPluralCluster, "", grantedCluster)
if err != nil {
klog.Error(err)
return nil, err
}
return result, nil
}
workspaceRoleBindings, err := t.am.ListWorkspaceRoleBindings(user.GetName(), user.GetGroups(), "")
if err != nil {
klog.Error(err)
return nil, err
}
clusters := map[string]*clusterv1alpha1.Cluster{}
for _, roleBinding := range workspaceRoleBindings {
workspaceName := roleBinding.Labels[tenantv1alpha1.WorkspaceLabel]
workspace, err := t.DescribeWorkspaceTemplate(workspaceName)
if err != nil {
klog.Error(err)
return nil, err
}
for _, grantedCluster := range workspace.Spec.Placement.Clusters {
// skip if cluster exist
if clusters[grantedCluster.Name] != nil {
if errors.IsNotFound(err) {
continue
}
obj, err := t.resourceGetter.Get(clusterv1alpha1.ResourcesPluralCluster, "", grantedCluster.Name)
if err != nil {
klog.Error(err)
if errors.IsNotFound(err) {
continue
}
return nil, err
}
cluster := obj.(*clusterv1alpha1.Cluster)
clusters[cluster.Name] = cluster
return nil, fmt.Errorf("failed to fetch cluster: %s", err)
}
cluster := obj.(*clusterv1alpha1.Cluster)
clusters = append(clusters, cluster)
}
items := make([]interface{}, 0)
items := make([]runtime.Object, 0)
for _, cluster := range clusters {
items = append(items, cluster)
}
return &api.ListResult{Items: items, TotalItems: len(items)}, nil
// apply additional labelSelector
if queryParam.LabelSelector != "" {
queryParam.Filters[query.FieldLabel] = query.Value(queryParam.LabelSelector)
}
// use default pagination search logic
result := resources.DefaultList(items, queryParam, func(left runtime.Object, right runtime.Object, field query.Field) bool {
return resources.DefaultObjectMetaCompare(left.(*clusterv1alpha1.Cluster).ObjectMeta, right.(*clusterv1alpha1.Cluster).ObjectMeta, field)
}, func(workspace runtime.Object, filter query.Filter) bool {
return resources.DefaultObjectMetaFilter(workspace.(*clusterv1alpha1.Cluster).ObjectMeta, filter)
})
return result, nil
}
func (t *tenantOperator) DeleteWorkspaceTemplate(workspace string, opts metav1.DeleteOptions) error {

View File

@@ -544,5 +544,5 @@ func prepare() Interface {
amOperator := am.NewOperator(ksClient, k8sClient, fakeInformerFactory, nil)
authorizer := rbac.NewRBACAuthorizer(amOperator)
return New(fakeInformerFactory, k8sClient, ksClient, nil, nil, nil, amOperator, authorizer, nil, nil, nil)
return New(fakeInformerFactory, k8sClient, ksClient, nil, nil, nil, amOperator, nil, authorizer, nil, nil, nil)
}

View File

@@ -81,6 +81,9 @@ type TerminalMessage struct {
func (t TerminalSession) Next() *remotecommand.TerminalSize {
select {
case size := <-t.sizeChan:
if size.Height == 0 && size.Width == 0 {
return nil
}
return &size
}
}
@@ -145,6 +148,7 @@ func (t TerminalSession) Toast(p string) error {
// For now the status code is unused and reason is shown to the user (unless "")
func (t TerminalSession) Close(status uint32, reason string) {
klog.Warning(status, reason)
close(t.sizeChan)
t.conn.Close()
}

View File

@@ -56,33 +56,26 @@ type ClusterClients interface {
GetInnerCluster(string) *innerCluster
}
var (
once sync.Once
c *clusterClients
)
func NewClusterClient(clusterInformer clusterinformer.ClusterInformer) ClusterClients {
once.Do(func() {
c = &clusterClients{
innerClusters: make(map[string]*innerCluster),
clusterLister: clusterInformer.Lister(),
}
c := &clusterClients{
innerClusters: make(map[string]*innerCluster),
clusterLister: clusterInformer.Lister(),
}
clusterInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
c.addCluster(obj)
},
UpdateFunc: func(oldObj, newObj interface{}) {
oldCluster := oldObj.(*clusterv1alpha1.Cluster)
newCluster := newObj.(*clusterv1alpha1.Cluster)
if !reflect.DeepEqual(oldCluster.Spec, newCluster.Spec) {
c.addCluster(newObj)
}
},
DeleteFunc: func(obj interface{}) {
c.removeCluster(obj)
},
})
clusterInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
c.addCluster(obj)
},
UpdateFunc: func(oldObj, newObj interface{}) {
oldCluster := oldObj.(*clusterv1alpha1.Cluster)
newCluster := newObj.(*clusterv1alpha1.Cluster)
if !reflect.DeepEqual(oldCluster.Spec, newCluster.Spec) {
c.addCluster(newObj)
}
},
DeleteFunc: func(obj interface{}) {
c.removeCluster(obj)
},
})
return c
}

View File

@@ -1,4 +1,3 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*

View File

@@ -58,6 +58,7 @@ const (
GlobalRoleAnnotation = "iam.kubesphere.io/globalrole"
WorkspaceRoleAnnotation = "iam.kubesphere.io/workspacerole"
ClusterRoleAnnotation = "iam.kubesphere.io/clusterrole"
GrantedClustersAnnotation = "iam.kubesphere.io/granted-clusters"
UninitializedAnnotation = "iam.kubesphere.io/uninitialized"
LastPasswordChangeTimeAnnotation = "iam.kubesphere.io/last-password-change-time"
RoleAnnotation = "iam.kubesphere.io/role"

View File

@@ -1,58 +0,0 @@
/*
Copyright 2020 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 v1beta1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
ResourcePluralFederatedResourceQuota = "federatedresourcequotas"
ResourceSingularFederatedResourceQuota = "federatedresourcequota"
FederatedResourceQuotaKind = "FederatedResourceQuota"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:openapi-gen=true
type FederatedResourceQuota struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FederatedResourceQuotaSpec `json:"spec"`
Status *GenericFederatedStatus `json:"status,omitempty"`
}
type FederatedResourceQuotaSpec struct {
Template ResourceQuotaTemplate `json:"template"`
Placement GenericPlacementFields `json:"placement"`
Overrides []GenericOverrideItem `json:"overrides,omitempty"`
}
type ResourceQuotaTemplate struct {
Spec corev1.ResourceQuotaSpec `json:"spec,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// FederatedResourceQuotaList contains a list of federatedresourcequotalists
type FederatedResourceQuotaList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FederatedResourceQuota `json:"items"`
}

View File

@@ -67,8 +67,6 @@ func init() {
&FederatedNotificationReceiverList{},
&FederatedPersistentVolumeClaim{},
&FederatedPersistentVolumeClaimList{},
&FederatedResourceQuota{},
&FederatedResourceQuotaList{},
&FederatedSecret{},
&FederatedSecretList{},
&FederatedService{},

View File

@@ -1425,96 +1425,6 @@ func (in *FederatedPersistentVolumeClaimSpec) DeepCopy() *FederatedPersistentVol
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FederatedResourceQuota) DeepCopyInto(out *FederatedResourceQuota) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(GenericFederatedStatus)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuota.
func (in *FederatedResourceQuota) DeepCopy() *FederatedResourceQuota {
if in == nil {
return nil
}
out := new(FederatedResourceQuota)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FederatedResourceQuota) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FederatedResourceQuotaList) DeepCopyInto(out *FederatedResourceQuotaList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]FederatedResourceQuota, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuotaList.
func (in *FederatedResourceQuotaList) DeepCopy() *FederatedResourceQuotaList {
if in == nil {
return nil
}
out := new(FederatedResourceQuotaList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FederatedResourceQuotaList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FederatedResourceQuotaSpec) DeepCopyInto(out *FederatedResourceQuotaSpec) {
*out = *in
in.Template.DeepCopyInto(&out.Template)
in.Placement.DeepCopyInto(&out.Placement)
if in.Overrides != nil {
in, out := &in.Overrides, &out.Overrides
*out = make([]GenericOverrideItem, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuotaSpec.
func (in *FederatedResourceQuotaSpec) DeepCopy() *FederatedResourceQuotaSpec {
if in == nil {
return nil
}
out := new(FederatedResourceQuotaSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FederatedSecret) DeepCopyInto(out *FederatedSecret) {
*out = *in
@@ -2543,23 +2453,6 @@ func (in *PersistentVolumeClaimTemplate) DeepCopy() *PersistentVolumeClaimTempla
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceQuotaTemplate) DeepCopyInto(out *ResourceQuotaTemplate) {
*out = *in
in.Spec.DeepCopyInto(&out.Spec)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceQuotaTemplate.
func (in *ResourceQuotaTemplate) DeepCopy() *ResourceQuotaTemplate {
if in == nil {
return nil
}
out := new(ResourceQuotaTemplate)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretTemplate) DeepCopyInto(out *SecretTemplate) {
*out = *in

View File

@@ -121,7 +121,7 @@ func generateSwaggerJson() []byte {
informerFactory.KubeSphereSharedInformerFactory(), "", "", ""))
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, nil))
urlruntime.Must(monitoringv1alpha3.AddToContainer(container, clientsets.Kubernetes(), nil, nil, informerFactory, nil, nil))
urlruntime.Must(openpitrixv1.AddToContainer(container, informerFactory, fake.NewSimpleClientset(), nil, nil))
urlruntime.Must(openpitrixv2.AddToContainer(container, informerFactory, fake.NewSimpleClientset(), nil))
urlruntime.Must(operationsv1alpha2.AddToContainer(container, clientsets.Kubernetes()))

7
vendor/modules.txt vendored
View File

@@ -511,7 +511,7 @@ github.com/kubesphere/pvc-autoresizer/runners
# github.com/kubesphere/sonargo v0.0.2 => github.com/kubesphere/sonargo v0.0.2
## explicit
github.com/kubesphere/sonargo/sonar
# github.com/kubesphere/storageclass-accessor v0.2.0
# github.com/kubesphere/storageclass-accessor v0.2.0 => github.com/kubesphere/storageclass-accessor v0.2.0
## explicit
github.com/kubesphere/storageclass-accessor/client/apis/accessor/v1alpha1
github.com/kubesphere/storageclass-accessor/webhook
@@ -2304,6 +2304,7 @@ sigs.k8s.io/yaml
# github.com/coreos/pkg => github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f
# github.com/cortexproject/cortex => github.com/cortexproject/cortex v1.3.1-0.20200901115931-255ff3306960
# github.com/cpuguy83/go-md2man => github.com/cpuguy83/go-md2man v1.0.10
# github.com/cpuguy83/go-md2man/v2 => github.com/cpuguy83/go-md2man/v2 v2.0.0
# github.com/creack/pty => github.com/creack/pty v1.1.7
# github.com/cyphar/filepath-securejoin => github.com/cyphar/filepath-securejoin v0.2.2
# github.com/cznic/b => github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07
@@ -2421,7 +2422,6 @@ sigs.k8s.io/yaml
# github.com/gobwas/pool => github.com/gobwas/pool v0.2.0
# github.com/gobwas/ws => github.com/gobwas/ws v1.0.2
# github.com/gocql/gocql => github.com/gocql/gocql v0.0.0-20200526081602-cd04bd7f22a7
# github.com/gocraft/dbr => github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6
# github.com/godbus/dbus => github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968
# github.com/godror/godror => github.com/godror/godror v0.13.3
# github.com/gofrs/flock => github.com/gofrs/flock v0.7.1
@@ -2547,10 +2547,10 @@ sigs.k8s.io/yaml
# github.com/kr/pty => github.com/kr/pty v1.1.5
# github.com/kr/text => github.com/kr/text v0.1.0
# github.com/kshvakov/clickhouse => github.com/kshvakov/clickhouse v1.3.5
# github.com/kubernetes-csi/external-snapshotter/client/v3 => github.com/kubernetes-csi/external-snapshotter/client/v3 v3.0.0
# github.com/kubernetes-csi/external-snapshotter/client/v4 => github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0
# github.com/kubesphere/pvc-autoresizer => github.com/kubesphere/pvc-autoresizer v0.1.1
# github.com/kubesphere/sonargo => github.com/kubesphere/sonargo v0.0.2
# github.com/kubesphere/storageclass-accessor => github.com/kubesphere/storageclass-accessor v0.2.0
# github.com/kylelemons/go-gypsy => github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28
# github.com/kylelemons/godebug => github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb
# github.com/lann/builder => github.com/lann/builder v0.0.0-20180802200727-47ae307949d0
@@ -2699,6 +2699,7 @@ sigs.k8s.io/yaml
# github.com/sergi/go-diff => github.com/sergi/go-diff v1.0.0
# github.com/shopspring/decimal => github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24
# github.com/shurcooL/httpfs => github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
# github.com/shurcooL/sanitized_anchor_name => github.com/shurcooL/sanitized_anchor_name v1.0.0
# github.com/shurcooL/vfsgen => github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
# github.com/siebenmann/go-kstat => github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745
# github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.4.2