提交 f20c1f33 编写于 作者: Z Zack Zhang 提交者: hongming

refactor application controller

Signed-off-by: Nzackzhang <zackzhang@yunify.com>
上级 fe6c5de0
......@@ -22,7 +22,6 @@ import (
"k8s.io/klog"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
"kubesphere.io/kubesphere/pkg/controller/application"
"kubesphere.io/kubesphere/pkg/controller/certificatesigningrequest"
"kubesphere.io/kubesphere/pkg/controller/cluster"
"kubesphere.io/kubesphere/pkg/controller/clusterrolebinding"
......@@ -76,7 +75,6 @@ func addControllers(
kubernetesInformer := informerFactory.KubernetesSharedInformerFactory()
istioInformer := informerFactory.IstioSharedInformerFactory()
kubesphereInformer := informerFactory.KubeSphereSharedInformerFactory()
applicationInformer := informerFactory.ApplicationSharedInformerFactory()
var vsController, drController manager.Runnable
if serviceMeshEnabled {
......@@ -97,15 +95,6 @@ func addControllers(
client.KubeSphere())
}
apController := application.NewApplicationController(kubernetesInformer.Core().V1().Services(),
kubernetesInformer.Apps().V1().Deployments(),
kubernetesInformer.Apps().V1().StatefulSets(),
kubesphereInformer.Servicemesh().V1alpha2().Strategies(),
kubesphereInformer.Servicemesh().V1alpha2().ServicePolicies(),
applicationInformer.App().V1beta1().Applications(),
client.Kubernetes(),
client.Application())
jobController := job.NewJobController(kubernetesInformer.Batch().V1().Jobs(), client.Kubernetes())
var s2iBinaryController, s2iRunController, devopsProjectController, devopsPipelineController, devopsCredentialController manager.Runnable
......@@ -272,7 +261,6 @@ func addControllers(
controllers := map[string]manager.Runnable{
"virtualservice-controller": vsController,
"destinationrule-controller": drController,
"application-controller": apController,
"job-controller": jobController,
"s2ibinary-controller": s2iBinaryController,
"s2irun-controller": s2iRunController,
......
......@@ -26,6 +26,7 @@ import (
"kubesphere.io/kubesphere/cmd/controller-manager/app/options"
"kubesphere.io/kubesphere/pkg/apis"
controllerconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
appcontroller "kubesphere.io/kubesphere/pkg/controller/application"
"kubesphere.io/kubesphere/pkg/controller/namespace"
"kubesphere.io/kubesphere/pkg/controller/network/webhooks"
"kubesphere.io/kubesphere/pkg/controller/user"
......@@ -122,7 +123,7 @@ func run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
}
var ldapClient ldapclient.Interface
//when there is no ldapOption, we set ldapClient as nil, which means we don't need to sync user info into ldap.
// when there is no ldapOption, we set ldapClient as nil, which means we don't need to sync user info into ldap.
if s.LdapOptions != nil && len(s.LdapOptions.Host) != 0 {
if s.LdapOptions.Host == ldapclient.FAKE_HOST { // for debug only
ldapClient = ldapclient.NewSimpleLdap()
......@@ -156,7 +157,6 @@ func run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
kubernetesClient.Kubernetes(),
kubernetesClient.KubeSphere(),
kubernetesClient.Istio(),
kubernetesClient.Application(),
kubernetesClient.Snapshot(),
kubernetesClient.ApiExtensions())
......@@ -215,6 +215,11 @@ func run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
klog.Fatal("Unable to create namespace controller")
}
err = appcontroller.Add(mgr)
if err != nil {
klog.Fatal("Unable to create ks application controller")
}
applicationReconciler := &application.ApplicationReconciler{
Scheme: mgr.GetScheme(),
Client: mgr.GetClient(),
......
......@@ -22,12 +22,16 @@ import (
"fmt"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apis"
"kubesphere.io/kubesphere/pkg/apiserver"
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
"kubesphere.io/kubesphere/pkg/informers"
genericoptions "kubesphere.io/kubesphere/pkg/server/options"
auditingclient "kubesphere.io/kubesphere/pkg/simple/client/auditing/elasticsearch"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
runtimecache "sigs.k8s.io/controller-runtime/pkg/cache"
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events/elasticsearch"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
......@@ -105,7 +109,7 @@ func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIS
apiServer.KubernetesClient = kubernetesClient
informerFactory := informers.NewInformerFactories(kubernetesClient.Kubernetes(), kubernetesClient.KubeSphere(),
kubernetesClient.Istio(), kubernetesClient.Application(), kubernetesClient.Snapshot(), kubernetesClient.ApiExtensions())
kubernetesClient.Istio(), kubernetesClient.Snapshot(), kubernetesClient.ApiExtensions())
apiServer.InformerFactory = informerFactory
if s.MonitoringOptions == nil || len(s.MonitoringOptions.Endpoint) == 0 {
......@@ -207,6 +211,16 @@ func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIS
server.TLSConfig.Certificates = []tls.Certificate{certificate}
}
sch := scheme.Scheme
if err := apis.AddToScheme(sch); err != nil {
klog.Fatalf("unable add APIs to scheme: %v", err)
}
apiServer.RuntimeCache, err = runtimecache.New(apiServer.KubernetesClient.Config(), runtimecache.Options{Scheme: sch})
if err != nil {
klog.Fatalf("unable to create runtime cache: %v", err)
}
apiServer.Server = server
return apiServer, nil
......
......@@ -22,7 +22,6 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
"kubesphere.io/kubesphere/cmd/ks-apiserver/app/options"
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
"kubesphere.io/kubesphere/pkg/utils/signals"
......
......@@ -90,6 +90,7 @@ require (
k8s.io/code-generator v0.19.0
k8s.io/component-base v0.18.6
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.0.0
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6
k8s.io/kubectl v0.18.6
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451
......
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package v1beta1
import (
"regexp"
"strings"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// Constants for condition
const (
// Ready => controller considers this resource Ready
Ready = "Ready"
// Qualified => functionally tested
Qualified = "Qualified"
// Settled => observed generation == generation + settled means controller is done acting functionally tested
Settled = "Settled"
// Cleanup => it is set to track finalizer failures
Cleanup = "Cleanup"
// Error => last recorded error
Error = "Error"
ReasonInit = "Init"
)
// Descriptor defines the Metadata and informations about the Application.
type Descriptor struct {
// Type is the type of the application (e.g. WordPress, MySQL, Cassandra).
Type string `json:"type,omitempty"`
// Version is an optional version indicator for the Application.
Version string `json:"version,omitempty"`
// Description is a brief string description of the Application.
Description string `json:"description,omitempty"`
// Icons is an optional list of icons for an application. Icon information includes the source, size,
// and mime type.
Icons []ImageSpec `json:"icons,omitempty"`
// Maintainers is an optional list of maintainers of the application. The maintainers in this list maintain the
// the source code, images, and package for the application.
Maintainers []ContactData `json:"maintainers,omitempty"`
// Owners is an optional list of the owners of the installed application. The owners of the application should be
// contacted in the event of a planned or unplanned disruption affecting the application.
Owners []ContactData `json:"owners,omitempty"`
// Keywords is an optional list of key words associated with the application (e.g. MySQL, RDBMS, database).
Keywords []string `json:"keywords,omitempty"`
// Links are a list of descriptive URLs intended to be used to surface additional documentation, dashboards, etc.
Links []Link `json:"links,omitempty"`
// Notes contain a human readable snippets intended as a quick start for the users of the Application.
// CommonMark markdown syntax may be used for rich text representation.
Notes string `json:"notes,omitempty"`
}
// ApplicationSpec defines the specification for an Application.
type ApplicationSpec struct {
// ComponentGroupKinds is a list of Kinds for Application's components (e.g. Deployments, Pods, Services, CRDs). It
// can be used in conjunction with the Application's Selector to list or watch the Applications components.
ComponentGroupKinds []metav1.GroupKind `json:"componentKinds,omitempty"`
// Descriptor regroups information and metadata about an application.
Descriptor Descriptor `json:"descriptor,omitempty"`
// Selector is a label query over kinds that created by the application. It must match the component objects' labels.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
Selector *metav1.LabelSelector `json:"selector,omitempty"`
// AddOwnerRef objects - flag to indicate if we need to add OwnerRefs to matching objects
// Matching is done by using Selector to query all ComponentGroupKinds
AddOwnerRef bool `json:"addOwnerRef,omitempty"`
// Info contains human readable key,value pairs for the Application.
// +patchStrategy=merge
// +patchMergeKey=name
Info []InfoItem `json:"info,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
// AssemblyPhase represents the current phase of the application's assembly.
// An empty value is equivalent to "Succeeded".
AssemblyPhase ApplicationAssemblyPhase `json:"assemblyPhase,omitempty"`
}
// ComponentList is a generic status holder for the top level resource
type ComponentList struct {
// Object status array for all matching objects
Objects []ObjectStatus `json:"components,omitempty"`
}
// ObjectStatus is a generic status holder for objects
type ObjectStatus struct {
// Link to object
Link string `json:"link,omitempty"`
// Name of object
Name string `json:"name,omitempty"`
// Kind of object
Kind string `json:"kind,omitempty"`
// Object group
Group string `json:"group,omitempty"`
// Status. Values: InProgress, Ready, Unknown
Status string `json:"status,omitempty"`
}
// ConditionType encodes information on the condition
type ConditionType string
// Condition describes the state of an object at a certain point.
type Condition struct {
// Type of condition.
Type ConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=StatefulSetConditionType"`
// Status of the condition, one of True, False, Unknown.
Status corev1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"`
// The reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
// A human readable message indicating details about the transition.
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
// Last time the condition was probed
// +optional
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty" protobuf:"bytes,3,opt,name=lastProbeTime"`
// Last time the condition transitioned from one status to another.
// +optional
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"`
}
// ApplicationStatus defines controller's the observed state of Application
type ApplicationStatus struct {
// ObservedGeneration is the most recent generation observed. It corresponds to the
// Object's generation, which is updated on mutation by the API Server.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
// Conditions represents the latest state of the object
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,10,rep,name=conditions"`
// Resources embeds a list of object statuses
// +optional
ComponentList `json:",inline,omitempty"`
// ComponentsReady: status of the components in the format ready/total
// +optional
ComponentsReady string `json:"componentsReady,omitempty"`
}
// ImageSpec contains information about an image used as an icon.
type ImageSpec struct {
// The source for image represented as either an absolute URL to the image or a Data URL containing
// the image. Data URLs are defined in RFC 2397.
Source string `json:"src"`
// (optional) The size of the image in pixels (e.g., 25x25).
Size string `json:"size,omitempty"`
// (optional) The mine type of the image (e.g., "image/png").
Type string `json:"type,omitempty"`
}
// ContactData contains information about an individual or organization.
type ContactData struct {
// Name is the descriptive name.
Name string `json:"name,omitempty"`
// Url could typically be a website address.
URL string `json:"url,omitempty"`
// Email is the email address.
Email string `json:"email,omitempty"`
}
// Link contains information about an URL to surface documentation, dashboards, etc.
type Link struct {
// Description is human readable content explaining the purpose of the link.
Description string `json:"description,omitempty"`
// Url typically points at a website address.
URL string `json:"url,omitempty"`
}
// InfoItem is a human readable key,value pair containing important information about how to access the Application.
type InfoItem struct {
// Name is a human readable title for this piece of information.
Name string `json:"name,omitempty"`
// Type of the value for this InfoItem.
Type InfoItemType `json:"type,omitempty"`
// Value is human readable content.
Value string `json:"value,omitempty"`
// ValueFrom defines a reference to derive the value from another source.
ValueFrom *InfoItemSource `json:"valueFrom,omitempty"`
}
// InfoItemType is a string that describes the value of InfoItem
type InfoItemType string
const (
// ValueInfoItemType const string for value type
ValueInfoItemType InfoItemType = "Value"
// ReferenceInfoItemType const string for ref type
ReferenceInfoItemType InfoItemType = "Reference"
)
// InfoItemSource represents a source for the value of an InfoItem.
type InfoItemSource struct {
// Type of source.
Type InfoItemSourceType `json:"type,omitempty"`
// Selects a key of a Secret.
SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty"`
// Selects a key of a ConfigMap.
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
// Select a Service.
ServiceRef *ServiceSelector `json:"serviceRef,omitempty"`
// Select an Ingress.
IngressRef *IngressSelector `json:"ingressRef,omitempty"`
}
// InfoItemSourceType is a string
type InfoItemSourceType string
// Constants for info type
const (
SecretKeyRefInfoItemSourceType InfoItemSourceType = "SecretKeyRef"
ConfigMapKeyRefInfoItemSourceType InfoItemSourceType = "ConfigMapKeyRef"
ServiceRefInfoItemSourceType InfoItemSourceType = "ServiceRef"
IngressRefInfoItemSourceType InfoItemSourceType = "IngressRef"
)
// ConfigMapKeySelector selects a key from a ConfigMap.
type ConfigMapKeySelector struct {
// The ConfigMap to select from.
corev1.ObjectReference `json:",inline"`
// The key to select.
Key string `json:"key,omitempty"`
}
// SecretKeySelector selects a key from a Secret.
type SecretKeySelector struct {
// The Secret to select from.
corev1.ObjectReference `json:",inline"`
// The key to select.
Key string `json:"key,omitempty"`
}
// ServiceSelector selects a Service.
type ServiceSelector struct {
// The Service to select from.
corev1.ObjectReference `json:",inline"`
// The optional port to select.
Port *int32 `json:"port,omitempty"`
// The optional HTTP path.
Path string `json:"path,omitempty"`
// Protocol for the service
Protocol string `json:"protocol,omitempty"`
}
// IngressSelector selects an Ingress.
type IngressSelector struct {
// The Ingress to select from.
corev1.ObjectReference `json:",inline"`
// The optional host to select.
Host string `json:"host,omitempty"`
// The optional HTTP path.
Path string `json:"path,omitempty"`
// Protocol for the ingress
Protocol string `json:"protocol,omitempty"`
}
// ApplicationAssemblyPhase tracks the Application CRD phases: pending, succeeded, failed
type ApplicationAssemblyPhase string
// Constants
const (
// Used to indicate that not all of application's components
// have been deployed yet.
Pending ApplicationAssemblyPhase = "Pending"
// Used to indicate that all of application's components
// have already been deployed.
Succeeded = "Succeeded"
// Used to indicate that deployment of application's components
// failed. Some components might be present, but deployment of
// the remaining ones will not be re-attempted.
Failed = "Failed"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=all,shortName=app
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Type",type=string,description="The type of the application",JSONPath=`.spec.descriptor.type`,priority=0
// +kubebuilder:printcolumn:name="Version",type=string,description="The creation date",JSONPath=`.spec.descriptor.version`,priority=0
// +kubebuilder:printcolumn:name="Owner",type=boolean,description="The application object owns the matched resources",JSONPath=`.spec.addOwnerRef`,priority=0
// +kubebuilder:printcolumn:name="Ready",type=string,description="Numbers of components ready",JSONPath=`.status.componentsReady`,priority=0
// +kubebuilder:printcolumn:name="Age",type=date,description="The creation date",JSONPath=`.metadata.creationTimestamp`,priority=0
// Application is the Schema for the applications API
type Application struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ApplicationSpec `json:"spec,omitempty"`
Status ApplicationStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ApplicationList contains a list of Application
type ApplicationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Application `json:"items"`
}
func init() {
SchemeBuilder.Register(&Application{}, &ApplicationList{})
}
// StripVersion the version part of gv
func StripVersion(gv string) string {
if gv == "" {
return gv
}
re := regexp.MustCompile(`^[vV][0-9].*`)
// If it begins with only version, (group is nil), return empty string which maps to core group
if re.MatchString(gv) {
return ""
}
return strings.Split(gv, "/")[0]
}
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package v1beta1
import (
"testing"
"context"
"github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)
func TestStorageApplication(t *testing.T) {
key := types.NamespacedName{
Name: "foo",
Namespace: "default",
}
created := &Application{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "default",
}}
g := gomega.NewGomegaWithT(t)
// Test Create
fetched := &Application{}
g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred())
g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred())
g.Expect(fetched).To(gomega.Equal(created))
// Test Updating the Labels
updated := fetched.DeepCopy()
updated.Labels = map[string]string{"hello": "world"}
g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred())
g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred())
g.Expect(fetched).To(gomega.Equal(updated))
// Test Delete
g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred())
g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred())
// Test stripVersion()
g.Expect(StripVersion("")).To(gomega.Equal(""))
g.Expect(StripVersion("v1beta1")).To(gomega.Equal(""))
g.Expect(StripVersion("apps/v1")).To(gomega.Equal("apps"))
g.Expect(StripVersion("apps/v1alpha2")).To(gomega.Equal("apps"))
}
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package v1beta1 contains API Schema definitions for the app v1beta1 API group
// +kubebuilder:object:generate=true
// +groupName=app.k8s.io
package v1beta1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
var (
// SchemeGroupVersion is group version used to register these objects
SchemeGroupVersion = schema.GroupVersion{Group: "app.k8s.io", Version: "v1beta1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
// Modified.
// Register GVR manually
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package v1beta1
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
var c client.Client
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 c, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}); err != nil {
log.Fatal(err)
}
code := m.Run()
_ = t.Stop()
os.Exit(code)
}
// +build !ignore_autogenerated
/*
Copyright 2018 The Kubernetes 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 controller-gen. DO NOT EDIT.
package v1beta1
import (
"k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Application) DeepCopyInto(out *Application) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application.
func (in *Application) DeepCopy() *Application {
if in == nil {
return nil
}
out := new(Application)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Application) 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 *ApplicationList) DeepCopyInto(out *ApplicationList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Application, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationList.
func (in *ApplicationList) DeepCopy() *ApplicationList {
if in == nil {
return nil
}
out := new(ApplicationList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ApplicationList) 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 *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) {
*out = *in
if in.ComponentGroupKinds != nil {
in, out := &in.ComponentGroupKinds, &out.ComponentGroupKinds
*out = make([]v1.GroupKind, len(*in))
copy(*out, *in)
}
in.Descriptor.DeepCopyInto(&out.Descriptor)
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = new(v1.LabelSelector)
(*in).DeepCopyInto(*out)
}
if in.Info != nil {
in, out := &in.Info, &out.Info
*out = make([]InfoItem, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSpec.
func (in *ApplicationSpec) DeepCopy() *ApplicationSpec {
if in == nil {
return nil
}
out := new(ApplicationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
in.ComponentList.DeepCopyInto(&out.ComponentList)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationStatus.
func (in *ApplicationStatus) DeepCopy() *ApplicationStatus {
if in == nil {
return nil
}
out := new(ApplicationStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentList) DeepCopyInto(out *ComponentList) {
*out = *in
if in.Objects != nil {
in, out := &in.Objects, &out.Objects
*out = make([]ObjectStatus, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentList.
func (in *ComponentList) DeepCopy() *ComponentList {
if in == nil {
return nil
}
out := new(ComponentList)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Condition) DeepCopyInto(out *Condition) {
*out = *in
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
func (in *Condition) DeepCopy() *Condition {
if in == nil {
return nil
}
out := new(Condition)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ConfigMapKeySelector) DeepCopyInto(out *ConfigMapKeySelector) {
*out = *in
out.ObjectReference = in.ObjectReference
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapKeySelector.
func (in *ConfigMapKeySelector) DeepCopy() *ConfigMapKeySelector {
if in == nil {
return nil
}
out := new(ConfigMapKeySelector)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContactData) DeepCopyInto(out *ContactData) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContactData.
func (in *ContactData) DeepCopy() *ContactData {
if in == nil {
return nil
}
out := new(ContactData)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Descriptor) DeepCopyInto(out *Descriptor) {
*out = *in
if in.Icons != nil {
in, out := &in.Icons, &out.Icons
*out = make([]ImageSpec, len(*in))
copy(*out, *in)
}
if in.Maintainers != nil {
in, out := &in.Maintainers, &out.Maintainers
*out = make([]ContactData, len(*in))
copy(*out, *in)
}
if in.Owners != nil {
in, out := &in.Owners, &out.Owners
*out = make([]ContactData, len(*in))
copy(*out, *in)
}
if in.Keywords != nil {
in, out := &in.Keywords, &out.Keywords
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Links != nil {
in, out := &in.Links, &out.Links
*out = make([]Link, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Descriptor.
func (in *Descriptor) DeepCopy() *Descriptor {
if in == nil {
return nil
}
out := new(Descriptor)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageSpec) DeepCopyInto(out *ImageSpec) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageSpec.
func (in *ImageSpec) DeepCopy() *ImageSpec {
if in == nil {
return nil
}
out := new(ImageSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfoItem) DeepCopyInto(out *InfoItem) {
*out = *in
if in.ValueFrom != nil {
in, out := &in.ValueFrom, &out.ValueFrom
*out = new(InfoItemSource)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfoItem.
func (in *InfoItem) DeepCopy() *InfoItem {
if in == nil {
return nil
}
out := new(InfoItem)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InfoItemSource) DeepCopyInto(out *InfoItemSource) {
*out = *in
if in.SecretKeyRef != nil {
in, out := &in.SecretKeyRef, &out.SecretKeyRef
*out = new(SecretKeySelector)
**out = **in
}
if in.ConfigMapKeyRef != nil {
in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef
*out = new(ConfigMapKeySelector)
**out = **in
}
if in.ServiceRef != nil {
in, out := &in.ServiceRef, &out.ServiceRef
*out = new(ServiceSelector)
(*in).DeepCopyInto(*out)
}
if in.IngressRef != nil {
in, out := &in.IngressRef, &out.IngressRef
*out = new(IngressSelector)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfoItemSource.
func (in *InfoItemSource) DeepCopy() *InfoItemSource {
if in == nil {
return nil
}
out := new(InfoItemSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IngressSelector) DeepCopyInto(out *IngressSelector) {
*out = *in
out.ObjectReference = in.ObjectReference
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressSelector.
func (in *IngressSelector) DeepCopy() *IngressSelector {
if in == nil {
return nil
}
out := new(IngressSelector)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Link) DeepCopyInto(out *Link) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Link.
func (in *Link) DeepCopy() *Link {
if in == nil {
return nil
}
out := new(Link)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ObjectStatus) DeepCopyInto(out *ObjectStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStatus.
func (in *ObjectStatus) DeepCopy() *ObjectStatus {
if in == nil {
return nil
}
out := new(ObjectStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) {
*out = *in
out.ObjectReference = in.ObjectReference
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeySelector.
func (in *SecretKeySelector) DeepCopy() *SecretKeySelector {
if in == nil {
return nil
}
out := new(SecretKeySelector)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceSelector) DeepCopyInto(out *ServiceSelector) {
*out = *in
out.ObjectReference = in.ObjectReference
if in.Port != nil {
in, out := &in.Port, &out.Port
*out = new(int32)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSelector.
func (in *ServiceSelector) DeepCopy() *ServiceSelector {
if in == nil {
return nil
}
out := new(ServiceSelector)
in.DeepCopyInto(out)
return out
}
......@@ -20,14 +20,6 @@ import (
"bytes"
"context"
"fmt"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/rbac"
"kubesphere.io/kubesphere/pkg/models/auth"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/loginrecord"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/user"
"net/http"
rt "runtime"
"time"
"github.com/emicklei/go-restful"
"k8s.io/apimachinery/pkg/runtime/schema"
urlruntime "k8s.io/apimachinery/pkg/util/runtime"
......@@ -49,6 +41,7 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizerfactory"
authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/path"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/rbac"
unionauthorizer "kubesphere.io/kubesphere/pkg/apiserver/authorization/union"
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
"kubesphere.io/kubesphere/pkg/apiserver/dispatch"
......@@ -73,9 +66,12 @@ import (
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2"
terminalv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/terminal/v1alpha2"
"kubesphere.io/kubesphere/pkg/kapis/version"
"kubesphere.io/kubesphere/pkg/models/auth"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/iam/group"
"kubesphere.io/kubesphere/pkg/models/iam/im"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/loginrecord"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/user"
"kubesphere.io/kubesphere/pkg/simple/client/auditing"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
......@@ -87,6 +83,10 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/s3"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
utilnet "kubesphere.io/kubesphere/pkg/utils/net"
"net/http"
rt "runtime"
runtimecache "sigs.k8s.io/controller-runtime/pkg/cache"
"time"
)
const (
......@@ -143,6 +143,9 @@ type APIServer struct {
EventsClient events.Client
AuditingClient auditing.Client
// controller-runtime cache
RuntimeCache runtimecache.Cache
}
func (s *APIServer) PrepareRun(stopCh <-chan struct{}) error {
......@@ -182,7 +185,7 @@ func (s *APIServer) installKubeSphereAPIs() {
rbacAuthorizer := rbac.NewRBACAuthorizer(amOperator)
urlruntime.Must(configv1alpha2.AddToContainer(s.container, s.Config))
urlruntime.Must(resourcev1alpha3.AddToContainer(s.container, s.InformerFactory))
urlruntime.Must(resourcev1alpha3.AddToContainer(s.container, s.InformerFactory, s.RuntimeCache))
urlruntime.Must(monitoringv1alpha3.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.InformerFactory, s.OpenpitrixClient))
urlruntime.Must(openpitrixv1.AddToContainer(s.container, s.InformerFactory, s.OpenpitrixClient))
urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes()))
......@@ -353,27 +356,20 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error {
{Group: "", Version: "v1", Resource: "persistentvolumeclaims"},
{Group: "", Version: "v1", Resource: "secrets"},
{Group: "", Version: "v1", Resource: "configmaps"},
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles"},
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "rolebindings"},
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles"},
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings"},
{Group: "apps", Version: "v1", Resource: "deployments"},
{Group: "apps", Version: "v1", Resource: "daemonsets"},
{Group: "apps", Version: "v1", Resource: "replicasets"},
{Group: "apps", Version: "v1", Resource: "statefulsets"},
{Group: "apps", Version: "v1", Resource: "controllerrevisions"},
{Group: "storage.k8s.io", Version: "v1", Resource: "storageclasses"},
{Group: "batch", Version: "v1", Resource: "jobs"},
{Group: "batch", Version: "v1beta1", Resource: "cronjobs"},
{Group: "extensions", Version: "v1beta1", Resource: "ingresses"},
{Group: "autoscaling", Version: "v2beta2", Resource: "horizontalpodautoscalers"},
{Group: "networking.k8s.io", Version: "v1", Resource: "networkpolicies"},
}
......@@ -470,26 +466,6 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error {
ksInformerFactory.Start(stopCh)
ksInformerFactory.WaitForCacheSync(stopCh)
appInformerFactory := s.InformerFactory.ApplicationSharedInformerFactory()
appGVRs := []schema.GroupVersionResource{
{Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"},
}
for _, gvr := range appGVRs {
if !isResourceExists(gvr) {
klog.Warningf("resource %s not exists in the cluster", gvr)
} else {
_, err = appInformerFactory.ForResource(gvr)
if err != nil {
return err
}
}
}
appInformerFactory.Start(stopCh)
appInformerFactory.WaitForCacheSync(stopCh)
snapshotInformerFactory := s.InformerFactory.SnapshotSharedInformerFactory()
snapshotGVRs := []schema.GroupVersionResource{
{Group: "snapshot.storage.k8s.io", Version: "v1beta1", Resource: "volumesnapshotclasses"},
......@@ -527,6 +503,10 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error {
apiextensionsInformerFactory.Start(stopCh)
apiextensionsInformerFactory.WaitForCacheSync(stopCh)
// controller runtime cache for resources
go s.RuntimeCache.Start(stopCh)
s.RuntimeCache.WaitForCacheSync(stopCh)
klog.V(0).Info("Finished caching objects")
return nil
......
......@@ -56,7 +56,7 @@ func TestGetAuditLevel(t *testing.T) {
ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
......@@ -85,7 +85,7 @@ func TestAuditing_Enabled(t *testing.T) {
ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
......@@ -115,7 +115,7 @@ func TestAuditing_K8sAuditingEnabled(t *testing.T) {
ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
......@@ -145,7 +145,7 @@ func TestAuditing_LogRequestObject(t *testing.T) {
ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
......@@ -236,7 +236,7 @@ func TestAuditing_LogResponseObject(t *testing.T) {
ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
......
......@@ -857,7 +857,7 @@ func newMockRBACAuthorizer(staticRoles *StaticRoles) (*RBACAuthorizer, error) {
ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
ksInformerFactory := fakeInformerFactory.KubeSphereSharedInformerFactory()
......
......@@ -18,262 +18,124 @@ package application
import (
"context"
"fmt"
"time"
v1 "k8s.io/api/core/v1"
v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
v1beta12 "k8s.io/api/networking/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
informersv1 "k8s.io/client-go/informers/apps/v1"
coreinformers "k8s.io/client-go/informers/core/v1"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
listersv1 "k8s.io/client-go/listers/apps/v1"
corelisters "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
log "k8s.io/klog"
servicemeshinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh/v1alpha2"
servicemeshlisters "kubesphere.io/kubesphere/pkg/client/listers/servicemesh/v1alpha2"
"k8s.io/klog"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
"kubesphere.io/kubesphere/pkg/controller/virtualservice/util"
applicationclient "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
applicationinformers "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions/app/v1beta1"
applicationlister "kubesphere.io/kubesphere/pkg/simple/client/app/listers/app/v1beta1"
)
const (
// maxRetries is the number of times a service will be retried before it is dropped out of the queue.
// With the current rate-limiter in use (5ms*2^(maxRetries-1)) the following numbers represent the
// sequence of delays between successive queuings of a service.
//
// 5ms, 10ms, 20ms, 40ms, 80ms, 160ms, 320ms, 640ms, 1.3s, 2.6s, 5.1s, 10.2s, 20.4s, 41s, 82s
maxRetries = 15
"sigs.k8s.io/application/api/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
"time"
)
type ApplicationController struct {
client clientset.Interface
applicationClient applicationclient.Interface
eventBroadcaster record.EventBroadcaster
eventRecorder record.EventRecorder
applicationLister applicationlister.ApplicationLister
applicationSynced cache.InformerSynced
serviceLister corelisters.ServiceLister
serviceSynced cache.InformerSynced
deploymentLister listersv1.DeploymentLister
deploymentSynced cache.InformerSynced
statefulSetLister listersv1.StatefulSetLister
statefulSetSynced cache.InformerSynced
strategyLister servicemeshlisters.StrategyLister
strategySynced cache.InformerSynced
servicePolicyLister servicemeshlisters.ServicePolicyLister
servicePolicySynced cache.InformerSynced
queue workqueue.RateLimitingInterface
workerLoopPeriod time.Duration
// Add creates a new Workspace Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager) error {
return add(mgr, newReconciler(mgr))
}
func NewApplicationController(serviceInformer coreinformers.ServiceInformer,
deploymentInformer informersv1.DeploymentInformer,
statefulSetInformer informersv1.StatefulSetInformer,
strategyInformer servicemeshinformers.StrategyInformer,
servicePolicyInformer servicemeshinformers.ServicePolicyInformer,
applicationInformer applicationinformers.ApplicationInformer,
client clientset.Interface,
applicationClient applicationclient.Interface) *ApplicationController {
broadcaster := record.NewBroadcaster()
broadcaster.StartLogging(func(format string, args ...interface{}) {
log.Info(fmt.Sprintf(format, args))
})
broadcaster.StartRecordingToSink(&corev1.EventSinkImpl{Interface: client.CoreV1().Events("")})
recorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "application-controller"})
v := &ApplicationController{
client: client,
applicationClient: applicationClient,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "application"),
workerLoopPeriod: time.Second,
}
v.deploymentLister = deploymentInformer.Lister()
v.deploymentSynced = deploymentInformer.Informer().HasSynced
deploymentInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: v.enqueueObject,
UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) },
DeleteFunc: v.enqueueObject,
})
v.statefulSetLister = statefulSetInformer.Lister()
v.statefulSetSynced = statefulSetInformer.Informer().HasSynced
statefulSetInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: v.enqueueObject,
UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) },
DeleteFunc: v.enqueueObject,
})
v.serviceLister = serviceInformer.Lister()
v.serviceSynced = serviceInformer.Informer().HasSynced
serviceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: v.enqueueObject,
UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) },
DeleteFunc: v.enqueueObject,
})
v.strategyLister = strategyInformer.Lister()
v.strategySynced = strategyInformer.Informer().HasSynced
strategyInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: v.enqueueObject,
UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) },
DeleteFunc: v.enqueueObject,
})
v.servicePolicyLister = servicePolicyInformer.Lister()
v.servicePolicySynced = servicePolicyInformer.Informer().HasSynced
servicePolicyInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: v.enqueueObject,
UpdateFunc: func(old, new interface{}) { v.enqueueObject(new) },
DeleteFunc: v.enqueueObject,
})
v.applicationLister = applicationInformer.Lister()
v.applicationSynced = applicationInformer.Informer().HasSynced
v.eventBroadcaster = broadcaster
v.eventRecorder = recorder
return v
}
func (v *ApplicationController) Start(stopCh <-chan struct{}) error {
return v.Run(2, stopCh)
// newReconciler returns a new reconcile.Reconciler
func newReconciler(mgr manager.Manager) reconcile.Reconciler {
return &ReconcileApplication{Client: mgr.GetClient(), scheme: mgr.GetScheme(),
recorder: mgr.GetEventRecorderFor("application-controller")}
}
func (v *ApplicationController) Run(workers int, stopCh <-chan struct{}) error {
defer utilruntime.HandleCrash()
defer v.queue.ShutDown()
log.Info("starting application controller")
defer log.Info("shutting down application controller")
if !cache.WaitForCacheSync(stopCh, v.deploymentSynced, v.statefulSetSynced, v.serviceSynced, v.strategySynced, v.servicePolicySynced, v.applicationSynced) {
return fmt.Errorf("failed to wait for caches to sync")
// add adds a new Controller to mgr with r as the reconcile.Reconciler
func add(mgr manager.Manager, r reconcile.Reconciler) error {
// Create a new controller
c, err := controller.New("application-controller", mgr, controller.Options{Reconciler: r})
if err != nil {
return err
}
for i := 0; i < workers; i++ {
go wait.Until(v.worker, v.workerLoopPeriod, stopCh)
sources := []runtime.Object{
&v1.Deployment{},
&corev1.Service{},
&v1.StatefulSet{},
&v1beta12.Ingress{},
&servicemeshv1alpha2.ServicePolicy{},
&servicemeshv1alpha2.Strategy{},
}
<-stopCh
return nil
}
func (v *ApplicationController) worker() {
for v.processNextWorkItem() {
}
}
func (v *ApplicationController) processNextWorkItem() bool {
eKey, quit := v.queue.Get()
if quit {
return false
for _, s := range sources {
// Watch for changes to Application
err = c.Watch(&source.Kind{Type: s},
&handler.EnqueueRequestForOwner{OwnerType: &v1beta1.Application{}, IsController: false},
predicate.Funcs{
UpdateFunc: func(e event.UpdateEvent) bool {
return isApp(e.MetaOld)
},
CreateFunc: func(e event.CreateEvent) bool {
return isApp(e.Meta)
},
DeleteFunc: func(e event.DeleteEvent) bool {
return isApp(e.Meta)
},
})
if err != nil {
return err
}
}
defer v.queue.Done(eKey)
err := v.syncApplication(eKey.(string))
v.handleErr(err, eKey)
return true
return nil
}
func (v *ApplicationController) syncApplication(key string) error {
startTime := time.Now()
namespace, name, err := cache.SplitMetaNamespaceKey(key)
if err != nil {
log.Error(err, "not a valid controller key", "key", key)
return err
}
var _ reconcile.Reconciler = &ReconcileApplication{}
defer func() {
log.V(4).Info("Finished updating application.", "namespace", namespace, "name", name, "duration", time.Since(startTime))
}()
// ReconcileApplication reconciles a Workspace object
type ReconcileApplication struct {
client.Client
scheme *runtime.Scheme
recorder record.EventRecorder
}
application, err := v.applicationLister.Applications(namespace).Get(name)
// +kubebuilder:rbac:groups=app.k8s.io,resources=applications,verbs=get;list;watch;create;update;patch;delete
func (r *ReconcileApplication) Reconcile(request reconcile.Request) (reconcile.Result, error) {
// Fetch the Application instance
ctx := context.Background()
app := &v1beta1.Application{}
err := r.Get(ctx, request.NamespacedName, app)
if err != nil {
if errors.IsNotFound(err) {
// application has been deleted
return nil
return reconcile.Result{}, nil
}
log.Error(err, "get application failed")
return reconcile.Result{}, err
}
annotations := application.GetAnnotations()
// add specified annotation for app when triggered by sub-resources,
// so the application in sigs.k8s.io can reconcile to update status
annotations := app.GetObjectMeta().GetAnnotations()
if annotations == nil {
annotations = make(map[string]string)
}
annotations["kubesphere.io/last-updated"] = time.Now().String()
application.SetAnnotations(annotations)
_, err = v.applicationClient.AppV1beta1().Applications(namespace).Update(context.Background(), application, metav1.UpdateOptions{})
app.SetAnnotations(annotations)
err = r.Update(ctx, app)
if err != nil {
if errors.IsNotFound(err) {
log.V(4).Info("application has been deleted during update")
return nil
klog.V(4).Info("application has been deleted during update")
return reconcile.Result{}, nil
}
log.Error(err, "failed to update application", "namespace", namespace, "name", name)
return err
}
return nil
return reconcile.Result{}, nil
}
func (v *ApplicationController) enqueueObject(obj interface{}) {
var resource = obj.(metav1.Object)
if resource.GetLabels() == nil || !util.IsApplicationComponent(resource.GetLabels()) {
return
}
applicationName := util.GetApplictionName(resource.GetLabels())
if len(applicationName) > 0 {
key := resource.GetNamespace() + "/" + applicationName
v.queue.Add(key)
}
}
func (v *ApplicationController) handleErr(err error, key interface{}) {
if err == nil {
v.queue.Forget(key)
return
}
if v.queue.NumRequeues(key) < maxRetries {
log.V(2).Info("Error syncing virtualservice for service retrying.", "key", key, "error", err)
v.queue.AddRateLimited(key)
return
func isApp(o metav1.Object) bool {
if o.GetLabels() == nil || !util.IsApplicationComponent(o.GetLabels()) {
return false
}
log.V(4).Info("Dropping service out of the queue.", "key", key, "error", err)
v.queue.Forget(key)
utilruntime.HandleError(err)
return true
}
......@@ -18,6 +18,7 @@ package cluster
import (
"bytes"
"context"
"encoding/json"
"fmt"
"math/rand"
......@@ -325,7 +326,7 @@ func (c *clusterController) reconcileHostCluster() error {
// no host cluster, create one
if len(clusters) == 0 {
hostCluster.Spec.Connection.KubeConfig = hostKubeConfig
_, err = c.clusterClient.Create(hostCluster)
_, err = c.clusterClient.Create(context.TODO(), hostCluster, metav1.CreateOptions{})
return err
} else if len(clusters) > 1 {
return fmt.Errorf("there MUST not be more than one host clusters, while there are %d", len(clusters))
......@@ -349,7 +350,7 @@ func (c *clusterController) reconcileHostCluster() error {
}
// update host cluster config
_, err = c.clusterClient.Update(cluster)
_, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
return err
}
......@@ -387,7 +388,7 @@ func (c *clusterController) syncCluster(key string) error {
// registering our finalizer.
if !sets.NewString(cluster.ObjectMeta.Finalizers...).Has(clusterv1alpha1.Finalizer) {
cluster.ObjectMeta.Finalizers = append(cluster.ObjectMeta.Finalizers, clusterv1alpha1.Finalizer)
if cluster, err = c.clusterClient.Update(cluster); err != nil {
if cluster, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
return err
}
}
......@@ -403,7 +404,7 @@ func (c *clusterController) syncCluster(key string) error {
return err
}
_, err = c.client.CoreV1().Services(defaultAgentNamespace).Get(serviceName, metav1.GetOptions{})
_, err = c.client.CoreV1().Services(defaultAgentNamespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
// nothing to do
......@@ -412,7 +413,7 @@ func (c *clusterController) syncCluster(key string) error {
return err
}
} else {
err = c.client.CoreV1().Services(defaultAgentNamespace).Delete(serviceName, metav1.NewDeleteOptions(0))
err = c.client.CoreV1().Services(defaultAgentNamespace).Delete(context.TODO(), serviceName, *metav1.NewDeleteOptions(0))
if err != nil {
klog.Errorf("Unable to delete service %s, error %v", serviceName, err)
return err
......@@ -435,7 +436,7 @@ func (c *clusterController) syncCluster(key string) error {
finalizers := sets.NewString(cluster.ObjectMeta.Finalizers...)
finalizers.Delete(clusterv1alpha1.Finalizer)
cluster.ObjectMeta.Finalizers = finalizers.List()
if _, err = c.clusterClient.Update(cluster); err != nil {
if _, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{}); err != nil {
return err
}
}
......@@ -504,10 +505,10 @@ func (c *clusterController) syncCluster(key string) error {
},
}
service, err := c.client.CoreV1().Services(defaultAgentNamespace).Get(serviceName, metav1.GetOptions{})
service, err := c.client.CoreV1().Services(defaultAgentNamespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
if err != nil { // proxy service not found
if errors.IsNotFound(err) {
service, err = c.client.CoreV1().Services(defaultAgentNamespace).Create(&mcService)
service, err = c.client.CoreV1().Services(defaultAgentNamespace).Create(context.TODO(), &mcService, metav1.CreateOptions{})
if err != nil {
return err
}
......@@ -519,7 +520,7 @@ func (c *clusterController) syncCluster(key string) error {
mcService.ObjectMeta = service.ObjectMeta
mcService.Spec.ClusterIP = service.Spec.ClusterIP
service, err = c.client.CoreV1().Services(defaultAgentNamespace).Update(&mcService)
service, err = c.client.CoreV1().Services(defaultAgentNamespace).Update(context.TODO(), &mcService, metav1.UpdateOptions{})
if err != nil {
return err
}
......@@ -544,7 +545,7 @@ func (c *clusterController) syncCluster(key string) error {
}
if !reflect.DeepEqual(oldCluster, cluster) {
cluster, err = c.clusterClient.Update(cluster)
cluster, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Error updating cluster %s, error %s", cluster.Name, err)
return err
......@@ -567,7 +568,7 @@ func (c *clusterController) syncCluster(key string) error {
c.updateClusterCondition(cluster, clusterNotReadyCondition)
cluster, err = c.clusterClient.Update(cluster)
cluster, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Error updating cluster %s, error %s", cluster.Name, err)
}
......@@ -630,7 +631,7 @@ func (c *clusterController) syncCluster(key string) error {
cluster.Status.KubernetesVersion = version.GitVersion
nodes, err := clusterDt.client.CoreV1().Nodes().List(metav1.ListOptions{})
nodes, err := clusterDt.client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get cluster nodes, %#v", err)
return err
......@@ -679,7 +680,7 @@ func (c *clusterController) syncCluster(key string) error {
}
if !reflect.DeepEqual(oldCluster, cluster) {
_, err = c.clusterClient.Update(cluster)
_, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update cluster status, %#v", err)
return err
......@@ -690,7 +691,7 @@ func (c *clusterController) syncCluster(key string) error {
}
func (c *clusterController) checkIfClusterIsHostCluster(memberClusterNodes *v1.NodeList) bool {
hostNodes, err := c.client.CoreV1().Nodes().List(metav1.ListOptions{})
hostNodes, err := c.client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
return false
}
......
......@@ -765,7 +765,7 @@ func checkWorkspaces(clusterConfig *rest.Config, hostClient client.Client, clust
return err
}
workspaces, err := tenantclient.Workspaces().List(metav1.ListOptions{LabelSelector: kubefedManagedSelector})
workspaces, err := tenantclient.Workspaces().List(context.TODO(), metav1.ListOptions{LabelSelector: kubefedManagedSelector})
if err != nil {
return err
}
......
......@@ -147,7 +147,7 @@ func (f *fixture) runController(user string, startInformers bool, expectError bo
actions := filterInformerActions(f.ksclient.Actions())
for j, action := range actions {
if len(f.actions) < j+1 {
f.t.Errorf("%d unexpected actions: %+v", len(actions)-len(f.actions), actions)
f.t.Errorf("%d unexpected actions: %+v", len(actions)-len(f.actions), actions[j:])
break
}
......@@ -180,7 +180,8 @@ func (f *fixture) runController(user string, startInformers bool, expectError bo
func checkAction(expected, actual core.Action, t *testing.T) {
if !(expected.Matches(actual.GetVerb(), actual.GetResource().Resource) && actual.GetSubresource() == expected.GetSubresource()) {
t.Errorf("Expected\n\t%#v\ngot\n\t%#v", expected, actual)
return
//return
// TODO : failed sometimes, need to be verified by hongming
}
if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
......
......@@ -17,6 +17,7 @@ limitations under the License.
package ippool
import (
"context"
"fmt"
"reflect"
"time"
......@@ -92,7 +93,7 @@ func (c *IPPoolController) addFinalizer(pool *networkv1alpha1.IPPool) error {
networkv1alpha1.IPPoolTypeLabel: clone.Spec.Type,
networkv1alpha1.IPPoolIDLabel: fmt.Sprintf("%d", clone.ID()),
}
pool, err := c.kubesphereClient.NetworkV1alpha1().IPPools().Update(clone)
pool, err := c.kubesphereClient.NetworkV1alpha1().IPPools().Update(context.TODO(), clone, metav1.UpdateOptions{})
if err != nil {
klog.V(3).Infof("Error adding finalizer to pool %s: %v", pool.Name, err)
return err
......@@ -104,7 +105,7 @@ func (c *IPPoolController) addFinalizer(pool *networkv1alpha1.IPPool) error {
func (c *IPPoolController) removeFinalizer(pool *networkv1alpha1.IPPool) error {
clone := pool.DeepCopy()
controllerutil.RemoveFinalizer(clone, networkv1alpha1.IPPoolFinalizer)
pool, err := c.kubesphereClient.NetworkV1alpha1().IPPools().Update(clone)
pool, err := c.kubesphereClient.NetworkV1alpha1().IPPools().Update(context.TODO(), clone, metav1.UpdateOptions{})
if err != nil {
klog.V(3).Infof("Error removing finalizer from pool %s: %v", pool.Name, err)
return err
......@@ -144,7 +145,7 @@ func (c *IPPoolController) ValidateCreate(obj runtime.Object) error {
}
}
pools, err := c.kubesphereClient.NetworkV1alpha1().IPPools().List(metav1.ListOptions{
pools, err := c.kubesphereClient.NetworkV1alpha1().IPPools().List(context.TODO(), metav1.ListOptions{
LabelSelector: labels.SelectorFromSet(labels.Set{
networkv1alpha1.IPPoolIDLabel: fmt.Sprintf("%d", b.ID()),
}).String(),
......@@ -203,7 +204,7 @@ func (c *IPPoolController) disableIPPool(old *networkv1alpha1.IPPool) error {
clone := old.DeepCopy()
clone.Spec.Disabled = true
old, err := c.kubesphereClient.NetworkV1alpha1().IPPools().Update(clone)
old, err := c.kubesphereClient.NetworkV1alpha1().IPPools().Update(context.TODO(), clone, metav1.UpdateOptions{})
return err
}
......@@ -218,7 +219,7 @@ func (c *IPPoolController) updateIPPoolStatus(old *networkv1alpha1.IPPool) error
return nil
}
_, err = c.kubesphereClient.NetworkV1alpha1().IPPools().UpdateStatus(new)
_, err = c.kubesphereClient.NetworkV1alpha1().IPPools().UpdateStatus(context.TODO(), new, metav1.UpdateOptions{})
if err != nil {
return fmt.Errorf("failed to update ippool %s status %v", old.Name, err)
}
......
......@@ -17,6 +17,7 @@ limitations under the License.
package ippool
import (
"context"
"flag"
"testing"
"time"
......@@ -94,11 +95,11 @@ var _ = Describe("test ippool", func() {
Expect(c.ValidateCreate(clone)).Should(HaveOccurred())
clone = pool.DeepCopy()
_, err := ksclient.NetworkV1alpha1().IPPools().Create(clone)
_, err := ksclient.NetworkV1alpha1().IPPools().Create(context.TODO(), clone, v1.CreateOptions{})
Expect(err).ShouldNot(HaveOccurred())
Eventually(func() bool {
result, _ := ksclient.NetworkV1alpha1().IPPools().Get(pool.Name, v1.GetOptions{})
result, _ := ksclient.NetworkV1alpha1().IPPools().Get(context.TODO(), pool.Name, v1.GetOptions{})
if len(result.Labels) != 3 {
return false
}
......@@ -115,7 +116,7 @@ var _ = Describe("test ippool", func() {
})
It("test update ippool", func() {
old, _ := ksclient.NetworkV1alpha1().IPPools().Get(pool.Name, v1.GetOptions{})
old, _ := ksclient.NetworkV1alpha1().IPPools().Get(context.TODO(), pool.Name, v1.GetOptions{})
new := old.DeepCopy()
new.Spec.CIDR = "192.168.1.0/24"
Expect(c.ValidateUpdate(old, new)).Should(HaveOccurred())
......@@ -129,7 +130,7 @@ var _ = Describe("test ippool", func() {
})
Eventually(func() bool {
result, _ := ksclient.NetworkV1alpha1().IPPools().Get(pool.Name, v1.GetOptions{})
result, _ := ksclient.NetworkV1alpha1().IPPools().Get(context.TODO(), pool.Name, v1.GetOptions{})
if result.Status.Allocations != 1 {
return false
}
......@@ -139,12 +140,12 @@ var _ = Describe("test ippool", func() {
})
It("test delete pool", func() {
result, _ := ksclient.NetworkV1alpha1().IPPools().Get(pool.Name, v1.GetOptions{})
result, _ := ksclient.NetworkV1alpha1().IPPools().Get(context.TODO(), pool.Name, v1.GetOptions{})
Expect(c.ValidateDelete(result)).Should(HaveOccurred())
ipamClient.ReleaseByHandle("testhandle")
Eventually(func() bool {
result, _ := ksclient.NetworkV1alpha1().IPPools().Get(pool.Name, v1.GetOptions{})
result, _ := ksclient.NetworkV1alpha1().IPPools().Get(context.TODO(), pool.Name, v1.GetOptions{})
if result.Status.Allocations != 0 {
return false
}
......@@ -152,9 +153,9 @@ var _ = Describe("test ippool", func() {
return true
}, 3*time.Second).Should(Equal(true))
err := ksclient.NetworkV1alpha1().IPPools().Delete(pool.Name, &v1.DeleteOptions{})
err := ksclient.NetworkV1alpha1().IPPools().Delete(context.TODO(), pool.Name, v1.DeleteOptions{})
Expect(err).ShouldNot(HaveOccurred())
blocks, _ := ksclient.NetworkV1alpha1().IPAMBlocks().List(v1.ListOptions{})
blocks, _ := ksclient.NetworkV1alpha1().IPAMBlocks().List(context.TODO(), v1.ListOptions{})
Expect(len(blocks.Items)).Should(Equal(0))
})
})
......@@ -27,8 +27,6 @@ import (
"k8s.io/client-go/kubernetes"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
applicationclient "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
applicationinformers "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions"
"time"
)
......@@ -41,7 +39,6 @@ type InformerFactory interface {
KubernetesSharedInformerFactory() k8sinformers.SharedInformerFactory
KubeSphereSharedInformerFactory() ksinformers.SharedInformerFactory
IstioSharedInformerFactory() istioinformers.SharedInformerFactory
ApplicationSharedInformerFactory() applicationinformers.SharedInformerFactory
SnapshotSharedInformerFactory() snapshotinformer.SharedInformerFactory
ApiExtensionSharedInformerFactory() apiextensionsinformers.SharedInformerFactory
......@@ -53,13 +50,11 @@ type informerFactories struct {
informerFactory k8sinformers.SharedInformerFactory
ksInformerFactory ksinformers.SharedInformerFactory
istioInformerFactory istioinformers.SharedInformerFactory
appInformerFactory applicationinformers.SharedInformerFactory
snapshotInformerFactory snapshotinformer.SharedInformerFactory
apiextensionsInformerFactory apiextensionsinformers.SharedInformerFactory
}
func NewInformerFactories(client kubernetes.Interface, ksClient versioned.Interface, istioClient istioclient.Interface,
appClient applicationclient.Interface,
snapshotClient snapshotclient.Interface, apiextensionsClient apiextensionsclient.Interface) InformerFactory {
factory := &informerFactories{}
......@@ -71,10 +66,6 @@ func NewInformerFactories(client kubernetes.Interface, ksClient versioned.Interf
factory.ksInformerFactory = ksinformers.NewSharedInformerFactory(ksClient, defaultResync)
}
if appClient != nil {
factory.appInformerFactory = applicationinformers.NewSharedInformerFactory(appClient, defaultResync)
}
if istioClient != nil {
factory.istioInformerFactory = istioinformers.NewSharedInformerFactory(istioClient, defaultResync)
}
......@@ -98,10 +89,6 @@ func (f *informerFactories) KubeSphereSharedInformerFactory() ksinformers.Shared
return f.ksInformerFactory
}
func (f *informerFactories) ApplicationSharedInformerFactory() applicationinformers.SharedInformerFactory {
return f.appInformerFactory
}
func (f *informerFactories) IstioSharedInformerFactory() istioinformers.SharedInformerFactory {
return f.istioInformerFactory
}
......@@ -127,10 +114,6 @@ func (f *informerFactories) Start(stopCh <-chan struct{}) {
f.istioInformerFactory.Start(stopCh)
}
if f.appInformerFactory != nil {
f.appInformerFactory.Start(stopCh)
}
if f.snapshotInformerFactory != nil {
f.snapshotInformerFactory.Start(stopCh)
}
......
......@@ -24,7 +24,6 @@ import (
"k8s.io/client-go/kubernetes/fake"
ksfake "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
appinformers "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions"
"time"
)
......@@ -58,10 +57,6 @@ func (n nullInformerFactory) IstioSharedInformerFactory() istioinformers.SharedI
return nil
}
func (n nullInformerFactory) ApplicationSharedInformerFactory() appinformers.SharedInformerFactory {
return nil
}
func (n nullInformerFactory) SnapshotSharedInformerFactory() snapshotinformer.SharedInformerFactory {
return nil
}
......
......@@ -125,7 +125,7 @@ func TestGeranteAgentDeployment(t *testing.T) {
k8sclient := k8sfake.NewSimpleClientset(service)
ksclient := fake.NewSimpleClientset(cluster)
informersFactory := informers.NewInformerFactories(k8sclient, ksclient, nil, nil, nil, nil)
informersFactory := informers.NewInformerFactories(k8sclient, ksclient, nil, nil, nil)
informersFactory.KubernetesSharedInformerFactory().Core().V1().Services().Informer().GetIndexer().Add(service)
informersFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster)
......@@ -233,7 +233,7 @@ func TestValidateKubeConfig(t *testing.T) {
k8sclient := k8sfake.NewSimpleClientset(service)
ksclient := fake.NewSimpleClientset(cluster)
informersFactory := informers.NewInformerFactories(k8sclient, ksclient, nil, nil, nil, nil)
informersFactory := informers.NewInformerFactories(k8sclient, ksclient, nil, nil, nil)
informersFactory.KubernetesSharedInformerFactory().Core().V1().Services().Informer().GetIndexer().Add(service)
informersFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster)
......
......@@ -216,7 +216,7 @@ func TestParseRequestParams(t *testing.T) {
for i, tt := range tests {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
client := fake.NewSimpleClientset(&tt.namespace)
fakeInformerFactory := informers.NewInformerFactories(client, nil, nil, nil, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(client, nil, nil, nil, nil)
handler := newHandler(client, nil, fakeInformerFactory, nil)
result, err := handler.makeQueryOptions(tt.params, tt.lvl)
......
......@@ -48,6 +48,7 @@ func (h *Handler) handleGetResources(request *restful.Request, response *restful
resourceType := request.PathParameter("resources")
name := request.PathParameter("name")
// use informers to retrieve resources
result, err := h.resourceGetterV1alpha3.Get(resourceType, namespace, name)
if err == nil {
response.WriteEntity(result)
......@@ -100,7 +101,6 @@ func (h *Handler) handleListResources(request *restful.Request, response *restfu
api.HandleInternalError(response, nil, err)
return
}
response.WriteEntity(result)
}
......
......@@ -33,7 +33,6 @@ import (
resourcev1alpha2 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
fakeapp "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake"
"testing"
)
......@@ -91,9 +90,7 @@ func TestResourceV1alpha2Fallback(t *testing.T) {
t.Fatal(err)
}
handler := New(resourcev1alpha3.NewResourceGetter(factory),
resourcev1alpha2.NewResourceGetter(factory),
components.NewComponentsGetter(factory.KubernetesSharedInformerFactory()))
handler := New(resourcev1alpha3.NewResourceGetter(factory, nil), resourcev1alpha2.NewResourceGetter(factory), components.NewComponentsGetter(factory.KubernetesSharedInformerFactory()))
for _, test := range tests {
got, err := listResources(test.namespace, test.resource, test.query, handler)
......@@ -186,11 +183,10 @@ func prepare() (informers.InformerFactory, error) {
ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset()
snapshotClient := fakesnapshot.NewSimpleClientset()
apiextensionsClient := fakeapiextensions.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, snapshotClient, apiextensionsClient)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, apiextensionsClient)
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
......
......@@ -28,6 +28,8 @@ import (
"kubesphere.io/kubesphere/pkg/models/components"
resourcev1alpha2 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"sigs.k8s.io/controller-runtime/pkg/cache"
"net/http"
)
......@@ -47,12 +49,10 @@ func Resource(resource string) schema.GroupResource {
return GroupVersion.WithResource(resource).GroupResource()
}
func AddToContainer(c *restful.Container, informerFactory informers.InformerFactory) error {
func AddToContainer(c *restful.Container, informerFactory informers.InformerFactory, cache cache.Cache) error {
webservice := runtime.NewWebService(GroupVersion)
handler := New(resourcev1alpha3.NewResourceGetter(informerFactory),
resourcev1alpha2.NewResourceGetter(informerFactory),
components.NewComponentsGetter(informerFactory.KubernetesSharedInformerFactory()))
handler := New(resourcev1alpha3.NewResourceGetter(informerFactory, cache), resourcev1alpha2.NewResourceGetter(informerFactory), components.NewComponentsGetter(informerFactory.KubernetesSharedInformerFactory()))
webservice.Route(webservice.GET("/{resources}").
To(handler.handleListResources).
......
......@@ -21,7 +21,7 @@ import (
"github.com/emicklei/go-restful-openapi"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
_ "net/http"
"net/http"
)
const groupName = "servicemesh.kubesphere.io"
......@@ -125,6 +125,8 @@ func AddToContainer(c *restful.Container) error {
Param(webservice.QueryParameter("groupBy", "app box grouping characteristic. Available groupings: [app, none, version].").DefaultValue("none")).
Param(webservice.QueryParameter("queryTime", "from which time point in UNIX timestamp, default now")).
Param(webservice.QueryParameter("injectServiceNodes", "flag for injecting the requested service node between source and destination nodes.").DefaultValue("false")).
Returns(http.StatusBadRequest, "bad request", BadRequestError{}).
Returns(http.StatusNotFound, "not found", NotFoundError{}).
Produces(restful.MIME_JSON))
// Get namespace health
......@@ -135,6 +137,8 @@ func AddToContainer(c *restful.Container) error {
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
Param(webservice.QueryParameter("queryTime", "the time to use for query")).
Returns(http.StatusBadRequest, "bad request", BadRequestError{}).
Returns(http.StatusNotFound, "not found", NotFoundError{}).
Produces(restful.MIME_JSON))
// Get workloads health
......
/*
Copyright 2020 The KubeSphere Authors.
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
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,
......@@ -14,14 +14,27 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha2
package v1beta1
/////////////////////
// SWAGGER RESPONSES
/////////////////////
// ApplicationListerExpansion allows custom methods to be added to
// ApplicationLister.
type ApplicationListerExpansion interface{}
// NoContent: the response is empty
type NoContent struct {
Status int32 `json:"status"`
Reason error `json:"reason"`
}
// ApplicationNamespaceListerExpansion allows custom methods to be added to
// ApplicationNamespaceLister.
type ApplicationNamespaceListerExpansion interface{}
// BadRequestError: the client request is incorrect
type BadRequestError struct {
Status int32 `json:"status"`
Reason error `json:"reason"`
}
// NotFoundError is the error message that is generated when server could not find
// what was requested
type NotFoundError struct {
Status int32 `json:"status"`
Reason error `json:"reason"`
}
......@@ -58,7 +58,7 @@ type groupOperator struct {
func New(informers informers.InformerFactory, ksclient kubesphere.Interface, k8sclient kubernetes.Interface) GroupOperator {
return &groupOperator{
resourceGetter: resourcesv1alpha3.NewResourceGetter(informers),
resourceGetter: resourcesv1alpha3.NewResourceGetter(informers, nil),
k8sclient: k8sclient,
ksclient: ksclient,
}
......
/*
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 application
import (
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/server/params"
"sigs.k8s.io/application/api/v1beta1"
)
type appSearcher struct {
//informer externalversions.SharedInformerFactory
}
func NewApplicationSearcher(informers interface{}) v1alpha2.Interface {
return &appSearcher{}
}
func (s *appSearcher) Get(namespace, name string) (interface{}, error) {
//return s.informer.App().V1beta1().Applications().Lister().Applications(namespace).Get(name)
panic("")
}
func (s *appSearcher) match(match map[string]string, item *v1beta1.Application) bool {
for k, v := range match {
if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
return false
}
}
return true
}
func (s *appSearcher) fuzzy(fuzzy map[string]string, item *v1beta1.Application) bool {
for k, v := range fuzzy {
if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
return false
}
}
return true
}
func (s *appSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
//apps, err := s.informer.App().V1beta1().Applications().Lister().Applications(namespace).List(labels.Everything())
//
//if err != nil {
// return nil, err
//}
//
//result := make([]*v1beta1.Application, 0)
//
//if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
// result = apps
//} else {
// for _, item := range apps {
// if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
// result = append(result, item)
// }
// }
//}
//sort.Slice(result, func(i, j int) bool {
// if reverse {
// i, j = j, i
// }
// return v1alpha2.ObjectMetaCompare(result[i].ObjectMeta, result[j].ObjectMeta, orderBy)
//})
//
//r := make([]interface{}, 0)
//for _, i := range result {
// r = append(r, i)
//}
//return r, nil
panic("")
}
......@@ -29,7 +29,6 @@ import (
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/server/params"
fakeapp "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake"
"testing"
)
......@@ -213,9 +212,8 @@ func prepare() (informers.InformerFactory, error) {
ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset()
snapshotClient := fakesnapshot.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, snapshotClient, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, nil)
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
......
......@@ -22,7 +22,6 @@ import (
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/application"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/clusterrole"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/configmap"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/cronjob"
......@@ -84,7 +83,6 @@ func NewResourceGetter(factory informers.InformerFactory) *ResourceGetter {
resourceGetters[v1alpha2.S2iRuns] = s2irun.NewS2iRunSearcher(factory.KubeSphereSharedInformerFactory())
resourceGetters[v1alpha2.S2iBuilderTemplates] = s2buildertemplate.NewS2iBuidlerTemplateSearcher(factory.KubeSphereSharedInformerFactory())
resourceGetters[v1alpha2.Workspaces] = workspace.NewWorkspaceSearcher(factory.KubeSphereSharedInformerFactory())
resourceGetters[v1alpha2.Applications] = application.NewApplicationSearcher(nil)
return &ResourceGetter{resourcesGetters: resourceGetters}
......
......@@ -17,36 +17,47 @@ limitations under the License.
package application
import (
"context"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api"
appv1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
"kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions"
appv1beta1 "sigs.k8s.io/application/api/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
"time"
)
type applicationsGetter struct {
informer externalversions.SharedInformerFactory
c cache.Cache
}
func New(sharedInformers externalversions.SharedInformerFactory) v1alpha3.Interface {
return &applicationsGetter{informer: sharedInformers}
func New(c cache.Cache) v1alpha3.Interface {
return &applicationsGetter{c}
}
func (d *applicationsGetter) Get(namespace, name string) (runtime.Object, error) {
return d.informer.App().V1beta1().Applications().Lister().Applications(namespace).Get(name)
app := appv1beta1.Application{}
err := d.c.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, &app)
if err != nil {
klog.Error(err)
return nil, err
}
return &app, nil
}
func (d *applicationsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
applications, err := d.informer.App().V1beta1().Applications().Lister().Applications(namespace).List(query.Selector())
applications := appv1beta1.ApplicationList{}
err := d.c.List(context.Background(), &applications, &client.ListOptions{Namespace: namespace})
if err != nil {
klog.Error(err)
return nil, err
}
var result []runtime.Object
for _, app := range applications {
result = append(result, app)
for _, app := range applications.Items {
result = append(result, &app)
}
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
......
......@@ -17,104 +17,78 @@ limitations under the License.
package application
import (
"github.com/google/go-cmp/cmp"
"context"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/api"
appv1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/klog/v2"
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions"
"path/filepath"
appv1beta1 "sigs.k8s.io/application/api/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"testing"
)
func applicationsToRuntimeObjects(applications ...*appv1beta1.Application) []runtime.Object {
var objs []runtime.Object
for _, app := range applications {
objs = append(objs, app)
var c client.Client
func createNamespace(name string, ctx context.Context) {
namespace := &core.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
}
err := c.Create(ctx, namespace)
if err != nil {
klog.Error(err)
}
return objs
}
func TestListApplications(t *testing.T) {
tests := []struct {
description string
namespace string
deployments []*appv1beta1.Application
query *query.Query
expected api.ListResult
expectedErr error
}{
{
"test name filter",
"bar2",
[]*appv1beta1.Application{
{
ObjectMeta: metav1.ObjectMeta{
Name: "foo-1",
Namespace: "bar",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "foo-2",
Namespace: "bar",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "bar-2",
Namespace: "bar2",
},
},
},
&query.Query{
Pagination: &query.Pagination{
Limit: 10,
Offset: 0,
},
SortBy: query.FieldName,
Ascending: false,
Filters: map[query.Field]query.Value{query.FieldNamespace: query.Value("bar2")},
},
api.ListResult{
Items: []interface{}{
&appv1beta1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "bar-2",
Namespace: "bar2",
},
},
},
TotalItems: 2,
},
nil,
},
func TestGetListApplications(t *testing.T) {
e := &envtest.Environment{CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "..", "config", "crds")}}
cfg, err := e.Start()
if err != nil {
t.Fatal(err)
}
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
objs := applicationsToRuntimeObjects(test.deployments...)
client := fake.NewSimpleClientset(objs...)
sch := scheme.Scheme
if err := appv1beta1.AddToScheme(sch); err != nil {
t.Fatalf("unable add APIs to scheme: %v", err)
}
informer := externalversions.NewSharedInformerFactory(client, 0)
stopCh := make(chan struct{})
for _, deployment := range test.deployments {
informer.App().V1beta1().Applications().Informer().GetIndexer().Add(deployment)
}
ce, _ := cache.New(cfg, cache.Options{Scheme: sch})
go ce.Start(stopCh)
ce.WaitForCacheSync(stopCh)
getter := New(informer)
c, _ = client.New(cfg, client.Options{Scheme: sch})
got, err := getter.List(test.namespace, test.query)
if test.expectedErr != nil && err != test.expectedErr {
t.Errorf("expected error, got nothing")
} else if err != nil {
t.Fatal(err)
}
var labelSet1 = map[string]string{"foo": "bar"}
application := &appv1beta1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
Namespace: "foo",
Labels: labelSet1,
},
}
ctx := context.TODO()
createNamespace("foo", ctx)
_ = c.Create(ctx, application)
getter := New(ce)
if diff := cmp.Diff(got.Items, test.expected.Items); diff != "" {
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
}
})
_, err = getter.List("foo", &query.Query{})
if err != nil {
t.Fatal(err)
}
_, err = getter.Get("foo", "bar")
if err != nil {
t.Fatal(err)
}
}
......@@ -18,7 +18,6 @@ package resource
import (
"errors"
snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v3/apis/volumesnapshot/v1beta1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime"
......@@ -74,6 +73,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacerole"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacerolebinding"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacetemplate"
"sigs.k8s.io/controller-runtime/pkg/cache"
)
var ErrResourceNotSupported = errors.New("resource is not supported")
......@@ -82,7 +82,7 @@ type ResourceGetter struct {
getters map[schema.GroupVersionResource]v1alpha3.Interface
}
func NewResourceGetter(factory informers.InformerFactory) *ResourceGetter {
func NewResourceGetter(factory informers.InformerFactory, cache cache.Cache) *ResourceGetter {
getters := make(map[schema.GroupVersionResource]v1alpha3.Interface)
getters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}] = deployment.New(factory.KubernetesSharedInformerFactory())
......@@ -94,9 +94,9 @@ func NewResourceGetter(factory informers.InformerFactory) *ResourceGetter {
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: "extensions", Version: "v1beta1", Resource: "ingresses"}] = ingress.New(factory.KubernetesSharedInformerFactory())
getters[schema.GroupVersionResource{Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"}] = application.New(factory.ApplicationSharedInformerFactory())
getters[schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "networkpolicies"}] = networkpolicy.New(factory.KubernetesSharedInformerFactory())
getters[schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "jobs"}] = job.New(factory.KubernetesSharedInformerFactory())
getters[schema.GroupVersionResource{Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"}] = application.New(cache)
// kubesphere resources
getters[devopsv1alpha3.SchemeGroupVersion.WithResource(devopsv1alpha3.ResourcePluralDevOpsProject)] = devops.New(factory.KubeSphereSharedInformerFactory())
......
......@@ -28,7 +28,6 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/query"
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/informers"
fakeapp "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake"
"testing"
)
......@@ -107,15 +106,14 @@ func prepare() *ResourceGetter {
ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset()
snapshotClient := fakesnapshot.NewSimpleClientset()
apiextensionsClient := fakeapiextensions.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, snapshotClient, apiextensionsClient)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, apiextensionsClient)
for _, namespace := range namespaces {
fakeInformerFactory.KubernetesSharedInformerFactory().Core().V1().
Namespaces().Informer().GetIndexer().Add(namespace)
}
return NewResourceGetter(fakeInformerFactory)
return NewResourceGetter(fakeInformerFactory, nil)
}
......@@ -96,7 +96,7 @@ func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ks
return &tenantOperator{
am: am,
authorizer: authorizer,
resourceGetter: resourcesv1alpha3.NewResourceGetter(informers),
resourceGetter: resourcesv1alpha3.NewResourceGetter(informers, nil),
k8sclient: k8sclient,
ksclient: ksclient,
events: events.NewEventsOperator(evtsClient),
......
......@@ -35,7 +35,6 @@ import (
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/iam/am"
fakeapp "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake"
"reflect"
"testing"
)
......@@ -492,8 +491,7 @@ func prepare() Interface {
ksClient := fakeks.NewSimpleClientset([]runtime.Object{testWorkspace, systemWorkspace}...)
k8sClient := fakek8s.NewSimpleClientset([]runtime.Object{testNamespace, kubesphereSystem}...)
istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, nil, nil)
for _, workspace := range workspaces {
fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha1().
......
/*
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 versioned
import (
"fmt"
discovery "k8s.io/client-go/discovery"
rest "k8s.io/client-go/rest"
flowcontrol "k8s.io/client-go/util/flowcontrol"
appv1beta1 "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/typed/app/v1beta1"
)
type Interface interface {
Discovery() discovery.DiscoveryInterface
AppV1beta1() appv1beta1.AppV1beta1Interface
}
// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
type Clientset struct {
*discovery.DiscoveryClient
appV1beta1 *appv1beta1.AppV1beta1Client
}
// AppV1beta1 retrieves the AppV1beta1Client
func (c *Clientset) AppV1beta1() appv1beta1.AppV1beta1Interface {
return c.appV1beta1
}
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
if c == nil {
return nil
}
return c.DiscoveryClient
}
// NewForConfig creates a new Clientset for the given config.
// If config's RateLimiter is not set and QPS and Burst are acceptable,
// NewForConfig will generate a rate-limiter in configShallowCopy.
func NewForConfig(c *rest.Config) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
if configShallowCopy.Burst <= 0 {
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
}
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
}
var cs Clientset
var err error
cs.appV1beta1, err = appv1beta1.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
return &cs, nil
}
// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *Clientset {
var cs Clientset
cs.appV1beta1 = appv1beta1.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs
}
// New creates a new Clientset for the given RESTClient.
func New(c rest.Interface) *Clientset {
var cs Clientset
cs.appV1beta1 = appv1beta1.New(c)
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &cs
}
/*
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 clientset.
package versioned
/*
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 (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/discovery"
fakediscovery "k8s.io/client-go/discovery/fake"
"k8s.io/client-go/testing"
clientset "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
appv1beta1 "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/typed/app/v1beta1"
fakeappv1beta1 "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/typed/app/v1beta1/fake"
)
// NewSimpleClientset returns a clientset that will respond with the provided objects.
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
// without applying any validations and/or defaults. It shouldn't be considered a replacement
// for a real clientset and is mostly useful in simple unit tests.
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
for _, obj := range objects {
if err := o.Add(obj); err != nil {
panic(err)
}
}
cs := &Clientset{tracker: o}
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
cs.AddReactor("*", "*", testing.ObjectReaction(o))
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
gvr := action.GetResource()
ns := action.GetNamespace()
watch, err := o.Watch(gvr, ns)
if err != nil {
return false, nil, err
}
return true, watch, nil
})
return cs
}
// Clientset implements clientset.Interface. Meant to be embedded into a
// struct to get a default implementation. This makes faking out just the method
// you want to test easier.
type Clientset struct {
testing.Fake
discovery *fakediscovery.FakeDiscovery
tracker testing.ObjectTracker
}
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
return c.discovery
}
func (c *Clientset) Tracker() testing.ObjectTracker {
return c.tracker
}
var _ clientset.Interface = &Clientset{}
// AppV1beta1 retrieves the AppV1beta1Client
func (c *Clientset) AppV1beta1() appv1beta1.AppV1beta1Interface {
return &fakeappv1beta1.FakeAppV1beta1{Fake: &c.Fake}
}
/*
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 fake clientset.
package fake
/*
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 (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
appv1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
)
var scheme = runtime.NewScheme()
var codecs = serializer.NewCodecFactory(scheme)
var parameterCodec = runtime.NewParameterCodec(scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
appv1beta1.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(AddToScheme(scheme))
}
/*
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 contains the scheme of the automatically generated clientset.
package scheme
/*
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 scheme
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
appv1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
)
var Scheme = runtime.NewScheme()
var Codecs = serializer.NewCodecFactory(Scheme)
var ParameterCodec = runtime.NewParameterCodec(Scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
appv1beta1.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(AddToScheme(Scheme))
}
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
rest "k8s.io/client-go/rest"
v1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
"kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/scheme"
)
type AppV1beta1Interface interface {
RESTClient() rest.Interface
ApplicationsGetter
}
// AppV1beta1Client is used to interact with features provided by the app group.
type AppV1beta1Client struct {
restClient rest.Interface
}
func (c *AppV1beta1Client) Applications(namespace string) ApplicationInterface {
return newApplications(c, namespace)
}
// NewForConfig creates a new AppV1beta1Client for the given config.
func NewForConfig(c *rest.Config) (*AppV1beta1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &AppV1beta1Client{client}, nil
}
// NewForConfigOrDie creates a new AppV1beta1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *AppV1beta1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new AppV1beta1Client for the given RESTClient.
func New(c rest.Interface) *AppV1beta1Client {
return &AppV1beta1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1beta1.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 *AppV1beta1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
"context"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
scheme "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/scheme"
)
// ApplicationsGetter has a method to return a ApplicationInterface.
// A group's client should implement this interface.
type ApplicationsGetter interface {
Applications(namespace string) ApplicationInterface
}
// ApplicationInterface has methods to work with Application resources.
type ApplicationInterface interface {
Create(ctx context.Context, application *v1beta1.Application, opts v1.CreateOptions) (*v1beta1.Application, error)
Update(ctx context.Context, application *v1beta1.Application, opts v1.UpdateOptions) (*v1beta1.Application, error)
UpdateStatus(ctx context.Context, application *v1beta1.Application, opts v1.UpdateOptions) (*v1beta1.Application, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.Application, error)
List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ApplicationList, error)
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Application, err error)
ApplicationExpansion
}
// applications implements ApplicationInterface
type applications struct {
client rest.Interface
ns string
}
// newApplications returns a Applications
func newApplications(c *AppV1beta1Client, namespace string) *applications {
return &applications{
client: c.RESTClient(),
ns: namespace,
}
}
// Get takes name of the application, and returns the corresponding application object, and an error if there is any.
func (c *applications) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Application, err error) {
result = &v1beta1.Application{}
err = c.client.Get().
Namespace(c.ns).
Resource("applications").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of Applications that match those selectors.
func (c *applications) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ApplicationList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1beta1.ApplicationList{}
err = c.client.Get().
Namespace(c.ns).
Resource("applications").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested applications.
func (c *applications) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("applications").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a application and creates it. Returns the server's representation of the application, and an error, if there is any.
func (c *applications) Create(ctx context.Context, application *v1beta1.Application, opts v1.CreateOptions) (result *v1beta1.Application, err error) {
result = &v1beta1.Application{}
err = c.client.Post().
Namespace(c.ns).
Resource("applications").
VersionedParams(&opts, scheme.ParameterCodec).
Body(application).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a application and updates it. Returns the server's representation of the application, and an error, if there is any.
func (c *applications) Update(ctx context.Context, application *v1beta1.Application, opts v1.UpdateOptions) (result *v1beta1.Application, err error) {
result = &v1beta1.Application{}
err = c.client.Put().
Namespace(c.ns).
Resource("applications").
Name(application.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(application).
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 *applications) UpdateStatus(ctx context.Context, application *v1beta1.Application, opts v1.UpdateOptions) (result *v1beta1.Application, err error) {
result = &v1beta1.Application{}
err = c.client.Put().
Namespace(c.ns).
Resource("applications").
Name(application.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(application).
Do(ctx).
Into(result)
return
}
// Delete takes name of the application and deletes it. Returns an error if one occurs.
func (c *applications) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("applications").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *applications) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Namespace(c.ns).
Resource("applications").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched application.
func (c *applications) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Application, err error) {
result = &v1beta1.Application{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("applications").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}
/*
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 v1beta1
/*
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
/*
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"
v1beta1 "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/typed/app/v1beta1"
)
type FakeAppV1beta1 struct {
*testing.Fake
}
func (c *FakeAppV1beta1) Applications(namespace string) v1beta1.ApplicationInterface {
return &FakeApplications{c, namespace}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeAppV1beta1) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
)
// FakeApplications implements ApplicationInterface
type FakeApplications struct {
Fake *FakeAppV1beta1
ns string
}
var applicationsResource = schema.GroupVersionResource{Group: "app", Version: "v1beta1", Resource: "applications"}
var applicationsKind = schema.GroupVersionKind{Group: "app", Version: "v1beta1", Kind: "Application"}
// Get takes name of the application, and returns the corresponding application object, and an error if there is any.
func (c *FakeApplications) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Application, err error) {
obj, err := c.Fake.
Invokes(testing.NewGetAction(applicationsResource, c.ns, name), &v1beta1.Application{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.Application), err
}
// List takes label and field selectors, and returns the list of Applications that match those selectors.
func (c *FakeApplications) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ApplicationList, err error) {
obj, err := c.Fake.
Invokes(testing.NewListAction(applicationsResource, applicationsKind, c.ns, opts), &v1beta1.ApplicationList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1beta1.ApplicationList{ListMeta: obj.(*v1beta1.ApplicationList).ListMeta}
for _, item := range obj.(*v1beta1.ApplicationList).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 applications.
func (c *FakeApplications) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewWatchAction(applicationsResource, c.ns, opts))
}
// Create takes the representation of a application and creates it. Returns the server's representation of the application, and an error, if there is any.
func (c *FakeApplications) Create(ctx context.Context, application *v1beta1.Application, opts v1.CreateOptions) (result *v1beta1.Application, err error) {
obj, err := c.Fake.
Invokes(testing.NewCreateAction(applicationsResource, c.ns, application), &v1beta1.Application{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.Application), err
}
// Update takes the representation of a application and updates it. Returns the server's representation of the application, and an error, if there is any.
func (c *FakeApplications) Update(ctx context.Context, application *v1beta1.Application, opts v1.UpdateOptions) (result *v1beta1.Application, err error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(applicationsResource, c.ns, application), &v1beta1.Application{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.Application), 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 *FakeApplications) UpdateStatus(ctx context.Context, application *v1beta1.Application, opts v1.UpdateOptions) (*v1beta1.Application, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(applicationsResource, "status", c.ns, application), &v1beta1.Application{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.Application), err
}
// Delete takes name of the application and deletes it. Returns an error if one occurs.
func (c *FakeApplications) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(applicationsResource, c.ns, name), &v1beta1.Application{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeApplications) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(applicationsResource, c.ns, listOpts)
_, err := c.Fake.Invokes(action, &v1beta1.ApplicationList{})
return err
}
// Patch applies the patch and returns the patched application.
func (c *FakeApplications) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Application, err error) {
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(applicationsResource, c.ns, name, pt, data, subresources...), &v1beta1.Application{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.Application), err
}
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
type ApplicationExpansion interface{}
/*
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 app
import (
v1beta1 "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions/app/v1beta1"
internalinterfaces "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions/internalinterfaces"
)
// Interface provides access to each of this group's versions.
type Interface interface {
// V1beta1 provides access to shared informers for resources in V1beta1.
V1beta1() v1beta1.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}
}
// V1beta1 returns a new v1beta1.Interface.
func (g *group) V1beta1() v1beta1.Interface {
return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
}
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1beta1
import (
"context"
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
appv1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
versioned "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
internalinterfaces "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions/internalinterfaces"
v1beta1 "kubesphere.io/kubesphere/pkg/simple/client/app/listers/app/v1beta1"
)
// ApplicationInformer provides access to a shared informer and lister for
// Applications.
type ApplicationInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1beta1.ApplicationLister
}
type applicationInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}
// NewApplicationInformer constructs a new informer for Application 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 NewApplicationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredApplicationInformer(client, namespace, resyncPeriod, indexers, nil)
}
// NewFilteredApplicationInformer constructs a new informer for Application 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 NewFilteredApplicationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.AppV1beta1().Applications(namespace).List(context.TODO(), options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.AppV1beta1().Applications(namespace).Watch(context.TODO(), options)
},
},
&appv1beta1.Application{},
resyncPeriod,
indexers,
)
}
func (f *applicationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredApplicationInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *applicationInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&appv1beta1.Application{}, f.defaultInformer)
}
func (f *applicationInformer) Lister() v1beta1.ApplicationLister {
return v1beta1.NewApplicationLister(f.Informer().GetIndexer())
}
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1beta1
import (
internalinterfaces "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions/internalinterfaces"
)
// Interface provides access to all the informers in this group version.
type Interface interface {
// Applications returns a ApplicationInformer.
Applications() ApplicationInformer
}
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}
}
// Applications returns a ApplicationInformer.
func (v *version) Applications() ApplicationInformer {
return &applicationInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
/*
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 externalversions
import (
reflect "reflect"
sync "sync"
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
versioned "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
app "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions/app"
internalinterfaces "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions/internalinterfaces"
)
// SharedInformerOption defines the functional option type for SharedInformerFactory.
type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory
type sharedInformerFactory struct {
client versioned.Interface
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
lock sync.Mutex
defaultResync time.Duration
customResync map[reflect.Type]time.Duration
informers map[reflect.Type]cache.SharedIndexInformer
// startedInformers is used for tracking which informers have been started.
// This allows Start() to be called multiple times safely.
startedInformers map[reflect.Type]bool
}
// WithCustomResyncConfig sets a custom resync period for the specified informer types.
func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
for k, v := range resyncConfig {
factory.customResync[reflect.TypeOf(k)] = v
}
return factory
}
}
// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
factory.tweakListOptions = tweakListOptions
return factory
}
}
// WithNamespace limits the SharedInformerFactory to the specified namespace.
func WithNamespace(namespace string) SharedInformerOption {
return func(factory *sharedInformerFactory) *sharedInformerFactory {
factory.namespace = namespace
return factory
}
}
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces.
func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
return NewSharedInformerFactoryWithOptions(client, defaultResync)
}
// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory.
// Listers obtained via this SharedInformerFactory will be subject to the same filters
// as specified here.
// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
}
// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
factory := &sharedInformerFactory{
client: client,
namespace: v1.NamespaceAll,
defaultResync: defaultResync,
informers: make(map[reflect.Type]cache.SharedIndexInformer),
startedInformers: make(map[reflect.Type]bool),
customResync: make(map[reflect.Type]time.Duration),
}
// Apply all options
for _, opt := range options {
factory = opt(factory)
}
return factory
}
// Start initializes all requested informers.
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
f.lock.Lock()
defer f.lock.Unlock()
for informerType, informer := range f.informers {
if !f.startedInformers[informerType] {
go informer.Run(stopCh)
f.startedInformers[informerType] = true
}
}
}
// WaitForCacheSync waits for all started informers' cache were synced.
func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
informers := func() map[reflect.Type]cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informers := map[reflect.Type]cache.SharedIndexInformer{}
for informerType, informer := range f.informers {
if f.startedInformers[informerType] {
informers[informerType] = informer
}
}
return informers
}()
res := map[reflect.Type]bool{}
for informType, informer := range informers {
res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
}
return res
}
// InternalInformerFor returns the SharedIndexInformer for obj using an internal
// client.
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(obj)
informer, exists := f.informers[informerType]
if exists {
return informer
}
resyncPeriod, exists := f.customResync[informerType]
if !exists {
resyncPeriod = f.defaultResync
}
informer = newFunc(f.client, resyncPeriod)
f.informers[informerType] = informer
return informer
}
// SharedInformerFactory provides shared informers for resources in all known
// API group versions.
type SharedInformerFactory interface {
internalinterfaces.SharedInformerFactory
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
App() app.Interface
}
func (f *sharedInformerFactory) App() app.Interface {
return app.New(f, f.namespace, f.tweakListOptions)
}
/*
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 externalversions
import (
"fmt"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
v1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
)
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
// sharedInformers based on type
type GenericInformer interface {
Informer() cache.SharedIndexInformer
Lister() cache.GenericLister
}
type genericInformer struct {
informer cache.SharedIndexInformer
resource schema.GroupResource
}
// Informer returns the SharedIndexInformer.
func (f *genericInformer) Informer() cache.SharedIndexInformer {
return f.informer
}
// Lister returns the GenericLister.
func (f *genericInformer) Lister() cache.GenericLister {
return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
}
// ForResource gives generic access to a shared informer of the matching type
// TODO extend this to unknown resources with a client pool
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
switch resource {
// Group=app, Version=v1beta1
case v1beta1.SchemeGroupVersion.WithResource("applications"):
return &genericInformer{resource: resource.GroupResource(), informer: f.App().V1beta1().Applications().Informer()}, nil
}
return nil, fmt.Errorf("no informer found for %v", resource)
}
/*
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 internalinterfaces
import (
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
cache "k8s.io/client-go/tools/cache"
versioned "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
)
// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
type SharedInformerFactory interface {
Start(stopCh <-chan struct{})
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
type TweakListOptionsFunc func(*v1.ListOptions)
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1beta1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
)
// ApplicationLister helps list Applications.
type ApplicationLister interface {
// List lists all Applications in the indexer.
List(selector labels.Selector) (ret []*v1beta1.Application, err error)
// Applications returns an object that can list and get Applications.
Applications(namespace string) ApplicationNamespaceLister
ApplicationListerExpansion
}
// applicationLister implements the ApplicationLister interface.
type applicationLister struct {
indexer cache.Indexer
}
// NewApplicationLister returns a new ApplicationLister.
func NewApplicationLister(indexer cache.Indexer) ApplicationLister {
return &applicationLister{indexer: indexer}
}
// List lists all Applications in the indexer.
func (s *applicationLister) List(selector labels.Selector) (ret []*v1beta1.Application, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1beta1.Application))
})
return ret, err
}
// Applications returns an object that can list and get Applications.
func (s *applicationLister) Applications(namespace string) ApplicationNamespaceLister {
return applicationNamespaceLister{indexer: s.indexer, namespace: namespace}
}
// ApplicationNamespaceLister helps list and get Applications.
type ApplicationNamespaceLister interface {
// List lists all Applications in the indexer for a given namespace.
List(selector labels.Selector) (ret []*v1beta1.Application, err error)
// Get retrieves the Application from the indexer for a given namespace and name.
Get(name string) (*v1beta1.Application, error)
ApplicationNamespaceListerExpansion
}
// applicationNamespaceLister implements the ApplicationNamespaceLister
// interface.
type applicationNamespaceLister struct {
indexer cache.Indexer
namespace string
}
// List lists all Applications in the indexer for a given namespace.
func (s applicationNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Application, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1beta1.Application))
})
return ret, err
}
// Get retrieves the Application from the indexer for a given namespace and name.
func (s applicationNamespaceLister) Get(name string) (*v1beta1.Application, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1beta1.Resource("application"), name)
}
return obj.(*v1beta1.Application), nil
}
......@@ -24,8 +24,6 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
application "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
applicationclientset "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
)
type FakeClient struct {
......@@ -38,8 +36,6 @@ type FakeClient struct {
// generated clientset
KubeSphereClient kubesphere.Interface
ApplicationClient applicationclientset.Interface
IstioClient istioclient.Interface
SnapshotClient snapshotclient.Interface
......@@ -52,14 +48,13 @@ type FakeClient struct {
}
func NewFakeClientSets(k8sClient kubernetes.Interface, discoveryClient *discovery.DiscoveryClient,
kubeSphereClient kubesphere.Interface, applicationClient applicationclientset.Interface,
kubeSphereClient kubesphere.Interface,
istioClient istioclient.Interface, snapshotClient snapshotclient.Interface,
apiextensionsclient apiextensionsclient.Interface, masterURL string, kubeConfig *rest.Config) Client {
return &FakeClient{
K8sClient: k8sClient,
DiscoveryClient: discoveryClient,
KubeSphereClient: kubeSphereClient,
ApplicationClient: applicationClient,
IstioClient: istioClient,
SnapshotClient: snapshotClient,
ApiExtensionClient: apiextensionsclient,
......@@ -80,10 +75,6 @@ func (n *FakeClient) Istio() istioclient.Interface {
return n.IstioClient
}
func (n *FakeClient) Application() application.Interface {
return n.ApplicationClient
}
func (n *FakeClient) Snapshot() snapshotclient.Interface {
return nil
}
......
......@@ -25,7 +25,6 @@ import (
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
applicationclientset "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
"strings"
)
......@@ -33,7 +32,6 @@ type Client interface {
Kubernetes() kubernetes.Interface
KubeSphere() kubesphere.Interface
Istio() istioclient.Interface
Application() applicationclientset.Interface
Snapshot() snapshotclient.Interface
ApiExtensions() apiextensionsclient.Interface
Discovery() discovery.DiscoveryInterface
......@@ -51,8 +49,6 @@ type kubernetesClient struct {
// generated clientset
ks kubesphere.Interface
application applicationclientset.Interface
istio istioclient.Interface
snapshot snapshotclient.Interface
......@@ -79,7 +75,6 @@ func NewKubernetesClientOrDie(options *KubernetesOptions) Client {
discoveryClient: discovery.NewDiscoveryClientForConfigOrDie(config),
ks: kubesphere.NewForConfigOrDie(config),
istio: istioclient.NewForConfigOrDie(config),
application: applicationclientset.NewForConfigOrDie(config),
snapshot: snapshotclient.NewForConfigOrDie(config),
apiextensions: apiextensionsclient.NewForConfigOrDie(config),
master: config.Host,
......@@ -124,11 +119,6 @@ func NewKubernetesClient(options *KubernetesOptions) (Client, error) {
return nil, err
}
k.application, err = applicationclientset.NewForConfig(config)
if err != nil {
return nil, err
}
k.istio, err = istioclient.NewForConfig(config)
if err != nil {
......@@ -163,10 +153,6 @@ func (k *kubernetesClient) KubeSphere() kubesphere.Interface {
return k.ks
}
func (k *kubernetesClient) Application() applicationclientset.Interface {
return k.application
}
func (k *kubernetesClient) Istio() istioclient.Interface {
return k.istio
}
......
......@@ -24,7 +24,6 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
application "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
)
type nullClient struct {
......@@ -46,10 +45,6 @@ func (n nullClient) Istio() istio.Interface {
return nil
}
func (n nullClient) Application() application.Interface {
return nil
}
func (n nullClient) Snapshot() snapshotclient.Interface {
return nil
}
......
......@@ -17,6 +17,7 @@ limitations under the License.
package calico
import (
"context"
"encoding/json"
"errors"
"fmt"
......@@ -120,7 +121,7 @@ func (c provider) CreateIPPool(pool *v1alpha1.IPPool) error {
klog.Warningf("cannot set reference for calico ippool %s, err=%v", pool.Name, err)
}
_, err = c.client.CrdCalicov3().IPPools().Create(calicoPool)
_, err = c.client.CrdCalicov3().IPPools().Create(context.TODO(), calicoPool, v1.CreateOptions{})
if k8serrors.IsAlreadyExists(err) {
return nil
}
......@@ -135,7 +136,7 @@ func (c provider) UpdateIPPool(pool *v1alpha1.IPPool) error {
func (c provider) GetIPPoolStats(pool *v1alpha1.IPPool) (*v1alpha1.IPPool, error) {
stats := pool.DeepCopy()
calicoPool, err := c.client.CrdCalicov3().IPPools().Get(pool.Name, v1.GetOptions{})
calicoPool, err := c.client.CrdCalicov3().IPPools().Get(context.TODO(), pool.Name, v1.GetOptions{})
if err != nil {
return nil, err
}
......@@ -195,7 +196,7 @@ func setBlockAffiDeletion(c calicoset.Interface, blockAffi *calicov3.BlockAffini
}
blockAffi.Spec.State = string(model.StatePendingDeletion)
_, err := c.CrdCalicov3().BlockAffinities().Update(blockAffi)
_, err := c.CrdCalicov3().BlockAffinities().Update(context.TODO(), blockAffi, v1.UpdateOptions{})
return err
}
......@@ -203,13 +204,13 @@ func deleteBlockAffi(c calicoset.Interface, blockAffi *calicov3.BlockAffinity) e
trueStr := fmt.Sprintf("%t", true)
if blockAffi.Spec.Deleted != trueStr {
blockAffi.Spec.Deleted = trueStr
_, err := c.CrdCalicov3().BlockAffinities().Update(blockAffi)
_, err := c.CrdCalicov3().BlockAffinities().Update(context.TODO(), blockAffi, v1.UpdateOptions{})
if err != nil {
return err
}
}
err := c.CrdCalicov3().BlockAffinities().Delete(blockAffi.Name, &v1.DeleteOptions{})
err := c.CrdCalicov3().BlockAffinities().Delete(context.TODO(), blockAffi.Name, v1.DeleteOptions{})
if err != nil {
return err
}
......@@ -220,7 +221,7 @@ func deleteBlockAffi(c calicoset.Interface, blockAffi *calicov3.BlockAffinity) e
func (c provider) doBlockAffis(pool *calicov3.IPPool, do func(calicoset.Interface, *calicov3.BlockAffinity) error) error {
_, cidrNet, _ := cnet.ParseCIDR(pool.Spec.CIDR)
blockAffis, err := c.client.CrdCalicov3().BlockAffinities().List(v1.ListOptions{})
blockAffis, err := c.client.CrdCalicov3().BlockAffinities().List(context.TODO(), v1.ListOptions{})
if err != nil {
return err
}
......@@ -243,7 +244,7 @@ func (c provider) doBlockAffis(pool *calicov3.IPPool, do func(calicoset.Interfac
func (c provider) listBlocks(pool *calicov3.IPPool) ([]calicov3.IPAMBlock, error) {
_, cidrNet, _ := cnet.ParseCIDR(pool.Spec.CIDR)
blocks, err := c.client.CrdCalicov3().IPAMBlocks().List(v1.ListOptions{})
blocks, err := c.client.CrdCalicov3().IPAMBlocks().List(context.TODO(), v1.ListOptions{})
if err != nil {
return nil, err
}
......@@ -280,7 +281,7 @@ func deleteBlock(c calicoset.Interface, block *calicov3.IPAMBlock) error {
if block.Empty() {
if !block.Spec.Deleted {
block.Spec.Deleted = true
_, err := c.CrdCalicov3().IPAMBlocks().Update(block)
_, err := c.CrdCalicov3().IPAMBlocks().Update(context.TODO(), block, v1.UpdateOptions{})
if err != nil {
return err
}
......@@ -288,7 +289,7 @@ func deleteBlock(c calicoset.Interface, block *calicov3.IPAMBlock) error {
} else {
return ErrBlockInuse
}
err := c.CrdCalicov3().IPAMBlocks().Delete(block.Name, &v1.DeleteOptions{})
err := c.CrdCalicov3().IPAMBlocks().Delete(context.TODO(), block.Name, v1.DeleteOptions{})
if err != nil {
return err
}
......@@ -305,7 +306,7 @@ func (c provider) DeleteIPPool(pool *v1alpha1.IPPool) (bool, error) {
// - delete the pool
// Get the pool so that we can find the CIDR associated with it.
calicoPool, err := c.client.CrdCalicov3().IPPools().Get(pool.Name, v1.GetOptions{})
calicoPool, err := c.client.CrdCalicov3().IPPools().Get(context.TODO(), pool.Name, v1.GetOptions{})
if err != nil {
if k8serrors.IsNotFound(err) {
return true, nil
......@@ -317,7 +318,7 @@ func (c provider) DeleteIPPool(pool *v1alpha1.IPPool) (bool, error) {
if !calicoPool.Spec.Disabled {
calicoPool.Spec.Disabled = true
calicoPool, err = c.client.CrdCalicov3().IPPools().Update(calicoPool)
calicoPool, err = c.client.CrdCalicov3().IPPools().Update(context.TODO(), calicoPool, v1.UpdateOptions{})
if err != nil {
return false, err
}
......@@ -354,7 +355,7 @@ func (c provider) DeleteIPPool(pool *v1alpha1.IPPool) (bool, error) {
}
//delete calico ippool
err = c.client.CrdCalicov3().IPPools().Delete(calicoPool.Name, &v1.DeleteOptions{})
err = c.client.CrdCalicov3().IPPools().Delete(context.TODO(), calicoPool.Name, v1.DeleteOptions{})
if err != nil {
return false, err
}
......@@ -365,13 +366,13 @@ func (c provider) DeleteIPPool(pool *v1alpha1.IPPool) (bool, error) {
//Synchronizing address pools at boot time
func (c provider) syncIPPools() error {
calicoPools, err := c.client.CrdCalicov3().IPPools().List(v1.ListOptions{})
calicoPools, err := c.client.CrdCalicov3().IPPools().List(context.TODO(), v1.ListOptions{})
if err != nil {
klog.V(4).Infof("syncIPPools: cannot list calico ippools, err=%v", err)
return err
}
pools, err := c.ksclient.NetworkV1alpha1().IPPools().List(v1.ListOptions{})
pools, err := c.ksclient.NetworkV1alpha1().IPPools().List(context.TODO(), v1.ListOptions{})
if err != nil {
klog.V(4).Infof("syncIPPools: cannot list kubesphere ippools, err=%v", err)
return err
......@@ -401,7 +402,7 @@ func (c provider) syncIPPools() error {
Status: v1alpha1.IPPoolStatus{},
}
_, err = c.ksclient.NetworkV1alpha1().IPPools().Create(pool)
_, err = c.ksclient.NetworkV1alpha1().IPPools().Create(context.TODO(), pool, v1.CreateOptions{})
if err != nil {
klog.V(4).Infof("syncIPPools: cannot create kubesphere ippools, err=%v", err)
return err
......@@ -417,7 +418,7 @@ func (p provider) getAssociatedWorkspaces(pool *v1alpha1.IPPool) ([]string, erro
poolLabel := constants.WorkspaceLabelKey
if pool.GetLabels() == nil || pool.GetLabels()[poolLabel] == "" {
wks, err := p.ksclient.TenantV1alpha1().Workspaces().List(v1.ListOptions{})
wks, err := p.ksclient.TenantV1alpha1().Workspaces().List(context.TODO(), v1.ListOptions{})
if err != nil {
return nil, err
}
......@@ -435,7 +436,7 @@ func (p provider) getAssociatedWorkspaces(pool *v1alpha1.IPPool) ([]string, erro
func (p provider) getWorkspaceStatus(name string, poolName string) (*v1alpha1.WorkspaceStatus, error) {
var result v1alpha1.WorkspaceStatus
namespaces, err := p.k8sclient.CoreV1().Namespaces().List(v1.ListOptions{
namespaces, err := p.k8sclient.CoreV1().Namespaces().List(context.TODO(), v1.ListOptions{
LabelSelector: labels.SelectorFromSet(
map[string]string{
constants.WorkspaceLabelKey: name,
......@@ -447,7 +448,7 @@ func (p provider) getWorkspaceStatus(name string, poolName string) (*v1alpha1.Wo
}
for _, ns := range namespaces.Items {
pods, err := p.k8sclient.CoreV1().Pods(ns.GetName()).List(v1.ListOptions{})
pods, err := p.k8sclient.CoreV1().Pods(ns.GetName()).List(context.TODO(), v1.ListOptions{})
if err != nil {
return nil, err
}
......@@ -499,7 +500,7 @@ func (p provider) processBlock(name string) error {
poolName := block.Labels[v1alpha1.IPPoolNameLabel]
if poolName == "" {
pools, err := p.ksclient.NetworkV1alpha1().IPPools().List(v1.ListOptions{})
pools, err := p.ksclient.NetworkV1alpha1().IPPools().List(context.TODO(), v1.ListOptions{})
if err != nil {
return err
}
......@@ -512,7 +513,7 @@ func (p provider) processBlock(name string) error {
block.Labels = map[string]string{
v1alpha1.IPPoolNameLabel: pool.Name,
}
p.client.CrdCalicov3().IPAMBlocks().Update(block)
p.client.CrdCalicov3().IPAMBlocks().Update(context.TODO(), block, v1.UpdateOptions{})
break
}
}
......@@ -540,7 +541,7 @@ func (p provider) processBlock(name string) error {
}
retry.RetryOnConflict(retry.DefaultBackoff, func() error {
pod, err = p.k8sclient.CoreV1().Pods(namespace).Get(name, v1.GetOptions{})
pod, err = p.k8sclient.CoreV1().Pods(namespace).Get(context.TODO(), name, v1.GetOptions{})
if err != nil {
return err
}
......@@ -563,7 +564,7 @@ func (p provider) processBlock(name string) error {
pod.GetAnnotations()[CalicoAnnotationIPPoolV4] = string(annostrs)
pod.Labels[v1alpha1.IPPoolNameLabel] = poolName
_, err = p.k8sclient.CoreV1().Pods(namespace).Update(pod)
_, err = p.k8sclient.CoreV1().Pods(namespace).Update(context.TODO(), pod, v1.UpdateOptions{})
return err
})
......@@ -617,7 +618,7 @@ func (p provider) Default(obj runtime.Object) error {
}
if annos[CalicoAnnotationIPPoolV4] == "" {
pools, err := p.ksclient.NetworkV1alpha1().IPPools().List(v1.ListOptions{
pools, err := p.ksclient.NetworkV1alpha1().IPPools().List(context.TODO(), v1.ListOptions{
LabelSelector: labels.SelectorFromSet(map[string]string{
v1alpha1.IPPoolDefaultLabel: "",
}).String(),
......@@ -650,7 +651,7 @@ func NewProvider(podInformer informercorev1.PodInformer, ksclient kubesphereclie
klog.Fatalf("failed to new calico client , err=%v", err)
}
ds, err := k8sClient.AppsV1().DaemonSets(CalicoNodeNamespace).Get(CalicoNodeDaemonset, v1.GetOptions{})
ds, err := k8sClient.AppsV1().DaemonSets(CalicoNodeNamespace).Get(context.TODO(), CalicoNodeDaemonset, v1.GetOptions{})
if err != nil {
klog.Fatalf("failed to get calico-node deployment in kube-system, err=%v", err)
}
......
......@@ -123,7 +123,7 @@ func generateSwaggerJson() []byte {
urlruntime.Must(openpitrixv1.AddToContainer(container, informerFactory, openpitrix.NewMockClient(nil)))
urlruntime.Must(operationsv1alpha2.AddToContainer(container, clientsets.Kubernetes()))
urlruntime.Must(resourcesv1alpha2.AddToContainer(container, clientsets.Kubernetes(), informerFactory, ""))
urlruntime.Must(resourcesv1alpha3.AddToContainer(container, informerFactory))
urlruntime.Must(resourcesv1alpha3.AddToContainer(container, informerFactory, nil))
urlruntime.Must(tenantv1alpha2.AddToContainer(container, informerFactory, nil, nil, nil, nil, nil, nil, nil))
urlruntime.Must(terminalv1alpha2.AddToContainer(container, clientsets.Kubernetes(), nil))
urlruntime.Must(metricsv1alpha2.AddToContainer(container))
......
......@@ -1486,6 +1486,7 @@ sigs.k8s.io/controller-runtime/pkg/controller
sigs.k8s.io/controller-runtime/pkg/controller/controllerutil
sigs.k8s.io/controller-runtime/pkg/conversion
sigs.k8s.io/controller-runtime/pkg/envtest
sigs.k8s.io/controller-runtime/pkg/envtest/printer
sigs.k8s.io/controller-runtime/pkg/event
sigs.k8s.io/controller-runtime/pkg/handler
sigs.k8s.io/controller-runtime/pkg/healthz
......
/*
Copyright 2016 The Kubernetes 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 printer contains setup for a friendlier Ginkgo printer that's easier
// to parse by test automation.
package printer
import (
"fmt"
"github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/types"
)
var _ ginkgo.Reporter = NewlineReporter{}
// NewlineReporter is Reporter that Prints a newline after the default Reporter output so that the results
// are correctly parsed by test automation.
// See issue https://github.com/jstemmer/go-junit-report/issues/31
type NewlineReporter struct{}
// SpecSuiteWillBegin implements ginkgo.Reporter
func (NewlineReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
}
// BeforeSuiteDidRun implements ginkgo.Reporter
func (NewlineReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {}
// AfterSuiteDidRun implements ginkgo.Reporter
func (NewlineReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {}
// SpecWillRun implements ginkgo.Reporter
func (NewlineReporter) SpecWillRun(specSummary *types.SpecSummary) {}
// SpecDidComplete implements ginkgo.Reporter
func (NewlineReporter) SpecDidComplete(specSummary *types.SpecSummary) {}
// SpecSuiteDidEnd Prints a newline between "35 Passed | 0 Failed | 0 Pending | 0 Skipped" and "--- PASS:"
func (NewlineReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { fmt.Printf("\n") }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册