add tenant-level apis for notification secret
Signed-off-by: wanjunlei <wanjunlei@yunify.com>
This commit is contained in:
@@ -128,7 +128,6 @@ const (
|
||||
|
||||
NotificationTag = "Notification"
|
||||
NotificationSecretNamespace = "kubesphere-monitoring-federated"
|
||||
NotificationManagedLabel = "notification-manager/managed"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -222,7 +222,7 @@ func (c *Controller) reconcile(obj interface{}) error {
|
||||
|
||||
// Only reconcile the secret which created by notification manager.
|
||||
if secret, ok := obj.(*corev1.Secret); ok {
|
||||
if secret.Namespace != constants.NotificationSecretNamespace || secret.Labels[constants.NotificationManagedLabel] != "true" {
|
||||
if secret.Namespace != constants.NotificationSecretNamespace {
|
||||
klog.V(8).Infof("No need to reconcile secret %s/%s", accessor.GetNamespace(), accessor.GetName())
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ var (
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{constants.NotificationManagedLabel: "true"},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package v2
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog"
|
||||
@@ -44,36 +43,6 @@ func newNotificationHandler(
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) ListSecret(req *restful.Request, resp *restful.Response) {
|
||||
q := query.ParseQueryParameter(req)
|
||||
objs, err := h.operator.ListSecret(q)
|
||||
handleResponse(req, resp, objs, err)
|
||||
}
|
||||
|
||||
func (h *handler) GetSecret(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
obj, err := h.operator.GetSecret(req.PathParameter("secret"))
|
||||
handleResponse(req, resp, obj, err)
|
||||
}
|
||||
|
||||
func (h *handler) CreateOrUpdateSecret(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
var obj corev1.Secret
|
||||
err := req.ReadEntity(&obj)
|
||||
if err != nil {
|
||||
api.HandleBadRequest(resp, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
created, err := h.operator.CreateOrUpdateSecret(&obj)
|
||||
handleResponse(req, resp, created, err)
|
||||
}
|
||||
|
||||
func (h *handler) DeleteSecret(req *restful.Request, resp *restful.Response) {
|
||||
err := h.operator.DeleteSecret(req.PathParameter("secret"))
|
||||
handleResponse(req, resp, servererr.None, err)
|
||||
}
|
||||
|
||||
func (h *handler) ListResource(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
user := req.PathParameter("user")
|
||||
@@ -128,6 +97,7 @@ func (h *handler) UpdateResource(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
user := req.PathParameter("user")
|
||||
resource := req.PathParameter("resources")
|
||||
name := req.PathParameter("name")
|
||||
|
||||
if !h.operator.IsKnownResource(resource) {
|
||||
api.HandleBadRequest(resp, req, servererr.New("unknown resource type %s", resource))
|
||||
@@ -140,7 +110,7 @@ func (h *handler) UpdateResource(req *restful.Request, resp *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
updated, err := h.operator.Update(user, resource, obj)
|
||||
updated, err := h.operator.Update(user, resource, name, obj)
|
||||
handleResponse(req, resp, updated, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ package v2
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
openapi "github.com/emicklei/go-restful-openapi"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
@@ -50,52 +49,12 @@ func AddToContainer(
|
||||
ws := runtime.NewWebService(GroupVersion)
|
||||
h := newNotificationHandler(informers, k8sClient, ksClient)
|
||||
|
||||
// apis for secrets
|
||||
ws.Route(ws.GET("/secrets").
|
||||
To(h.ListSecret).
|
||||
Doc("list the secrets").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.QueryParameter(query.ParameterName, "name used for filtering").Required(false)).
|
||||
Param(ws.QueryParameter(query.ParameterLabelSelector, "label selector used for filtering").Required(false)).
|
||||
Param(ws.QueryParameter(query.ParameterPage, "page").Required(false).DataFormat("page=%d").DefaultValue("page=1")).
|
||||
Param(ws.QueryParameter(query.ParameterLimit, "limit").Required(false)).
|
||||
Param(ws.QueryParameter(query.ParameterAscending, "sort parameters, e.g. ascending=false").Required(false).DefaultValue("ascending=false")).
|
||||
Param(ws.QueryParameter(query.ParameterOrderBy, "sort parameters, e.g. orderBy=createTime")).
|
||||
Returns(http.StatusOK, api.StatusOK, api.ListResult{Items: []interface{}{}}))
|
||||
|
||||
ws.Route(ws.GET("/secrets/{secret}").
|
||||
To(h.GetSecret).
|
||||
Doc("get the secret").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("secret", "secret name")).
|
||||
Returns(http.StatusOK, api.StatusOK, []v1.Secret{}))
|
||||
|
||||
ws.Route(ws.POST("/secrets").
|
||||
To(h.CreateOrUpdateSecret).
|
||||
Doc("create a secret").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Returns(http.StatusOK, api.StatusOK, []v1.Secret{}))
|
||||
|
||||
ws.Route(ws.PUT("/secrets/{secret}").
|
||||
To(h.CreateOrUpdateSecret).
|
||||
Doc("update the secret").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("secret", "secret name")).
|
||||
Returns(http.StatusOK, api.StatusOK, []v1.Secret{}))
|
||||
|
||||
ws.Route(ws.DELETE("/secrets/{secret}").
|
||||
To(h.DeleteSecret).
|
||||
Doc("delete the secret").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("secret", "secret name")).
|
||||
Returns(http.StatusOK, api.StatusOK, errors.None))
|
||||
|
||||
// apis for global notification config and receiver
|
||||
// apis for global notification config, receiver, and secret
|
||||
ws.Route(ws.GET("/{resources}").
|
||||
To(h.ListResource).
|
||||
Doc("list the notification configs or receivers").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Param(ws.QueryParameter(query.ParameterName, "name used for filtering").Required(false)).
|
||||
Param(ws.QueryParameter(query.ParameterLabelSelector, "label selector used for filtering").Required(false)).
|
||||
Param(ws.QueryParameter(query.ParameterPage, "page").Required(false).DataFormat("page=%d").DefaultValue("page=1")).
|
||||
@@ -108,7 +67,7 @@ func AddToContainer(
|
||||
To(h.GetResource).
|
||||
Doc("get the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Param(ws.PathParameter("name", "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
@@ -116,14 +75,14 @@ func AddToContainer(
|
||||
To(h.CreateResource).
|
||||
Doc("create a notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("resource", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resource", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
ws.Route(ws.PUT("/{resources}/{name}").
|
||||
To(h.UpdateResource).
|
||||
Doc("update the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Param(ws.PathParameter("name", "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
@@ -131,7 +90,7 @@ func AddToContainer(
|
||||
To(h.DeleteResource).
|
||||
Doc("delete the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Param(ws.PathParameter("name", "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, errors.None))
|
||||
|
||||
@@ -141,7 +100,7 @@ func AddToContainer(
|
||||
Doc("list the notification configs or receivers").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Param(ws.QueryParameter(query.ParameterName, "name used for filtering").Required(false)).
|
||||
Param(ws.QueryParameter(query.ParameterLabelSelector, "label selector used for filtering").Required(false)).
|
||||
Param(ws.QueryParameter(query.ParameterPage, "page").Required(false).DataFormat("page=%d").DefaultValue("page=1")).
|
||||
@@ -155,7 +114,7 @@ func AddToContainer(
|
||||
Doc("get the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Param(ws.PathParameter("name", "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
@@ -171,7 +130,7 @@ func AddToContainer(
|
||||
Doc("update the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resources", "notification configs or receivers, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Param(ws.PathParameter("name", "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
@@ -180,7 +139,7 @@ func AddToContainer(
|
||||
Doc("delete the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "notification config or receiver, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers")).
|
||||
Param(ws.PathParameter("resources", "notification config or receiver, known values include dingtalkconfigs, dingtalkreceivers, emailconfigs. emailreceivers, slackconfigs, slackreceivers, webhookconfigs, webhookreceivers, wechatconfigs, wechatreceivers, secrets")).
|
||||
Param(ws.PathParameter("name", "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, errors.None))
|
||||
|
||||
|
||||
@@ -24,12 +24,7 @@ type Operator interface {
|
||||
Get(user, resource, name string) (runtime.Object, error)
|
||||
Create(user, resource string, obj runtime.Object) (runtime.Object, error)
|
||||
Delete(user, resource, name string) error
|
||||
Update(user, resource string, obj runtime.Object) (runtime.Object, error)
|
||||
|
||||
ListSecret(query *query.Query) (*api.ListResult, error)
|
||||
GetSecret(name string) (interface{}, error)
|
||||
CreateOrUpdateSecret(obj *corev1.Secret) (*corev1.Secret, error)
|
||||
DeleteSecret(name string) error
|
||||
Update(user, resource, name string, obj runtime.Object) (runtime.Object, error)
|
||||
|
||||
GetObject(resource string) runtime.Object
|
||||
IsKnownResource(resource string) bool
|
||||
@@ -59,21 +54,32 @@ func NewOperator(
|
||||
// If the user is not nil, only tenant objects whose tenant label matches the user will be returned.
|
||||
func (o *operator) List(user, resource string, q *query.Query) (*api.ListResult, error) {
|
||||
|
||||
// If user is nil, it will list all global object.
|
||||
if user == "" {
|
||||
appendGlobalLabel(resource, q)
|
||||
} else {
|
||||
// If the user is not nil, only return the object belong to this user.
|
||||
appendTenantLabel(user, q)
|
||||
if len(q.LabelSelector) > 0 {
|
||||
q.LabelSelector = q.LabelSelector + ","
|
||||
}
|
||||
|
||||
return o.resourceGetter.List(resource, "", q)
|
||||
filter := ""
|
||||
// If user is nil, it will list all global object.
|
||||
if user == "" {
|
||||
if isConfig(o.GetObject(resource)) {
|
||||
filter = "type=default"
|
||||
} else {
|
||||
filter = "type=global"
|
||||
}
|
||||
} else {
|
||||
// If the user is not nil, only return the object belong to this user.
|
||||
filter = "type=tenant,user=" + user
|
||||
}
|
||||
|
||||
q.LabelSelector = q.LabelSelector + filter
|
||||
|
||||
return o.resourceGetter.List(resource, constants.NotificationSecretNamespace, q)
|
||||
}
|
||||
|
||||
// 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 string) (runtime.Object, error) {
|
||||
obj, err := o.resourceGetter.Get(resource, "", name)
|
||||
obj, err := o.resourceGetter.Get(resource, constants.NotificationSecretNamespace, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -89,7 +95,7 @@ func (o *operator) Get(user, resource, name string) (runtime.Object, error) {
|
||||
// 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) {
|
||||
|
||||
if err := authorizer(user, obj); err != nil {
|
||||
if err := appendLabel(user, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -114,6 +120,8 @@ func (o *operator) Create(user, resource string, obj runtime.Object) (runtime.Ob
|
||||
return o.ksClient.NotificationV2().WechatConfigs().Create(context.Background(), obj.(*v2.WechatConfig), v1.CreateOptions{})
|
||||
case v2.ResourcesPluralWechatReceiver:
|
||||
return o.ksClient.NotificationV2().WechatReceivers().Create(context.Background(), obj.(*v2.WechatReceiver), v1.CreateOptions{})
|
||||
case "secrets":
|
||||
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Create(context.Background(), obj.(*corev1.Secret), v1.CreateOptions{})
|
||||
default:
|
||||
return nil, errors.NewInternalError(nil)
|
||||
}
|
||||
@@ -152,6 +160,8 @@ func (o *operator) Delete(user, resource, name string) error {
|
||||
return o.ksClient.NotificationV2().WechatConfigs().Delete(context.Background(), name, v1.DeleteOptions{})
|
||||
case v2.ResourcesPluralWechatReceiver:
|
||||
return o.ksClient.NotificationV2().WechatReceivers().Delete(context.Background(), name, v1.DeleteOptions{})
|
||||
case "secrets":
|
||||
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Delete(context.Background(), name, v1.DeleteOptions{})
|
||||
default:
|
||||
return errors.NewInternalError(nil)
|
||||
}
|
||||
@@ -159,17 +169,16 @@ func (o *operator) Delete(user, resource, name string) error {
|
||||
|
||||
// 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 string, obj runtime.Object) (runtime.Object, error) {
|
||||
func (o *operator) Update(user, resource, name string, obj runtime.Object) (runtime.Object, error) {
|
||||
|
||||
name, err := getName(obj)
|
||||
if err != nil {
|
||||
if err := appendLabel(user, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := o.Get(user, resource, name); err != nil {
|
||||
if old, err := o.Get(user, resource, name); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
if err := authorizer(user, obj); err != nil {
|
||||
if err := authorizer(user, old); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -195,54 +204,13 @@ func (o *operator) Update(user, resource string, obj runtime.Object) (runtime.Ob
|
||||
return o.ksClient.NotificationV2().WechatConfigs().Update(context.Background(), obj.(*v2.WechatConfig), v1.UpdateOptions{})
|
||||
case v2.ResourcesPluralWechatReceiver:
|
||||
return o.ksClient.NotificationV2().WechatReceivers().Update(context.Background(), obj.(*v2.WechatReceiver), v1.UpdateOptions{})
|
||||
case "secrets":
|
||||
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Update(context.Background(), obj.(*corev1.Secret), v1.UpdateOptions{})
|
||||
default:
|
||||
return nil, errors.NewInternalError(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *operator) ListSecret(q *query.Query) (*api.ListResult, error) {
|
||||
|
||||
appendManagedLabel(q)
|
||||
return o.resourceGetter.List("secrets", constants.NotificationSecretNamespace, q)
|
||||
}
|
||||
|
||||
func (o *operator) GetSecret(name string) (interface{}, error) {
|
||||
obj, err := o.resourceGetter.Get("secrets", constants.NotificationSecretNamespace, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !isManagedByNotification(obj.(*corev1.Secret)) {
|
||||
return nil, errors.NewForbidden(v2.Resource(obj.GetObjectKind().GroupVersionKind().GroupKind().Kind), "",
|
||||
fmt.Errorf("secret '%s' is not managed by notification", name))
|
||||
}
|
||||
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func (o *operator) CreateOrUpdateSecret(obj *corev1.Secret) (*corev1.Secret, error) {
|
||||
|
||||
obj.Namespace = constants.NotificationSecretNamespace
|
||||
if obj.Labels == nil {
|
||||
obj.Labels = make(map[string]string)
|
||||
}
|
||||
obj.Labels[constants.NotificationManagedLabel] = "true"
|
||||
if obj.ResourceVersion == "" {
|
||||
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Create(context.Background(), obj, v1.CreateOptions{})
|
||||
} else {
|
||||
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Update(context.Background(), obj, v1.UpdateOptions{})
|
||||
}
|
||||
}
|
||||
|
||||
func (o *operator) DeleteSecret(name string) error {
|
||||
|
||||
if _, err := o.GetSecret(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Delete(context.Background(), name, v1.DeleteOptions{})
|
||||
}
|
||||
|
||||
func (o *operator) GetObject(resource string) runtime.Object {
|
||||
|
||||
switch resource {
|
||||
@@ -266,6 +234,8 @@ func (o *operator) GetObject(resource string) runtime.Object {
|
||||
return &v2.WechatConfig{}
|
||||
case v2.ResourcesPluralWechatReceiver:
|
||||
return &v2.WechatReceiver{}
|
||||
case "secrets":
|
||||
return &corev1.Secret{}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@@ -333,48 +303,30 @@ func isGlobal(obj runtime.Object) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func appendTenantLabel(user string, q *query.Query) {
|
||||
|
||||
if len(q.LabelSelector) > 0 {
|
||||
q.LabelSelector = q.LabelSelector + ","
|
||||
}
|
||||
q.LabelSelector = q.LabelSelector + "type=tenant,user=" + user
|
||||
}
|
||||
|
||||
func appendGlobalLabel(resource string, q *query.Query) {
|
||||
|
||||
if len(q.LabelSelector) > 0 {
|
||||
q.LabelSelector = q.LabelSelector + ","
|
||||
}
|
||||
|
||||
switch resource {
|
||||
case v2.ResourcesPluralDingTalkConfig, v2.ResourcesPluralEmailConfig,
|
||||
v2.ResourcesPluralSlackConfig, v2.ResourcesPluralWebhookConfig, v2.ResourcesPluralWechatConfig:
|
||||
q.LabelSelector = q.LabelSelector + "type=default"
|
||||
case v2.ResourcesPluralDingTalkReceiver, v2.ResourcesPluralEmailReceiver,
|
||||
v2.ResourcesPluralSlackReceiver, v2.ResourcesPluralWebhookReceiver, v2.ResourcesPluralWechatReceiver:
|
||||
q.LabelSelector = q.LabelSelector + "type=global"
|
||||
}
|
||||
}
|
||||
|
||||
func appendManagedLabel(q *query.Query) {
|
||||
|
||||
if len(q.LabelSelector) > 0 {
|
||||
q.LabelSelector = q.LabelSelector + ","
|
||||
}
|
||||
q.LabelSelector = q.LabelSelector + constants.NotificationManagedLabel + "=" + "true"
|
||||
}
|
||||
|
||||
func isManagedByNotification(secret *corev1.Secret) bool {
|
||||
return secret.Labels[constants.NotificationManagedLabel] == "true"
|
||||
}
|
||||
|
||||
func getName(obj runtime.Object) (string, error) {
|
||||
func appendLabel(user string, obj runtime.Object) error {
|
||||
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
klog.Errorln(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return accessor.GetName(), nil
|
||||
labels := accessor.GetLabels()
|
||||
if labels == nil {
|
||||
labels = make(map[string]string)
|
||||
}
|
||||
|
||||
if user == "" {
|
||||
if isConfig(obj) {
|
||||
labels["type"] = "default"
|
||||
} else {
|
||||
labels["type"] = "global"
|
||||
}
|
||||
} else {
|
||||
labels["type"] = "tenant"
|
||||
labels["user"] = user
|
||||
}
|
||||
|
||||
accessor.SetLabels(labels)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOperator_ListSecret(t *testing.T) {
|
||||
func TestOperator_List(t *testing.T) {
|
||||
o := prepare()
|
||||
tests := []struct {
|
||||
result *api.ListResult
|
||||
@@ -46,7 +46,7 @@ func TestOperator_ListSecret(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
result, err := o.ListSecret(&query.Query{
|
||||
result, err := o.List("", "secrets", &query.Query{
|
||||
SortBy: query.FieldName,
|
||||
Ascending: true,
|
||||
})
|
||||
@@ -64,7 +64,7 @@ func TestOperator_ListSecret(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperator_GetSecret(t *testing.T) {
|
||||
func TestOperator_Get(t *testing.T) {
|
||||
o := prepare()
|
||||
tests := []struct {
|
||||
result *corev1.Secret
|
||||
@@ -83,7 +83,7 @@ func TestOperator_GetSecret(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result, err := o.GetSecret(test.name)
|
||||
result, err := o.Get("", "secrets", test.name)
|
||||
|
||||
if err != nil {
|
||||
if !reflect.DeepEqual(err, test.expectError) {
|
||||
@@ -98,7 +98,7 @@ func TestOperator_GetSecret(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperator_CreateOrUpdateSecret(t *testing.T) {
|
||||
func TestOperator_Create(t *testing.T) {
|
||||
o := prepare()
|
||||
tests := []struct {
|
||||
result *corev1.Secret
|
||||
@@ -110,12 +110,17 @@ func TestOperator_CreateOrUpdateSecret(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{constants.NotificationManagedLabel: "true"},
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
},
|
||||
secret: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectError: nil,
|
||||
@@ -123,7 +128,7 @@ func TestOperator_CreateOrUpdateSecret(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
result, err := o.CreateOrUpdateSecret(test.secret)
|
||||
result, err := o.Create("", "secrets", test.secret)
|
||||
|
||||
if err != nil {
|
||||
if !reflect.DeepEqual(err, test.expectError) {
|
||||
@@ -138,7 +143,7 @@ func TestOperator_CreateOrUpdateSecret(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperator_DeleteSecret(t *testing.T) {
|
||||
func TestOperator_Delete(t *testing.T) {
|
||||
o := prepare()
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -151,7 +156,7 @@ func TestOperator_DeleteSecret(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
err := o.DeleteSecret(test.name)
|
||||
err := o.Delete("", "secrets", test.name)
|
||||
if err != nil {
|
||||
if test.expectError != nil && test.expectError.Error() == err.Error() {
|
||||
continue
|
||||
@@ -169,7 +174,9 @@ var (
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{constants.NotificationManagedLabel: "true"},
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -177,7 +184,9 @@ var (
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{constants.NotificationManagedLabel: "true"},
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -185,7 +194,9 @@ var (
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo3",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{constants.NotificationManagedLabel: "true"},
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user