Merge pull request #3356 from wanjunlei/nm
support customize notification receiver
This commit is contained in:
25
pkg/apis/addtoscheme_notification_v2beta1.go
Normal file
25
pkg/apis/addtoscheme_notification_v2beta1.go
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright 2019 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 apis
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
AddToSchemes = append(AddToSchemes, v2beta1.SchemeBuilder.AddToScheme)
|
||||
}
|
||||
18
pkg/apis/notification/group.go
Normal file
18
pkg/apis/notification/group.go
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package auditing contains auditing API versions
|
||||
package notification
|
||||
161
pkg/apis/notification/v2beta1/config_types.go
Normal file
161
pkg/apis/notification/v2beta1/config_types.go
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
|
||||
|
||||
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 v2beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Configuration of conversation
|
||||
type DingTalkApplicationConfig struct {
|
||||
// The key of the application with which to send messages.
|
||||
AppKey *SecretKeySelector `json:"appkey,omitempty"`
|
||||
// The key in the secret to be used. Must be a valid secret key.
|
||||
AppSecret *SecretKeySelector `json:"appsecret,omitempty"`
|
||||
}
|
||||
|
||||
type DingTalkConfig struct {
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
// Only needed when send alerts to the conversation.
|
||||
Conversation *DingTalkApplicationConfig `json:"conversation,omitempty"`
|
||||
}
|
||||
|
||||
type ClientCertificate struct {
|
||||
// The client cert file for the targets.
|
||||
Cert *SecretKeySelector `json:"cert,omitempty"`
|
||||
// The client key file for the targets.
|
||||
Key *SecretKeySelector `json:"key,omitempty"`
|
||||
}
|
||||
|
||||
// TLSConfig configures the options for TLS connections.
|
||||
type TLSConfig struct {
|
||||
// RootCA defines the root certificate authorities
|
||||
// that clients use when verifying server certificates.
|
||||
RootCA *SecretKeySelector `json:"rootCA,omitempty"`
|
||||
// The certificate of the client.
|
||||
*ClientCertificate `json:"clientCertificate,omitempty"`
|
||||
// Used to verify the hostname for the targets.
|
||||
ServerName string `json:"serverName,omitempty"`
|
||||
// Disable target certificate validation.
|
||||
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
|
||||
}
|
||||
|
||||
// BasicAuth contains basic HTTP authentication credentials.
|
||||
type BasicAuth struct {
|
||||
Username string `json:"username"`
|
||||
Password *SecretKeySelector `json:"password,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPClientConfig configures an HTTP client.
|
||||
type HTTPClientConfig struct {
|
||||
// The HTTP basic authentication credentials for the targets.
|
||||
BasicAuth *BasicAuth `json:"basicAuth,omitempty"`
|
||||
// The bearer token for the targets.
|
||||
BearerToken *SecretKeySelector `json:"bearerToken,omitempty"`
|
||||
// HTTP proxy server to use to connect to the targets.
|
||||
ProxyURL string `json:"proxyUrl,omitempty"`
|
||||
// TLSConfig to use to connect to the targets.
|
||||
TLSConfig *TLSConfig `json:"tlsConfig,omitempty"`
|
||||
}
|
||||
|
||||
type HostPort struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
}
|
||||
|
||||
type EmailConfig struct {
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
// The sender address.
|
||||
From string `json:"from"`
|
||||
// The address of the SMTP server.
|
||||
SmartHost HostPort `json:"smartHost"`
|
||||
// The hostname to use when identifying to the SMTP server.
|
||||
Hello *string `json:"hello,omitempty"`
|
||||
// The username for CRAM-MD5, LOGIN and PLAIN authentications.
|
||||
AuthUsername *string `json:"authUsername,omitempty"`
|
||||
// The identity for PLAIN authentication.
|
||||
AuthIdentify *string `json:"authIdentify,omitempty"`
|
||||
// The secret contains the SMTP password for LOGIN and PLAIN authentications.
|
||||
AuthPassword *SecretKeySelector `json:"authPassword,omitempty"`
|
||||
// The secret contains the SMTP secret for CRAM-MD5 authentication.
|
||||
AuthSecret *SecretKeySelector `json:"authSecret,omitempty"`
|
||||
// The default SMTP TLS requirement.
|
||||
RequireTLS *bool `json:"requireTLS,omitempty"`
|
||||
TLS *TLSConfig `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
type SlackConfig struct {
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
// The token of user or bot.
|
||||
SlackTokenSecret *SecretKeySelector `json:"slackTokenSecret,omitempty"`
|
||||
}
|
||||
|
||||
type WebhookConfig struct {
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
}
|
||||
|
||||
type WechatConfig struct {
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
// The WeChat API URL.
|
||||
WechatApiUrl string `json:"wechatApiUrl,omitempty"`
|
||||
// The corp id for authentication.
|
||||
WechatApiCorpId string `json:"wechatApiCorpId"`
|
||||
// The id of the application which sending message.
|
||||
WechatApiAgentId string `json:"wechatApiAgentId"`
|
||||
// The API key to use when talking to the WeChat API.
|
||||
WechatApiSecret *SecretKeySelector `json:"wechatApiSecret"`
|
||||
}
|
||||
|
||||
//ConfigSpec defines the desired state of Config
|
||||
type ConfigSpec struct {
|
||||
DingTalk *DingTalkConfig `json:"dingtalk,omitempty"`
|
||||
Email *EmailConfig `json:"email,omitempty"`
|
||||
Slack *SlackConfig `json:"slack,omitempty"`
|
||||
Webhook *WebhookConfig `json:"webhook,omitempty"`
|
||||
Wechat *WechatConfig `json:"wechat,omitempty"`
|
||||
}
|
||||
|
||||
// ConfigStatus defines the observed state of Config
|
||||
type ConfigStatus struct {
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Cluster,shortName=nc,categories=notification-manager
|
||||
// +kubebuilder:subresource:status
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// DingTalkConfig is the Schema for the dingtalkconfigs API
|
||||
type Config struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ConfigSpec `json:"spec,omitempty"`
|
||||
Status ConfigStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ConfigList contains a list of Config
|
||||
type ConfigList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Config `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Config{}, &ConfigList{})
|
||||
}
|
||||
21
pkg/apis/notification/v2beta1/doc.go
Normal file
21
pkg/apis/notification/v2beta1/doc.go
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v2beta1 contains API Schema definitions for the notification v2beta1 API group
|
||||
// +groupName=notification.kubesphere.io
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
package v2beta1
|
||||
213
pkg/apis/notification/v2beta1/notificationmanager_types.go
Normal file
213
pkg/apis/notification/v2beta1/notificationmanager_types.go
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
|
||||
|
||||
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 v2beta1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SecretKeySelector selects a key of a Secret.
|
||||
type SecretKeySelector struct {
|
||||
// The namespace of the secret, default to the pod's namespace.
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"`
|
||||
// Name of the secret.
|
||||
// +optional
|
||||
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
|
||||
// The key of the secret to select from. Must be a valid secret key.
|
||||
Key string `json:"key" protobuf:"bytes,2,opt,name=key"`
|
||||
}
|
||||
|
||||
// NotificationManagerSpec defines the desired state of NotificationManager
|
||||
type NotificationManagerSpec struct {
|
||||
// Compute Resources required by container.
|
||||
Resources v1.ResourceRequirements `json:"resources,omitempty"`
|
||||
// Docker Image used to start Notification Manager container,
|
||||
// for example kubesphere/notification-manager:v0.1.0
|
||||
Image *string `json:"image,omitempty"`
|
||||
// Image pull policy. One of Always, Never, IfNotPresent.
|
||||
// Defaults to IfNotPresent if not specified
|
||||
ImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"`
|
||||
// Number of instances to deploy for Notification Manager deployment.
|
||||
Replicas *int32 `json:"replicas,omitempty"`
|
||||
// Define which Nodes the Pods will be scheduled to.
|
||||
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
|
||||
// Pod's scheduling constraints.
|
||||
Affinity *v1.Affinity `json:"affinity,omitempty"`
|
||||
// Pod's tolerations.
|
||||
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
|
||||
// ServiceAccountName is the name of the ServiceAccount to use to run Notification Manager Pods.
|
||||
// ServiceAccount 'default' in notification manager's namespace will be used if not specified.
|
||||
ServiceAccountName string `json:"serviceAccountName,omitempty"`
|
||||
// Port name used for the pods and service, defaults to webhook
|
||||
PortName string `json:"portName,omitempty"`
|
||||
// Default Email/Wechat/Slack/Webhook Config to be selected
|
||||
DefaultConfigSelector *metav1.LabelSelector `json:"defaultConfigSelector,omitempty"`
|
||||
// Receivers to send notifications to
|
||||
Receivers *ReceiversSpec `json:"receivers"`
|
||||
// The default namespace to which notification manager secrets belong.
|
||||
DefaultSecretNamespace string `json:"defaultSecretNamespace,omitempty"`
|
||||
// List of volumes that can be mounted by containers belonging to the pod.
|
||||
Volumes []v1.Volume `json:"volumes,omitempty"`
|
||||
// Pod volumes to mount into the container's filesystem.
|
||||
// Cannot be updated.
|
||||
VolumeMounts []v1.VolumeMount `json:"volumeMounts,omitempty"`
|
||||
// Arguments to the entrypoint.
|
||||
// The docker image's CMD is used if this is not provided.
|
||||
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
|
||||
// cannot be resolved, the reference in the input string will remain unchanged. The $(VAR_NAME) syntax
|
||||
// can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
|
||||
// regardless of whether the variable exists or not.
|
||||
// Cannot be updated.
|
||||
// +optional
|
||||
Args []string `json:"args,omitempty"`
|
||||
}
|
||||
|
||||
type ReceiversSpec struct {
|
||||
// Key used to identify tenant, default to be "namespace" if not specified
|
||||
TenantKey string `json:"tenantKey"`
|
||||
// Selector to find global notification receivers
|
||||
// which will be used when tenant receivers cannot be found.
|
||||
// Only matchLabels expression is allowed.
|
||||
GlobalReceiverSelector *metav1.LabelSelector `json:"globalReceiverSelector"`
|
||||
// Selector to find tenant notification receivers.
|
||||
// Only matchLabels expression is allowed.
|
||||
TenantReceiverSelector *metav1.LabelSelector `json:"tenantReceiverSelector"`
|
||||
// Various receiver options
|
||||
Options *Options `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
type GlobalOptions struct {
|
||||
// Template file path, must be a absolute path.
|
||||
TemplateFiles []string `json:"templateFile,omitempty"`
|
||||
// The name of the template to generate message.
|
||||
// If the receiver dose not setup template, it will use this.
|
||||
Template string `json:"template,omitempty"`
|
||||
// The name of the cluster in which the notification manager is deployed.
|
||||
Cluster string `json:"cluster,omitempty"`
|
||||
}
|
||||
|
||||
type EmailOptions struct {
|
||||
// Notification Sending Timeout
|
||||
NotificationTimeout *int32 `json:"notificationTimeout,omitempty"`
|
||||
// Type of sending email, bulk or single
|
||||
DeliveryType string `json:"deliveryType,omitempty"`
|
||||
// The maximum size of receivers in one email.
|
||||
MaxEmailReceivers int `json:"maxEmailReceivers,omitempty"`
|
||||
// The name of the template to generate email message.
|
||||
// If the global template is not set, it will use default.
|
||||
Template string `json:"template,omitempty"`
|
||||
// The name of the template to generate email subject
|
||||
SubjectTemplate string `json:"subjectTemplate,omitempty"`
|
||||
}
|
||||
|
||||
type WechatOptions struct {
|
||||
// Notification Sending Timeout
|
||||
NotificationTimeout *int32 `json:"notificationTimeout,omitempty"`
|
||||
// The name of the template to generate wechat message.
|
||||
Template string `json:"template,omitempty"`
|
||||
// The maximum message size that can be sent in a request.
|
||||
MessageMaxSize int `json:"messageMaxSize,omitempty"`
|
||||
// The time of token expired.
|
||||
TokenExpires time.Duration `json:"tokenExpires,omitempty"`
|
||||
}
|
||||
|
||||
type SlackOptions struct {
|
||||
// Notification Sending Timeout
|
||||
NotificationTimeout *int32 `json:"notificationTimeout,omitempty"`
|
||||
// The name of the template to generate slack message.
|
||||
// If the global template is not set, it will use default.
|
||||
Template string `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
type WebhookOptions struct {
|
||||
// Notification Sending Timeout
|
||||
NotificationTimeout *int32 `json:"notificationTimeout,omitempty"`
|
||||
// The name of the template to generate webhook message.
|
||||
// If the global template is not set, it will use default.
|
||||
Template string `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// The config of flow control.
|
||||
type Throttle struct {
|
||||
// The maximum calls in `Unit`.
|
||||
Threshold int `json:"threshold,omitempty"`
|
||||
Unit time.Duration `json:"unit,omitempty"`
|
||||
// The maximum tolerable waiting time when the calls trigger flow control, if the actual waiting time is more than this time, it will
|
||||
// return a error, else it will wait for the flow restriction lifted, and send the message.
|
||||
// Nil means do not wait, the maximum value is `Unit`.
|
||||
MaxWaitTime time.Duration `json:"maxWaitTime,omitempty"`
|
||||
}
|
||||
|
||||
type DingTalkOptions struct {
|
||||
// Notification Sending Timeout
|
||||
NotificationTimeout *int32 `json:"notificationTimeout,omitempty"`
|
||||
// The name of the template to generate DingTalk message.
|
||||
// If the global template is not set, it will use default.
|
||||
Template string `json:"template,omitempty"`
|
||||
// The time of token expired.
|
||||
TokenExpires time.Duration `json:"tokenExpires,omitempty"`
|
||||
// The maximum message size that can be sent to conversation in a request.
|
||||
ConversationMessageMaxSize int `json:"conversationMessageMaxSize,omitempty"`
|
||||
// The maximum message size that can be sent to chatbot in a request.
|
||||
ChatbotMessageMaxSize int `json:"chatbotMessageMaxSize,omitempty"`
|
||||
// The flow control fo chatbot.
|
||||
ChatBotThrottle *Throttle `json:"chatBotThrottle,omitempty"`
|
||||
// The flow control fo conversation.
|
||||
ConversationThrottle *Throttle `json:"conversationThrottle,omitempty"`
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
Global *GlobalOptions `json:"global,omitempty"`
|
||||
Email *EmailOptions `json:"email,omitempty"`
|
||||
Wechat *WechatOptions `json:"wechat,omitempty"`
|
||||
Slack *SlackOptions `json:"slack,omitempty"`
|
||||
Webhook *WebhookOptions `json:"webhook,omitempty"`
|
||||
DingTalk *DingTalkOptions `json:"dingtalk,omitempty"`
|
||||
}
|
||||
|
||||
// NotificationManagerStatus defines the observed state of NotificationManager
|
||||
type NotificationManagerStatus struct {
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Cluster,shortName=nm,categories=notification-manager
|
||||
// +kubebuilder:subresource:status
|
||||
|
||||
// NotificationManager is the Schema for the notificationmanagers API
|
||||
type NotificationManager struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec NotificationManagerSpec `json:"spec,omitempty"`
|
||||
Status NotificationManagerStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// NotificationManagerList contains a list of NotificationManager
|
||||
type NotificationManagerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []NotificationManager `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&NotificationManager{}, &NotificationManagerList{})
|
||||
}
|
||||
197
pkg/apis/notification/v2beta1/receiver_types.go
Normal file
197
pkg/apis/notification/v2beta1/receiver_types.go
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
|
||||
|
||||
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 v2beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Configuration of ChatBot
|
||||
type DingTalkChatBot struct {
|
||||
// The webhook of ChatBot which the message will send to.
|
||||
Webhook *SecretKeySelector `json:"webhook"`
|
||||
|
||||
// Custom keywords of ChatBot
|
||||
Keywords []string `json:"keywords,omitempty"`
|
||||
|
||||
// Secret of ChatBot, you can get it after enabled Additional Signature of ChatBot.
|
||||
Secret *SecretKeySelector `json:"secret,omitempty"`
|
||||
}
|
||||
|
||||
// Configuration of conversation
|
||||
type DingTalkConversation struct {
|
||||
ChatIDs []string `json:"chatids"`
|
||||
}
|
||||
|
||||
type DingTalkReceiver struct {
|
||||
// whether the receiver is enabled
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
// DingTalkConfig to be selected for this receiver
|
||||
DingTalkConfigSelector *metav1.LabelSelector `json:"dingtalkConfigSelector,omitempty"`
|
||||
// Selector to filter alerts.
|
||||
AlertSelector *metav1.LabelSelector `json:"alertSelector,omitempty"`
|
||||
// Be careful, a ChatBot only can send 20 message per minute.
|
||||
ChatBot *DingTalkChatBot `json:"chatbot,omitempty"`
|
||||
// The conversation which message will send to.
|
||||
Conversation *DingTalkConversation `json:"conversation,omitempty"`
|
||||
}
|
||||
|
||||
type EmailReceiver struct {
|
||||
// whether the receiver is enabled
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
// Receivers' email addresses
|
||||
To []string `json:"to"`
|
||||
// EmailConfig to be selected for this receiver
|
||||
EmailConfigSelector *metav1.LabelSelector `json:"emailConfigSelector,omitempty"`
|
||||
// Selector to filter alerts.
|
||||
AlertSelector *metav1.LabelSelector `json:"alertSelector,omitempty"`
|
||||
}
|
||||
|
||||
type SlackReceiver struct {
|
||||
// whether the receiver is enabled
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
// SlackConfig to be selected for this receiver
|
||||
SlackConfigSelector *metav1.LabelSelector `json:"slackConfigSelector,omitempty"`
|
||||
// Selector to filter alerts.
|
||||
AlertSelector *metav1.LabelSelector `json:"alertSelector,omitempty"`
|
||||
// The channel or user to send notifications to.
|
||||
Channels []string `json:"channels"`
|
||||
}
|
||||
|
||||
// ServiceReference holds a reference to Service.legacy.k8s.io
|
||||
type ServiceReference struct {
|
||||
// `namespace` is the namespace of the service.
|
||||
// Required
|
||||
Namespace string `json:"namespace"`
|
||||
|
||||
// `name` is the name of the service.
|
||||
// Required
|
||||
Name string `json:"name"`
|
||||
|
||||
// `path` is an optional URL path which will be sent in any request to
|
||||
// this service.
|
||||
// +optional
|
||||
Path *string `json:"path,omitempty"`
|
||||
|
||||
// If specified, the port on the service that hosting webhook.
|
||||
// Default to 443 for backward compatibility.
|
||||
// `port` should be a valid port number (1-65535, inclusive).
|
||||
// +optional
|
||||
Port *int32 `json:"port,omitempty"`
|
||||
|
||||
// Http scheme, default is http.
|
||||
// +optional
|
||||
Scheme *string `json:"scheme,omitempty"`
|
||||
}
|
||||
|
||||
type WebhookReceiver struct {
|
||||
// whether the receiver is enabled
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
// WebhookConfig to be selected for this receiver
|
||||
WebhookConfigSelector *metav1.LabelSelector `json:"webhookConfigSelector,omitempty"`
|
||||
// Selector to filter alerts.
|
||||
AlertSelector *metav1.LabelSelector `json:"alertSelector,omitempty"`
|
||||
// `url` gives the location of the webhook, in standard URL form
|
||||
// (`scheme://host:port/path`). Exactly one of `url` or `service`
|
||||
// must be specified.
|
||||
//
|
||||
// The `host` should not refer to a service running in the cluster; use
|
||||
// the `service` field instead. The host might be resolved via external
|
||||
// DNS in some api servers (e.g., `kube-apiserver` cannot resolve
|
||||
// in-cluster DNS as that would be a layering violation). `host` may
|
||||
// also be an IP address.
|
||||
//
|
||||
// Please note that using `localhost` or `127.0.0.1` as a `host` is
|
||||
// risky unless you take great care to run this webhook on all hosts
|
||||
// which run an apiserver which might need to make calls to this
|
||||
// webhook. Such installs are likely to be non-portable, i.e., not easy
|
||||
// to turn up in a new cluster.
|
||||
//
|
||||
// A path is optional, and if present may be any string permissible in
|
||||
// a URL. You may use the path to pass an arbitrary string to the
|
||||
// webhook, for example, a cluster identifier.
|
||||
//
|
||||
// Attempting to use a user or basic auth e.g. "user:password@" is not
|
||||
// allowed. Fragments ("#...") and query parameters ("?...") are not
|
||||
// allowed, either.
|
||||
//
|
||||
// +optional
|
||||
URL *string `json:"url,omitempty"`
|
||||
|
||||
// `service` is a reference to the service for this webhook. Either
|
||||
// `service` or `url` must be specified.
|
||||
//
|
||||
// If the webhook is running within the cluster, then you should use `service`.
|
||||
//
|
||||
// +optional
|
||||
Service *ServiceReference `json:"service,omitempty"`
|
||||
|
||||
HTTPConfig *HTTPClientConfig `json:"httpConfig,omitempty"`
|
||||
}
|
||||
|
||||
type WechatReceiver struct {
|
||||
// whether the receiver is enabled
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
// WechatConfig to be selected for this receiver
|
||||
WechatConfigSelector *metav1.LabelSelector `json:"wechatConfigSelector,omitempty"`
|
||||
// Selector to filter alerts.
|
||||
AlertSelector *metav1.LabelSelector `json:"alertSelector,omitempty"`
|
||||
// +optional
|
||||
ToUser []string `json:"toUser,omitempty"`
|
||||
ToParty []string `json:"toParty,omitempty"`
|
||||
ToTag []string `json:"toTag,omitempty"`
|
||||
}
|
||||
|
||||
//ReceiverSpec defines the desired state of Receiver
|
||||
type ReceiverSpec struct {
|
||||
DingTalk *DingTalkReceiver `json:"dingtalk,omitempty"`
|
||||
Email *EmailReceiver `json:"email,omitempty"`
|
||||
Slack *SlackReceiver `json:"slack,omitempty"`
|
||||
Webhook *WebhookReceiver `json:"webhook,omitempty"`
|
||||
Wechat *WechatReceiver `json:"wechat,omitempty"`
|
||||
}
|
||||
|
||||
// ReceiverStatus defines the observed state of Receiver
|
||||
type ReceiverStatus struct {
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:scope=Cluster,shortName=nr,categories=notification-manager
|
||||
// +kubebuilder:subresource:status
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// Receiver is the Schema for the receivers API
|
||||
type Receiver struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ReceiverSpec `json:"spec,omitempty"`
|
||||
Status ReceiverStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ReceiverList contains a list of Receiver
|
||||
type ReceiverList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Receiver `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Receiver{}, &ReceiverList{})
|
||||
}
|
||||
41
pkg/apis/notification/v2beta1/register.go
Normal file
41
pkg/apis/notification/v2beta1/register.go
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// NOTE: Boilerplate only. Ignore this file.
|
||||
|
||||
// Package v2beta1 contains API Schema definitions for the notification v2beta1 API group
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
// +groupName=notification.kubesphere.io
|
||||
package v2beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: "notification.kubesphere.io", Version: "v2beta1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
|
||||
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
27
pkg/apis/notification/v2beta1/types.go
Normal file
27
pkg/apis/notification/v2beta1/types.go
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2beta1
|
||||
|
||||
const (
|
||||
ResourceKindConfig = "Configs"
|
||||
ResourcesSingularConfig = "config"
|
||||
ResourcesPluralConfig = "configs"
|
||||
|
||||
ResourceKindReceiver = "Receiver"
|
||||
ResourcesSingularReceiver = "receiver"
|
||||
ResourcesPluralReceiver = "receivers"
|
||||
)
|
||||
54
pkg/apis/notification/v2beta1/v2beta1_suite_test.go
Normal file
54
pkg/apis/notification/v2beta1/v2beta1_suite_test.go
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2beta1
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
)
|
||||
|
||||
var cfg *rest.Config
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
t := &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crds")},
|
||||
}
|
||||
|
||||
err := SchemeBuilder.AddToScheme(scheme.Scheme)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if cfg, err = t.Start(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
code := m.Run()
|
||||
_ = t.Stop()
|
||||
os.Exit(code)
|
||||
}
|
||||
1224
pkg/apis/notification/v2beta1/zz_generated.deepcopy.go
generated
Normal file
1224
pkg/apis/notification/v2beta1/zz_generated.deepcopy.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
63
pkg/apis/types/v1beta1/federatednotificationconfig_types.go
Normal file
63
pkg/apis/types/v1beta1/federatednotificationconfig_types.go
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
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 (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
)
|
||||
|
||||
const (
|
||||
ResourcePluralFederatedNotificationConfig = "federatednotificationconfigs"
|
||||
ResourceSingularFederatedNotificationConfig = "federatednotificationconfig"
|
||||
FederatedNotificationConfigKind = "FederatedNotificationConfig"
|
||||
)
|
||||
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:openapi-gen=true
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
// +kubebuilder:subresource:status
|
||||
type FederatedNotificationConfig struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec FederatedNotificationConfigSpec `json:"spec"`
|
||||
|
||||
Status *GenericFederatedStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type FederatedNotificationConfigSpec struct {
|
||||
Template NotificationConfigTemplate `json:"template"`
|
||||
Placement GenericPlacementFields `json:"placement"`
|
||||
Overrides []GenericOverrideItem `json:"overrides,omitempty"`
|
||||
}
|
||||
|
||||
type NotificationConfigTemplate struct {
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec v2beta1.ConfigSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// FederatedNotificationConfigList contains a list of federatednotificationconfiglists
|
||||
type FederatedNotificationConfigList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []FederatedNotificationConfig `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
)
|
||||
|
||||
const (
|
||||
ResourcePluralFederatedNotificationReceiver = "federatednotificationreceivers"
|
||||
ResourceSingularFederatedNotificationReceiver = "federatednotificationreceiver"
|
||||
FederatedNotificationReceiverKind = "FederatedNotificationReceiver"
|
||||
)
|
||||
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:openapi-gen=true
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
// +kubebuilder:subresource:status
|
||||
type FederatedNotificationReceiver struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec FederatedNotificationReceiverSpec `json:"spec"`
|
||||
|
||||
Status *GenericFederatedStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type FederatedNotificationReceiverSpec struct {
|
||||
Template NotificationReceiverTemplate `json:"template"`
|
||||
Placement GenericPlacementFields `json:"placement"`
|
||||
Overrides []GenericOverrideItem `json:"overrides,omitempty"`
|
||||
}
|
||||
|
||||
type NotificationReceiverTemplate struct {
|
||||
// +kubebuilder:pruning:PreserveUnknownFields
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec v2beta1.ReceiverSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// FederatedNotificationConfigList contains a list of federatednotificationreceiverlists
|
||||
type FederatedNotificationReceiverList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []FederatedNotificationReceiver `json:"items"`
|
||||
}
|
||||
@@ -62,6 +62,10 @@ func init() {
|
||||
&FederatedLimitRangeList{},
|
||||
&FederatedNamespace{},
|
||||
&FederatedNamespaceList{},
|
||||
&FederatedNotificationConfig{},
|
||||
&FederatedNotificationConfigList{},
|
||||
&FederatedNotificationReceiver{},
|
||||
&FederatedNotificationReceiverList{},
|
||||
&FederatedPersistentVolumeClaim{},
|
||||
&FederatedPersistentVolumeClaimList{},
|
||||
&FederatedResourceQuota{},
|
||||
|
||||
282
pkg/apis/types/v1beta1/zz_generated.deepcopy.go
generated
282
pkg/apis/types/v1beta1/zz_generated.deepcopy.go
generated
@@ -636,6 +636,7 @@ func (in *FederatedGroupBinding) DeepCopyInto(out *FederatedGroupBinding) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedGroupBinding.
|
||||
@@ -756,6 +757,7 @@ func (in *FederatedGroupSpec) DeepCopyInto(out *FederatedGroupSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedGroupSpec.
|
||||
@@ -779,6 +781,7 @@ func (in *FederatedIngress) DeepCopyInto(out *FederatedIngress) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedIngress.
|
||||
@@ -811,6 +814,7 @@ func (in *FederatedIngressList) DeepCopyInto(out *FederatedIngressList) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedIngressList.
|
||||
@@ -843,6 +847,7 @@ func (in *FederatedIngressSpec) DeepCopyInto(out *FederatedIngressSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedIngressSpec.
|
||||
@@ -866,6 +871,7 @@ func (in *FederatedJob) DeepCopyInto(out *FederatedJob) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedJob.
|
||||
@@ -898,6 +904,7 @@ func (in *FederatedJobList) DeepCopyInto(out *FederatedJobList) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedJobList.
|
||||
@@ -930,6 +937,7 @@ func (in *FederatedJobSpec) DeepCopyInto(out *FederatedJobSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedJobSpec.
|
||||
@@ -953,6 +961,7 @@ func (in *FederatedLimitRange) DeepCopyInto(out *FederatedLimitRange) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedLimitRange.
|
||||
@@ -985,6 +994,7 @@ func (in *FederatedLimitRangeList) DeepCopyInto(out *FederatedLimitRangeList) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedLimitRangeList.
|
||||
@@ -1017,6 +1027,7 @@ func (in *FederatedLimitRangeSpec) DeepCopyInto(out *FederatedLimitRangeSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedLimitRangeSpec.
|
||||
@@ -1040,6 +1051,7 @@ func (in *FederatedNamespace) DeepCopyInto(out *FederatedNamespace) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedNamespace.
|
||||
@@ -1072,6 +1084,7 @@ func (in *FederatedNamespaceList) DeepCopyInto(out *FederatedNamespaceList) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedNamespaceList.
|
||||
@@ -1104,6 +1117,7 @@ func (in *FederatedNamespaceSpec) DeepCopyInto(out *FederatedNamespaceSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedNamespaceSpec.
|
||||
@@ -1116,6 +1130,186 @@ func (in *FederatedNamespaceSpec) DeepCopy() *FederatedNamespaceSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FederatedNotificationConfig) DeepCopyInto(out *FederatedNotificationConfig) {
|
||||
*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 FederatedNotificationConfig.
|
||||
func (in *FederatedNotificationConfig) DeepCopy() *FederatedNotificationConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FederatedNotificationConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *FederatedNotificationConfig) 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 *FederatedNotificationConfigList) DeepCopyInto(out *FederatedNotificationConfigList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]FederatedNotificationConfig, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedNotificationConfigList.
|
||||
func (in *FederatedNotificationConfigList) DeepCopy() *FederatedNotificationConfigList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FederatedNotificationConfigList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *FederatedNotificationConfigList) 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 *FederatedNotificationConfigSpec) DeepCopyInto(out *FederatedNotificationConfigSpec) {
|
||||
*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 FederatedNotificationConfigSpec.
|
||||
func (in *FederatedNotificationConfigSpec) DeepCopy() *FederatedNotificationConfigSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FederatedNotificationConfigSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FederatedNotificationReceiver) DeepCopyInto(out *FederatedNotificationReceiver) {
|
||||
*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 FederatedNotificationReceiver.
|
||||
func (in *FederatedNotificationReceiver) DeepCopy() *FederatedNotificationReceiver {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FederatedNotificationReceiver)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *FederatedNotificationReceiver) 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 *FederatedNotificationReceiverList) DeepCopyInto(out *FederatedNotificationReceiverList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]FederatedNotificationReceiver, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedNotificationReceiverList.
|
||||
func (in *FederatedNotificationReceiverList) DeepCopy() *FederatedNotificationReceiverList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FederatedNotificationReceiverList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *FederatedNotificationReceiverList) 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 *FederatedNotificationReceiverSpec) DeepCopyInto(out *FederatedNotificationReceiverSpec) {
|
||||
*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 FederatedNotificationReceiverSpec.
|
||||
func (in *FederatedNotificationReceiverSpec) DeepCopy() *FederatedNotificationReceiverSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FederatedNotificationReceiverSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FederatedPersistentVolumeClaim) DeepCopyInto(out *FederatedPersistentVolumeClaim) {
|
||||
*out = *in
|
||||
@@ -1127,6 +1321,7 @@ func (in *FederatedPersistentVolumeClaim) DeepCopyInto(out *FederatedPersistentV
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedPersistentVolumeClaim.
|
||||
@@ -1191,6 +1386,7 @@ func (in *FederatedPersistentVolumeClaimSpec) DeepCopyInto(out *FederatedPersist
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedPersistentVolumeClaimSpec.
|
||||
@@ -1214,6 +1410,7 @@ func (in *FederatedResourceQuota) DeepCopyInto(out *FederatedResourceQuota) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuota.
|
||||
@@ -1246,6 +1443,7 @@ func (in *FederatedResourceQuotaList) DeepCopyInto(out *FederatedResourceQuotaLi
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuotaList.
|
||||
@@ -1278,6 +1476,7 @@ func (in *FederatedResourceQuotaSpec) DeepCopyInto(out *FederatedResourceQuotaSp
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedResourceQuotaSpec.
|
||||
@@ -1301,6 +1500,7 @@ func (in *FederatedSecret) DeepCopyInto(out *FederatedSecret) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedSecret.
|
||||
@@ -1333,6 +1533,7 @@ func (in *FederatedSecretList) DeepCopyInto(out *FederatedSecretList) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedSecretList.
|
||||
@@ -1365,6 +1566,7 @@ func (in *FederatedSecretSpec) DeepCopyInto(out *FederatedSecretSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedSecretSpec.
|
||||
@@ -1388,6 +1590,7 @@ func (in *FederatedService) DeepCopyInto(out *FederatedService) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedService.
|
||||
@@ -1420,6 +1623,7 @@ func (in *FederatedServiceList) DeepCopyInto(out *FederatedServiceList) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedServiceList.
|
||||
@@ -1452,6 +1656,7 @@ func (in *FederatedServiceSpec) DeepCopyInto(out *FederatedServiceSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedServiceSpec.
|
||||
@@ -1475,6 +1680,7 @@ func (in *FederatedStatefulSet) DeepCopyInto(out *FederatedStatefulSet) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedStatefulSet.
|
||||
@@ -1507,6 +1713,7 @@ func (in *FederatedStatefulSetList) DeepCopyInto(out *FederatedStatefulSetList)
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedStatefulSetList.
|
||||
@@ -1539,6 +1746,7 @@ func (in *FederatedStatefulSetSpec) DeepCopyInto(out *FederatedStatefulSetSpec)
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedStatefulSetSpec.
|
||||
@@ -1562,6 +1770,7 @@ func (in *FederatedUser) DeepCopyInto(out *FederatedUser) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedUser.
|
||||
@@ -1594,6 +1803,7 @@ func (in *FederatedUserList) DeepCopyInto(out *FederatedUserList) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedUserList.
|
||||
@@ -1626,6 +1836,7 @@ func (in *FederatedUserSpec) DeepCopyInto(out *FederatedUserSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedUserSpec.
|
||||
@@ -1649,6 +1860,7 @@ func (in *FederatedWorkspace) DeepCopyInto(out *FederatedWorkspace) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspace.
|
||||
@@ -1681,6 +1893,7 @@ func (in *FederatedWorkspaceList) DeepCopyInto(out *FederatedWorkspaceList) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceList.
|
||||
@@ -1712,6 +1925,7 @@ func (in *FederatedWorkspaceRole) DeepCopyInto(out *FederatedWorkspaceRole) {
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceRole.
|
||||
@@ -1743,6 +1957,7 @@ func (in *FederatedWorkspaceRoleBinding) DeepCopyInto(out *FederatedWorkspaceRol
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceRoleBinding.
|
||||
@@ -1775,6 +1990,7 @@ func (in *FederatedWorkspaceRoleBindingList) DeepCopyInto(out *FederatedWorkspac
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceRoleBindingList.
|
||||
@@ -1807,6 +2023,7 @@ func (in *FederatedWorkspaceRoleBindingSpec) DeepCopyInto(out *FederatedWorkspac
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceRoleBindingSpec.
|
||||
@@ -1831,6 +2048,7 @@ func (in *FederatedWorkspaceRoleList) DeepCopyInto(out *FederatedWorkspaceRoleLi
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceRoleList.
|
||||
@@ -1863,6 +2081,7 @@ func (in *FederatedWorkspaceRoleSpec) DeepCopyInto(out *FederatedWorkspaceRoleSp
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceRoleSpec.
|
||||
@@ -1887,6 +2106,7 @@ func (in *FederatedWorkspaceSpec) DeepCopyInto(out *FederatedWorkspaceSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspaceSpec.
|
||||
@@ -1902,6 +2122,7 @@ func (in *FederatedWorkspaceSpec) DeepCopy() *FederatedWorkspaceSpec {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GenericClusterReference) DeepCopyInto(out *GenericClusterReference) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericClusterReference.
|
||||
@@ -1917,6 +2138,7 @@ func (in *GenericClusterReference) DeepCopy() *GenericClusterReference {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GenericClusterStatus) DeepCopyInto(out *GenericClusterStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericClusterStatus.
|
||||
@@ -1932,6 +2154,7 @@ func (in *GenericClusterStatus) DeepCopy() *GenericClusterStatus {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GenericCondition) DeepCopyInto(out *GenericCondition) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericCondition.
|
||||
@@ -1954,6 +2177,7 @@ func (in *GenericFederatedResource) DeepCopyInto(out *GenericFederatedResource)
|
||||
*out = new(GenericFederatedStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericFederatedResource.
|
||||
@@ -1985,6 +2209,7 @@ func (in *GenericFederatedStatus) DeepCopyInto(out *GenericFederatedStatus) {
|
||||
*out = make([]GenericClusterStatus, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericFederatedStatus.
|
||||
@@ -2007,6 +2232,7 @@ func (in *GenericOverride) DeepCopyInto(out *GenericOverride) {
|
||||
*out = new(GenericOverrideSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOverride.
|
||||
@@ -2029,6 +2255,7 @@ func (in *GenericOverrideItem) DeepCopyInto(out *GenericOverrideItem) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOverrideItem.
|
||||
@@ -2051,6 +2278,7 @@ func (in *GenericOverrideSpec) DeepCopyInto(out *GenericOverrideSpec) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOverrideSpec.
|
||||
@@ -2069,6 +2297,7 @@ func (in *GenericPlacement) DeepCopyInto(out *GenericPlacement) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericPlacement.
|
||||
@@ -2094,6 +2323,7 @@ func (in *GenericPlacementFields) DeepCopyInto(out *GenericPlacementFields) {
|
||||
*out = new(metav1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericPlacementFields.
|
||||
@@ -2110,6 +2340,7 @@ func (in *GenericPlacementFields) DeepCopy() *GenericPlacementFields {
|
||||
func (in *GenericPlacementSpec) DeepCopyInto(out *GenericPlacementSpec) {
|
||||
*out = *in
|
||||
in.Placement.DeepCopyInto(&out.Placement)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericPlacementSpec.
|
||||
@@ -2132,6 +2363,7 @@ func (in *GroupBindingTemplate) DeepCopyInto(out *GroupBindingTemplate) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupBindingTemplate.
|
||||
@@ -2149,6 +2381,7 @@ func (in *GroupTemplate) DeepCopyInto(out *GroupTemplate) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupTemplate.
|
||||
@@ -2165,6 +2398,7 @@ func (in *GroupTemplate) DeepCopy() *GroupTemplate {
|
||||
func (in *IngressTemplate) DeepCopyInto(out *IngressTemplate) {
|
||||
*out = *in
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressTemplate.
|
||||
@@ -2181,6 +2415,7 @@ func (in *IngressTemplate) DeepCopy() *IngressTemplate {
|
||||
func (in *JobTemplate) DeepCopyInto(out *JobTemplate) {
|
||||
*out = *in
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobTemplate.
|
||||
@@ -2197,6 +2432,7 @@ func (in *JobTemplate) DeepCopy() *JobTemplate {
|
||||
func (in *LimitRangeTemplate) DeepCopyInto(out *LimitRangeTemplate) {
|
||||
*out = *in
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LimitRangeTemplate.
|
||||
@@ -2213,6 +2449,7 @@ func (in *LimitRangeTemplate) DeepCopy() *LimitRangeTemplate {
|
||||
func (in *NamespaceTemplate) DeepCopyInto(out *NamespaceTemplate) {
|
||||
*out = *in
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceTemplate.
|
||||
@@ -2225,12 +2462,49 @@ func (in *NamespaceTemplate) DeepCopy() *NamespaceTemplate {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NotificationConfigTemplate) DeepCopyInto(out *NotificationConfigTemplate) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NotificationConfigTemplate.
|
||||
func (in *NotificationConfigTemplate) DeepCopy() *NotificationConfigTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NotificationConfigTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NotificationReceiverTemplate) DeepCopyInto(out *NotificationReceiverTemplate) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NotificationReceiverTemplate.
|
||||
func (in *NotificationReceiverTemplate) DeepCopy() *NotificationReceiverTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NotificationReceiverTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PersistentVolumeClaimTemplate) DeepCopyInto(out *PersistentVolumeClaimTemplate) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PersistentVolumeClaimTemplate.
|
||||
@@ -2247,6 +2521,7 @@ func (in *PersistentVolumeClaimTemplate) DeepCopy() *PersistentVolumeClaimTempla
|
||||
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.
|
||||
@@ -2284,6 +2559,7 @@ func (in *SecretTemplate) DeepCopyInto(out *SecretTemplate) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretTemplate.
|
||||
@@ -2302,6 +2578,7 @@ func (in *ServiceTemplate) DeepCopyInto(out *ServiceTemplate) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceTemplate.
|
||||
@@ -2320,6 +2597,7 @@ func (in *StatefulSetTemplate) DeepCopyInto(out *StatefulSetTemplate) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetTemplate.
|
||||
@@ -2336,6 +2614,7 @@ func (in *StatefulSetTemplate) DeepCopy() *StatefulSetTemplate {
|
||||
func (in *UserTemplate) DeepCopyInto(out *UserTemplate) {
|
||||
*out = *in
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserTemplate.
|
||||
@@ -2358,6 +2637,7 @@ func (in *WorkspaceRoleBindingTemplate) DeepCopyInto(out *WorkspaceRoleBindingTe
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.RoleRef = in.RoleRef
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceRoleBindingTemplate.
|
||||
@@ -2381,6 +2661,7 @@ func (in *WorkspaceRoleTemplate) DeepCopyInto(out *WorkspaceRoleTemplate) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceRoleTemplate.
|
||||
@@ -2398,6 +2679,7 @@ func (in *WorkspaceTemplate) DeepCopyInto(out *WorkspaceTemplate) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceTemplate.
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
"net/http"
|
||||
rt "runtime"
|
||||
"time"
|
||||
@@ -37,6 +38,7 @@ import (
|
||||
"k8s.io/klog"
|
||||
clusterv1alpha1 "kubesphere.io/kubesphere/pkg/apis/cluster/v1alpha1"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
notificationv2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
typesv1beta1 "kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
|
||||
audit "kubesphere.io/kubesphere/pkg/apiserver/auditing"
|
||||
@@ -68,6 +70,7 @@ import (
|
||||
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
|
||||
networkv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/network/v1alpha2"
|
||||
notificationv1 "kubesphere.io/kubesphere/pkg/kapis/notification/v1"
|
||||
notificationkapisv2beta1 "kubesphere.io/kubesphere/pkg/kapis/notification/v2beta1"
|
||||
"kubesphere.io/kubesphere/pkg/kapis/oauth"
|
||||
openpitrixv1 "kubesphere.io/kubesphere/pkg/kapis/openpitrix/v1"
|
||||
operationsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/operations/v1alpha2"
|
||||
@@ -270,6 +273,8 @@ func (s *APIServer) installKubeSphereAPIs() {
|
||||
s.KubernetesClient.Prometheus(), s.AlertingClient, s.Config.AlertingOptions))
|
||||
urlruntime.Must(version.AddToContainer(s.container, s.KubernetesClient.Discovery()))
|
||||
urlruntime.Must(kubeedgev1alpha1.AddToContainer(s.container, s.Config.KubeEdgeOptions.Endpoint))
|
||||
urlruntime.Must(notificationkapisv2beta1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.Kubernetes(),
|
||||
s.KubernetesClient.KubeSphere()))
|
||||
}
|
||||
|
||||
func (s *APIServer) Run(stopCh <-chan struct{}) (err error) {
|
||||
@@ -310,6 +315,8 @@ func (s *APIServer) buildHandlerChain(stopCh <-chan struct{}) {
|
||||
tenantv1alpha2.Resource(clusterv1alpha1.ResourcesPluralCluster),
|
||||
clusterv1alpha1.Resource(clusterv1alpha1.ResourcesPluralCluster),
|
||||
resourcev1alpha3.Resource(clusterv1alpha1.ResourcesPluralCluster),
|
||||
notificationv2beta1.Resource(v2beta1.ResourcesPluralConfig),
|
||||
notificationv2beta1.Resource(v2beta1.ResourcesPluralReceiver),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -443,6 +450,8 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error {
|
||||
{Group: "cluster.kubesphere.io", Version: "v1alpha1", Resource: "clusters"},
|
||||
{Group: "devops.kubesphere.io", Version: "v1alpha3", Resource: "devopsprojects"},
|
||||
{Group: "network.kubesphere.io", Version: "v1alpha1", Resource: "ippools"},
|
||||
{Group: "notification.kubesphere.io", Version: "v2beta1", Resource: v2beta1.ResourcesPluralConfig},
|
||||
{Group: "notification.kubesphere.io", Version: "v2beta1", Resource: v2beta1.ResourcesPluralReceiver},
|
||||
}
|
||||
|
||||
devopsGVRs := []schema.GroupVersionResource{
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/devops/v1alpha3"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/iam/v1alpha2"
|
||||
networkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1"
|
||||
notificationv2beta1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/notification/v2beta1"
|
||||
quotav1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/quota/v1alpha2"
|
||||
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2"
|
||||
storagev1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/storage/v1alpha1"
|
||||
@@ -48,6 +49,7 @@ type Interface interface {
|
||||
DevopsV1alpha3() devopsv1alpha3.DevopsV1alpha3Interface
|
||||
IamV1alpha2() iamv1alpha2.IamV1alpha2Interface
|
||||
NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface
|
||||
NotificationV2beta1() notificationv2beta1.NotificationV2beta1Interface
|
||||
QuotaV1alpha2() quotav1alpha2.QuotaV1alpha2Interface
|
||||
ServicemeshV1alpha2() servicemeshv1alpha2.ServicemeshV1alpha2Interface
|
||||
StorageV1alpha1() storagev1alpha1.StorageV1alpha1Interface
|
||||
@@ -67,6 +69,7 @@ type Clientset struct {
|
||||
devopsV1alpha3 *devopsv1alpha3.DevopsV1alpha3Client
|
||||
iamV1alpha2 *iamv1alpha2.IamV1alpha2Client
|
||||
networkV1alpha1 *networkv1alpha1.NetworkV1alpha1Client
|
||||
notificationV2beta1 *notificationv2beta1.NotificationV2beta1Client
|
||||
quotaV1alpha2 *quotav1alpha2.QuotaV1alpha2Client
|
||||
servicemeshV1alpha2 *servicemeshv1alpha2.ServicemeshV1alpha2Client
|
||||
storageV1alpha1 *storagev1alpha1.StorageV1alpha1Client
|
||||
@@ -110,6 +113,11 @@ func (c *Clientset) NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface {
|
||||
return c.networkV1alpha1
|
||||
}
|
||||
|
||||
// NotificationV2beta1 retrieves the NotificationV2beta1Client
|
||||
func (c *Clientset) NotificationV2beta1() notificationv2beta1.NotificationV2beta1Interface {
|
||||
return c.notificationV2beta1
|
||||
}
|
||||
|
||||
// QuotaV1alpha2 retrieves the QuotaV1alpha2Client
|
||||
func (c *Clientset) QuotaV1alpha2() quotav1alpha2.QuotaV1alpha2Interface {
|
||||
return c.quotaV1alpha2
|
||||
@@ -189,6 +197,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.notificationV2beta1, err = notificationv2beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.quotaV1alpha2, err = quotav1alpha2.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -232,6 +244,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
cs.devopsV1alpha3 = devopsv1alpha3.NewForConfigOrDie(c)
|
||||
cs.iamV1alpha2 = iamv1alpha2.NewForConfigOrDie(c)
|
||||
cs.networkV1alpha1 = networkv1alpha1.NewForConfigOrDie(c)
|
||||
cs.notificationV2beta1 = notificationv2beta1.NewForConfigOrDie(c)
|
||||
cs.quotaV1alpha2 = quotav1alpha2.NewForConfigOrDie(c)
|
||||
cs.servicemeshV1alpha2 = servicemeshv1alpha2.NewForConfigOrDie(c)
|
||||
cs.storageV1alpha1 = storagev1alpha1.NewForConfigOrDie(c)
|
||||
@@ -253,6 +266,7 @@ func New(c rest.Interface) *Clientset {
|
||||
cs.devopsV1alpha3 = devopsv1alpha3.New(c)
|
||||
cs.iamV1alpha2 = iamv1alpha2.New(c)
|
||||
cs.networkV1alpha1 = networkv1alpha1.New(c)
|
||||
cs.notificationV2beta1 = notificationv2beta1.New(c)
|
||||
cs.quotaV1alpha2 = quotav1alpha2.New(c)
|
||||
cs.servicemeshV1alpha2 = servicemeshv1alpha2.New(c)
|
||||
cs.storageV1alpha1 = storagev1alpha1.New(c)
|
||||
|
||||
@@ -39,6 +39,8 @@ import (
|
||||
fakeiamv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/iam/v1alpha2/fake"
|
||||
networkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1"
|
||||
fakenetworkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1/fake"
|
||||
notificationv2beta1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/notification/v2beta1"
|
||||
fakenotificationv2beta1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/notification/v2beta1/fake"
|
||||
quotav1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/quota/v1alpha2"
|
||||
fakequotav1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/quota/v1alpha2/fake"
|
||||
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2"
|
||||
@@ -135,6 +137,11 @@ func (c *Clientset) NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface {
|
||||
return &fakenetworkv1alpha1.FakeNetworkV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// NotificationV2beta1 retrieves the NotificationV2beta1Client
|
||||
func (c *Clientset) NotificationV2beta1() notificationv2beta1.NotificationV2beta1Interface {
|
||||
return &fakenotificationv2beta1.FakeNotificationV2beta1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// QuotaV1alpha2 retrieves the QuotaV1alpha2Client
|
||||
func (c *Clientset) QuotaV1alpha2() quotav1alpha2.QuotaV1alpha2Interface {
|
||||
return &fakequotav1alpha2.FakeQuotaV1alpha2{Fake: &c.Fake}
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
|
||||
notificationv2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
quotav1alpha2 "kubesphere.io/kubesphere/pkg/apis/quota/v1alpha2"
|
||||
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
|
||||
storagev1alpha1 "kubesphere.io/kubesphere/pkg/apis/storage/v1alpha1"
|
||||
@@ -50,6 +51,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
devopsv1alpha3.AddToScheme,
|
||||
iamv1alpha2.AddToScheme,
|
||||
networkv1alpha1.AddToScheme,
|
||||
notificationv2beta1.AddToScheme,
|
||||
quotav1alpha2.AddToScheme,
|
||||
servicemeshv1alpha2.AddToScheme,
|
||||
storagev1alpha1.AddToScheme,
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
|
||||
notificationv2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
quotav1alpha2 "kubesphere.io/kubesphere/pkg/apis/quota/v1alpha2"
|
||||
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
|
||||
storagev1alpha1 "kubesphere.io/kubesphere/pkg/apis/storage/v1alpha1"
|
||||
@@ -50,6 +51,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
devopsv1alpha3.AddToScheme,
|
||||
iamv1alpha2.AddToScheme,
|
||||
networkv1alpha1.AddToScheme,
|
||||
notificationv2beta1.AddToScheme,
|
||||
quotav1alpha2.AddToScheme,
|
||||
servicemeshv1alpha2.AddToScheme,
|
||||
storagev1alpha1.AddToScheme,
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
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"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// ConfigsGetter has a method to return a ConfigInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ConfigsGetter interface {
|
||||
Configs() ConfigInterface
|
||||
}
|
||||
|
||||
// ConfigInterface has methods to work with Config resources.
|
||||
type ConfigInterface interface {
|
||||
Create(ctx context.Context, config *v2beta1.Config, opts v1.CreateOptions) (*v2beta1.Config, error)
|
||||
Update(ctx context.Context, config *v2beta1.Config, opts v1.UpdateOptions) (*v2beta1.Config, error)
|
||||
UpdateStatus(ctx context.Context, config *v2beta1.Config, opts v1.UpdateOptions) (*v2beta1.Config, 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) (*v2beta1.Config, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v2beta1.ConfigList, 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 *v2beta1.Config, err error)
|
||||
ConfigExpansion
|
||||
}
|
||||
|
||||
// configs implements ConfigInterface
|
||||
type configs struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newConfigs returns a Configs
|
||||
func newConfigs(c *NotificationV2beta1Client) *configs {
|
||||
return &configs{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the config, and returns the corresponding config object, and an error if there is any.
|
||||
func (c *configs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2beta1.Config, err error) {
|
||||
result = &v2beta1.Config{}
|
||||
err = c.client.Get().
|
||||
Resource("configs").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Configs that match those selectors.
|
||||
func (c *configs) List(ctx context.Context, opts v1.ListOptions) (result *v2beta1.ConfigList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v2beta1.ConfigList{}
|
||||
err = c.client.Get().
|
||||
Resource("configs").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested configs.
|
||||
func (c *configs) 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().
|
||||
Resource("configs").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a config and creates it. Returns the server's representation of the config, and an error, if there is any.
|
||||
func (c *configs) Create(ctx context.Context, config *v2beta1.Config, opts v1.CreateOptions) (result *v2beta1.Config, err error) {
|
||||
result = &v2beta1.Config{}
|
||||
err = c.client.Post().
|
||||
Resource("configs").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(config).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a config and updates it. Returns the server's representation of the config, and an error, if there is any.
|
||||
func (c *configs) Update(ctx context.Context, config *v2beta1.Config, opts v1.UpdateOptions) (result *v2beta1.Config, err error) {
|
||||
result = &v2beta1.Config{}
|
||||
err = c.client.Put().
|
||||
Resource("configs").
|
||||
Name(config.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(config).
|
||||
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 *configs) UpdateStatus(ctx context.Context, config *v2beta1.Config, opts v1.UpdateOptions) (result *v2beta1.Config, err error) {
|
||||
result = &v2beta1.Config{}
|
||||
err = c.client.Put().
|
||||
Resource("configs").
|
||||
Name(config.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(config).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the config and deletes it. Returns an error if one occurs.
|
||||
func (c *configs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("configs").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *configs) 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().
|
||||
Resource("configs").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched config.
|
||||
func (c *configs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2beta1.Config, err error) {
|
||||
result = &v2beta1.Config{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("configs").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v2beta1
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
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 has the automatically generated clients.
|
||||
package fake
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
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"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
)
|
||||
|
||||
// FakeConfigs implements ConfigInterface
|
||||
type FakeConfigs struct {
|
||||
Fake *FakeNotificationV2beta1
|
||||
}
|
||||
|
||||
var configsResource = schema.GroupVersionResource{Group: "notification.kubesphere.io", Version: "v2beta1", Resource: "configs"}
|
||||
|
||||
var configsKind = schema.GroupVersionKind{Group: "notification.kubesphere.io", Version: "v2beta1", Kind: "Config"}
|
||||
|
||||
// Get takes name of the config, and returns the corresponding config object, and an error if there is any.
|
||||
func (c *FakeConfigs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2beta1.Config, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(configsResource, name), &v2beta1.Config{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Config), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Configs that match those selectors.
|
||||
func (c *FakeConfigs) List(ctx context.Context, opts v1.ListOptions) (result *v2beta1.ConfigList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(configsResource, configsKind, opts), &v2beta1.ConfigList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v2beta1.ConfigList{ListMeta: obj.(*v2beta1.ConfigList).ListMeta}
|
||||
for _, item := range obj.(*v2beta1.ConfigList).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 configs.
|
||||
func (c *FakeConfigs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(configsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a config and creates it. Returns the server's representation of the config, and an error, if there is any.
|
||||
func (c *FakeConfigs) Create(ctx context.Context, config *v2beta1.Config, opts v1.CreateOptions) (result *v2beta1.Config, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(configsResource, config), &v2beta1.Config{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Config), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a config and updates it. Returns the server's representation of the config, and an error, if there is any.
|
||||
func (c *FakeConfigs) Update(ctx context.Context, config *v2beta1.Config, opts v1.UpdateOptions) (result *v2beta1.Config, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(configsResource, config), &v2beta1.Config{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Config), 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 *FakeConfigs) UpdateStatus(ctx context.Context, config *v2beta1.Config, opts v1.UpdateOptions) (*v2beta1.Config, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(configsResource, "status", config), &v2beta1.Config{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Config), err
|
||||
}
|
||||
|
||||
// Delete takes name of the config and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeConfigs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(configsResource, name), &v2beta1.Config{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeConfigs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(configsResource, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v2beta1.ConfigList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched config.
|
||||
func (c *FakeConfigs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2beta1.Config, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(configsResource, name, pt, data, subresources...), &v2beta1.Config{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Config), err
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
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 (
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/notification/v2beta1"
|
||||
)
|
||||
|
||||
type FakeNotificationV2beta1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeNotificationV2beta1) Configs() v2beta1.ConfigInterface {
|
||||
return &FakeConfigs{c}
|
||||
}
|
||||
|
||||
func (c *FakeNotificationV2beta1) Receivers() v2beta1.ReceiverInterface {
|
||||
return &FakeReceivers{c}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeNotificationV2beta1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
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"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
)
|
||||
|
||||
// FakeReceivers implements ReceiverInterface
|
||||
type FakeReceivers struct {
|
||||
Fake *FakeNotificationV2beta1
|
||||
}
|
||||
|
||||
var receiversResource = schema.GroupVersionResource{Group: "notification.kubesphere.io", Version: "v2beta1", Resource: "receivers"}
|
||||
|
||||
var receiversKind = schema.GroupVersionKind{Group: "notification.kubesphere.io", Version: "v2beta1", Kind: "Receiver"}
|
||||
|
||||
// Get takes name of the receiver, and returns the corresponding receiver object, and an error if there is any.
|
||||
func (c *FakeReceivers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2beta1.Receiver, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(receiversResource, name), &v2beta1.Receiver{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Receiver), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Receivers that match those selectors.
|
||||
func (c *FakeReceivers) List(ctx context.Context, opts v1.ListOptions) (result *v2beta1.ReceiverList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(receiversResource, receiversKind, opts), &v2beta1.ReceiverList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v2beta1.ReceiverList{ListMeta: obj.(*v2beta1.ReceiverList).ListMeta}
|
||||
for _, item := range obj.(*v2beta1.ReceiverList).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 receivers.
|
||||
func (c *FakeReceivers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(receiversResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a receiver and creates it. Returns the server's representation of the receiver, and an error, if there is any.
|
||||
func (c *FakeReceivers) Create(ctx context.Context, receiver *v2beta1.Receiver, opts v1.CreateOptions) (result *v2beta1.Receiver, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(receiversResource, receiver), &v2beta1.Receiver{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Receiver), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a receiver and updates it. Returns the server's representation of the receiver, and an error, if there is any.
|
||||
func (c *FakeReceivers) Update(ctx context.Context, receiver *v2beta1.Receiver, opts v1.UpdateOptions) (result *v2beta1.Receiver, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(receiversResource, receiver), &v2beta1.Receiver{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Receiver), 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 *FakeReceivers) UpdateStatus(ctx context.Context, receiver *v2beta1.Receiver, opts v1.UpdateOptions) (*v2beta1.Receiver, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(receiversResource, "status", receiver), &v2beta1.Receiver{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Receiver), err
|
||||
}
|
||||
|
||||
// Delete takes name of the receiver and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeReceivers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(receiversResource, name), &v2beta1.Receiver{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeReceivers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(receiversResource, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v2beta1.ReceiverList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched receiver.
|
||||
func (c *FakeReceivers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2beta1.Receiver, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(receiversResource, name, pt, data, subresources...), &v2beta1.Receiver{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v2beta1.Receiver), err
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
type ConfigExpansion interface{}
|
||||
|
||||
type ReceiverExpansion interface{}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
import (
|
||||
rest "k8s.io/client-go/rest"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
type NotificationV2beta1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
ConfigsGetter
|
||||
ReceiversGetter
|
||||
}
|
||||
|
||||
// NotificationV2beta1Client is used to interact with features provided by the notification.kubesphere.io group.
|
||||
type NotificationV2beta1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *NotificationV2beta1Client) Configs() ConfigInterface {
|
||||
return newConfigs(c)
|
||||
}
|
||||
|
||||
func (c *NotificationV2beta1Client) Receivers() ReceiverInterface {
|
||||
return newReceivers(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new NotificationV2beta1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*NotificationV2beta1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &NotificationV2beta1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new NotificationV2beta1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *NotificationV2beta1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new NotificationV2beta1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *NotificationV2beta1Client {
|
||||
return &NotificationV2beta1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v2beta1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *NotificationV2beta1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
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"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// ReceiversGetter has a method to return a ReceiverInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ReceiversGetter interface {
|
||||
Receivers() ReceiverInterface
|
||||
}
|
||||
|
||||
// ReceiverInterface has methods to work with Receiver resources.
|
||||
type ReceiverInterface interface {
|
||||
Create(ctx context.Context, receiver *v2beta1.Receiver, opts v1.CreateOptions) (*v2beta1.Receiver, error)
|
||||
Update(ctx context.Context, receiver *v2beta1.Receiver, opts v1.UpdateOptions) (*v2beta1.Receiver, error)
|
||||
UpdateStatus(ctx context.Context, receiver *v2beta1.Receiver, opts v1.UpdateOptions) (*v2beta1.Receiver, 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) (*v2beta1.Receiver, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v2beta1.ReceiverList, 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 *v2beta1.Receiver, err error)
|
||||
ReceiverExpansion
|
||||
}
|
||||
|
||||
// receivers implements ReceiverInterface
|
||||
type receivers struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newReceivers returns a Receivers
|
||||
func newReceivers(c *NotificationV2beta1Client) *receivers {
|
||||
return &receivers{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the receiver, and returns the corresponding receiver object, and an error if there is any.
|
||||
func (c *receivers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2beta1.Receiver, err error) {
|
||||
result = &v2beta1.Receiver{}
|
||||
err = c.client.Get().
|
||||
Resource("receivers").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Receivers that match those selectors.
|
||||
func (c *receivers) List(ctx context.Context, opts v1.ListOptions) (result *v2beta1.ReceiverList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v2beta1.ReceiverList{}
|
||||
err = c.client.Get().
|
||||
Resource("receivers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested receivers.
|
||||
func (c *receivers) 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().
|
||||
Resource("receivers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a receiver and creates it. Returns the server's representation of the receiver, and an error, if there is any.
|
||||
func (c *receivers) Create(ctx context.Context, receiver *v2beta1.Receiver, opts v1.CreateOptions) (result *v2beta1.Receiver, err error) {
|
||||
result = &v2beta1.Receiver{}
|
||||
err = c.client.Post().
|
||||
Resource("receivers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(receiver).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a receiver and updates it. Returns the server's representation of the receiver, and an error, if there is any.
|
||||
func (c *receivers) Update(ctx context.Context, receiver *v2beta1.Receiver, opts v1.UpdateOptions) (result *v2beta1.Receiver, err error) {
|
||||
result = &v2beta1.Receiver{}
|
||||
err = c.client.Put().
|
||||
Resource("receivers").
|
||||
Name(receiver.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(receiver).
|
||||
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 *receivers) UpdateStatus(ctx context.Context, receiver *v2beta1.Receiver, opts v1.UpdateOptions) (result *v2beta1.Receiver, err error) {
|
||||
result = &v2beta1.Receiver{}
|
||||
err = c.client.Put().
|
||||
Resource("receivers").
|
||||
Name(receiver.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(receiver).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the receiver and deletes it. Returns an error if one occurs.
|
||||
func (c *receivers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("receivers").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *receivers) 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().
|
||||
Resource("receivers").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched receiver.
|
||||
func (c *receivers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2beta1.Receiver, err error) {
|
||||
result = &v2beta1.Receiver{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("receivers").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
iam "kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam"
|
||||
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
|
||||
network "kubesphere.io/kubesphere/pkg/client/informers/externalversions/network"
|
||||
notification "kubesphere.io/kubesphere/pkg/client/informers/externalversions/notification"
|
||||
quota "kubesphere.io/kubesphere/pkg/client/informers/externalversions/quota"
|
||||
servicemesh "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh"
|
||||
storage "kubesphere.io/kubesphere/pkg/client/informers/externalversions/storage"
|
||||
@@ -188,6 +189,7 @@ type SharedInformerFactory interface {
|
||||
Devops() devops.Interface
|
||||
Iam() iam.Interface
|
||||
Network() network.Interface
|
||||
Notification() notification.Interface
|
||||
Quota() quota.Interface
|
||||
Servicemesh() servicemesh.Interface
|
||||
Storage() storage.Interface
|
||||
@@ -219,6 +221,10 @@ func (f *sharedInformerFactory) Network() network.Interface {
|
||||
return network.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Notification() notification.Interface {
|
||||
return notification.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Quota() quota.Interface {
|
||||
return quota.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
v1alpha3 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
quotav1alpha2 "kubesphere.io/kubesphere/pkg/apis/quota/v1alpha2"
|
||||
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
|
||||
storagev1alpha1 "kubesphere.io/kubesphere/pkg/apis/storage/v1alpha1"
|
||||
@@ -132,6 +133,12 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
case networkv1alpha1.SchemeGroupVersion.WithResource("namespacenetworkpolicies"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Network().V1alpha1().NamespaceNetworkPolicies().Informer()}, nil
|
||||
|
||||
// Group=notification.kubesphere.io, Version=v2beta1
|
||||
case v2beta1.SchemeGroupVersion.WithResource("configs"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Notification().V2beta1().Configs().Informer()}, nil
|
||||
case v2beta1.SchemeGroupVersion.WithResource("receivers"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Notification().V2beta1().Receivers().Informer()}, nil
|
||||
|
||||
// Group=quota.kubesphere.io, Version=v1alpha2
|
||||
case quotav1alpha2.SchemeGroupVersion.WithResource("resourcequotas"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Quota().V1alpha2().ResourceQuotas().Informer()}, nil
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 notification
|
||||
|
||||
import (
|
||||
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/client/informers/externalversions/notification/v2beta1"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V2beta1 provides access to shared informers for resources in V2beta1.
|
||||
V2beta1() v2beta1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V2beta1 returns a new v2beta1.Interface.
|
||||
func (g *group) V2beta1() v2beta1.Interface {
|
||||
return v2beta1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
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"
|
||||
notificationv2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/client/listers/notification/v2beta1"
|
||||
)
|
||||
|
||||
// ConfigInformer provides access to a shared informer and lister for
|
||||
// Configs.
|
||||
type ConfigInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v2beta1.ConfigLister
|
||||
}
|
||||
|
||||
type configInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewConfigInformer constructs a new informer for Config 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 NewConfigInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredConfigInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredConfigInformer constructs a new informer for Config 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 NewFilteredConfigInformer(client versioned.Interface, 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.NotificationV2beta1().Configs().List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.NotificationV2beta1().Configs().Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
¬ificationv2beta1.Config{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *configInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredConfigInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *configInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(¬ificationv2beta1.Config{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *configInformer) Lister() v2beta1.ConfigLister {
|
||||
return v2beta1.NewConfigLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
import (
|
||||
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// Configs returns a ConfigInformer.
|
||||
Configs() ConfigInformer
|
||||
// Receivers returns a ReceiverInformer.
|
||||
Receivers() ReceiverInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// Configs returns a ConfigInformer.
|
||||
func (v *version) Configs() ConfigInformer {
|
||||
return &configInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// Receivers returns a ReceiverInformer.
|
||||
func (v *version) Receivers() ReceiverInformer {
|
||||
return &receiverInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
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"
|
||||
notificationv2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/client/listers/notification/v2beta1"
|
||||
)
|
||||
|
||||
// ReceiverInformer provides access to a shared informer and lister for
|
||||
// Receivers.
|
||||
type ReceiverInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v2beta1.ReceiverLister
|
||||
}
|
||||
|
||||
type receiverInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewReceiverInformer constructs a new informer for Receiver 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 NewReceiverInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredReceiverInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredReceiverInformer constructs a new informer for Receiver 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 NewFilteredReceiverInformer(client versioned.Interface, 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.NotificationV2beta1().Receivers().List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.NotificationV2beta1().Receivers().Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
¬ificationv2beta1.Receiver{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *receiverInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredReceiverInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *receiverInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(¬ificationv2beta1.Receiver{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *receiverInformer) Lister() v2beta1.ReceiverLister {
|
||||
return v2beta1.NewReceiverLister(f.Informer().GetIndexer())
|
||||
}
|
||||
65
pkg/client/listers/notification/v2beta1/config.go
Normal file
65
pkg/client/listers/notification/v2beta1/config.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
)
|
||||
|
||||
// ConfigLister helps list Configs.
|
||||
type ConfigLister interface {
|
||||
// List lists all Configs in the indexer.
|
||||
List(selector labels.Selector) (ret []*v2beta1.Config, err error)
|
||||
// Get retrieves the Config from the index for a given name.
|
||||
Get(name string) (*v2beta1.Config, error)
|
||||
ConfigListerExpansion
|
||||
}
|
||||
|
||||
// configLister implements the ConfigLister interface.
|
||||
type configLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewConfigLister returns a new ConfigLister.
|
||||
func NewConfigLister(indexer cache.Indexer) ConfigLister {
|
||||
return &configLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all Configs in the indexer.
|
||||
func (s *configLister) List(selector labels.Selector) (ret []*v2beta1.Config, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v2beta1.Config))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the Config from the index for a given name.
|
||||
func (s *configLister) Get(name string) (*v2beta1.Config, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v2beta1.Resource("config"), name)
|
||||
}
|
||||
return obj.(*v2beta1.Config), nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
// ConfigListerExpansion allows custom methods to be added to
|
||||
// ConfigLister.
|
||||
type ConfigListerExpansion interface{}
|
||||
|
||||
// ReceiverListerExpansion allows custom methods to be added to
|
||||
// ReceiverLister.
|
||||
type ReceiverListerExpansion interface{}
|
||||
65
pkg/client/listers/notification/v2beta1/receiver.go
Normal file
65
pkg/client/listers/notification/v2beta1/receiver.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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 v2beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
v2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
)
|
||||
|
||||
// ReceiverLister helps list Receivers.
|
||||
type ReceiverLister interface {
|
||||
// List lists all Receivers in the indexer.
|
||||
List(selector labels.Selector) (ret []*v2beta1.Receiver, err error)
|
||||
// Get retrieves the Receiver from the index for a given name.
|
||||
Get(name string) (*v2beta1.Receiver, error)
|
||||
ReceiverListerExpansion
|
||||
}
|
||||
|
||||
// receiverLister implements the ReceiverLister interface.
|
||||
type receiverLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewReceiverLister returns a new ReceiverLister.
|
||||
func NewReceiverLister(indexer cache.Indexer) ReceiverLister {
|
||||
return &receiverLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all Receivers in the indexer.
|
||||
func (s *receiverLister) List(selector labels.Selector) (ret []*v2beta1.Receiver, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v2beta1.Receiver))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the Receiver from the index for a given name.
|
||||
func (s *receiverLister) Get(name string) (*v2beta1.Receiver, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v2beta1.Resource("receiver"), name)
|
||||
}
|
||||
return obj.(*v2beta1.Receiver), nil
|
||||
}
|
||||
@@ -125,6 +125,9 @@ const (
|
||||
ApplicationName = "app.kubernetes.io/name"
|
||||
ApplicationVersion = "app.kubernetes.io/version"
|
||||
AlertingTag = "Alerting"
|
||||
|
||||
NotificationTag = "Notification"
|
||||
NotificationSecretNamespace = "kubesphere-monitoring-federated"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
513
pkg/controller/notification/notification_controller.go
Normal file
513
pkg/controller/notification/notification_controller.go
Normal file
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
Copyright 2019 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 notification
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
toolscache "k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"reflect"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// SuccessSynced is used as part of the Event 'reason' when a Foo is synced
|
||||
successSynced = "Synced"
|
||||
controllerName = "notification-controller"
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
client.Client
|
||||
ksCache cache.Cache
|
||||
reconciledObjs []runtime.Object
|
||||
informerSynced []toolscache.InformerSynced
|
||||
// workqueue is a rate limited work queue. This is used to queue work to be
|
||||
// processed instead of performing it as soon as a change happens. This
|
||||
// means we can ensure we only process a fixed amount of resources at a
|
||||
// time, and makes it easy to ensure we are never processing the same item
|
||||
// simultaneously in two different workers.
|
||||
workqueue workqueue.RateLimitingInterface
|
||||
// recorder is an event recorder for recording Event resources to the
|
||||
// Kubernetes API.
|
||||
recorder record.EventRecorder
|
||||
}
|
||||
|
||||
func NewController(k8sClient kubernetes.Interface, ksClient client.Client, ksCache cache.Cache) (*Controller, error) {
|
||||
// Create event broadcaster
|
||||
// Add sample-controller types to the default Kubernetes Scheme so Events can be
|
||||
// logged for sample-controller types.
|
||||
|
||||
klog.V(4).Info("Creating event broadcaster")
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(klog.Infof)
|
||||
eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: k8sClient.CoreV1().Events("")})
|
||||
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerName})
|
||||
ctl := &Controller{
|
||||
Client: ksClient,
|
||||
ksCache: ksCache,
|
||||
workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Notification"),
|
||||
recorder: recorder,
|
||||
}
|
||||
klog.Info("Setting up event handlers")
|
||||
|
||||
if err := ctl.setEventHandlers(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctl, nil
|
||||
}
|
||||
|
||||
func (c *Controller) setEventHandlers() error {
|
||||
|
||||
if c.reconciledObjs != nil && len(c.reconciledObjs) > 0 {
|
||||
c.reconciledObjs = c.reconciledObjs[:0]
|
||||
}
|
||||
c.reconciledObjs = append(c.reconciledObjs, &v2beta1.Config{})
|
||||
c.reconciledObjs = append(c.reconciledObjs, &v2beta1.Receiver{})
|
||||
c.reconciledObjs = append(c.reconciledObjs, &corev1.Secret{})
|
||||
|
||||
if c.informerSynced != nil && len(c.informerSynced) > 0 {
|
||||
c.informerSynced = c.informerSynced[:0]
|
||||
}
|
||||
|
||||
for _, obj := range c.reconciledObjs {
|
||||
if informer, err := c.ksCache.GetInformer(context.Background(), obj); err != nil {
|
||||
klog.Errorf("get %s informer error, %v", obj.GetObjectKind().GroupVersionKind().String(), err)
|
||||
return err
|
||||
} else {
|
||||
informer.AddEventHandler(toolscache.ResourceEventHandlerFuncs{
|
||||
AddFunc: c.enqueue,
|
||||
UpdateFunc: func(old, new interface{}) {
|
||||
c.enqueue(new)
|
||||
},
|
||||
DeleteFunc: c.enqueue,
|
||||
})
|
||||
c.informerSynced = append(c.informerSynced, informer.HasSynced)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer c.workqueue.ShutDown()
|
||||
|
||||
// Start the informer factories to begin populating the informer caches
|
||||
klog.Info("Starting Notification controller")
|
||||
|
||||
// Wait for the caches to be synced before starting workers
|
||||
klog.Info("Waiting for informer caches to sync")
|
||||
|
||||
if ok := toolscache.WaitForCacheSync(stopCh, c.informerSynced...); !ok {
|
||||
return fmt.Errorf("failed to wait for caches to sync")
|
||||
}
|
||||
|
||||
klog.Info("Starting workers")
|
||||
// Launch two workers to process Foo resources
|
||||
for i := 0; i < threadiness; i++ {
|
||||
go wait.Until(c.runWorker, time.Second, stopCh)
|
||||
}
|
||||
|
||||
klog.Info("Started workers")
|
||||
<-stopCh
|
||||
klog.Info("Shutting down workers")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) enqueue(obj interface{}) {
|
||||
c.workqueue.Add(obj)
|
||||
}
|
||||
|
||||
func (c *Controller) runWorker() {
|
||||
for c.processNextWorkItem() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) processNextWorkItem() bool {
|
||||
obj, shutdown := c.workqueue.Get()
|
||||
|
||||
if shutdown {
|
||||
return false
|
||||
}
|
||||
|
||||
// We wrap this block in a func so we can defer c.workqueue.Done.
|
||||
err := func(obj interface{}) error {
|
||||
// We call Done here so the workqueue knows we have finished
|
||||
// processing this item. We also must remember to call Forget if we
|
||||
// do not want this work item being re-queued. For example, we do
|
||||
// not call Forget if a transient error occurs, instead the item is
|
||||
// put back on the workqueue and attempted again after a back-off
|
||||
// period.
|
||||
defer c.workqueue.Done(obj)
|
||||
|
||||
// Run the reconcile, passing it the namespace/name string of the
|
||||
// Foo resource to be synced.
|
||||
if err := c.reconcile(obj); err != nil {
|
||||
// Put the item back on the workqueue to handle any transient errors.
|
||||
c.workqueue.AddRateLimited(obj)
|
||||
}
|
||||
// Finally, if no error occurs we Forget this item so it does not
|
||||
// get queued again until another change happens.
|
||||
c.workqueue.Forget(obj)
|
||||
return nil
|
||||
}(obj)
|
||||
|
||||
if err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
return true
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// syncHandler compares the actual state with the desired, and attempts to
|
||||
// converge the two. It then updates the Status block of the Foo resource
|
||||
// with the current status of the resource.
|
||||
func (c *Controller) reconcile(obj interface{}) error {
|
||||
|
||||
runtimeObj, ok := obj.(runtime.Object)
|
||||
if !ok {
|
||||
utilruntime.HandleError(fmt.Errorf("object does not implement the Object interfaces"))
|
||||
return nil
|
||||
}
|
||||
runtimeObj = runtimeObj.DeepCopyObject()
|
||||
|
||||
accessor, err := meta.Accessor(runtimeObj)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("object does not implement the Object interfaces"))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Only reconcile the secret which created by notification manager.
|
||||
if secret, ok := obj.(*corev1.Secret); ok {
|
||||
if secret.Namespace != constants.NotificationSecretNamespace {
|
||||
klog.V(8).Infof("No need to reconcile secret %s/%s", accessor.GetNamespace(), accessor.GetName())
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := c.ensureNotificationNamespaceExist(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
name := accessor.GetName()
|
||||
kind := runtimeObj.GetObjectKind().GroupVersionKind().String()
|
||||
err = c.Get(context.Background(), client.ObjectKey{Name: accessor.GetName(), Namespace: accessor.GetNamespace()}, runtimeObj)
|
||||
if err != nil {
|
||||
// The user may no longer exist, in which case we stop
|
||||
// processing.
|
||||
if errors.IsNotFound(err) {
|
||||
utilruntime.HandleError(fmt.Errorf("obj '%s, %s' in work queue no longer exists", kind, name))
|
||||
c.recorder.Event(runtimeObj, corev1.EventTypeNormal, successSynced, fmt.Sprintf("%s synced successfully", kind))
|
||||
klog.Infof("Successfully synced %s:%s", kind, name)
|
||||
return nil
|
||||
}
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.multiClusterSync(context.Background(), runtimeObj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.recorder.Event(runtimeObj, corev1.EventTypeNormal, successSynced, fmt.Sprintf("%s synced successfully", kind))
|
||||
klog.Infof("Successfully synced %s:%s", kind, name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) Start(stopCh <-chan struct{}) error {
|
||||
return c.Run(4, stopCh)
|
||||
}
|
||||
|
||||
func (c *Controller) multiClusterSync(ctx context.Context, obj runtime.Object) error {
|
||||
|
||||
if err := c.ensureNotControlledByKubefed(ctx, obj); err != nil {
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
switch obj.(type) {
|
||||
case *v2beta1.Config:
|
||||
return c.syncFederatedConfig(obj.(*v2beta1.Config))
|
||||
case *v2beta1.Receiver:
|
||||
return c.syncFederatedReceiver(obj.(*v2beta1.Receiver))
|
||||
case *corev1.Secret:
|
||||
return c.syncFederatedSecret(obj.(*corev1.Secret))
|
||||
default:
|
||||
klog.Errorf("unknown type for notification, %v", obj)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) syncFederatedConfig(obj *v2beta1.Config) error {
|
||||
|
||||
fedObj := &v1beta1.FederatedNotificationConfig{}
|
||||
err := c.Get(context.Background(), client.ObjectKey{Name: obj.Name}, fedObj)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
fedObj = &v1beta1.FederatedNotificationConfig{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: v1beta1.FederatedNotificationConfigKind,
|
||||
APIVersion: v1beta1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: obj.Name,
|
||||
},
|
||||
Spec: v1beta1.FederatedNotificationConfigSpec{
|
||||
Template: v1beta1.NotificationConfigTemplate{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: obj.Labels,
|
||||
},
|
||||
Spec: obj.Spec,
|
||||
},
|
||||
Placement: v1beta1.GenericPlacementFields{
|
||||
ClusterSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := controllerutil.SetControllerReference(obj, fedObj, scheme.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.Create(context.Background(), fedObj); err != nil {
|
||||
klog.Errorf("create '%s:%s' failed, %s", fedObj.GetObjectKind().GroupVersionKind().String(), obj.Name, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(fedObj.Spec.Template.Labels, obj.Labels) || !reflect.DeepEqual(fedObj.Spec.Template.Spec, obj.Spec) {
|
||||
|
||||
fedObj.Spec.Template.Spec = obj.Spec
|
||||
fedObj.Spec.Template.Labels = obj.Labels
|
||||
|
||||
if err := c.Update(context.Background(), fedObj); err != nil {
|
||||
klog.Errorf("update '%s:%s' failed, %s", fedObj.GetObjectKind().GroupVersionKind().String(), obj.Name, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) syncFederatedReceiver(obj *v2beta1.Receiver) error {
|
||||
|
||||
fedObj := &v1beta1.FederatedNotificationReceiver{}
|
||||
err := c.Get(context.Background(), client.ObjectKey{Name: obj.Name}, fedObj)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
fedObj = &v1beta1.FederatedNotificationReceiver{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: v1beta1.FederatedNotificationReceiverKind,
|
||||
APIVersion: v1beta1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: obj.Name,
|
||||
},
|
||||
Spec: v1beta1.FederatedNotificationReceiverSpec{
|
||||
Template: v1beta1.NotificationReceiverTemplate{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: obj.Labels,
|
||||
},
|
||||
Spec: obj.Spec,
|
||||
},
|
||||
Placement: v1beta1.GenericPlacementFields{
|
||||
ClusterSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := controllerutil.SetControllerReference(obj, fedObj, scheme.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.Create(context.Background(), fedObj); err != nil {
|
||||
klog.Errorf("create '%s:%s' failed, %s", fedObj.GetObjectKind().GroupVersionKind().String(), obj.Name, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(fedObj.Spec.Template.Labels, obj.Labels) || !reflect.DeepEqual(fedObj.Spec.Template.Spec, obj.Spec) {
|
||||
|
||||
fedObj.Spec.Template.Spec = obj.Spec
|
||||
fedObj.Spec.Template.Labels = obj.Labels
|
||||
|
||||
if err := c.Update(context.Background(), fedObj); err != nil {
|
||||
klog.Errorf("update '%s:%s' failed, %s", fedObj.GetObjectKind().GroupVersionKind().String(), obj.Name, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) syncFederatedSecret(obj *corev1.Secret) error {
|
||||
|
||||
fedObj := &v1beta1.FederatedSecret{}
|
||||
err := c.Get(context.Background(), client.ObjectKey{Name: obj.Name, Namespace: obj.Namespace}, fedObj)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
fedObj = &v1beta1.FederatedSecret{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: v1beta1.FederatedSecretKind,
|
||||
APIVersion: v1beta1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: obj.Name,
|
||||
Namespace: obj.Namespace,
|
||||
},
|
||||
Spec: v1beta1.FederatedSecretSpec{
|
||||
Template: v1beta1.SecretTemplate{
|
||||
Data: obj.Data,
|
||||
StringData: obj.StringData,
|
||||
Type: obj.Type,
|
||||
},
|
||||
Placement: v1beta1.GenericPlacementFields{
|
||||
ClusterSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := controllerutil.SetControllerReference(obj, fedObj, scheme.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.Create(context.Background(), fedObj); err != nil {
|
||||
klog.Errorf("create '%s:%s' failed, %s", fedObj.GetObjectKind().GroupVersionKind().String(), obj.Name, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(fedObj.Spec.Template.Data, obj.Data) ||
|
||||
!reflect.DeepEqual(fedObj.Spec.Template.StringData, obj.StringData) ||
|
||||
!reflect.DeepEqual(fedObj.Spec.Template.Type, obj.Type) {
|
||||
|
||||
fedObj.Spec.Template.Data = obj.Data
|
||||
fedObj.Spec.Template.StringData = obj.StringData
|
||||
fedObj.Spec.Template.Type = obj.Type
|
||||
|
||||
if err := c.Update(context.Background(), fedObj); err != nil {
|
||||
klog.Errorf("update '%s:%s' failed, %s", fedObj.GetObjectKind().GroupVersionKind().String(), obj.Name, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) ensureNotificationNamespaceExist() error {
|
||||
|
||||
ns := corev1.Namespace{}
|
||||
if err := c.Get(context.Background(), client.ObjectKey{Name: constants.NotificationSecretNamespace}, &ns); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fedNs := v1beta1.FederatedNamespace{}
|
||||
if err := c.Get(context.Background(), client.ObjectKey{Name: constants.NotificationSecretNamespace, Namespace: constants.NotificationSecretNamespace}, &fedNs); err != nil {
|
||||
if errors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if errors.IsNotFound(err) {
|
||||
fedNs = v1beta1.FederatedNamespace{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: v1beta1.FederatedNamespaceKind,
|
||||
APIVersion: v1beta1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: constants.NotificationSecretNamespace,
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
},
|
||||
Spec: v1beta1.FederatedNamespaceSpec{
|
||||
Placement: v1beta1.GenericPlacementFields{
|
||||
ClusterSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := controllerutil.SetControllerReference(&ns, &fedNs, scheme.Scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Create(context.Background(), &fedNs)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (c *Controller) ensureNotControlledByKubefed(ctx context.Context, obj runtime.Object) error {
|
||||
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
labels := accessor.GetLabels()
|
||||
if labels == nil {
|
||||
labels = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
if labels[constants.KubefedManagedLabel] != "false" {
|
||||
labels[constants.KubefedManagedLabel] = "false"
|
||||
accessor.SetLabels(labels)
|
||||
err := c.Update(ctx, accessor.(runtime.Object))
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package notification
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"kubesphere.io/kubesphere/pkg/apis"
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/client-go/rest"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
|
||||
)
|
||||
|
||||
func TestSource(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
suiteName := "Cache Suite"
|
||||
RunSpecsWithDefaultAndCustomReporters(t, suiteName, []Reporter{printer.NewlineReporter{}, printer.NewProwReporter(suiteName)})
|
||||
}
|
||||
|
||||
var testenv *envtest.Environment
|
||||
var cfg *rest.Config
|
||||
var k8sManager ctrl.Manager
|
||||
|
||||
var _ = BeforeSuite(func(done Done) {
|
||||
|
||||
testenv = &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")},
|
||||
}
|
||||
|
||||
var err error
|
||||
cfg, err = testenv.Start()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cfg).ToNot(BeNil())
|
||||
|
||||
err = v2beta1.AddToScheme(scheme.Scheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = apis.AddToScheme(scheme.Scheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
k8sManager, err = ctrl.NewManager(cfg, ctrl.Options{
|
||||
Scheme: scheme.Scheme,
|
||||
MetricsBindAddress: "0",
|
||||
})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r, err := NewController(fake.NewSimpleClientset(), k8sManager.GetClient(), k8sManager.GetCache())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
err = k8sManager.Add(r)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
go func() {
|
||||
err = k8sManager.Start(ctrl.SetupSignalHandler())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}()
|
||||
|
||||
close(done)
|
||||
}, 60)
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
Expect(testenv.Stop()).To(Succeed())
|
||||
})
|
||||
201
pkg/controller/notification/notification_controller_test.go
Normal file
201
pkg/controller/notification/notification_controller_test.go
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package notification
|
||||
|
||||
import (
|
||||
"context"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
"kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
_ = Describe("Secret", func() {
|
||||
|
||||
const timeout = time.Second * 30
|
||||
const interval = time.Second * 1
|
||||
|
||||
namespace := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: constants.NotificationSecretNamespace,
|
||||
},
|
||||
}
|
||||
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
cl client.Client
|
||||
ksCache cache.Cache
|
||||
informerCacheCtx context.Context
|
||||
informerCacheCancel context.CancelFunc
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
cl, err = client.New(cfg, client.Options{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ksCache, err = cache.New(cfg, cache.Options{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
informerCacheCtx, informerCacheCancel = context.WithCancel(context.Background())
|
||||
go func(ctx context.Context) {
|
||||
defer GinkgoRecover()
|
||||
Expect(ksCache.Start(ctx.Done())).To(Succeed())
|
||||
}(informerCacheCtx)
|
||||
Expect(ksCache.WaitForCacheSync(informerCacheCtx.Done())).To(BeTrue())
|
||||
|
||||
Eventually(func() bool {
|
||||
err = cl.Create(informerCacheCtx, namespace)
|
||||
if err == nil || errors.IsAlreadyExists(err) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, timeout, interval).Should(BeTrue())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
By("cleaning up")
|
||||
informerCacheCancel()
|
||||
})
|
||||
|
||||
// Add Tests for OpenAPI validation (or additonal CRD features) specified in
|
||||
// your API definition.
|
||||
// Avoid adding tests for vanilla CRUD operations because they would
|
||||
// test Kubernetes API server, which isn't the goal here.
|
||||
Context("Notification Controller", func() {
|
||||
It("Should create successfully", func() {
|
||||
|
||||
// Create a secret
|
||||
Expect(cl.Create(context.Background(), secret)).Should(Succeed())
|
||||
time.Sleep(time.Second)
|
||||
|
||||
fedSecret := &v1beta1.FederatedSecret{}
|
||||
By("Expecting to create federated secret successfully")
|
||||
Eventually(func() bool {
|
||||
err := ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret)
|
||||
Expect(err).Should(Succeed())
|
||||
return !fedSecret.CreationTimestamp.IsZero()
|
||||
}, timeout, interval).Should(BeTrue())
|
||||
|
||||
err := ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, secret)
|
||||
Expect(err).Should(Succeed())
|
||||
secret.StringData = map[string]string{"foo": "bar"}
|
||||
Expect(cl.Update(context.Background(), secret)).Should(Succeed())
|
||||
time.Sleep(time.Second)
|
||||
|
||||
By("Expecting to update federated secret successfully")
|
||||
Eventually(func() bool {
|
||||
err := ksCache.Get(context.Background(), client.ObjectKey{Name: secret.Name, Namespace: constants.NotificationSecretNamespace}, fedSecret)
|
||||
Expect(err).Should(Succeed())
|
||||
return string(fedSecret.Spec.Template.Data["foo"]) == "bar"
|
||||
}, timeout, interval).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
_ = Describe("Notification", func() {
|
||||
|
||||
const timeout = time.Second * 30
|
||||
const interval = time.Second * 1
|
||||
|
||||
obj := &v2beta1.Config{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{
|
||||
"type": "default",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
cl client.Client
|
||||
ksCache cache.Cache
|
||||
informerCacheCtx context.Context
|
||||
informerCacheCancel context.CancelFunc
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
cl, err = client.New(cfg, client.Options{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ksCache, err = cache.New(cfg, cache.Options{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
informerCacheCtx, informerCacheCancel = context.WithCancel(context.Background())
|
||||
go func(ctx context.Context) {
|
||||
defer GinkgoRecover()
|
||||
Expect(ksCache.Start(ctx.Done())).To(Succeed())
|
||||
}(informerCacheCtx)
|
||||
Expect(ksCache.WaitForCacheSync(informerCacheCtx.Done())).To(BeTrue())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
By("cleaning up")
|
||||
informerCacheCancel()
|
||||
})
|
||||
|
||||
// Add Tests for OpenAPI validation (or additonal CRD features) specified in
|
||||
// your API definition.
|
||||
// Avoid adding tests for vanilla CRUD operations because they would
|
||||
// test Kubernetes API server, which isn't the goal here.
|
||||
Context("Notification Controller", func() {
|
||||
It("Should create successfully", func() {
|
||||
|
||||
// Create a bject
|
||||
Expect(cl.Create(context.Background(), obj)).Should(Succeed())
|
||||
time.Sleep(time.Second)
|
||||
|
||||
fedObj := &v1beta1.FederatedNotificationConfig{}
|
||||
By("Expecting to create federated object successfully")
|
||||
Eventually(func() bool {
|
||||
err := ksCache.Get(context.Background(), client.ObjectKey{Name: obj.Name}, fedObj)
|
||||
Expect(err).Should(Succeed())
|
||||
return !fedObj.CreationTimestamp.IsZero()
|
||||
}, timeout, interval).Should(BeTrue())
|
||||
|
||||
err := ksCache.Get(context.Background(), client.ObjectKey{Name: obj.Name}, obj)
|
||||
Expect(err).Should(Succeed())
|
||||
obj.Labels = map[string]string{"foo": "bar"}
|
||||
Expect(cl.Update(context.Background(), obj)).Should(Succeed())
|
||||
time.Sleep(time.Second)
|
||||
|
||||
By("Expecting to update federated object successfully")
|
||||
Eventually(func() bool {
|
||||
err := ksCache.Get(context.Background(), client.ObjectKey{Name: obj.Name}, fedObj)
|
||||
Expect(err).Should(Succeed())
|
||||
return fedObj.Spec.Template.Labels["foo"] == "bar"
|
||||
}, timeout, interval).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
})
|
||||
)
|
||||
149
pkg/kapis/notification/v2beta1/handler.go
Normal file
149
pkg/kapis/notification/v2beta1/handler.go
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2beta1
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/notification"
|
||||
servererr "kubesphere.io/kubesphere/pkg/server/errors"
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
operator notification.Operator
|
||||
}
|
||||
|
||||
func newNotificationHandler(
|
||||
informers informers.InformerFactory,
|
||||
k8sClient kubernetes.Interface,
|
||||
ksClient kubesphere.Interface) *handler {
|
||||
|
||||
return &handler{
|
||||
operator: notification.NewOperator(informers, k8sClient, ksClient),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) ListResource(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
user := req.PathParameter("user")
|
||||
resource := req.PathParameter("resources")
|
||||
subresource := req.QueryParameter("type")
|
||||
q := query.ParseQueryParameter(req)
|
||||
|
||||
if !h.operator.IsKnownResource(resource, subresource) {
|
||||
api.HandleBadRequest(resp, req, servererr.New("unknown resource type %s/%s", resource, subresource))
|
||||
return
|
||||
}
|
||||
|
||||
objs, err := h.operator.List(user, resource, subresource, q)
|
||||
handleResponse(req, resp, objs, err)
|
||||
}
|
||||
|
||||
func (h *handler) GetResource(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
user := req.PathParameter("user")
|
||||
resource := req.PathParameter("resources")
|
||||
name := req.PathParameter("name")
|
||||
subresource := req.QueryParameter("type")
|
||||
|
||||
if !h.operator.IsKnownResource(resource, subresource) {
|
||||
api.HandleBadRequest(resp, req, servererr.New("unknown resource type %s/%s", resource, subresource))
|
||||
return
|
||||
}
|
||||
|
||||
obj, err := h.operator.Get(user, resource, name, subresource)
|
||||
handleResponse(req, resp, obj, err)
|
||||
}
|
||||
|
||||
func (h *handler) CreateResource(req *restful.Request, resp *restful.Response) {
|
||||
|
||||
user := req.PathParameter("user")
|
||||
resource := req.PathParameter("resources")
|
||||
|
||||
if !h.operator.IsKnownResource(resource, "") {
|
||||
api.HandleBadRequest(resp, req, servererr.New("unknown resource type %s", resource))
|
||||
return
|
||||
}
|
||||
|
||||
obj := h.operator.GetObject(resource)
|
||||
if err := req.ReadEntity(obj); err != nil {
|
||||
api.HandleBadRequest(resp, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
created, err := h.operator.Create(user, resource, obj)
|
||||
handleResponse(req, resp, created, err)
|
||||
}
|
||||
|
||||
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))
|
||||
return
|
||||
}
|
||||
|
||||
obj := h.operator.GetObject(resource)
|
||||
if err := req.ReadEntity(obj); err != nil {
|
||||
api.HandleBadRequest(resp, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
updated, err := h.operator.Update(user, resource, name, obj)
|
||||
handleResponse(req, resp, updated, err)
|
||||
}
|
||||
|
||||
func (h *handler) DeleteResource(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))
|
||||
return
|
||||
}
|
||||
|
||||
handleResponse(req, resp, servererr.None, h.operator.Delete(user, resource, name))
|
||||
}
|
||||
|
||||
func handleResponse(req *restful.Request, resp *restful.Response, obj interface{}, err error) {
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
if errors.IsNotFound(err) {
|
||||
api.HandleNotFound(resp, req, err)
|
||||
return
|
||||
} else if errors.IsConflict(err) {
|
||||
api.HandleConflict(resp, req, err)
|
||||
return
|
||||
}
|
||||
api.HandleBadRequest(resp, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
_ = resp.WriteEntity(obj)
|
||||
}
|
||||
153
pkg/kapis/notification/v2beta1/register.go
Normal file
153
pkg/kapis/notification/v2beta1/register.go
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
package v2beta1
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
openapi "github.com/emicklei/go-restful-openapi"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
|
||||
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
GroupName = "notification.kubesphere.io"
|
||||
KeyOpenAPITags = openapi.KeyOpenAPITags
|
||||
)
|
||||
|
||||
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v2beta1"}
|
||||
|
||||
func AddToContainer(
|
||||
container *restful.Container,
|
||||
informers informers.InformerFactory,
|
||||
k8sClient kubernetes.Interface,
|
||||
ksClient kubesphere.Interface) error {
|
||||
|
||||
ws := runtime.NewWebService(GroupVersion)
|
||||
h := newNotificationHandler(informers, k8sClient, ksClient)
|
||||
|
||||
// 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", "known values include configs, receivers, 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("type", "config or receiver type, known values include dingtalk, email, slack, webhook, wechat").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("/{resources}/{name}").
|
||||
To(h.GetResource).
|
||||
Doc("get the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("resources", "known values include configs, receivers, secrets")).
|
||||
Param(ws.PathParameter(query.ParameterName, "the name of the resource")).
|
||||
Param(ws.QueryParameter("type", "config or receiver type, known values include dingtalk, email, slack, webhook, wechat").Required(false)).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
ws.Route(ws.POST("/{resources}").
|
||||
To(h.CreateResource).
|
||||
Doc("create a notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("resources", "known values include configs, receivers, 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", "known values include configs, receivers, secrets")).
|
||||
Param(ws.PathParameter(query.ParameterName, "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
ws.Route(ws.DELETE("/{resources}/{name}").
|
||||
To(h.DeleteResource).
|
||||
Doc("delete the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("resources", "known values include configs, receivers, secrets")).
|
||||
Param(ws.PathParameter(query.ParameterName, "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, errors.None))
|
||||
|
||||
// apis for tenant notification config and receiver
|
||||
ws.Route(ws.GET("/users/{user}/{resources}").
|
||||
To(h.ListResource).
|
||||
Doc("list the notification configs or receivers").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "known values include configs, receivers, 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("type", "config or receiver type, known values include dingtalk, email, slack, webhook, wechat").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("/users/{user}/{resources}/{name}").
|
||||
To(h.GetResource).
|
||||
Doc("get the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "known values include configs, receivers, secrets")).
|
||||
Param(ws.PathParameter(query.ParameterName, "the name of the resource")).
|
||||
Param(ws.QueryParameter("type", "config or receiver type, known values include dingtalk, email, slack, webhook, wechat").Required(false)).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
ws.Route(ws.POST("/users/{user}/{resources}").
|
||||
To(h.CreateResource).
|
||||
Doc("create the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "known values include configs, receivers, secrets")).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
ws.Route(ws.PUT("/users/{user}/{resources}/{name}").
|
||||
To(h.UpdateResource).
|
||||
Doc("update the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "known values include configs, receivers, secrets")).
|
||||
Param(ws.PathParameter(query.ParameterName, "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, nil))
|
||||
|
||||
ws.Route(ws.DELETE("/users/{user}/{resources}/{name}").
|
||||
To(h.DeleteResource).
|
||||
Doc("delete the specified notification config or receiver").
|
||||
Metadata(KeyOpenAPITags, []string{constants.NotificationTag}).
|
||||
Param(ws.PathParameter("user", "user name")).
|
||||
Param(ws.PathParameter("resources", "known values include configs, receivers, secrets")).
|
||||
Param(ws.PathParameter(query.ParameterName, "the name of the resource")).
|
||||
Returns(http.StatusOK, api.StatusOK, errors.None))
|
||||
|
||||
container.Add(ws)
|
||||
return nil
|
||||
}
|
||||
358
pkg/models/notification/notification.go
Normal file
358
pkg/models/notification/notification.go
Normal file
@@ -0,0 +1,358 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type Operator interface {
|
||||
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
|
||||
}
|
||||
|
||||
type operator struct {
|
||||
k8sClient kubernetes.Interface
|
||||
ksClient kubesphere.Interface
|
||||
informers informers.InformerFactory
|
||||
resourceGetter *resource.ResourceGetter
|
||||
}
|
||||
|
||||
func NewOperator(
|
||||
informers informers.InformerFactory,
|
||||
k8sClient kubernetes.Interface,
|
||||
ksClient kubesphere.Interface) Operator {
|
||||
|
||||
return &operator{
|
||||
informers: informers,
|
||||
k8sClient: k8sClient,
|
||||
ksClient: ksClient,
|
||||
resourceGetter: resource.NewResourceGetter(informers, nil),
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
if len(q.LabelSelector) > 0 {
|
||||
q.LabelSelector = q.LabelSelector + ","
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
res, err := o.resourceGetter.List(resource, constants.NotificationSecretNamespace, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if subresource == "" || resource == "secrets" {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
results := &api.ListResult{}
|
||||
for _, item := range res.Items {
|
||||
obj := clean(item, resource, subresource)
|
||||
if obj != nil {
|
||||
results.Items = append(results.Items, obj)
|
||||
}
|
||||
}
|
||||
results.TotalItems = len(results.Items)
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
obj, err := o.resourceGetter.Get(resource, constants.NotificationSecretNamespace, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := authorizer(user, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if subresource == "" || resource == "secrets" {
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
res := clean(obj, resource, subresource)
|
||||
if res == nil {
|
||||
return nil, errors.NewNotFound(v2beta1.Resource(obj.GetObjectKind().GroupVersionKind().GroupKind().Kind), name)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
if err := appendLabel(user, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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 "secrets":
|
||||
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Create(context.Background(), obj.(*corev1.Secret), v1.CreateOptions{})
|
||||
default:
|
||||
return nil, errors.NewInternalError(nil)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
||||
if obj, err := o.Get(user, resource, name, ""); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if err := authorizer(user, obj); err != nil {
|
||||
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 "secrets":
|
||||
return o.k8sClient.CoreV1().Secrets(constants.NotificationSecretNamespace).Delete(context.Background(), name, v1.DeleteOptions{})
|
||||
default:
|
||||
return errors.NewInternalError(nil)
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
if err := appendLabel(user, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if old, err := o.Get(user, resource, name, ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
if err := authorizer(user, old); err != nil {
|
||||
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 "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) GetObject(resource string) runtime.Object {
|
||||
|
||||
switch resource {
|
||||
case v2beta1.ResourcesPluralConfig:
|
||||
return &v2beta1.Config{}
|
||||
case v2beta1.ResourcesPluralReceiver:
|
||||
return &v2beta1.Receiver{}
|
||||
case "secrets":
|
||||
return &corev1.Secret{}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *operator) IsKnownResource(resource, subresource string) bool {
|
||||
|
||||
if obj := o.GetObject(resource); obj == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// "" means get all types of the config or receiver.
|
||||
if subresource != "dingtalk" &&
|
||||
subresource != "email" &&
|
||||
subresource != "slack" &&
|
||||
subresource != "webhook" &&
|
||||
subresource != "wechat" &&
|
||||
subresource != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 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), "",
|
||||
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), "",
|
||||
fmt.Errorf("object is not a global object"))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Is the user equal to the tenant specified in the object labels.
|
||||
func isOwner(user string, obj interface{}) bool {
|
||||
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
klog.Errorln(err)
|
||||
return false
|
||||
}
|
||||
|
||||
return accessor.GetLabels()["user"] == user
|
||||
}
|
||||
|
||||
func isConfig(obj runtime.Object) bool {
|
||||
switch obj.(type) {
|
||||
case *v2beta1.Config:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Is the object is a global object.
|
||||
func isGlobal(obj runtime.Object) bool {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
klog.Errorln(err)
|
||||
return false
|
||||
}
|
||||
|
||||
if isConfig(obj) {
|
||||
return accessor.GetLabels()["type"] == "default"
|
||||
} else {
|
||||
return accessor.GetLabels()["type"] == "global"
|
||||
}
|
||||
}
|
||||
|
||||
func appendLabel(user string, obj runtime.Object) error {
|
||||
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
klog.Errorln(err)
|
||||
return err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func clean(obj interface{}, resource, subresource string) runtime.Object {
|
||||
if resource == v2beta1.ResourcesPluralConfig {
|
||||
config := obj.(*v2beta1.Config)
|
||||
newConfig := config.DeepCopy()
|
||||
newConfig.Spec = v2beta1.ConfigSpec{}
|
||||
switch subresource {
|
||||
case "dingtalk":
|
||||
newConfig.Spec.DingTalk = config.Spec.DingTalk
|
||||
case "email":
|
||||
newConfig.Spec.Email = config.Spec.Email
|
||||
case "slack":
|
||||
newConfig.Spec.Slack = config.Spec.Slack
|
||||
case "webhook":
|
||||
newConfig.Spec.Webhook = config.Spec.Webhook
|
||||
case "wechat":
|
||||
newConfig.Spec.Wechat = config.Spec.Wechat
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if reflect.ValueOf(newConfig.Spec).IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return newConfig
|
||||
} else {
|
||||
receiver := obj.(*v2beta1.Receiver)
|
||||
newReceiver := receiver.DeepCopy()
|
||||
newReceiver.Spec = v2beta1.ReceiverSpec{}
|
||||
switch subresource {
|
||||
case "dingtalk":
|
||||
newReceiver.Spec.DingTalk = receiver.Spec.DingTalk
|
||||
case "email":
|
||||
newReceiver.Spec.Email = receiver.Spec.Email
|
||||
case "slack":
|
||||
newReceiver.Spec.Slack = receiver.Spec.Slack
|
||||
case "webhook":
|
||||
newReceiver.Spec.Webhook = receiver.Spec.Webhook
|
||||
case "wechat":
|
||||
newReceiver.Spec.Wechat = receiver.Spec.Wechat
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if reflect.ValueOf(newReceiver.Spec).IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return newReceiver
|
||||
}
|
||||
}
|
||||
217
pkg/models/notification/notification_test.go
Normal file
217
pkg/models/notification/notification_test.go
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package notification
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
fakek8s "k8s.io/client-go/kubernetes/fake"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOperator_List(t *testing.T) {
|
||||
o := prepare()
|
||||
tests := []struct {
|
||||
result *api.ListResult
|
||||
expectError error
|
||||
}{
|
||||
{
|
||||
result: &api.ListResult{
|
||||
Items: []interface{}{secret1, secret2, secret3},
|
||||
TotalItems: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
result, err := o.List("", "secrets", "", &query.Query{
|
||||
SortBy: query.FieldName,
|
||||
Ascending: true,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if !reflect.DeepEqual(err, test.expectError) {
|
||||
t.Errorf("got %#v, expected %#v", err, test.expectError)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(result, test.result); diff != "" {
|
||||
t.Errorf("case %d, %s", i, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperator_Get(t *testing.T) {
|
||||
o := prepare()
|
||||
tests := []struct {
|
||||
result *corev1.Secret
|
||||
name string
|
||||
expectError error
|
||||
}{
|
||||
{
|
||||
result: secret1,
|
||||
name: secret1.Name,
|
||||
expectError: nil,
|
||||
},
|
||||
{
|
||||
name: "foo4",
|
||||
expectError: errors.NewNotFound(corev1.Resource("secret"), "foo4"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result, err := o.Get("", "secrets", test.name, "")
|
||||
|
||||
if err != nil {
|
||||
if !reflect.DeepEqual(err, test.expectError) {
|
||||
t.Errorf("got %#v, expected %#v", err, test.expectError)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(result, test.result); diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperator_Create(t *testing.T) {
|
||||
o := prepare()
|
||||
tests := []struct {
|
||||
result *corev1.Secret
|
||||
secret *corev1.Secret
|
||||
expectError error
|
||||
}{
|
||||
{
|
||||
result: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
},
|
||||
secret: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
result, err := o.Create("", "secrets", test.secret)
|
||||
|
||||
if err != nil {
|
||||
if !reflect.DeepEqual(err, test.expectError) {
|
||||
t.Errorf("case %d, got %#v, expected %#v", i, err, test.expectError)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(result, test.result); diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperator_Delete(t *testing.T) {
|
||||
o := prepare()
|
||||
tests := []struct {
|
||||
name string
|
||||
expectError error
|
||||
}{
|
||||
{
|
||||
name: "foo4",
|
||||
expectError: errors.NewNotFound(corev1.Resource("secret"), "foo4"),
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
err := o.Delete("", "secrets", test.name)
|
||||
if err != nil {
|
||||
if test.expectError != nil && test.expectError.Error() == err.Error() {
|
||||
continue
|
||||
} else {
|
||||
if !reflect.DeepEqual(err, test.expectError) {
|
||||
t.Errorf("case %d, got %#v, expected %#v", i, err, test.expectError)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
secret1 = &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
secret2 = &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
secret3 = &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo3",
|
||||
Namespace: constants.NotificationSecretNamespace,
|
||||
Labels: map[string]string{
|
||||
"type": "global",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
secrets = []*corev1.Secret{secret1, secret2, secret3}
|
||||
)
|
||||
|
||||
func prepare() Operator {
|
||||
|
||||
ksClient := fakeks.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
for _, secret := range secrets {
|
||||
_ = fakeInformerFactory.KubernetesSharedInformerFactory().Core().V1().Secrets().Informer().GetIndexer().Add(secret)
|
||||
}
|
||||
|
||||
return NewOperator(fakeInformerFactory, k8sClient, ksClient)
|
||||
}
|
||||
115
pkg/models/resources/v1alpha3/notification/notification.go
Normal file
115
pkg/models/resources/v1alpha3/notification/notification.go
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
Copyright 2019 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 notification
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type configGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNotificationConfigGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &configGetter{ksInformer: informer}
|
||||
}
|
||||
|
||||
func (g *configGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return g.ksInformer.Notification().V2beta1().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())
|
||||
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 receiverGetter struct {
|
||||
ksInformer ksinformers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func NewNotificationReceiverGetter(informer ksinformers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &receiverGetter{ksInformer: informer}
|
||||
}
|
||||
|
||||
func (g *receiverGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return g.ksInformer.Notification().V2beta1().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())
|
||||
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
|
||||
}
|
||||
|
||||
func compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftObj, err := meta.Accessor(left)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
rightObj, err := meta.Accessor(right)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(meta.AsPartialObjectMetadata(leftObj).ObjectMeta,
|
||||
meta.AsPartialObjectMetadata(rightObj).ObjectMeta, field)
|
||||
}
|
||||
|
||||
func filter(object runtime.Object, filter query.Filter) bool {
|
||||
|
||||
accessor, err := meta.Accessor(object)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
switch filter.Field {
|
||||
case query.FieldNames:
|
||||
for _, name := range strings.Split(string(filter.Value), ",") {
|
||||
if accessor.GetName() == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
case query.FieldName:
|
||||
return strings.Contains(accessor.GetName(), string(filter.Value))
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
140
pkg/models/resources/v1alpha3/notification/notification_test.go
Normal file
140
pkg/models/resources/v1alpha3/notification/notification_test.go
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
Copyright 2019 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 notification
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/uuid"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
Prefix = "foo"
|
||||
LengthMin = 3
|
||||
LengthMax = 10
|
||||
)
|
||||
|
||||
func TestListObjects(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
key string
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
v2beta1.ResourcesPluralConfig,
|
||||
},
|
||||
{
|
||||
"test name filter",
|
||||
v2beta1.ResourcesPluralReceiver,
|
||||
},
|
||||
}
|
||||
|
||||
q := &query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: true,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value(Prefix)},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
getter, objects, err := prepare(test.key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
got, err := getter.List("", q)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := &api.ListResult{
|
||||
Items: objects,
|
||||
TotalItems: len(objects),
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, expected); diff != "" {
|
||||
t.Errorf("[%s] %T differ (-got, +want): %s", test.description, expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func prepare(key string) (v1alpha3.Interface, []interface{}, error) {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := ksinformers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
var obj runtime.Object
|
||||
var indexer cache.Indexer
|
||||
var getter func(informer ksinformers.SharedInformerFactory) v1alpha3.Interface
|
||||
switch key {
|
||||
case v2beta1.ResourcesPluralConfig:
|
||||
indexer = informer.Notification().V2beta1().Configs().Informer().GetIndexer()
|
||||
getter = NewNotificationConfigGetter
|
||||
obj = &v2beta1.Config{}
|
||||
case v2beta1.ResourcesPluralReceiver:
|
||||
indexer = informer.Notification().V2beta1().Receivers().Informer().GetIndexer()
|
||||
getter = NewNotificationReceiverGetter
|
||||
obj = &v2beta1.Receiver{}
|
||||
default:
|
||||
return nil, nil, errors.New("unowned type %s", key)
|
||||
}
|
||||
|
||||
num := rand.Intn(LengthMax)
|
||||
if num < LengthMin {
|
||||
num = LengthMin
|
||||
}
|
||||
|
||||
var suffix []string
|
||||
for i := 0; i < num; i++ {
|
||||
s := uuid.New().String()
|
||||
suffix = append(suffix, s)
|
||||
}
|
||||
sort.Strings(suffix)
|
||||
|
||||
var objects []interface{}
|
||||
for i := 0; i < num; i++ {
|
||||
val := obj.DeepCopyObject()
|
||||
accessor, err := meta.Accessor(val)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
accessor.SetName(Prefix + "-" + suffix[i])
|
||||
err = indexer.Add(accessor)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
objects = append(objects, val)
|
||||
}
|
||||
|
||||
return getter(informer), objects, nil
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
|
||||
notificationv2beta1 "kubesphere.io/kubesphere/pkg/apis/notification/v2beta1"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha2"
|
||||
typesv1beta1 "kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
|
||||
@@ -61,10 +62,12 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/namespace"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/networkpolicy"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/node"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/notification"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/persistentvolumeclaim"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/pod"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/role"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/rolebinding"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/secret"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/service"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/serviceaccount"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/statefulset"
|
||||
@@ -92,6 +95,7 @@ func NewResourceGetter(factory informers.InformerFactory, cache cache.Cache) *Re
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "services"}] = service.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"}] = namespace.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"}] = configmap.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"}] = secret.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}] = pod.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "nodes"}] = node.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "serviceaccounts"}] = serviceaccount.New(factory.KubernetesSharedInformerFactory())
|
||||
@@ -122,6 +126,9 @@ func NewResourceGetter(factory informers.InformerFactory, cache cache.Cache) *Re
|
||||
getters[schema.GroupVersionResource{Group: "cluster.kubesphere.io", Version: "v1alpha1", Resource: "clusters"}] = cluster.New(factory.KubeSphereSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"}] = customresourcedefinition.New(factory.ApiExtensionSharedInformerFactory())
|
||||
|
||||
getters[notificationv2beta1.SchemeGroupVersion.WithResource(notificationv2beta1.ResourcesPluralConfig)] = notification.NewNotificationConfigGetter(factory.KubeSphereSharedInformerFactory())
|
||||
getters[notificationv2beta1.SchemeGroupVersion.WithResource(notificationv2beta1.ResourcesPluralReceiver)] = notification.NewNotificationReceiverGetter(factory.KubeSphereSharedInformerFactory())
|
||||
|
||||
// federated resources
|
||||
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedNamespace)] = federatednamespace.New(factory.KubeSphereSharedInformerFactory())
|
||||
getters[typesv1beta1.SchemeGroupVersion.WithResource(typesv1beta1.ResourcePluralFederatedDeployment)] = federateddeployment.New(factory.KubeSphereSharedInformerFactory())
|
||||
|
||||
77
pkg/models/resources/v1alpha3/secret/secrets.go
Normal file
77
pkg/models/resources/v1alpha3/secret/secrets.go
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
Copyright 2019 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 secret
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type secretSearcher struct {
|
||||
informers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(informers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &secretSearcher{informers: informers}
|
||||
}
|
||||
|
||||
func (s *secretSearcher) Get(namespace, name string) (runtime.Object, error) {
|
||||
return s.informers.Core().V1().Secrets().Lister().Secrets(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (s *secretSearcher) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
secrets, err := s.informers.Core().V1().Secrets().Lister().Secrets(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, secret := range secrets {
|
||||
result = append(result, secret)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, s.compare, s.filter), nil
|
||||
}
|
||||
|
||||
func (s *secretSearcher) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftSecret, ok := left.(*v1.Secret)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightSecret, ok := right.(*v1.Secret)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftSecret.ObjectMeta, rightSecret.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (s *secretSearcher) filter(object runtime.Object, filter query.Filter) bool {
|
||||
secret, ok := object.(*v1.Secret)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(secret.ObjectMeta, filter)
|
||||
}
|
||||
Reference in New Issue
Block a user