refactor application controller

Signed-off-by: zackzhang <zackzhang@yunify.com>
This commit is contained in:
Zack Zhang
2020-12-29 16:18:31 +08:00
committed by hongming
parent fe6c5de00f
commit f20c1f33f1
69 changed files with 1015 additions and 3155 deletions

View File

@@ -22,7 +22,6 @@ import (
"k8s.io/klog" "k8s.io/klog"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options" 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/certificatesigningrequest"
"kubesphere.io/kubesphere/pkg/controller/cluster" "kubesphere.io/kubesphere/pkg/controller/cluster"
"kubesphere.io/kubesphere/pkg/controller/clusterrolebinding" "kubesphere.io/kubesphere/pkg/controller/clusterrolebinding"
@@ -76,7 +75,6 @@ func addControllers(
kubernetesInformer := informerFactory.KubernetesSharedInformerFactory() kubernetesInformer := informerFactory.KubernetesSharedInformerFactory()
istioInformer := informerFactory.IstioSharedInformerFactory() istioInformer := informerFactory.IstioSharedInformerFactory()
kubesphereInformer := informerFactory.KubeSphereSharedInformerFactory() kubesphereInformer := informerFactory.KubeSphereSharedInformerFactory()
applicationInformer := informerFactory.ApplicationSharedInformerFactory()
var vsController, drController manager.Runnable var vsController, drController manager.Runnable
if serviceMeshEnabled { if serviceMeshEnabled {
@@ -97,15 +95,6 @@ func addControllers(
client.KubeSphere()) 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()) jobController := job.NewJobController(kubernetesInformer.Batch().V1().Jobs(), client.Kubernetes())
var s2iBinaryController, s2iRunController, devopsProjectController, devopsPipelineController, devopsCredentialController manager.Runnable var s2iBinaryController, s2iRunController, devopsProjectController, devopsPipelineController, devopsCredentialController manager.Runnable
@@ -272,7 +261,6 @@ func addControllers(
controllers := map[string]manager.Runnable{ controllers := map[string]manager.Runnable{
"virtualservice-controller": vsController, "virtualservice-controller": vsController,
"destinationrule-controller": drController, "destinationrule-controller": drController,
"application-controller": apController,
"job-controller": jobController, "job-controller": jobController,
"s2ibinary-controller": s2iBinaryController, "s2ibinary-controller": s2iBinaryController,
"s2irun-controller": s2iRunController, "s2irun-controller": s2iRunController,

View File

@@ -26,6 +26,7 @@ import (
"kubesphere.io/kubesphere/cmd/controller-manager/app/options" "kubesphere.io/kubesphere/cmd/controller-manager/app/options"
"kubesphere.io/kubesphere/pkg/apis" "kubesphere.io/kubesphere/pkg/apis"
controllerconfig "kubesphere.io/kubesphere/pkg/apiserver/config" 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/namespace"
"kubesphere.io/kubesphere/pkg/controller/network/webhooks" "kubesphere.io/kubesphere/pkg/controller/network/webhooks"
"kubesphere.io/kubesphere/pkg/controller/user" "kubesphere.io/kubesphere/pkg/controller/user"
@@ -122,7 +123,7 @@ func run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
} }
var ldapClient ldapclient.Interface 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 != nil && len(s.LdapOptions.Host) != 0 {
if s.LdapOptions.Host == ldapclient.FAKE_HOST { // for debug only if s.LdapOptions.Host == ldapclient.FAKE_HOST { // for debug only
ldapClient = ldapclient.NewSimpleLdap() ldapClient = ldapclient.NewSimpleLdap()
@@ -156,7 +157,6 @@ func run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
kubernetesClient.Kubernetes(), kubernetesClient.Kubernetes(),
kubernetesClient.KubeSphere(), kubernetesClient.KubeSphere(),
kubernetesClient.Istio(), kubernetesClient.Istio(),
kubernetesClient.Application(),
kubernetesClient.Snapshot(), kubernetesClient.Snapshot(),
kubernetesClient.ApiExtensions()) kubernetesClient.ApiExtensions())
@@ -215,6 +215,11 @@ func run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
klog.Fatal("Unable to create namespace controller") 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{ applicationReconciler := &application.ApplicationReconciler{
Scheme: mgr.GetScheme(), Scheme: mgr.GetScheme(),
Client: mgr.GetClient(), Client: mgr.GetClient(),

View File

@@ -22,12 +22,16 @@ import (
"fmt" "fmt"
cliflag "k8s.io/component-base/cli/flag" cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apis"
"kubesphere.io/kubesphere/pkg/apiserver" "kubesphere.io/kubesphere/pkg/apiserver"
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config" apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
genericoptions "kubesphere.io/kubesphere/pkg/server/options" genericoptions "kubesphere.io/kubesphere/pkg/server/options"
auditingclient "kubesphere.io/kubesphere/pkg/simple/client/auditing/elasticsearch" auditingclient "kubesphere.io/kubesphere/pkg/simple/client/auditing/elasticsearch"
"kubesphere.io/kubesphere/pkg/simple/client/cache" "kubesphere.io/kubesphere/pkg/simple/client/cache"
runtimecache "sigs.k8s.io/controller-runtime/pkg/cache"
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins" "kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events/elasticsearch" eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events/elasticsearch"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client/k8s"
@@ -105,7 +109,7 @@ func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIS
apiServer.KubernetesClient = kubernetesClient apiServer.KubernetesClient = kubernetesClient
informerFactory := informers.NewInformerFactories(kubernetesClient.Kubernetes(), kubernetesClient.KubeSphere(), informerFactory := informers.NewInformerFactories(kubernetesClient.Kubernetes(), kubernetesClient.KubeSphere(),
kubernetesClient.Istio(), kubernetesClient.Application(), kubernetesClient.Snapshot(), kubernetesClient.ApiExtensions()) kubernetesClient.Istio(), kubernetesClient.Snapshot(), kubernetesClient.ApiExtensions())
apiServer.InformerFactory = informerFactory apiServer.InformerFactory = informerFactory
if s.MonitoringOptions == nil || len(s.MonitoringOptions.Endpoint) == 0 { 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} 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 apiServer.Server = server
return apiServer, nil return apiServer, nil

View File

@@ -22,7 +22,6 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
cliflag "k8s.io/component-base/cli/flag" cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/cmd/ks-apiserver/app/options" "kubesphere.io/kubesphere/cmd/ks-apiserver/app/options"
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config" apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
"kubesphere.io/kubesphere/pkg/utils/signals" "kubesphere.io/kubesphere/pkg/utils/signals"

View File

@@ -1,236 +1,529 @@
apiVersion: apiextensions.k8s.io/v1beta1 # Copyright 2020 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations:
api-approved.kubernetes.io: https://github.com/kubernetes-sigs/application/pull/2
controller-gen.kubebuilder.io/version: v0.4.0
creationTimestamp: null creationTimestamp: null
labels:
controller-tools.k8s.io: "1.0"
name: applications.app.k8s.io name: applications.app.k8s.io
spec: spec:
group: app.k8s.io group: app.k8s.io
names: names:
categories:
- all
kind: Application kind: Application
listKind: ApplicationList
plural: applications plural: applications
shortNames:
- app
singular: application
scope: Namespaced scope: Namespaced
validation: versions:
openAPIV3Schema: - additionalPrinterColumns:
properties: - description: The type of the application
apiVersion: jsonPath: .spec.descriptor.type
type: string name: Type
kind: type: string
type: string - description: The creation date
metadata: jsonPath: .spec.descriptor.version
type: object name: Version
spec: type: string
properties: - description: The application object owns the matched resources
assemblyPhase: jsonPath: .spec.addOwnerRef
type: string name: Owner
componentKinds: type: boolean
items: - description: Numbers of components ready
type: object jsonPath: .status.componentsReady
type: array name: Ready
descriptor: type: string
properties: - description: The creation date
description: jsonPath: .metadata.creationTimestamp
type: string name: Age
icons: type: date
items: name: v1beta1
properties: schema:
size: openAPIV3Schema:
type: string description: Application is the Schema for the applications API
src: properties:
type: string apiVersion:
type: description: 'APIVersion defines the versioned schema of this representation
type: string of an object. Servers should convert recognized schemas to the latest
required: internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- src type: string
type: object kind:
type: array description: 'Kind is a string value representing the REST resource this
keywords: object represents. Servers may infer this from the endpoint the client
items: submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string type: string
type: array metadata:
links: type: object
items: spec:
properties: description: ApplicationSpec defines the specification for an Application.
description: properties:
type: string addOwnerRef:
url: description: AddOwnerRef objects - flag to indicate if we need to
type: string add OwnerRefs to matching objects Matching is done by using Selector
type: object to query all ComponentGroupKinds
type: array type: boolean
maintainers: assemblyPhase:
items: description: AssemblyPhase represents the current phase of the application's
properties: assembly. An empty value is equivalent to "Succeeded".
email: type: string
type: string componentKinds:
name: description: ComponentGroupKinds is a list of Kinds for Application's
type: string components (e.g. Deployments, Pods, Services, CRDs). It can be used
url: in conjunction with the Application's Selector to list or watch
type: string the Applications components.
type: object items:
type: array description: GroupKind specifies a Group and a Kind, but does not
notes: force a version. This is useful for identifying concepts during
type: string lookup stages without having partially valid types
owners: properties:
items: group:
properties: type: string
email: kind:
type: string type: string
name: required:
type: string - group
url: - kind
type: string type: object
type: object type: array
type: array descriptor:
type: description: Descriptor regroups information and metadata about an
type: string application.
version:
type: string
type: object
info:
items:
properties: properties:
name: description:
description: Description is a brief string description of the
Application.
type: string type: string
icons:
description: Icons is an optional list of icons for an application.
Icon information includes the source, size, and mime type.
items:
description: ImageSpec contains information about an image used
as an icon.
properties:
size:
description: (optional) The size of the image in pixels
(e.g., 25x25).
type: string
src:
description: 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.
type: string
type:
description: (optional) The mine type of the image (e.g.,
"image/png").
type: string
required:
- src
type: object
type: array
keywords:
description: Keywords is an optional list of key words associated
with the application (e.g. MySQL, RDBMS, database).
items:
type: string
type: array
links:
description: Links are a list of descriptive URLs intended to
be used to surface additional documentation, dashboards, etc.
items:
description: Link contains information about an URL to surface
documentation, dashboards, etc.
properties:
description:
description: Description is human readable content explaining
the purpose of the link.
type: string
url:
description: Url typically points at a website address.
type: string
type: object
type: array
maintainers:
description: 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.
items:
description: ContactData contains information about an individual
or organization.
properties:
email:
description: Email is the email address.
type: string
name:
description: Name is the descriptive name.
type: string
url:
description: Url could typically be a website address.
type: string
type: object
type: array
notes:
description: 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.
type: string
owners:
description: 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.
items:
description: ContactData contains information about an individual
or organization.
properties:
email:
description: Email is the email address.
type: string
name:
description: Name is the descriptive name.
type: string
url:
description: Url could typically be a website address.
type: string
type: object
type: array
type: type:
description: Type is the type of the application (e.g. WordPress,
MySQL, Cassandra).
type: string type: string
value: version:
description: Version is an optional version indicator for the
Application.
type: string type: string
valueFrom: type: object
properties: info:
configMapKeyRef: description: Info contains human readable key,value pairs for the
properties: Application.
apiVersion: items:
description: InfoItem is a human readable key,value pair containing
important information about how to access the Application.
properties:
name:
description: Name is a human readable title for this piece of
information.
type: string
type:
description: Type of the value for this InfoItem.
type: string
value:
description: Value is human readable content.
type: string
valueFrom:
description: ValueFrom defines a reference to derive the value
from another source.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a
valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container
within a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container
that triggered the event) or if no container name
is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to
have some well-defined way of referencing a part of
an object. TODO: this design is not final and this
field is subject to change in the future.'
type: string
key:
description: The key to select.
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info:
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this
reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
ingressRef:
description: Select an Ingress.
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a
valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container
within a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container
that triggered the event) or if no container name
is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to
have some well-defined way of referencing a part of
an object. TODO: this design is not final and this
field is subject to change in the future.'
type: string
host:
description: The optional host to select.
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info:
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
path:
description: The optional HTTP path.
type: string
protocol:
description: Protocol for the ingress
type: string
resourceVersion:
description: 'Specific resourceVersion to which this
reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
secretKeyRef:
description: Selects a key of a Secret.
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a
valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container
within a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container
that triggered the event) or if no container name
is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to
have some well-defined way of referencing a part of
an object. TODO: this design is not final and this
field is subject to change in the future.'
type: string
key:
description: The key to select.
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info:
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this
reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
serviceRef:
description: Select a Service.
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a
valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container
within a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container
that triggered the event) or if no container name
is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to
have some well-defined way of referencing a part of
an object. TODO: this design is not final and this
field is subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info:
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
path:
description: The optional HTTP path.
type: string
port:
description: The optional port to select.
format: int32
type: integer
protocol:
description: Protocol for the service
type: string
resourceVersion:
description: 'Specific resourceVersion to which this
reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
type:
description: Type of source.
type: string
type: object
type: object
type: array
selector:
description: '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'
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: A label selector requirement is a selector that
contains values, a key, and an operator that relates the key
and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: operator represents a key's relationship to
a set of values. Valid operators are In, NotIn, Exists
and DoesNotExist.
type: string
values:
description: values is an array of string values. If the
operator is In or NotIn, the values array must be non-empty.
If the operator is Exists or DoesNotExist, the values
array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string type: string
fieldPath: type: array
type: string required:
key: - key
type: string - operator
kind: type: object
type: string type: array
name: matchLabels:
type: string additionalProperties:
namespace: type: string
type: string description: matchLabels is a map of {key,value} pairs. A single
resourceVersion: {key,value} in the matchLabels map is equivalent to an element
type: string of matchExpressions, whose key field is "key", the operator
uid: is "In", and the values array contains only "value". The requirements
type: string are ANDed.
type: object
ingressRef:
properties:
apiVersion:
type: string
fieldPath:
type: string
host:
type: string
kind:
type: string
name:
type: string
namespace:
type: string
path:
type: string
resourceVersion:
type: string
uid:
type: string
type: object
secretKeyRef:
properties:
apiVersion:
type: string
fieldPath:
type: string
key:
type: string
kind:
type: string
name:
type: string
namespace:
type: string
resourceVersion:
type: string
uid:
type: string
type: object
serviceRef:
properties:
apiVersion:
type: string
fieldPath:
type: string
kind:
type: string
name:
type: string
namespace:
type: string
path:
type: string
port:
format: int32
type: integer
resourceVersion:
type: string
uid:
type: string
type: object
type:
type: string
type: object type: object
type: object type: object
type: array type: object
selector: status:
type: object description: ApplicationStatus defines controller's the observed state
type: object of Application
status: properties:
properties: components:
components: description: Object status array for all matching objects
items: items:
properties: description: ObjectStatus is a generic status holder for objects
group: properties:
type: string group:
kind: description: Object group
type: string type: string
link: kind:
type: string description: Kind of object
name: type: string
type: string link:
status: description: Link to object
type: string type: string
type: object name:
type: array description: Name of object
conditions: type: string
items: status:
properties: description: 'Status. Values: InProgress, Ready, Unknown'
lastTransitionTime: type: string
format: date-time type: object
type: string type: array
lastUpdateTime: componentsReady:
format: date-time description: 'ComponentsReady: status of the components in the format
type: string ready/total'
message: type: string
type: string conditions:
reason: description: Conditions represents the latest state of the object
type: string items:
status: description: Condition describes the state of an object at a certain
type: string point.
type: properties:
type: string lastTransitionTime:
required: description: Last time the condition transitioned from one status
- type to another.
- status format: date-time
type: object type: string
type: array lastUpdateTime:
observedGeneration: description: Last time the condition was probed
format: int64 format: date-time
type: integer type: string
type: object message:
version: v1beta1 description: A human readable message indicating details about
the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition.
type: string
required:
- status
- type
type: object
type: array
observedGeneration:
description: ObservedGeneration is the most recent generation observed.
It corresponds to the Object's generation, which is updated on mutation
by the API Server.
format: int64
type: integer
type: object
type: object
served: true
storage: true
subresources:
status: {}
status: status:
acceptedNames: acceptedNames:
kind: "" kind: ""

1
go.mod
View File

@@ -90,6 +90,7 @@ require (
k8s.io/code-generator v0.19.0 k8s.io/code-generator v0.19.0
k8s.io/component-base v0.18.6 k8s.io/component-base v0.18.6
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.0.0
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6
k8s.io/kubectl v0.18.6 k8s.io/kubectl v0.18.6
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451

View File

@@ -1,344 +0,0 @@
// 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]
}

View File

@@ -1,51 +0,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"))
}

View File

@@ -1,29 +0,0 @@
// 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()
}

View File

@@ -1,42 +0,0 @@
// 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)
}

View File

@@ -1,402 +0,0 @@
// +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
}

