update notification manager to v2.0 (#5030)

Signed-off-by: wanjunlei <wanjunlei@kubesphere.io>
This commit is contained in:
wanjunlei
2022-07-05 16:04:33 +08:00
committed by GitHub
parent 8e00ba29ca
commit 5cead172cd
87 changed files with 7877 additions and 253 deletions

View File

@@ -12,13 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
package notification
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"reflect"
"github.com/emicklei/go-restful"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
@@ -26,8 +33,8 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
"k8s.io/klog"
"kubesphere.io/api/notification/v2beta1"
"kubesphere.io/api/notification/v2beta2"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/query"
@@ -35,21 +42,34 @@ import (
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/simple/client/notification"
)
const (
Secret = "secrets"
Secret = "secrets"
VerificationAPIPath = "/api/v2/verify"
V2beta1 = "v2beta1"
V2beta2 = "v2beta2"
)
type Operator interface {
ListV2beta1(user, resource, subresource string, query *query.Query) (*api.ListResult, error)
GetV2beta1(user, resource, name, subresource string) (runtime.Object, error)
CreateV2beta1(user, resource string, obj runtime.Object) (runtime.Object, error)
DeleteV2beta1(user, resource, name string) error
UpdateV2beta1(user, resource, name string, obj runtime.Object) (runtime.Object, error)
List(user, resource, subresource string, query *query.Query) (*api.ListResult, error)
Get(user, resource, name, subresource string) (runtime.Object, error)
Create(user, resource string, obj runtime.Object) (runtime.Object, error)
Delete(user, resource, name string) error
Update(user, resource, name string, obj runtime.Object) (runtime.Object, error)
GetObject(resource string) runtime.Object
IsKnownResource(resource, subresource string) bool
Verify(request *restful.Request, response *restful.Response)
GetObject(resource, version string) runtime.Object
IsKnownResource(resource, version, subresource string) bool
}
type operator struct {
@@ -57,24 +77,52 @@ type operator struct {
ksClient kubesphere.Interface
informers informers.InformerFactory
resourceGetter *resource.ResourceGetter
options *notification.Options
}
type Data struct {
Config v2beta2.Config `json:"config"`
Receiver v2beta2.Receiver `json:"receiver"`
}
type Result struct {
Code int `json:"Status"`
Message string `json:"Message"`
}
func NewOperator(
informers informers.InformerFactory,
k8sClient kubernetes.Interface,
ksClient kubesphere.Interface) Operator {
ksClient kubesphere.Interface,
options *notification.Options) Operator {
return &operator{
informers: informers,
k8sClient: k8sClient,
ksClient: ksClient,
resourceGetter: resource.NewResourceGetter(informers, nil),
options: options,
}
}
// ListV2beta1 list objects of version v2beta1. Only global objects will be returned if the user is nil.
// If the user is not nil, only tenant objects whose tenant label matches the user will be returned.
func (o *operator) ListV2beta1(user, resource, subresource string, q *query.Query) (*api.ListResult, error) {
return o.list(user, resource, V2beta1, subresource, q)
}
// List objects. Only global objects will be returned if the user is nil.
// If the user is not nil, only tenant objects whose tenant label matches the user will be returned.
func (o *operator) List(user, resource, subresource string, q *query.Query) (*api.ListResult, error) {
return o.list(user, resource, V2beta2, subresource, q)
}
func (o *operator) list(user, resource, version, subresource string, q *query.Query) (*api.ListResult, error) {
if user != "" && resource == v2beta2.ResourcesPluralRouter {
return nil, errors.NewForbidden(v2beta2.Resource(v2beta2.ResourcesPluralRouter), "",
fmt.Errorf("tenant can not list router"))
}
if len(q.LabelSelector) > 0 {
q.LabelSelector = q.LabelSelector + ","
@@ -83,7 +131,7 @@ func (o *operator) List(user, resource, subresource string, q *query.Query) (*ap
filter := ""
// If user is nil, it will list all global object.
if user == "" {
if isConfig(o.GetObject(resource)) {
if isConfig(o.GetObject(resource, version)) {
filter = "type=default"
} else {
filter = "type=global"
@@ -102,6 +150,7 @@ func (o *operator) List(user, resource, subresource string, q *query.Query) (*ap
res, err := o.resourceGetter.List(resource, ns, q)
if err != nil {
klog.Error(err)
return nil, err
}
@@ -113,6 +162,9 @@ func (o *operator) List(user, resource, subresource string, q *query.Query) (*ap
for _, item := range res.Items {
obj := clean(item, resource, subresource)
if obj != nil {
if version == V2beta1 {
obj = convert(obj)
}
results.Items = append(results.Items, obj)
}
}
@@ -121,9 +173,24 @@ func (o *operator) List(user, resource, subresource string, q *query.Query) (*ap
return results, nil
}
// GetV2beta1 get the specified object of version v2beta1, if you want to get a global object, the user must be nil.
// If you want to get a tenant object, the user must equal to the tenant specified in labels of the object.
func (o *operator) GetV2beta1(user, resource, name, subresource string) (runtime.Object, error) {
return o.get(user, resource, V2beta1, name, subresource)
}
// Get the specified object, if you want to get a global object, the user must be nil.
// If you want to get a tenant object, the user must equal to the tenant specified in labels of the object.
func (o *operator) Get(user, resource, name, subresource string) (runtime.Object, error) {
return o.get(user, resource, V2beta2, name, subresource)
}
func (o *operator) get(user, resource, version, name, subresource string) (runtime.Object, error) {
if user != "" && resource == v2beta2.ResourcesPluralRouter {
return nil, errors.NewForbidden(v2beta2.Resource(v2beta2.ResourcesPluralRouter), "",
fmt.Errorf("tenant can not get router"))
}
ns := ""
if resource == Secret {
@@ -132,10 +199,12 @@ func (o *operator) Get(user, resource, name, subresource string) (runtime.Object
obj, err := o.resourceGetter.Get(resource, ns, name)
if err != nil {
klog.Error(err)
return nil, err
}
if err := authorizer(user, obj); err != nil {
klog.Error(err)
return nil, err
}
@@ -148,22 +217,53 @@ func (o *operator) Get(user, resource, name, subresource string) (runtime.Object
return nil, errors.NewNotFound(v2beta1.Resource(obj.GetObjectKind().GroupVersionKind().GroupKind().Kind), name)
}
if version == V2beta1 {
res = convert(res)
}
return res, nil
}
// CreateV2beta1 an object of version v2beta1. A global object will be created if the user is nil.
// A tenant object will be created if the user is not nil.
func (o *operator) CreateV2beta1(user, resource string, obj runtime.Object) (runtime.Object, error) {
return o.create(user, resource, V2beta1, obj)
}
// Create an object. A global object will be created if the user is nil.
// A tenant object will be created if the user is not nil.
func (o *operator) Create(user, resource string, obj runtime.Object) (runtime.Object, error) {
return o.create(user, resource, V2beta2, obj)
}
func (o *operator) create(user, resource, version string, obj runtime.Object) (runtime.Object, error) {
if err := appendLabel(user, resource, obj); err != nil {
return nil, err
}
if user != "" && resource == v2beta2.ResourcesPluralRouter {
return nil, errors.NewForbidden(v2beta2.Resource(v2beta2.ResourcesPluralRouter), "",
fmt.Errorf("tenant can not create router"))
}
switch resource {
case v2beta1.ResourcesPluralConfig:
return o.ksClient.NotificationV2beta1().Configs().Create(context.Background(), obj.(*v2beta1.Config), v1.CreateOptions{})
case v2beta1.ResourcesPluralReceiver:
return o.ksClient.NotificationV2beta1().Receivers().Create(context.Background(), obj.(*v2beta1.Receiver), v1.CreateOptions{})
case v2beta2.ResourcesPluralConfig:
if version == V2beta1 {
return o.ksClient.NotificationV2beta1().Configs().Create(context.Background(), obj.(*v2beta1.Config), v1.CreateOptions{})
} else {
return o.ksClient.NotificationV2beta2().Configs().Create(context.Background(), obj.(*v2beta2.Config), v1.CreateOptions{})
}
case v2beta2.ResourcesPluralReceiver:
if version == V2beta1 {
return o.ksClient.NotificationV2beta1().Receivers().Create(context.Background(), obj.(*v2beta1.Receiver), v1.CreateOptions{})
} else {
return o.ksClient.NotificationV2beta2().Receivers().Create(context.Background(), obj.(*v2beta2.Receiver), v1.CreateOptions{})
}
case v2beta2.ResourcesPluralRouter:
return o.ksClient.NotificationV2beta2().Routers().Create(context.Background(), obj.(*v2beta2.Router), v1.CreateOptions{})
case v2beta2.ResourcesPluralSilence:
return o.ksClient.NotificationV2beta2().Silences().Create(context.Background(), obj.(*v2beta2.Silence), v1.CreateOptions{})
case "secrets":
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Create(context.Background(), obj.(*corev1.Secret), v1.CreateOptions{})
default:
@@ -171,23 +271,44 @@ func (o *operator) Create(user, resource string, obj runtime.Object) (runtime.Ob
}
}
// DeleteV2beta1 an object of version v2beta1. A global object will be deleted if the user is nil.
// If the user is not nil, a tenant object whose tenant label matches the user will be deleted.
func (o *operator) DeleteV2beta1(user, resource, name string) error {
return o.delete(user, resource, name)
}
// Delete an object. A global object will be deleted if the user is nil.
// If the user is not nil, a tenant object whose tenant label matches the user will be deleted.
func (o *operator) Delete(user, resource, name string) error {
return o.delete(user, resource, name)
}
func (o *operator) delete(user, resource, name string) error {
if user != "" && resource == v2beta2.ResourcesPluralRouter {
return errors.NewForbidden(v2beta2.Resource(v2beta2.ResourcesPluralRouter), "",
fmt.Errorf("tenant can not delete router"))
}
if obj, err := o.Get(user, resource, name, ""); err != nil {
klog.Error(err)
return err
} else {
if err := authorizer(user, obj); err != nil {
klog.Error(err)
return err
}
}
switch resource {
case v2beta1.ResourcesPluralConfig:
return o.ksClient.NotificationV2beta1().Configs().Delete(context.Background(), name, v1.DeleteOptions{})
case v2beta1.ResourcesPluralReceiver:
return o.ksClient.NotificationV2beta1().Receivers().Delete(context.Background(), name, v1.DeleteOptions{})
case v2beta2.ResourcesPluralConfig:
return o.ksClient.NotificationV2beta2().Configs().Delete(context.Background(), name, v1.DeleteOptions{})
case v2beta2.ResourcesPluralReceiver:
return o.ksClient.NotificationV2beta2().Receivers().Delete(context.Background(), name, v1.DeleteOptions{})
case v2beta2.ResourcesPluralRouter:
return o.ksClient.NotificationV2beta2().Routers().Delete(context.Background(), name, v1.DeleteOptions{})
case v2beta2.ResourcesPluralSilence:
return o.ksClient.NotificationV2beta2().Silences().Delete(context.Background(), name, v1.DeleteOptions{})
case "secrets":
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Delete(context.Background(), name, v1.DeleteOptions{})
default:
@@ -195,27 +316,56 @@ func (o *operator) Delete(user, resource, name string) error {
}
}
// UpdateV2beta1 an object of version v2beta1, only a global object will be updated if the user is nil.
// If the user is not nil, a tenant object whose tenant label matches the user will be updated.
func (o *operator) UpdateV2beta1(user, resource, name string, obj runtime.Object) (runtime.Object, error) {
return o.update(user, resource, V2beta1, name, obj)
}
// Update an object, only a global object will be updated if the user is nil.
// If the user is not nil, a tenant object whose tenant label matches the user will be updated.
func (o *operator) Update(user, resource, name string, obj runtime.Object) (runtime.Object, error) {
return o.update(user, resource, V2beta2, name, obj)
}
func (o *operator) update(user, resource, version, name string, obj runtime.Object) (runtime.Object, error) {
if user != "" && resource == v2beta2.ResourcesPluralRouter {
return nil, errors.NewForbidden(v2beta2.Resource(v2beta2.ResourcesPluralRouter), "",
fmt.Errorf("tenant can not update router"))
}
if err := appendLabel(user, resource, obj); err != nil {
return nil, err
}
if old, err := o.Get(user, resource, name, ""); err != nil {
klog.Error(err)
return nil, err
} else {
if err := authorizer(user, old); err != nil {
klog.Error(err)
return nil, err
}
}
switch resource {
case v2beta1.ResourcesPluralConfig:
return o.ksClient.NotificationV2beta1().Configs().Update(context.Background(), obj.(*v2beta1.Config), v1.UpdateOptions{})
case v2beta1.ResourcesPluralReceiver:
return o.ksClient.NotificationV2beta1().Receivers().Update(context.Background(), obj.(*v2beta1.Receiver), v1.UpdateOptions{})
case v2beta2.ResourcesPluralConfig:
if version == V2beta1 {
return o.ksClient.NotificationV2beta1().Configs().Update(context.Background(), obj.(*v2beta1.Config), v1.UpdateOptions{})
} else {
return o.ksClient.NotificationV2beta2().Configs().Update(context.Background(), obj.(*v2beta2.Config), v1.UpdateOptions{})
}
case v2beta2.ResourcesPluralReceiver:
if version == V2beta1 {
return o.ksClient.NotificationV2beta1().Receivers().Update(context.Background(), obj.(*v2beta1.Receiver), v1.UpdateOptions{})
} else {
return o.ksClient.NotificationV2beta2().Receivers().Update(context.Background(), obj.(*v2beta2.Receiver), v1.UpdateOptions{})
}
case v2beta2.ResourcesPluralRouter:
return o.ksClient.NotificationV2beta2().Routers().Update(context.Background(), obj.(*v2beta2.Router), v1.UpdateOptions{})
case v2beta2.ResourcesPluralSilence:
return o.ksClient.NotificationV2beta2().Silences().Update(context.Background(), obj.(*v2beta2.Silence), v1.UpdateOptions{})
case "secrets":
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Update(context.Background(), obj.(*corev1.Secret), v1.UpdateOptions{})
default:
@@ -223,13 +373,31 @@ func (o *operator) Update(user, resource, name string, obj runtime.Object) (runt
}
}
func (o *operator) GetObject(resource string) runtime.Object {
func (o *operator) GetObject(resource, version string) runtime.Object {
switch resource {
case v2beta1.ResourcesPluralConfig:
return &v2beta1.Config{}
case v2beta1.ResourcesPluralReceiver:
return &v2beta1.Receiver{}
case v2beta2.ResourcesPluralConfig:
if version == V2beta1 {
return &v2beta1.Config{}
} else {
return &v2beta2.Config{}
}
case v2beta2.ResourcesPluralReceiver:
if version == V2beta1 {
return &v2beta1.Receiver{}
} else {
return &v2beta2.Receiver{}
}
case v2beta2.ResourcesPluralRouter:
if version == V2beta1 {
return nil
}
return &v2beta2.Router{}
case v2beta2.ResourcesPluralSilence:
if version == V2beta1 {
return nil
}
return &v2beta2.Silence{}
case Secret:
return &corev1.Secret{}
default:
@@ -237,36 +405,105 @@ func (o *operator) GetObject(resource string) runtime.Object {
}
}
func (o *operator) IsKnownResource(resource, subresource string) bool {
func (o *operator) IsKnownResource(resource, version, subresource string) bool {
if obj := o.GetObject(resource); obj == nil {
if obj := o.GetObject(resource, version); obj == nil {
return false
}
res := false
// "" means get all types of the config or receiver.
if subresource != "dingtalk" &&
subresource != "email" &&
subresource != "slack" &&
subresource != "webhook" &&
subresource != "wechat" &&
subresource != "" {
return false
if subresource == "dingtalk" ||
subresource == "email" ||
subresource == "slack" ||
subresource == "webhook" ||
subresource == "wechat" ||
subresource == "" {
res = true
}
return true
if version == V2beta2 && subresource == "feishu" {
res = true
}
return res
}
func (o *operator) Verify(request *restful.Request, response *restful.Response) {
if o.options == nil || len(o.options.Endpoint) == 0 {
_ = response.WriteAsJson(Result{
http.StatusInternalServerError,
"Cannot find Notification Manager endpoint",
})
return
}
reqBody, err := ioutil.ReadAll(request.Request.Body)
if err != nil {
klog.Error(err)
_ = response.WriteHeaderAndEntity(http.StatusBadRequest, err)
return
}
data := Data{}
err = json.Unmarshal(reqBody, &data)
if err != nil {
_ = response.WriteHeaderAndEntity(http.StatusBadRequest, err)
return
}
receiver := data.Receiver
user := request.PathParameter("user")
if err := authorizer(user, &receiver); err != nil {
klog.Error(err)
_ = response.WriteHeaderAndEntity(http.StatusBadRequest, err)
return
}
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", o.options.Endpoint, VerificationAPIPath), bytes.NewReader(reqBody))
if err != nil {
klog.Error(err)
_ = response.WriteHeaderAndEntity(http.StatusInternalServerError, err)
return
}
req.Header = request.Request.Header
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
klog.Error(err)
_ = response.WriteHeaderAndEntity(http.StatusInternalServerError, err)
return
}
defer func() {
_ = resp.Body.Close()
}()
body, err := io.ReadAll(resp.Body)
if err != nil {
klog.Error(err)
// return 500
_ = response.WriteHeaderAndEntity(http.StatusInternalServerError, err)
return
}
response.AddHeader(restful.HEADER_ContentType, restful.MIME_JSON)
response.WriteHeader(http.StatusOK)
_, _ = response.Write(body)
}
// Does the user has permission to access this object.
func authorizer(user string, obj runtime.Object) error {
// If the user is not nil, it must equal to the tenant specified in labels of the object.
if user != "" && !isOwner(user, obj) {
return errors.NewForbidden(v2beta1.Resource(obj.GetObjectKind().GroupVersionKind().GroupKind().Kind), "",
return errors.NewForbidden(v2beta2.Resource(obj.GetObjectKind().GroupVersionKind().GroupKind().Kind), "",
fmt.Errorf("user '%s' is not the owner of object", user))
}
// If the user is nil, the object must be a global object.
if user == "" && !isGlobal(obj) {
return errors.NewForbidden(v2beta1.Resource(obj.GetObjectKind().GroupVersionKind().GroupKind().Kind), "",
return errors.NewForbidden(v2beta2.Resource(obj.GetObjectKind().GroupVersionKind().GroupKind().Kind), "",
fmt.Errorf("object is not a global object"))
}
@@ -282,12 +519,12 @@ func isOwner(user string, obj interface{}) bool {
return false
}
return accessor.GetLabels()["user"] == user
return accessor.GetLabels()["user"] == user && accessor.GetLabels()["type"] == "tenant"
}
func isConfig(obj runtime.Object) bool {
switch obj.(type) {
case *v2beta1.Config:
case *v2beta1.Config, *v2beta2.Config:
return true
default:
return false
@@ -342,15 +579,17 @@ func appendLabel(user, resource string, obj runtime.Object) error {
}
func clean(obj interface{}, resource, subresource string) runtime.Object {
if resource == v2beta1.ResourcesPluralConfig {
config := obj.(*v2beta1.Config)
if resource == v2beta2.ResourcesPluralConfig {
config := obj.(*v2beta2.Config)
newConfig := config.DeepCopy()
newConfig.Spec = v2beta1.ConfigSpec{}
newConfig.Spec = v2beta2.ConfigSpec{}
switch subresource {
case "dingtalk":
newConfig.Spec.DingTalk = config.Spec.DingTalk
case "email":
newConfig.Spec.Email = config.Spec.Email
case "feishu":
newConfig.Spec.Feishu = config.Spec.Feishu
case "slack":
newConfig.Spec.Slack = config.Spec.Slack
case "webhook":
@@ -366,15 +605,17 @@ func clean(obj interface{}, resource, subresource string) runtime.Object {
}
return newConfig
} else {
receiver := obj.(*v2beta1.Receiver)
} else if resource == v2beta2.ResourcesPluralReceiver {
receiver := obj.(*v2beta2.Receiver)
newReceiver := receiver.DeepCopy()
newReceiver.Spec = v2beta1.ReceiverSpec{}
newReceiver.Spec = v2beta2.ReceiverSpec{}
switch subresource {
case "dingtalk":
newReceiver.Spec.DingTalk = receiver.Spec.DingTalk
case "email":
newReceiver.Spec.Email = receiver.Spec.Email
case "feishu":
newReceiver.Spec.Feishu = receiver.Spec.Feishu
case "slack":
newReceiver.Spec.Slack = receiver.Spec.Slack
case "webhook":
@@ -390,5 +631,22 @@ func clean(obj interface{}, resource, subresource string) runtime.Object {
}
return newReceiver
} else {
return obj.(runtime.Object)
}
}
func convert(obj runtime.Object) runtime.Object {
switch obj := obj.(type) {
case *v2beta2.Config:
dst := &v2beta1.Config{}
_ = obj.ConvertTo(dst)
return dst
case *v2beta2.Receiver:
dst := &v2beta1.Receiver{}
_ = obj.ConvertTo(dst)
return dst
default:
return obj
}
}

View File

@@ -217,5 +217,5 @@ func prepare() Operator {
_ = fakeInformerFactory.KubernetesSharedInformerFactory().Core().V1().Secrets().Informer().GetIndexer().Add(secret)
}
return NewOperator(fakeInformerFactory, k8sClient, ksClient)
return NewOperator(fakeInformerFactory, k8sClient, ksClient, nil)
}

View File

@@ -37,11 +37,11 @@ func NewNotificationConfigGetter(informer ksinformers.SharedInformerFactory) v1a
}
func (g *configGetter) Get(_, name string) (runtime.Object, error) {
return g.ksInformer.Notification().V2beta1().Configs().Lister().Get(name)
return g.ksInformer.Notification().V2beta2().Configs().Lister().Get(name)
}
func (g *configGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
objs, err := g.ksInformer.Notification().V2beta1().Configs().Lister().List(query.Selector())
objs, err := g.ksInformer.Notification().V2beta2().Configs().Lister().List(query.Selector())
if err != nil {
return nil, err
}
@@ -62,11 +62,61 @@ func NewNotificationReceiverGetter(informer ksinformers.SharedInformerFactory) v
}
func (g *receiverGetter) Get(_, name string) (runtime.Object, error) {
return g.ksInformer.Notification().V2beta1().Receivers().Lister().Get(name)
return g.ksInformer.Notification().V2beta2().Receivers().Lister().Get(name)
}
func (g *receiverGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
objs, err := g.ksInformer.Notification().V2beta1().Receivers().Lister().List(query.Selector())
objs, err := g.ksInformer.Notification().V2beta2().Receivers().Lister().List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, obj := range objs {
result = append(result, obj)
}
return v1alpha3.DefaultList(result, query, compare, filter), nil
}
type routerGetter struct {
ksInformer ksinformers.SharedInformerFactory
}
func NewNotificationRouterGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
return &routerGetter{ksInformer: informer}
}
func (g *routerGetter) Get(_, name string) (runtime.Object, error) {
return g.ksInformer.Notification().V2beta2().Routers().Lister().Get(name)
}
func (g *routerGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
objs, err := g.ksInformer.Notification().V2beta2().Routers().Lister().List(query.Selector())
if err != nil {
return nil, err
}
var result []runtime.Object
for _, obj := range objs {
result = append(result, obj)
}
return v1alpha3.DefaultList(result, query, compare, filter), nil
}
type silenceGetter struct {
ksInformer ksinformers.SharedInformerFactory
}
func NewNotificationSilenceGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
return &silenceGetter{ksInformer: informer}
}
func (g *silenceGetter) Get(_, name string) (runtime.Object, error) {
return g.ksInformer.Notification().V2beta2().Silences().Lister().Get(name)
}
func (g *silenceGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
objs, err := g.ksInformer.Notification().V2beta2().Silences().Lister().List(query.Selector())
if err != nil {
return nil, err
}

View File

@@ -26,8 +26,7 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/cache"
"kubesphere.io/api/notification/v2beta1"
"kubesphere.io/api/notification/v2beta2"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/query"
@@ -50,11 +49,19 @@ func TestListObjects(t *testing.T) {
}{
{
"test name filter",
v2beta1.ResourcesPluralConfig,
v2beta2.ResourcesPluralConfig,
},
{
"test name filter",
v2beta1.ResourcesPluralReceiver,
v2beta2.ResourcesPluralReceiver,
},
{
"test name filter",
v2beta2.ResourcesPluralRouter,
},
{
"test name filter",
v2beta2.ResourcesPluralSilence,
},
}
@@ -99,14 +106,22 @@ func prepare(key string) (v1alpha3.Interface, []interface{}, error) {
var indexer cache.Indexer
var getter func(informer ksinformers.SharedInformerFactory) v1alpha3.Interface
switch key {
case v2beta1.ResourcesPluralConfig:
indexer = informer.Notification().V2beta1().Configs().Informer().GetIndexer()
case v2beta2.ResourcesPluralConfig:
indexer = informer.Notification().V2beta2().Configs().Informer().GetIndexer()
getter = NewNotificationConfigGetter
obj = &v2beta1.Config{}
case v2beta1.ResourcesPluralReceiver:
indexer = informer.Notification().V2beta1().Receivers().Informer().GetIndexer()
obj = &v2beta2.Config{}
case v2beta2.ResourcesPluralReceiver:
indexer = informer.Notification().V2beta2().Receivers().Informer().GetIndexer()
getter = NewNotificationReceiverGetter
obj = &v2beta1.Receiver{}
obj = &v2beta2.Receiver{}
case v2beta2.ResourcesPluralRouter:
indexer = informer.Notification().V2beta2().Routers().Informer().GetIndexer()
getter = NewNotificationRouterGetter
obj = &v2beta2.Router{}
case v2beta2.ResourcesPluralSilence:
indexer = informer.Notification().V2beta2().Silences().Informer().GetIndexer()
getter = NewNotificationSilenceGetter
obj = &v2beta2.Silence{}
default:
return nil, nil, errors.New("unowned type %s", key)
}

View File

@@ -36,7 +36,7 @@ import (
devopsv1alpha3 "kubesphere.io/api/devops/v1alpha3"
iamv1alpha2 "kubesphere.io/api/iam/v1alpha2"
networkv1alpha1 "kubesphere.io/api/network/v1alpha1"
notificationv2beta1 "kubesphere.io/api/notification/v2beta1"
notificationv2beta2 "kubesphere.io/api/notification/v2beta2"
tenantv1alpha1 "kubesphere.io/api/tenant/v1alpha1"
tenantv1alpha2 "kubesphere.io/api/tenant/v1alpha2"
typesv1beta1 "kubesphere.io/api/types/v1beta1"
@@ -143,8 +143,10 @@ func NewResourceGetter(factory informers.InformerFactory, cache cache.Cache) *Re
clusterResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralClusterRole)] = clusterrole.New(factory.KubernetesSharedInformerFactory())
clusterResourceGetters[rbacv1.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralClusterRoleBinding)] = clusterrolebinding.New(factory.KubernetesSharedInformerFactory())
clusterResourceGetters[clusterv1alpha1.SchemeGroupVersion.WithResource(clusterv1alpha1.ResourcesPluralCluster)] = cluster.New(factory.KubeSphereSharedInformerFactory())
clusterResourceGetters[notificationv2beta1.SchemeGroupVersion.WithResource(notificationv2beta1.ResourcesPluralConfig)] = notification.NewNotificationConfigGetter(factory.KubeSphereSharedInformerFactory())
clusterResourceGetters[notificationv2beta1.SchemeGroupVersion.WithResource(notificationv2beta1.ResourcesPluralReceiver)] = notification.NewNotificationReceiverGetter(factory.KubeSphereSharedInformerFactory())
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralConfig)] = notification.NewNotificationConfigGetter(factory.KubeSphereSharedInformerFactory())
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralReceiver)] = notification.NewNotificationReceiverGetter(factory.KubeSphereSharedInformerFactory())
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralRouter)] = notification.NewNotificationRouterGetter(factory.KubeSphereSharedInformerFactory())
clusterResourceGetters[notificationv2beta2.SchemeGroupVersion.WithResource(notificationv2beta2.ResourcesPluralSilence)] = notification.NewNotificationSilenceGetter(factory.KubeSphereSharedInformerFactory())
clusterResourceGetters[monitoringdashboardv1alpha2.GroupVersion.WithResource("clusterdashboards")] = clusterdashboard.New(cache)
// federated resources