View File

@@ -20,14 +20,6 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "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" "github.com/emicklei/go-restful"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
urlruntime "k8s.io/apimachinery/pkg/util/runtime" urlruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -49,6 +41,7 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizerfactory" "kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizerfactory"
authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options" authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/path" "kubesphere.io/kubesphere/pkg/apiserver/authorization/path"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/rbac"
unionauthorizer "kubesphere.io/kubesphere/pkg/apiserver/authorization/union" unionauthorizer "kubesphere.io/kubesphere/pkg/apiserver/authorization/union"
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config" apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
"kubesphere.io/kubesphere/pkg/apiserver/dispatch" "kubesphere.io/kubesphere/pkg/apiserver/dispatch"
@@ -73,9 +66,12 @@ import (
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2" tenantv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2"
terminalv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/terminal/v1alpha2" terminalv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/terminal/v1alpha2"
"kubesphere.io/kubesphere/pkg/kapis/version" "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/am"
"kubesphere.io/kubesphere/pkg/models/iam/group" "kubesphere.io/kubesphere/pkg/models/iam/group"
"kubesphere.io/kubesphere/pkg/models/iam/im" "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/auditing"
"kubesphere.io/kubesphere/pkg/simple/client/cache" "kubesphere.io/kubesphere/pkg/simple/client/cache"
"kubesphere.io/kubesphere/pkg/simple/client/devops" "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/s3"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube" "kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
utilnet "kubesphere.io/kubesphere/pkg/utils/net" utilnet "kubesphere.io/kubesphere/pkg/utils/net"
"net/http"
rt "runtime"
runtimecache "sigs.k8s.io/controller-runtime/pkg/cache"
"time"
) )
const ( const (
@@ -143,6 +143,9 @@ type APIServer struct {
EventsClient events.Client EventsClient events.Client
AuditingClient auditing.Client AuditingClient auditing.Client
// controller-runtime cache
RuntimeCache runtimecache.Cache
} }
func (s *APIServer) PrepareRun(stopCh <-chan struct{}) error { func (s *APIServer) PrepareRun(stopCh <-chan struct{}) error {
@@ -182,7 +185,7 @@ func (s *APIServer) installKubeSphereAPIs() {
rbacAuthorizer := rbac.NewRBACAuthorizer(amOperator) rbacAuthorizer := rbac.NewRBACAuthorizer(amOperator)
urlruntime.Must(configv1alpha2.AddToContainer(s.container, s.Config)) 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(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(openpitrixv1.AddToContainer(s.container, s.InformerFactory, s.OpenpitrixClient))
urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes())) 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: "persistentvolumeclaims"},
{Group: "", Version: "v1", Resource: "secrets"}, {Group: "", Version: "v1", Resource: "secrets"},
{Group: "", Version: "v1", Resource: "configmaps"}, {Group: "", Version: "v1", Resource: "configmaps"},
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles"}, {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: "rolebindings"},
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles"}, {Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles"},
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings"}, {Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings"},
{Group: "apps", Version: "v1", Resource: "deployments"}, {Group: "apps", Version: "v1", Resource: "deployments"},
{Group: "apps", Version: "v1", Resource: "daemonsets"}, {Group: "apps", Version: "v1", Resource: "daemonsets"},
{Group: "apps", Version: "v1", Resource: "replicasets"}, {Group: "apps", Version: "v1", Resource: "replicasets"},
{Group: "apps", Version: "v1", Resource: "statefulsets"}, {Group: "apps", Version: "v1", Resource: "statefulsets"},
{Group: "apps", Version: "v1", Resource: "controllerrevisions"}, {Group: "apps", Version: "v1", Resource: "controllerrevisions"},
{Group: "storage.k8s.io", Version: "v1", Resource: "storageclasses"}, {Group: "storage.k8s.io", Version: "v1", Resource: "storageclasses"},
{Group: "batch", Version: "v1", Resource: "jobs"}, {Group: "batch", Version: "v1", Resource: "jobs"},
{Group: "batch", Version: "v1beta1", Resource: "cronjobs"}, {Group: "batch", Version: "v1beta1", Resource: "cronjobs"},
{Group: "extensions", Version: "v1beta1", Resource: "ingresses"}, {Group: "extensions", Version: "v1beta1", Resource: "ingresses"},
{Group: "autoscaling", Version: "v2beta2", Resource: "horizontalpodautoscalers"}, {Group: "autoscaling", Version: "v2beta2", Resource: "horizontalpodautoscalers"},
{Group: "networking.k8s.io", Version: "v1", Resource: "networkpolicies"}, {Group: "networking.k8s.io", Version: "v1", Resource: "networkpolicies"},
} }
@@ -470,26 +466,6 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error {
ksInformerFactory.Start(stopCh) ksInformerFactory.Start(stopCh)
ksInformerFactory.WaitForCacheSync(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() snapshotInformerFactory := s.InformerFactory.SnapshotSharedInformerFactory()
snapshotGVRs := []schema.GroupVersionResource{ snapshotGVRs := []schema.GroupVersionResource{
{Group: "snapshot.storage.k8s.io", Version: "v1beta1", Resource: "volumesnapshotclasses"}, {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.Start(stopCh)
apiextensionsInformerFactory.WaitForCacheSync(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") klog.V(0).Info("Finished caching objects")
return nil return nil

View File

@@ -56,7 +56,7 @@ func TestGetAuditLevel(t *testing.T) {
ksClient := fake.NewSimpleClientset() ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{ a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(), webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
@@ -85,7 +85,7 @@ func TestAuditing_Enabled(t *testing.T) {
ksClient := fake.NewSimpleClientset() ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{ a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(), webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
@@ -115,7 +115,7 @@ func TestAuditing_K8sAuditingEnabled(t *testing.T) {
ksClient := fake.NewSimpleClientset() ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{ a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(), webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
@@ -145,7 +145,7 @@ func TestAuditing_LogRequestObject(t *testing.T) {
ksClient := fake.NewSimpleClientset() ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{ a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(), webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
@@ -236,7 +236,7 @@ func TestAuditing_LogResponseObject(t *testing.T) {
ksClient := fake.NewSimpleClientset() ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
a := auditing{ a := auditing{
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(), webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),

View File

@@ -857,7 +857,7 @@ func newMockRBACAuthorizer(staticRoles *StaticRoles) (*RBACAuthorizer, error) {
ksClient := fakeks.NewSimpleClientset() ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil)
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory() k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
ksInformerFactory := fakeInformerFactory.KubeSphereSharedInformerFactory() ksInformerFactory := fakeInformerFactory.KubeSphereSharedInformerFactory()

View File

@@ -18,262 +18,124 @@ package application
import ( import (
"context" "context"
"fmt" v1 "k8s.io/api/apps/v1"
"time" corev1 "k8s.io/api/core/v1"
v1beta12 "k8s.io/api/networking/v1beta1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/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/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue" "k8s.io/klog"
log "k8s.io/klog" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
servicemeshinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh/v1alpha2"
servicemeshlisters "kubesphere.io/kubesphere/pkg/client/listers/servicemesh/v1alpha2"
"kubesphere.io/kubesphere/pkg/controller/virtualservice/util" "kubesphere.io/kubesphere/pkg/controller/virtualservice/util"
applicationclient "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned" "sigs.k8s.io/application/api/v1beta1"
applicationinformers "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions/app/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client"
applicationlister "kubesphere.io/kubesphere/pkg/simple/client/app/listers/app/v1beta1" "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"
) )
const ( // Add creates a new Workspace Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
// maxRetries is the number of times a service will be retried before it is dropped out of the queue. // and Start it when the Manager is Started.
// With the current rate-limiter in use (5ms*2^(maxRetries-1)) the following numbers represent the func Add(mgr manager.Manager) error {
// sequence of delays between successive queuings of a service. return add(mgr, newReconciler(mgr))
//
// 5ms, 10ms, 20ms, 40ms, 80ms, 160ms, 320ms, 640ms, 1.3s, 2.6s, 5.1s, 10.2s, 20.4s, 41s, 82s
maxRetries = 15
)
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
} }
func NewApplicationController(serviceInformer coreinformers.ServiceInformer, // newReconciler returns a new reconcile.Reconciler
deploymentInformer informersv1.DeploymentInformer, func newReconciler(mgr manager.Manager) reconcile.Reconciler {
statefulSetInformer informersv1.StatefulSetInformer, return &ReconcileApplication{Client: mgr.GetClient(), scheme: mgr.GetScheme(),
strategyInformer servicemeshinformers.StrategyInformer, recorder: mgr.GetEventRecorderFor("application-controller")}
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 { // add adds a new Controller to mgr with r as the reconcile.Reconciler
return v.Run(2, stopCh) func add(mgr manager.Manager, r reconcile.Reconciler) error {
} // Create a new controller
c, err := controller.New("application-controller", mgr, controller.Options{Reconciler: r})
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")
}
for i := 0; i < workers; i++ {
go wait.Until(v.worker, v.workerLoopPeriod, stopCh)
}
<-stopCh
return nil
}
func (v *ApplicationController) worker() {
for v.processNextWorkItem() {
}
}
func (v *ApplicationController) processNextWorkItem() bool {
eKey, quit := v.queue.Get()
if quit {
return false
}
defer v.queue.Done(eKey)
err := v.syncApplication(eKey.(string))
v.handleErr(err, eKey)
return true
}
func (v *ApplicationController) syncApplication(key string) error {
startTime := time.Now()
namespace, name, err := cache.SplitMetaNamespaceKey(key)
if err != nil { if err != nil {
log.Error(err, "not a valid controller key", "key", key)
return err return err
} }
defer func() { sources := []runtime.Object{
log.V(4).Info("Finished updating application.", "namespace", namespace, "name", name, "duration", time.Since(startTime)) &v1.Deployment{},
}() &corev1.Service{},
&v1.StatefulSet{},
application, err := v.applicationLister.Applications(namespace).Get(name) &v1beta12.Ingress{},
if err != nil { &servicemeshv1alpha2.ServicePolicy{},
if errors.IsNotFound(err) { &servicemeshv1alpha2.Strategy{},
// application has been deleted
return nil
}
log.Error(err, "get application failed")
} }
annotations := application.GetAnnotations() 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
}
}
return nil
}
var _ reconcile.Reconciler = &ReconcileApplication{}
// ReconcileApplication reconciles a Workspace object
type ReconcileApplication struct {
client.Client
scheme *runtime.Scheme
recorder record.EventRecorder
}
// +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) {
return reconcile.Result{}, nil
}
return reconcile.Result{}, err
}
// 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 { if annotations == nil {
annotations = make(map[string]string) annotations = make(map[string]string)
} }
annotations["kubesphere.io/last-updated"] = time.Now().String() annotations["kubesphere.io/last-updated"] = time.Now().String()
application.SetAnnotations(annotations) app.SetAnnotations(annotations)
err = r.Update(ctx, app)
_, err = v.applicationClient.AppV1beta1().Applications(namespace).Update(context.Background(), application, metav1.UpdateOptions{})
if err != nil { if err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
log.V(4).Info("application has been deleted during update") klog.V(4).Info("application has been deleted during update")
return nil return reconcile.Result{}, nil
} }
log.Error(err, "failed to update application", "namespace", namespace, "name", name)
return err
} }
return reconcile.Result{}, nil
return nil
} }
func (v *ApplicationController) enqueueObject(obj interface{}) { func isApp(o metav1.Object) bool {
var resource = obj.(metav1.Object) if o.GetLabels() == nil || !util.IsApplicationComponent(o.GetLabels()) {
return false
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)
} }
} return true
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
}
log.V(4).Info("Dropping service out of the queue.", "key", key, "error", err)
v.queue.Forget(key)
utilruntime.HandleError(err)
} }

View File

@@ -18,6 +18,7 @@ package cluster
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand" "math/rand"
@@ -325,7 +326,7 @@ func (c *clusterController) reconcileHostCluster() error {
// no host cluster, create one // no host cluster, create one
if len(clusters) == 0 { if len(clusters) == 0 {
hostCluster.Spec.Connection.KubeConfig = hostKubeConfig hostCluster.Spec.Connection.KubeConfig = hostKubeConfig
_, err = c.clusterClient.Create(hostCluster) _, err = c.clusterClient.Create(context.TODO(), hostCluster, metav1.CreateOptions{})
return err return err
} else if len(clusters) > 1 { } else if len(clusters) > 1 {
return fmt.Errorf("there MUST not be more than one host clusters, while there are %d", len(clusters)) 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 // update host cluster config
_, err = c.clusterClient.Update(cluster) _, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
return err return err
} }
@@ -387,7 +388,7 @@ func (c *clusterController) syncCluster(key string) error {
// registering our finalizer. // registering our finalizer.
if !sets.NewString(cluster.ObjectMeta.Finalizers...).Has(clusterv1alpha1.Finalizer) { if !sets.NewString(cluster.ObjectMeta.Finalizers...).Has(clusterv1alpha1.Finalizer) {
cluster.ObjectMeta.Finalizers = append(cluster.ObjectMeta.Finalizers, 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 return err
} }
} }
@@ -403,7 +404,7 @@ func (c *clusterController) syncCluster(key string) error {
return err 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 err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
// nothing to do // nothing to do
@@ -412,7 +413,7 @@ func (c *clusterController) syncCluster(key string) error {
return err return err
} }
} else { } 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 { if err != nil {
klog.Errorf("Unable to delete service %s, error %v", serviceName, err) klog.Errorf("Unable to delete service %s, error %v", serviceName, err)
return err return err
@@ -435,7 +436,7 @@ func (c *clusterController) syncCluster(key string) error {
finalizers := sets.NewString(cluster.ObjectMeta.Finalizers...) finalizers := sets.NewString(cluster.ObjectMeta.Finalizers...)
finalizers.Delete(clusterv1alpha1.Finalizer) finalizers.Delete(clusterv1alpha1.Finalizer)
cluster.ObjectMeta.Finalizers = finalizers.List() 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 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 err != nil { // proxy service not found
if errors.IsNotFound(err) { 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 { if err != nil {
return err return err
} }
@@ -519,7 +520,7 @@ func (c *clusterController) syncCluster(key string) error {
mcService.ObjectMeta = service.ObjectMeta mcService.ObjectMeta = service.ObjectMeta
mcService.Spec.ClusterIP = service.Spec.ClusterIP 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 { if err != nil {
return err return err
} }
@@ -544,7 +545,7 @@ func (c *clusterController) syncCluster(key string) error {
} }
if !reflect.DeepEqual(oldCluster, cluster) { if !reflect.DeepEqual(oldCluster, cluster) {
cluster, err = c.clusterClient.Update(cluster) cluster, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
if err != nil { if err != nil {
klog.Errorf("Error updating cluster %s, error %s", cluster.Name, err) klog.Errorf("Error updating cluster %s, error %s", cluster.Name, err)
return err return err
@@ -567,7 +568,7 @@ func (c *clusterController) syncCluster(key string) error {
c.updateClusterCondition(cluster, clusterNotReadyCondition) c.updateClusterCondition(cluster, clusterNotReadyCondition)
cluster, err = c.clusterClient.Update(cluster) cluster, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
if err != nil { if err != nil {
klog.Errorf("Error updating cluster %s, error %s", cluster.Name, err) 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 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 { if err != nil {
klog.Errorf("Failed to get cluster nodes, %#v", err) klog.Errorf("Failed to get cluster nodes, %#v", err)
return err return err
@@ -679,7 +680,7 @@ func (c *clusterController) syncCluster(key string) error {
} }
if !reflect.DeepEqual(oldCluster, cluster) { if !reflect.DeepEqual(oldCluster, cluster) {
_, err = c.clusterClient.Update(cluster) _, err = c.clusterClient.Update(context.TODO(), cluster, metav1.UpdateOptions{})
if err != nil { if err != nil {
klog.Errorf("Failed to update cluster status, %#v", err) klog.Errorf("Failed to update cluster status, %#v", err)
return err return err
@@ -690,7 +691,7 @@ func (c *clusterController) syncCluster(key string) error {
} }
func (c *clusterController) checkIfClusterIsHostCluster(memberClusterNodes *v1.NodeList) bool { 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 { if err != nil {
return false return false
} }

View File

@@ -765,7 +765,7 @@ func checkWorkspaces(clusterConfig *rest.Config, hostClient client.Client, clust
return err 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 { if err != nil {
return err return err
} }

View File

@@ -147,7 +147,7 @@ func (f *fixture) runController(user string, startInformers bool, expectError bo
actions := filterInformerActions(f.ksclient.Actions()) actions := filterInformerActions(f.ksclient.Actions())
for j, action := range actions { for j, action := range actions {
if len(f.actions) < j+1 { 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 break
} }
@@ -180,7 +180,8 @@ func (f *fixture) runController(user string, startInformers bool, expectError bo
func checkAction(expected, actual core.Action, t *testing.T) { func checkAction(expected, actual core.Action, t *testing.T) {
if !(expected.Matches(actual.GetVerb(), actual.GetResource().Resource) && actual.GetSubresource() == expected.GetSubresource()) { if !(expected.Matches(actual.GetVerb(), actual.GetResource().Resource) && actual.GetSubresource() == expected.GetSubresource()) {
t.Errorf("Expected\n\t%#v\ngot\n\t%#v", expected, actual) 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) { if reflect.TypeOf(actual) != reflect.TypeOf(expected) {

View File

@@ -17,6 +17,7 @@ limitations under the License.
package ippool package ippool
import ( import (
"context"
"fmt" "fmt"
"reflect" "reflect"
"time" "time"
@@ -92,7 +93,7 @@ func (c *IPPoolController) addFinalizer(pool *networkv1alpha1.IPPool) error {
networkv1alpha1.IPPoolTypeLabel: clone.Spec.Type, networkv1alpha1.IPPoolTypeLabel: clone.Spec.Type,
networkv1alpha1.IPPoolIDLabel: fmt.Sprintf("%d", clone.ID()), 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 { if err != nil {
klog.V(3).Infof("Error adding finalizer to pool %s: %v", pool.Name, err) klog.V(3).Infof("Error adding finalizer to pool %s: %v", pool.Name, err)
return err return err
@@ -104,7 +105,7 @@ func (c *IPPoolController) addFinalizer(pool *networkv1alpha1.IPPool) error {
func (c *IPPoolController) removeFinalizer(pool *networkv1alpha1.IPPool) error { func (c *IPPoolController) removeFinalizer(pool *networkv1alpha1.IPPool) error {
clone := pool.DeepCopy() clone := pool.DeepCopy()
controllerutil.RemoveFinalizer(clone, networkv1alpha1.IPPoolFinalizer) 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 { if err != nil {
klog.V(3).Infof("Error removing finalizer from pool %s: %v", pool.Name, err) klog.V(3).Infof("Error removing finalizer from pool %s: %v", pool.Name, err)
return 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{ LabelSelector: labels.SelectorFromSet(labels.Set{
networkv1alpha1.IPPoolIDLabel: fmt.Sprintf("%d", b.ID()), networkv1alpha1.IPPoolIDLabel: fmt.Sprintf("%d", b.ID()),
}).String(), }).String(),
@@ -203,7 +204,7 @@ func (c *IPPoolController) disableIPPool(old *networkv1alpha1.IPPool) error {
clone := old.DeepCopy() clone := old.DeepCopy()
clone.Spec.Disabled = true 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 return err
} }
@@ -218,7 +219,7 @@ func (c *IPPoolController) updateIPPoolStatus(old *networkv1alpha1.IPPool) error
return nil return nil
} }
_, err = c.kubesphereClient.NetworkV1alpha1().IPPools().UpdateStatus(new) _, err = c.kubesphereClient.NetworkV1alpha1().IPPools().UpdateStatus(context.TODO(), new, metav1.UpdateOptions{})
if err != nil { if err != nil {
return fmt.Errorf("failed to update ippool %s status %v", old.Name, err) return fmt.Errorf("failed to update ippool %s status %v", old.Name, err)
} }

View File

@@ -17,6 +17,7 @@ limitations under the License.
package ippool package ippool
import ( import (
"context"
"flag" "flag"
"testing" "testing"
"time" "time"
@@ -94,11 +95,11 @@ var _ = Describe("test ippool", func() {
Expect(c.ValidateCreate(clone)).Should(HaveOccurred()) Expect(c.ValidateCreate(clone)).Should(HaveOccurred())
clone = pool.DeepCopy() clone = pool.DeepCopy()
_, err := ksclient.NetworkV1alpha1().IPPools().Create(clone) _, err := ksclient.NetworkV1alpha1().IPPools().Create(context.TODO(), clone, v1.CreateOptions{})
Expect(err).ShouldNot(HaveOccurred()) Expect(err).ShouldNot(HaveOccurred())
Eventually(func() bool { 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 { if len(result.Labels) != 3 {
return false return false
} }
@@ -115,7 +116,7 @@ var _ = Describe("test ippool", func() {
}) })
It("test update 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 := old.DeepCopy()
new.Spec.CIDR = "192.168.1.0/24" new.Spec.CIDR = "192.168.1.0/24"
Expect(c.ValidateUpdate(old, new)).Should(HaveOccurred()) Expect(c.ValidateUpdate(old, new)).Should(HaveOccurred())
@@ -129,7 +130,7 @@ var _ = Describe("test ippool", func() {
}) })
Eventually(func() bool { 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 { if result.Status.Allocations != 1 {
return false return false
} }
@@ -139,12 +140,12 @@ var _ = Describe("test ippool", func() {
}) })
It("test delete pool", 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()) Expect(c.ValidateDelete(result)).Should(HaveOccurred())
ipamClient.ReleaseByHandle("testhandle") ipamClient.ReleaseByHandle("testhandle")
Eventually(func() bool { 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 { if result.Status.Allocations != 0 {
return false return false
} }
@@ -152,9 +153,9 @@ var _ = Describe("test ippool", func() {
return true return true
}, 3*time.Second).Should(Equal(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()) 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)) Expect(len(blocks.Items)).Should(Equal(0))
}) })
}) })

View File

@@ -27,8 +27,6 @@ import (
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned" "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions" 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" "time"
) )
@@ -41,7 +39,6 @@ type InformerFactory interface {
KubernetesSharedInformerFactory() k8sinformers.SharedInformerFactory KubernetesSharedInformerFactory() k8sinformers.SharedInformerFactory
KubeSphereSharedInformerFactory() ksinformers.SharedInformerFactory KubeSphereSharedInformerFactory() ksinformers.SharedInformerFactory
IstioSharedInformerFactory() istioinformers.SharedInformerFactory IstioSharedInformerFactory() istioinformers.SharedInformerFactory
ApplicationSharedInformerFactory() applicationinformers.SharedInformerFactory
SnapshotSharedInformerFactory() snapshotinformer.SharedInformerFactory SnapshotSharedInformerFactory() snapshotinformer.SharedInformerFactory
ApiExtensionSharedInformerFactory() apiextensionsinformers.SharedInformerFactory ApiExtensionSharedInformerFactory() apiextensionsinformers.SharedInformerFactory
@@ -53,13 +50,11 @@ type informerFactories struct {
informerFactory k8sinformers.SharedInformerFactory informerFactory k8sinformers.SharedInformerFactory
ksInformerFactory ksinformers.SharedInformerFactory ksInformerFactory ksinformers.SharedInformerFactory
istioInformerFactory istioinformers.SharedInformerFactory istioInformerFactory istioinformers.SharedInformerFactory
appInformerFactory applicationinformers.SharedInformerFactory
snapshotInformerFactory snapshotinformer.SharedInformerFactory snapshotInformerFactory snapshotinformer.SharedInformerFactory
apiextensionsInformerFactory apiextensionsinformers.SharedInformerFactory apiextensionsInformerFactory apiextensionsinformers.SharedInformerFactory
} }
func NewInformerFactories(client kubernetes.Interface, ksClient versioned.Interface, istioClient istioclient.Interface, func NewInformerFactories(client kubernetes.Interface, ksClient versioned.Interface, istioClient istioclient.Interface,
appClient applicationclient.Interface,
snapshotClient snapshotclient.Interface, apiextensionsClient apiextensionsclient.Interface) InformerFactory { snapshotClient snapshotclient.Interface, apiextensionsClient apiextensionsclient.Interface) InformerFactory {
factory := &informerFactories{} factory := &informerFactories{}
@@ -71,10 +66,6 @@ func NewInformerFactories(client kubernetes.Interface, ksClient versioned.Interf
factory.ksInformerFactory = ksinformers.NewSharedInformerFactory(ksClient, defaultResync) factory.ksInformerFactory = ksinformers.NewSharedInformerFactory(ksClient, defaultResync)
} }
if appClient != nil {
factory.appInformerFactory = applicationinformers.NewSharedInformerFactory(appClient, defaultResync)
}
if istioClient != nil { if istioClient != nil {
factory.istioInformerFactory = istioinformers.NewSharedInformerFactory(istioClient, defaultResync) factory.istioInformerFactory = istioinformers.NewSharedInformerFactory(istioClient, defaultResync)
} }
@@ -98,10 +89,6 @@ func (f *informerFactories) KubeSphereSharedInformerFactory() ksinformers.Shared
return f.ksInformerFactory return f.ksInformerFactory
} }
func (f *informerFactories) ApplicationSharedInformerFactory() applicationinformers.SharedInformerFactory {
return f.appInformerFactory
}
func (f *informerFactories) IstioSharedInformerFactory() istioinformers.SharedInformerFactory { func (f *informerFactories) IstioSharedInformerFactory() istioinformers.SharedInformerFactory {
return f.istioInformerFactory return f.istioInformerFactory
} }
@@ -127,10 +114,6 @@ func (f *informerFactories) Start(stopCh <-chan struct{}) {
f.istioInformerFactory.Start(stopCh) f.istioInformerFactory.Start(stopCh)
} }
if f.appInformerFactory != nil {
f.appInformerFactory.Start(stopCh)
}
if f.snapshotInformerFactory != nil { if f.snapshotInformerFactory != nil {
f.snapshotInformerFactory.Start(stopCh) f.snapshotInformerFactory.Start(stopCh)
} }

View File

@@ -24,7 +24,6 @@ import (
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
ksfake "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake" ksfake "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions" ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
appinformers "kubesphere.io/kubesphere/pkg/simple/client/app/informers/externalversions"
"time" "time"
) )
@@ -58,10 +57,6 @@ func (n nullInformerFactory) IstioSharedInformerFactory() istioinformers.SharedI
return nil return nil
} }
func (n nullInformerFactory) ApplicationSharedInformerFactory() appinformers.SharedInformerFactory {
return nil
}
func (n nullInformerFactory) SnapshotSharedInformerFactory() snapshotinformer.SharedInformerFactory { func (n nullInformerFactory) SnapshotSharedInformerFactory() snapshotinformer.SharedInformerFactory {
return nil return nil
} }

View File

@@ -125,7 +125,7 @@ func TestGeranteAgentDeployment(t *testing.T) {
k8sclient := k8sfake.NewSimpleClientset(service) k8sclient := k8sfake.NewSimpleClientset(service)
ksclient := fake.NewSimpleClientset(cluster) 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.KubernetesSharedInformerFactory().Core().V1().Services().Informer().GetIndexer().Add(service)
informersFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster) informersFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster)
@@ -233,7 +233,7 @@ func TestValidateKubeConfig(t *testing.T) {
k8sclient := k8sfake.NewSimpleClientset(service) k8sclient := k8sfake.NewSimpleClientset(service)
ksclient := fake.NewSimpleClientset(cluster) 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.KubernetesSharedInformerFactory().Core().V1().Services().Informer().GetIndexer().Add(service)
informersFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster) informersFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Informer().GetIndexer().Add(cluster)

View File

@@ -216,7 +216,7 @@ func TestParseRequestParams(t *testing.T) {
for i, tt := range tests { for i, tt := range tests {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
client := fake.NewSimpleClientset(&tt.namespace) 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) handler := newHandler(client, nil, fakeInformerFactory, nil)
result, err := handler.makeQueryOptions(tt.params, tt.lvl) result, err := handler.makeQueryOptions(tt.params, tt.lvl)

View File

@@ -48,6 +48,7 @@ func (h *Handler) handleGetResources(request *restful.Request, response *restful
resourceType := request.PathParameter("resources") resourceType := request.PathParameter("resources")
name := request.PathParameter("name") name := request.PathParameter("name")
// use informers to retrieve resources
result, err := h.resourceGetterV1alpha3.Get(resourceType, namespace, name) result, err := h.resourceGetterV1alpha3.Get(resourceType, namespace, name)
if err == nil { if err == nil {
response.WriteEntity(result) response.WriteEntity(result)
@@ -100,7 +101,6 @@ func (h *Handler) handleListResources(request *restful.Request, response *restfu
api.HandleInternalError(response, nil, err) api.HandleInternalError(response, nil, err)
return return
} }
response.WriteEntity(result) response.WriteEntity(result)
} }

View File

@@ -33,7 +33,6 @@ import (
resourcev1alpha2 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource" resourcev1alpha2 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
resourcev1alpha3 "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" "testing"
) )
@@ -91,9 +90,7 @@ func TestResourceV1alpha2Fallback(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
handler := New(resourcev1alpha3.NewResourceGetter(factory), handler := New(resourcev1alpha3.NewResourceGetter(factory, nil), resourcev1alpha2.NewResourceGetter(factory), components.NewComponentsGetter(factory.KubernetesSharedInformerFactory()))
resourcev1alpha2.NewResourceGetter(factory),
components.NewComponentsGetter(factory.KubernetesSharedInformerFactory()))
for _, test := range tests { for _, test := range tests {
got, err := listResources(test.namespace, test.resource, test.query, handler) got, err := listResources(test.namespace, test.resource, test.query, handler)
@@ -186,11 +183,10 @@ func prepare() (informers.InformerFactory, error) {
ksClient := fakeks.NewSimpleClientset() ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
istioClient := fakeistio.NewSimpleClientset() istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset()
snapshotClient := fakesnapshot.NewSimpleClientset() snapshotClient := fakesnapshot.NewSimpleClientset()
apiextensionsClient := fakeapiextensions.NewSimpleClientset() apiextensionsClient := fakeapiextensions.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, snapshotClient, apiextensionsClient) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, apiextensionsClient)
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory() k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()

View File

@@ -28,6 +28,8 @@ import (
"kubesphere.io/kubesphere/pkg/models/components" "kubesphere.io/kubesphere/pkg/models/components"
resourcev1alpha2 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource" resourcev1alpha2 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"sigs.k8s.io/controller-runtime/pkg/cache"
"net/http" "net/http"
) )
@@ -47,12 +49,10 @@ func Resource(resource string) schema.GroupResource {
return GroupVersion.WithResource(resource).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) webservice := runtime.NewWebService(GroupVersion)
handler := New(resourcev1alpha3.NewResourceGetter(informerFactory), handler := New(resourcev1alpha3.NewResourceGetter(informerFactory, cache), resourcev1alpha2.NewResourceGetter(informerFactory), components.NewComponentsGetter(informerFactory.KubernetesSharedInformerFactory()))
resourcev1alpha2.NewResourceGetter(informerFactory),
components.NewComponentsGetter(informerFactory.KubernetesSharedInformerFactory()))
webservice.Route(webservice.GET("/{resources}"). webservice.Route(webservice.GET("/{resources}").
To(handler.handleListResources). To(handler.handleListResources).

View File

@@ -21,7 +21,7 @@ import (
"github.com/emicklei/go-restful-openapi" "github.com/emicklei/go-restful-openapi"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/apiserver/runtime"
_ "net/http" "net/http"
) )
const groupName = "servicemesh.kubesphere.io" 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("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("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")). 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)) Produces(restful.MIME_JSON))
// Get namespace health // 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.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("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
Param(webservice.QueryParameter("queryTime", "the time to use for query")). 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)) Produces(restful.MIME_JSON))
// Get workloads health // Get workloads health

View File

@@ -0,0 +1,40 @@
/*
Copyright 2020 KubeSphere Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha2
/////////////////////
// SWAGGER RESPONSES
/////////////////////
// NoContent: the response is empty
type NoContent struct {
Status int32 `json:"status"`
Reason error `json:"reason"`
}
// 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"`
}

View File

@@ -58,7 +58,7 @@ type groupOperator struct {
func New(informers informers.InformerFactory, ksclient kubesphere.Interface, k8sclient kubernetes.Interface) GroupOperator { func New(informers informers.InformerFactory, ksclient kubesphere.Interface, k8sclient kubernetes.Interface) GroupOperator {
return &groupOperator{ return &groupOperator{
resourceGetter: resourcesv1alpha3.NewResourceGetter(informers), resourceGetter: resourcesv1alpha3.NewResourceGetter(informers, nil),
k8sclient: k8sclient, k8sclient: k8sclient,
ksclient: ksclient, ksclient: ksclient,
} }

View File

@@ -1,87 +0,0 @@
/*
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("")
}

View File

@@ -29,7 +29,6 @@ import (
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2" "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/server/params" "kubesphere.io/kubesphere/pkg/server/params"
fakeapp "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake"
"testing" "testing"
) )
@@ -213,9 +212,8 @@ func prepare() (informers.InformerFactory, error) {
ksClient := fakeks.NewSimpleClientset() ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
istioClient := fakeistio.NewSimpleClientset() istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset()
snapshotClient := fakesnapshot.NewSimpleClientset() snapshotClient := fakesnapshot.NewSimpleClientset()
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, snapshotClient, nil) fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, snapshotClient, nil)
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory() k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()

View File

@@ -22,7 +22,6 @@ import (
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2" "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/clusterrole"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/configmap" "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/configmap"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/cronjob" "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.S2iRuns] = s2irun.NewS2iRunSearcher(factory.KubeSphereSharedInformerFactory())
resourceGetters[v1alpha2.S2iBuilderTemplates] = s2buildertemplate.NewS2iBuidlerTemplateSearcher(factory.KubeSphereSharedInformerFactory()) resourceGetters[v1alpha2.S2iBuilderTemplates] = s2buildertemplate.NewS2iBuidlerTemplateSearcher(factory.KubeSphereSharedInformerFactory())
resourceGetters[v1alpha2.Workspaces] = workspace.NewWorkspaceSearcher(factory.KubeSphereSharedInformerFactory()) resourceGetters[v1alpha2.Workspaces] = workspace.NewWorkspaceSearcher(factory.KubeSphereSharedInformerFactory())
resourceGetters[v1alpha2.Applications] = application.NewApplicationSearcher(nil)
return &ResourceGetter{resourcesGetters: resourceGetters} return &ResourceGetter{resourcesGetters: resourceGetters}

View File

@@ -17,36 +17,47 @@ limitations under the License.
package application package application
import ( import (
"context"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api" "kubesphere.io/kubesphere/pkg/api"
appv1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query" "kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3" "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" "time"
) )
type applicationsGetter struct { type applicationsGetter struct {
informer externalversions.SharedInformerFactory c cache.Cache
} }
func New(sharedInformers externalversions.SharedInformerFactory) v1alpha3.Interface { func New(c cache.Cache) v1alpha3.Interface {
return &applicationsGetter{informer: sharedInformers} return &applicationsGetter{c}
} }
func (d *applicationsGetter) Get(namespace, name string) (runtime.Object, error) { 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) { 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 { if err != nil {
klog.Error(err)
return nil, err return nil, err
} }
var result []runtime.Object var result []runtime.Object
for _, app := range applications { for _, app := range applications.Items {
result = append(result, app) result = append(result, &app)
} }
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil

View File

@@ -17,104 +17,78 @@ limitations under the License.
package application package application
import ( import (
"github.com/google/go-cmp/cmp" "context"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme"
"kubesphere.io/kubesphere/pkg/api" "k8s.io/klog/v2"
appv1beta1 "kubesphere.io/kubesphere/pkg/apis/app/v1beta1"
"kubesphere.io/kubesphere/pkg/apiserver/query" "kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake" "path/filepath"
"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"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"testing" "testing"
) )
func applicationsToRuntimeObjects(applications ...*appv1beta1.Application) []runtime.Object { var c client.Client
var objs []runtime.Object
for _, app := range applications { func createNamespace(name string, ctx context.Context) {
objs = append(objs, app) 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) { func TestGetListApplications(t *testing.T) {
tests := []struct { e := &envtest.Environment{CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "..", "config", "crds")}}
description string cfg, err := e.Start()
namespace string if err != nil {
deployments []*appv1beta1.Application t.Fatal(err)
query *query.Query }
expected api.ListResult
expectedErr error sch := scheme.Scheme
}{ if err := appv1beta1.AddToScheme(sch); err != nil {
{ t.Fatalf("unable add APIs to scheme: %v", err)
"test name filter", }
"bar2",
[]*appv1beta1.Application{ stopCh := make(chan struct{})
{
ObjectMeta: metav1.ObjectMeta{ ce, _ := cache.New(cfg, cache.Options{Scheme: sch})
Name: "foo-1", go ce.Start(stopCh)
Namespace: "bar", ce.WaitForCacheSync(stopCh)
},
}, c, _ = client.New(cfg, client.Options{Scheme: sch})
{
ObjectMeta: metav1.ObjectMeta{ var labelSet1 = map[string]string{"foo": "bar"}
Name: "foo-2", application := &appv1beta1.Application{
Namespace: "bar", ObjectMeta: metav1.ObjectMeta{
}, Name: "bar",
}, Namespace: "foo",
{ Labels: labelSet1,
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,
}, },
} }
for _, test := range tests { ctx := context.TODO()
t.Run(test.description, func(t *testing.T) { createNamespace("foo", ctx)
objs := applicationsToRuntimeObjects(test.deployments...) _ = c.Create(ctx, application)
client := fake.NewSimpleClientset(objs...)
informer := externalversions.NewSharedInformerFactory(client, 0) getter := New(ce)
for _, deployment := range test.deployments { _, err = getter.List("foo", &query.Query{})
informer.App().V1beta1().Applications().Informer().GetIndexer().Add(deployment) if err != nil {
} t.Fatal(err)
getter := New(informer)
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)
}
if diff := cmp.Diff(got.Items, test.expected.Items); diff != "" {
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
}
})
} }
_, err = getter.Get("foo", "bar")
if err != nil {
t.Fatal(err)
}
} }

View File

@@ -18,7 +18,6 @@ package resource
import ( import (
"errors" "errors"
snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v3/apis/volumesnapshot/v1beta1" snapshotv1beta1 "github.com/kubernetes-csi/external-snapshotter/client/v3/apis/volumesnapshot/v1beta1"
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime" "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/workspacerole"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacerolebinding" "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacerolebinding"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacetemplate" "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacetemplate"
"sigs.k8s.io/controller-runtime/pkg/cache"
) )
var ErrResourceNotSupported = errors.New("resource is not supported") var ErrResourceNotSupported = errors.New("resource is not supported")
@@ -82,7 +82,7 @@ type ResourceGetter struct {
getters map[schema.GroupVersionResource]v1alpha3.Interface 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 := make(map[schema.GroupVersionResource]v1alpha3.Interface)
getters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}] = deployment.New(factory.KubernetesSharedInformerFactory()) 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: "pods"}] = pod.New(factory.KubernetesSharedInformerFactory())
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "nodes"}] = node.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: "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: "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: "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 // kubesphere resources
getters[devopsv1alpha3.SchemeGroupVersion.WithResource(devopsv1alpha3.ResourcePluralDevOpsProject)] = devops.New(factory.KubeSphereSharedInformerFactory()) getters[devopsv1alpha3.SchemeGroupVersion.WithResource(devopsv1alpha3.ResourcePluralDevOpsProject)] = devops.New(factory.KubeSphereSharedInformerFactory())

View File

@@ -28,7 +28,6 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/query" "kubesphere.io/kubesphere/pkg/apiserver/query"
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake" fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
fakeapp "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake"
"testing" "testing"
) )
@@ -107,15 +106,14 @@ func prepare() *ResourceGetter {
ksClient := fakeks.NewSimpleClientset() ksClient := fakeks.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset() k8sClient := fakek8s.NewSimpleClientset()
istioClient := fakeistio.NewSimpleClientset() istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset()
snapshotClient := fakesnapshot.NewSimpleClientset() snapshotClient := fakesnapshot.NewSimpleClientset()
apiextensionsClient := fakeapiextensions.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 { for _, namespace := range namespaces {
fakeInformerFactory.KubernetesSharedInformerFactory().Core().V1(). fakeInformerFactory.KubernetesSharedInformerFactory().Core().V1().
Namespaces().Informer().GetIndexer().Add(namespace) Namespaces().Informer().GetIndexer().Add(namespace)
} }
return NewResourceGetter(fakeInformerFactory) return NewResourceGetter(fakeInformerFactory, nil)
} }

View File

@@ -96,7 +96,7 @@ func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ks
return &tenantOperator{ return &tenantOperator{
am: am, am: am,
authorizer: authorizer, authorizer: authorizer,
resourceGetter: resourcesv1alpha3.NewResourceGetter(informers), resourceGetter: resourcesv1alpha3.NewResourceGetter(informers, nil),
k8sclient: k8sclient, k8sclient: k8sclient,
ksclient: ksclient, ksclient: ksclient,
events: events.NewEventsOperator(evtsClient), events: events.NewEventsOperator(evtsClient),

View File

@@ -35,7 +35,6 @@ import (
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake" fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/iam/am" "kubesphere.io/kubesphere/pkg/models/iam/am"
fakeapp "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned/fake"
"reflect" "reflect"
"testing" "testing"
) )
@@ -492,8 +491,7 @@ func prepare() Interface {
ksClient := fakeks.NewSimpleClientset([]runtime.Object{testWorkspace, systemWorkspace}...) ksClient := fakeks.NewSimpleClientset([]runtime.Object{testWorkspace, systemWorkspace}...)
k8sClient := fakek8s.NewSimpleClientset([]runtime.Object{testNamespace, kubesphereSystem}...) k8sClient := fakek8s.NewSimpleClientset([]runtime.Object{testNamespace, kubesphereSystem}...)
istioClient := fakeistio.NewSimpleClientset() istioClient := fakeistio.NewSimpleClientset()
appClient := fakeapp.NewSimpleClientset() fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, nil, nil)
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient, nil, nil)
for _, workspace := range workspaces { for _, workspace := range workspaces {
fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha1(). fakeInformerFactory.KubeSphereSharedInformerFactory().Tenant().V1alpha1().

View File

@@ -1,97 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package 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
}

View File

@@ -1,20 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated clientset.
package versioned

View File

@@ -1,82 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"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}
}

View File

@@ -1,20 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated fake clientset.
package fake

View File

@@ -1,56 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
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))
}

View File

@@ -1,20 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package contains the scheme of the automatically generated clientset.
package scheme

View File

@@ -1,56 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package 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))
}

View File

@@ -1,89 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
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
}

View File

@@ -1,195 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
import (
"context"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1beta1 "kubesphere.io/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
}

View File

@@ -1,20 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1beta1

View File

@@ -1,20 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
// Package fake has the automatically generated clients.
package fake

View File

@@ -1,40 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
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
}

View File

@@ -1,142 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1beta1 "kubesphere.io/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
}

View File

@@ -1,21 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1beta1
type ApplicationExpansion interface{}

View File

@@ -1,46 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package 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)
}

View File

@@ -1,90 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1beta1
import (
"context"
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
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())
}

View File

@@ -1,45 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1beta1
import (
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}
}

View File

@@ -1,180 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package 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)
}

View File

@@ -1,62 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package 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)
}

View File

@@ -1,40 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by informer-gen. DO NOT EDIT.
package 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)

View File

@@ -1,94 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1beta1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1beta1 "kubesphere.io/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
}

View File

@@ -1,27 +0,0 @@
/*
Copyright 2020 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1beta1
// ApplicationListerExpansion allows custom methods to be added to
// ApplicationLister.
type ApplicationListerExpansion interface{}
// ApplicationNamespaceListerExpansion allows custom methods to be added to
// ApplicationNamespaceLister.
type ApplicationNamespaceListerExpansion interface{}

View File

@@ -24,8 +24,6 @@ import (
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned" 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 { type FakeClient struct {
@@ -38,8 +36,6 @@ type FakeClient struct {
// generated clientset // generated clientset
KubeSphereClient kubesphere.Interface KubeSphereClient kubesphere.Interface
ApplicationClient applicationclientset.Interface
IstioClient istioclient.Interface IstioClient istioclient.Interface
SnapshotClient snapshotclient.Interface SnapshotClient snapshotclient.Interface
@@ -52,14 +48,13 @@ type FakeClient struct {
} }
func NewFakeClientSets(k8sClient kubernetes.Interface, discoveryClient *discovery.DiscoveryClient, func NewFakeClientSets(k8sClient kubernetes.Interface, discoveryClient *discovery.DiscoveryClient,
kubeSphereClient kubesphere.Interface, applicationClient applicationclientset.Interface, kubeSphereClient kubesphere.Interface,
istioClient istioclient.Interface, snapshotClient snapshotclient.Interface, istioClient istioclient.Interface, snapshotClient snapshotclient.Interface,
apiextensionsclient apiextensionsclient.Interface, masterURL string, kubeConfig *rest.Config) Client { apiextensionsclient apiextensionsclient.Interface, masterURL string, kubeConfig *rest.Config) Client {
return &FakeClient{ return &FakeClient{
K8sClient: k8sClient, K8sClient: k8sClient,
DiscoveryClient: discoveryClient, DiscoveryClient: discoveryClient,
KubeSphereClient: kubeSphereClient, KubeSphereClient: kubeSphereClient,
ApplicationClient: applicationClient,
IstioClient: istioClient, IstioClient: istioClient,
SnapshotClient: snapshotClient, SnapshotClient: snapshotClient,
ApiExtensionClient: apiextensionsclient, ApiExtensionClient: apiextensionsclient,
@@ -80,10 +75,6 @@ func (n *FakeClient) Istio() istioclient.Interface {
return n.IstioClient return n.IstioClient
} }
func (n *FakeClient) Application() application.Interface {
return n.ApplicationClient
}
func (n *FakeClient) Snapshot() snapshotclient.Interface { func (n *FakeClient) Snapshot() snapshotclient.Interface {
return nil return nil
} }

View File

@@ -25,7 +25,6 @@ import (
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned" kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
applicationclientset "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
"strings" "strings"
) )
@@ -33,7 +32,6 @@ type Client interface {
Kubernetes() kubernetes.Interface Kubernetes() kubernetes.Interface
KubeSphere() kubesphere.Interface KubeSphere() kubesphere.Interface
Istio() istioclient.Interface Istio() istioclient.Interface
Application() applicationclientset.Interface
Snapshot() snapshotclient.Interface Snapshot() snapshotclient.Interface
ApiExtensions() apiextensionsclient.Interface ApiExtensions() apiextensionsclient.Interface
Discovery() discovery.DiscoveryInterface Discovery() discovery.DiscoveryInterface
@@ -51,8 +49,6 @@ type kubernetesClient struct {
// generated clientset // generated clientset
ks kubesphere.Interface ks kubesphere.Interface
application applicationclientset.Interface
istio istioclient.Interface istio istioclient.Interface
snapshot snapshotclient.Interface snapshot snapshotclient.Interface
@@ -79,7 +75,6 @@ func NewKubernetesClientOrDie(options *KubernetesOptions) Client {
discoveryClient: discovery.NewDiscoveryClientForConfigOrDie(config), discoveryClient: discovery.NewDiscoveryClientForConfigOrDie(config),
ks: kubesphere.NewForConfigOrDie(config), ks: kubesphere.NewForConfigOrDie(config),
istio: istioclient.NewForConfigOrDie(config), istio: istioclient.NewForConfigOrDie(config),
application: applicationclientset.NewForConfigOrDie(config),
snapshot: snapshotclient.NewForConfigOrDie(config), snapshot: snapshotclient.NewForConfigOrDie(config),
apiextensions: apiextensionsclient.NewForConfigOrDie(config), apiextensions: apiextensionsclient.NewForConfigOrDie(config),
master: config.Host, master: config.Host,
@@ -124,11 +119,6 @@ func NewKubernetesClient(options *KubernetesOptions) (Client, error) {
return nil, err return nil, err
} }
k.application, err = applicationclientset.NewForConfig(config)
if err != nil {
return nil, err
}
k.istio, err = istioclient.NewForConfig(config) k.istio, err = istioclient.NewForConfig(config)
if err != nil { if err != nil {
@@ -163,10 +153,6 @@ func (k *kubernetesClient) KubeSphere() kubesphere.Interface {
return k.ks return k.ks
} }
func (k *kubernetesClient) Application() applicationclientset.Interface {
return k.application
}
func (k *kubernetesClient) Istio() istioclient.Interface { func (k *kubernetesClient) Istio() istioclient.Interface {
return k.istio return k.istio
} }

View File

@@ -24,7 +24,6 @@ import (
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned" kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
application "kubesphere.io/kubesphere/pkg/simple/client/app/clientset/versioned"
) )
type nullClient struct { type nullClient struct {
@@ -46,10 +45,6 @@ func (n nullClient) Istio() istio.Interface {
return nil return nil
} }
func (n nullClient) Application() application.Interface {
return nil
}
func (n nullClient) Snapshot() snapshotclient.Interface { func (n nullClient) Snapshot() snapshotclient.Interface {
return nil return nil
} }

View File

@@ -17,6 +17,7 @@ limitations under the License.
package calico package calico
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "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) 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) { if k8serrors.IsAlreadyExists(err) {
return nil return nil
} }
@@ -135,7 +136,7 @@ func (c provider) UpdateIPPool(pool *v1alpha1.IPPool) error {
func (c provider) GetIPPoolStats(pool *v1alpha1.IPPool) (*v1alpha1.IPPool, error) { func (c provider) GetIPPoolStats(pool *v1alpha1.IPPool) (*v1alpha1.IPPool, error) {
stats := pool.DeepCopy() 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 { if err != nil {
return nil, err return nil, err
} }
@@ -195,7 +196,7 @@ func setBlockAffiDeletion(c calicoset.Interface, blockAffi *calicov3.BlockAffini
} }
blockAffi.Spec.State = string(model.StatePendingDeletion) blockAffi.Spec.State = string(model.StatePendingDeletion)
_, err := c.CrdCalicov3().BlockAffinities().Update(blockAffi) _, err := c.CrdCalicov3().BlockAffinities().Update(context.TODO(), blockAffi, v1.UpdateOptions{})
return err return err
} }
@@ -203,13 +204,13 @@ func deleteBlockAffi(c calicoset.Interface, blockAffi *calicov3.BlockAffinity) e
trueStr := fmt.Sprintf("%t", true) trueStr := fmt.Sprintf("%t", true)
if blockAffi.Spec.Deleted != trueStr { if blockAffi.Spec.Deleted != trueStr {
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 { if err != nil {
return err 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 { if err != nil {
return err 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 { func (c provider) doBlockAffis(pool *calicov3.IPPool, do func(calicoset.Interface, *calicov3.BlockAffinity) error) error {
_, cidrNet, _ := cnet.ParseCIDR(pool.Spec.CIDR) _, 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 { if err != nil {
return err 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) { func (c provider) listBlocks(pool *calicov3.IPPool) ([]calicov3.IPAMBlock, error) {
_, cidrNet, _ := cnet.ParseCIDR(pool.Spec.CIDR) _, 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 { if err != nil {
return nil, err return nil, err
} }
@@ -280,7 +281,7 @@ func deleteBlock(c calicoset.Interface, block *calicov3.IPAMBlock) error {
if block.Empty() { if block.Empty() {
if !block.Spec.Deleted { if !block.Spec.Deleted {
block.Spec.Deleted = true block.Spec.Deleted = true
_, err := c.CrdCalicov3().IPAMBlocks().Update(block) _, err := c.CrdCalicov3().IPAMBlocks().Update(context.TODO(), block, v1.UpdateOptions{})
if err != nil { if err != nil {
return err return err
} }
@@ -288,7 +289,7 @@ func deleteBlock(c calicoset.Interface, block *calicov3.IPAMBlock) error {
} else { } else {
return ErrBlockInuse 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 { if err != nil {
return err return err
} }
@@ -305,7 +306,7 @@ func (c provider) DeleteIPPool(pool *v1alpha1.IPPool) (bool, error) {
// - delete the pool // - delete the pool
// Get the pool so that we can find the CIDR associated with it. // 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 err != nil {
if k8serrors.IsNotFound(err) { if k8serrors.IsNotFound(err) {
return true, nil return true, nil
@@ -317,7 +318,7 @@ func (c provider) DeleteIPPool(pool *v1alpha1.IPPool) (bool, error) {
if !calicoPool.Spec.Disabled { if !calicoPool.Spec.Disabled {
calicoPool.Spec.Disabled = true 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 { if err != nil {
return false, err return false, err
} }
@@ -354,7 +355,7 @@ func (c provider) DeleteIPPool(pool *v1alpha1.IPPool) (bool, error) {
} }
//delete calico ippool //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 { if err != nil {
return false, err return false, err
} }
@@ -365,13 +366,13 @@ func (c provider) DeleteIPPool(pool *v1alpha1.IPPool) (bool, error) {
//Synchronizing address pools at boot time //Synchronizing address pools at boot time
func (c provider) syncIPPools() error { 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 { if err != nil {
klog.V(4).Infof("syncIPPools: cannot list calico ippools, err=%v", err) klog.V(4).Infof("syncIPPools: cannot list calico ippools, err=%v", err)
return 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 { if err != nil {
klog.V(4).Infof("syncIPPools: cannot list kubesphere ippools, err=%v", err) klog.V(4).Infof("syncIPPools: cannot list kubesphere ippools, err=%v", err)
return err return err
@@ -401,7 +402,7 @@ func (c provider) syncIPPools() error {
Status: v1alpha1.IPPoolStatus{}, Status: v1alpha1.IPPoolStatus{},
} }
_, err = c.ksclient.NetworkV1alpha1().IPPools().Create(pool) _, err = c.ksclient.NetworkV1alpha1().IPPools().Create(context.TODO(), pool, v1.CreateOptions{})
if err != nil { if err != nil {
klog.V(4).Infof("syncIPPools: cannot create kubesphere ippools, err=%v", err) klog.V(4).Infof("syncIPPools: cannot create kubesphere ippools, err=%v", err)
return err return err
@@ -417,7 +418,7 @@ func (p provider) getAssociatedWorkspaces(pool *v1alpha1.IPPool) ([]string, erro
poolLabel := constants.WorkspaceLabelKey poolLabel := constants.WorkspaceLabelKey
if pool.GetLabels() == nil || pool.GetLabels()[poolLabel] == "" { 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 { if err != nil {
return nil, err 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) { func (p provider) getWorkspaceStatus(name string, poolName string) (*v1alpha1.WorkspaceStatus, error) {
var result v1alpha1.WorkspaceStatus 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( LabelSelector: labels.SelectorFromSet(
map[string]string{ map[string]string{
constants.WorkspaceLabelKey: name, constants.WorkspaceLabelKey: name,
@@ -447,7 +448,7 @@ func (p provider) getWorkspaceStatus(name string, poolName string) (*v1alpha1.Wo
} }
for _, ns := range namespaces.Items { 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 { if err != nil {
return nil, err return nil, err
} }
@@ -499,7 +500,7 @@ func (p provider) processBlock(name string) error {
poolName := block.Labels[v1alpha1.IPPoolNameLabel] poolName := block.Labels[v1alpha1.IPPoolNameLabel]
if poolName == "" { 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 { if err != nil {
return err return err
} }
@@ -512,7 +513,7 @@ func (p provider) processBlock(name string) error {
block.Labels = map[string]string{ block.Labels = map[string]string{
v1alpha1.IPPoolNameLabel: pool.Name, v1alpha1.IPPoolNameLabel: pool.Name,
} }
p.client.CrdCalicov3().IPAMBlocks().Update(block) p.client.CrdCalicov3().IPAMBlocks().Update(context.TODO(), block, v1.UpdateOptions{})
break break
} }
} }
@@ -540,7 +541,7 @@ func (p provider) processBlock(name string) error {
} }
retry.RetryOnConflict(retry.DefaultBackoff, func() 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 { if err != nil {
return err return err
} }
@@ -563,7 +564,7 @@ func (p provider) processBlock(name string) error {
pod.GetAnnotations()[CalicoAnnotationIPPoolV4] = string(annostrs) pod.GetAnnotations()[CalicoAnnotationIPPoolV4] = string(annostrs)
pod.Labels[v1alpha1.IPPoolNameLabel] = poolName 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 return err
}) })
@@ -617,7 +618,7 @@ func (p provider) Default(obj runtime.Object) error {
} }
if annos[CalicoAnnotationIPPoolV4] == "" { 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{ LabelSelector: labels.SelectorFromSet(map[string]string{
v1alpha1.IPPoolDefaultLabel: "", v1alpha1.IPPoolDefaultLabel: "",
}).String(), }).String(),
@@ -650,7 +651,7 @@ func NewProvider(podInformer informercorev1.PodInformer, ksclient kubesphereclie
klog.Fatalf("failed to new calico client , err=%v", err) 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 { if err != nil {
klog.Fatalf("failed to get calico-node deployment in kube-system, err=%v", err) klog.Fatalf("failed to get calico-node deployment in kube-system, err=%v", err)
} }

View File

@@ -123,7 +123,7 @@ func generateSwaggerJson() []byte {
urlruntime.Must(openpitrixv1.AddToContainer(container, informerFactory, openpitrix.NewMockClient(nil))) urlruntime.Must(openpitrixv1.AddToContainer(container, informerFactory, openpitrix.NewMockClient(nil)))
urlruntime.Must(operationsv1alpha2.AddToContainer(container, clientsets.Kubernetes())) urlruntime.Must(operationsv1alpha2.AddToContainer(container, clientsets.Kubernetes()))
urlruntime.Must(resourcesv1alpha2.AddToContainer(container, clientsets.Kubernetes(), informerFactory, "")) 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(tenantv1alpha2.AddToContainer(container, informerFactory, nil, nil, nil, nil, nil, nil, nil))
urlruntime.Must(terminalv1alpha2.AddToContainer(container, clientsets.Kubernetes(), nil)) urlruntime.Must(terminalv1alpha2.AddToContainer(container, clientsets.Kubernetes(), nil))
urlruntime.Must(metricsv1alpha2.AddToContainer(container)) urlruntime.Must(metricsv1alpha2.AddToContainer(container))

1
vendor/modules.txt vendored
View File

@@ -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/controller/controllerutil
sigs.k8s.io/controller-runtime/pkg/conversion sigs.k8s.io/controller-runtime/pkg/conversion
sigs.k8s.io/controller-runtime/pkg/envtest 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/event
sigs.k8s.io/controller-runtime/pkg/handler sigs.k8s.io/controller-runtime/pkg/handler
sigs.k8s.io/controller-runtime/pkg/healthz sigs.k8s.io/controller-runtime/pkg/healthz

View File

@@ -0,0 +1,53 @@
/*
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") }

View File

@@ -0,0 +1,109 @@
/*
Copyright 2020 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
import (
"fmt"
"os"
"path/filepath"
"sync"
"github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/reporters"
"github.com/onsi/ginkgo/types"
"k8s.io/apimachinery/pkg/util/sets"
)
var (
allRegisteredSuites = sets.String{}
allRegisteredSuitesLock = &sync.Mutex{}
)
type prowReporter struct {
junitReporter *reporters.JUnitReporter
}
// NewProwReporter returns a prowReporter that will write out junit if running in Prow and do
// nothing otherwise.
// WARNING: It seems this does not always properly fail the test runs when there are failures,
// see https://github.com/onsi/ginkgo/issues/706
// When using this you must make sure to grep for failures in your junit xmls and fail the run
// if there are any.
func NewProwReporter(suiteName string) ginkgo.Reporter {
allRegisteredSuitesLock.Lock()
if allRegisteredSuites.Has(suiteName) {
panic(fmt.Sprintf("Suite named %q registered more than once", suiteName))
}
allRegisteredSuites.Insert(suiteName)
allRegisteredSuitesLock.Unlock()
if os.Getenv("CI") == "" {
return &prowReporter{}
}
artifactsDir := os.Getenv("ARTIFACTS")
if artifactsDir == "" {
return &prowReporter{}
}
path := filepath.Join(artifactsDir, fmt.Sprintf("junit_%s_%d.xml", suiteName, config.GinkgoConfig.ParallelNode))
return &prowReporter{
junitReporter: reporters.NewJUnitReporter(path),
}
}
func (pr *prowReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
if pr.junitReporter != nil {
pr.junitReporter.SpecSuiteWillBegin(config, summary)
}
}
// BeforeSuiteDidRun implements ginkgo.Reporter
func (pr *prowReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {
if pr.junitReporter != nil {
pr.junitReporter.BeforeSuiteDidRun(setupSummary)
}
}
// AfterSuiteDidRun implements ginkgo.Reporter
func (pr *prowReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
if pr.junitReporter != nil {
pr.junitReporter.AfterSuiteDidRun(setupSummary)
}
}
// SpecWillRun implements ginkgo.Reporter
func (pr *prowReporter) SpecWillRun(specSummary *types.SpecSummary) {
if pr.junitReporter != nil {
pr.junitReporter.SpecWillRun(specSummary)
}
}
// SpecDidComplete implements ginkgo.Reporter
func (pr *prowReporter) SpecDidComplete(specSummary *types.SpecSummary) {
if pr.junitReporter != nil {
pr.junitReporter.SpecDidComplete(specSummary)
}
}
// SpecSuiteDidEnd Prints a newline between "35 Passed | 0 Failed | 0 Pending | 0 Skipped" and "--- PASS:"
func (pr *prowReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
if pr.junitReporter != nil {
pr.junitReporter.SpecSuiteDidEnd(summary)
}
}