fix cluster controller (#1996)
This commit is contained in:
2
Makefile
2
Makefile
@@ -63,7 +63,7 @@ vet: generate
|
|||||||
|
|
||||||
# Generate manifests e.g. CRD, RBAC etc.
|
# Generate manifests e.g. CRD, RBAC etc.
|
||||||
manifests:
|
manifests:
|
||||||
go run ./vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go object:headerFile=./hack/boilerplate.go.txt paths=./pkg/apis/...
|
go run ./vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go object:headerFile=./hack/boilerplate.go.txt paths=./pkg/apis/... rbac:roleName=controller-perms ${CRD_OPTIONS} output:crd:artifacts:config=config/crd/bases
|
||||||
|
|
||||||
deploy: manifests
|
deploy: manifests
|
||||||
kubectl apply -f config/crds
|
kubectl apply -f config/crds
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ spec:
|
|||||||
listKind: ClusterList
|
listKind: ClusterList
|
||||||
plural: clusters
|
plural: clusters
|
||||||
singular: cluster
|
singular: cluster
|
||||||
scope: Namespaced
|
scope: Cluster
|
||||||
validation:
|
validation:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
description: Cluster is the schema for the clusters API
|
description: Cluster is the schema for the clusters API
|
||||||
@@ -37,35 +37,52 @@ spec:
|
|||||||
description: Desired state of the cluster
|
description: Desired state of the cluster
|
||||||
type: boolean
|
type: boolean
|
||||||
federated:
|
federated:
|
||||||
description: Join cluster as kubefed cluster
|
description: Join cluster as a kubefed cluster
|
||||||
type: boolean
|
type: boolean
|
||||||
|
provider:
|
||||||
|
description: Provider of the cluster, this field is just for description
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
properties:
|
properties:
|
||||||
lastTransitionTime:
|
conditions:
|
||||||
description: Last time the condition transitioned from one status to
|
description: Represents the latest available observations of a cluster's
|
||||||
another.
|
current state.
|
||||||
format: date-time
|
items:
|
||||||
|
properties:
|
||||||
|
lastTransitionTime:
|
||||||
|
description: Last time the condition transitioned from one status
|
||||||
|
to another.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
lastUpdateTime:
|
||||||
|
description: The last time this condition was updated.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
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 the condition
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
version:
|
||||||
|
description: GitVersion of the kubernetes cluster, this field is set
|
||||||
|
by cluster controller
|
||||||
type: string
|
type: string
|
||||||
lastUpdateTime:
|
|
||||||
description: The last time this condition was updated.
|
|
||||||
format: date-time
|
|
||||||
type: string
|
|
||||||
message:
|
|
||||||
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 the condition
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- status
|
|
||||||
- type
|
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
version: v1alpha1
|
version: v1alpha1
|
||||||
|
|||||||
@@ -82,8 +82,6 @@ type AgentCondition struct {
|
|||||||
|
|
||||||
// AgentStatus defines the observed state of Agent
|
// AgentStatus defines the observed state of Agent
|
||||||
type AgentStatus struct {
|
type AgentStatus struct {
|
||||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
|
||||||
// Important: Run "make" to regenerate code after modifying this file
|
|
||||||
|
|
||||||
// Represents the latest available observations of a agent's current state.
|
// Represents the latest available observations of a agent's current state.
|
||||||
Conditions []AgentCondition `json:"conditions,omitempty"`
|
Conditions []AgentCondition `json:"conditions,omitempty"`
|
||||||
@@ -99,6 +97,8 @@ type AgentStatus struct {
|
|||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
// +k8s:openapi-gen=true
|
// +k8s:openapi-gen=true
|
||||||
// +genclient:nonNamespaced
|
// +genclient:nonNamespaced
|
||||||
|
// +kubebuilder:printcolumn:name="Paused",type="bool",JSONPath=".spec.Paused"
|
||||||
|
// +kubebuilder:resource:scope=Cluster
|
||||||
|
|
||||||
// Agent is the Schema for the agents API
|
// Agent is the Schema for the agents API
|
||||||
type Agent struct {
|
type Agent struct {
|
||||||
|
|||||||
@@ -9,31 +9,38 @@ const (
|
|||||||
ResourceKindCluster = "Cluster"
|
ResourceKindCluster = "Cluster"
|
||||||
ResourcesSingularCluster = "cluster"
|
ResourcesSingularCluster = "cluster"
|
||||||
ResourcesPluralCluster = "clusters"
|
ResourcesPluralCluster = "clusters"
|
||||||
|
|
||||||
|
IsHostCluster = "cluster.kubesphere.io/is-host-cluster"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ClusterSpec struct {
|
type ClusterSpec struct {
|
||||||
|
|
||||||
// Join cluster as kubefed cluster
|
// Join cluster as a kubefed cluster
|
||||||
|
// +optional
|
||||||
Federated bool `json:"federated,omitempty"`
|
Federated bool `json:"federated,omitempty"`
|
||||||
|
|
||||||
// Desired state of the cluster
|
// Desired state of the cluster
|
||||||
Active bool `json:"active,omitempty"`
|
Active bool `json:"active,omitempty"`
|
||||||
|
|
||||||
|
// Provider of the cluster, this field is just for description
|
||||||
|
// +optional
|
||||||
|
Provider string `json:"provider,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClusterConditionType string
|
type ClusterConditionType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Cluster agent is initialized and waiting for connecting
|
// Cluster agent is initialized and waiting for connecting
|
||||||
ClusterAgentInitialized ClusterConditionType = "AgentInitialized"
|
ClusterInitialized ClusterConditionType = "Initialized"
|
||||||
|
|
||||||
// Cluster agent is available
|
// Cluster agent is available
|
||||||
ClusterAgentAvailable ClusterConditionType = "AgentAvailable"
|
ClusterAgentAvailable ClusterConditionType = "AgentAvailable"
|
||||||
|
|
||||||
//
|
// Cluster has been one of federated clusters
|
||||||
|
ClusterFederated ClusterConditionType = "Federated"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ClusterStatus struct {
|
type ClusterCondition struct {
|
||||||
// Type of the condition
|
// Type of the condition
|
||||||
Type ClusterConditionType `json:"type"`
|
Type ClusterConditionType `json:"type"`
|
||||||
// Status of the condition, one of True, False, Unknown.
|
// Status of the condition, one of True, False, Unknown.
|
||||||
@@ -48,10 +55,28 @@ type ClusterStatus struct {
|
|||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ClusterStatus struct {
|
||||||
|
|
||||||
|
// Represents the latest available observations of a cluster's current state.
|
||||||
|
Conditions []ClusterCondition `json:"conditions,omitempty"`
|
||||||
|
|
||||||
|
// GitVersion of the kubernetes cluster, this field is set by cluster controller
|
||||||
|
// +optional
|
||||||
|
KubernetesVersion string `json:"version,omitempty"`
|
||||||
|
|
||||||
|
//
|
||||||
|
NodeCount int `json:"count,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// +genclient
|
// +genclient
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
// +k8s:openapi-gen=true
|
// +k8s:openapi-gen=true
|
||||||
// +genclient:nonNamespaced
|
// +genclient:nonNamespaced
|
||||||
|
// +groupName
|
||||||
|
// +kubebuilder:printcolumn:name="Federated",type="bool",JSONPath=".spec.Federated"
|
||||||
|
// +kubebuilder:printcolumn:name="Provider",type="string",JSONPath=".spec.Provider"
|
||||||
|
// +kubebuilder:printcolumn:name="Active",type="bool",JSONPath=".spec.Active"
|
||||||
|
// +kubebuilder:resource:scope=Cluster
|
||||||
|
|
||||||
// Cluster is the schema for the clusters API
|
// Cluster is the schema for the clusters API
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
|
|||||||
37
pkg/apis/cluster/v1alpha1/zz_generated.deepcopy.go
generated
37
pkg/apis/cluster/v1alpha1/zz_generated.deepcopy.go
generated
@@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
@@ -31,7 +31,6 @@ func (in *Agent) DeepCopyInto(out *Agent) {
|
|||||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
out.Spec = in.Spec
|
out.Spec = in.Spec
|
||||||
in.Status.DeepCopyInto(&out.Status)
|
in.Status.DeepCopyInto(&out.Status)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Agent.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Agent.
|
||||||
@@ -57,7 +56,6 @@ func (in *AgentCondition) DeepCopyInto(out *AgentCondition) {
|
|||||||
*out = *in
|
*out = *in
|
||||||
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
|
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
|
||||||
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentCondition.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentCondition.
|
||||||
@@ -82,7 +80,6 @@ func (in *AgentList) DeepCopyInto(out *AgentList) {
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentList.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentList.
|
||||||
@@ -106,7 +103,6 @@ func (in *AgentList) DeepCopyObject() runtime.Object {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *AgentSpec) DeepCopyInto(out *AgentSpec) {
|
func (in *AgentSpec) DeepCopyInto(out *AgentSpec) {
|
||||||
*out = *in
|
*out = *in
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentSpec.
|
||||||
@@ -134,7 +130,6 @@ func (in *AgentStatus) DeepCopyInto(out *AgentStatus) {
|
|||||||
*out = make([]byte, len(*in))
|
*out = make([]byte, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentStatus.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentStatus.
|
||||||
@@ -154,7 +149,6 @@ func (in *Cluster) DeepCopyInto(out *Cluster) {
|
|||||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
out.Spec = in.Spec
|
out.Spec = in.Spec
|
||||||
in.Status.DeepCopyInto(&out.Status)
|
in.Status.DeepCopyInto(&out.Status)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
|
||||||
@@ -175,6 +169,23 @@ func (in *Cluster) DeepCopyObject() runtime.Object {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ClusterCondition) DeepCopyInto(out *ClusterCondition) {
|
||||||
|
*out = *in
|
||||||
|
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
|
||||||
|
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCondition.
|
||||||
|
func (in *ClusterCondition) DeepCopy() *ClusterCondition {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ClusterCondition)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ClusterList) DeepCopyInto(out *ClusterList) {
|
func (in *ClusterList) DeepCopyInto(out *ClusterList) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -187,7 +198,6 @@ func (in *ClusterList) DeepCopyInto(out *ClusterList) {
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList.
|
||||||
@@ -211,7 +221,6 @@ func (in *ClusterList) DeepCopyObject() runtime.Object {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
||||||
*out = *in
|
*out = *in
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
|
||||||
@@ -227,9 +236,13 @@ func (in *ClusterSpec) DeepCopy() *ClusterSpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) {
|
func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
|
if in.Conditions != nil {
|
||||||
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
in, out := &in.Conditions, &out.Conditions
|
||||||
return
|
*out = make([]ClusterCondition, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus.
|
||||||
|
|||||||
7
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
generated
7
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
generated
@@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
package v1alpha2
|
package v1alpha2
|
||||||
|
|
||||||
@@ -31,7 +31,6 @@ func (in *User) DeepCopyInto(out *User) {
|
|||||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
in.Spec.DeepCopyInto(&out.Spec)
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
in.Status.DeepCopyInto(&out.Status)
|
in.Status.DeepCopyInto(&out.Status)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new User.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new User.
|
||||||
@@ -56,7 +55,6 @@ func (in *User) DeepCopyObject() runtime.Object {
|
|||||||
func (in *UserCondition) DeepCopyInto(out *UserCondition) {
|
func (in *UserCondition) DeepCopyInto(out *UserCondition) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserCondition.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserCondition.
|
||||||
@@ -81,7 +79,6 @@ func (in *UserList) DeepCopyInto(out *UserList) {
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserList.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserList.
|
||||||
@@ -115,7 +112,6 @@ func (in *UserSpec) DeepCopyInto(out *UserSpec) {
|
|||||||
*out = make([]FinalizerName, len(*in))
|
*out = make([]FinalizerName, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserSpec.
|
||||||
@@ -138,7 +134,6 @@ func (in *UserStatus) DeepCopyInto(out *UserStatus) {
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserStatus.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserStatus.
|
||||||
|
|||||||
@@ -182,7 +182,9 @@ func (s *APIServer) buildHandlerChain() {
|
|||||||
|
|
||||||
handler := s.Server.Handler
|
handler := s.Server.Handler
|
||||||
handler = filters.WithKubeAPIServer(handler, s.KubernetesClient.Config(), &errorResponder{})
|
handler = filters.WithKubeAPIServer(handler, s.KubernetesClient.Config(), &errorResponder{})
|
||||||
handler = filters.WithMultipleClusterDispatcher(handler, dispatch.NewClusterDispatch(s.InformerFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Agents().Lister()))
|
|
||||||
|
clusterDispatcher := dispatch.NewClusterDispatch(s.InformerFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Agents().Lister(), s.InformerFactory.KubeSphereSharedInformerFactory().Cluster().V1alpha1().Clusters().Lister())
|
||||||
|
handler = filters.WithMultipleClusterDispatcher(handler, clusterDispatcher)
|
||||||
|
|
||||||
excludedPaths := []string{"/oauth/*", "/kapis/config.kubesphere.io/*"}
|
excludedPaths := []string{"/oauth/*", "/kapis/config.kubesphere.io/*"}
|
||||||
pathAuthorizer, _ := path.NewAuthorizer(excludedPaths)
|
pathAuthorizer, _ := path.NewAuthorizer(excludedPaths)
|
||||||
|
|||||||
@@ -2,11 +2,8 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/emicklei/go-restful"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
|
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
|
||||||
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
|
|
||||||
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
|
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
|
||||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
||||||
@@ -20,7 +17,6 @@ import (
|
|||||||
"kubesphere.io/kubesphere/pkg/simple/client/s3"
|
"kubesphere.io/kubesphere/pkg/simple/client/s3"
|
||||||
"kubesphere.io/kubesphere/pkg/simple/client/servicemesh"
|
"kubesphere.io/kubesphere/pkg/simple/client/servicemesh"
|
||||||
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
|
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
|
||||||
"net/http"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -126,26 +122,6 @@ func TryLoadFromDisk() (*Config, error) {
|
|||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstallAPI installs api for config
|
|
||||||
func (conf *Config) InstallAPI(c *restful.Container) {
|
|
||||||
ws := runtime.NewWebService(schema.GroupVersion{
|
|
||||||
Group: "",
|
|
||||||
Version: "v1alpha1",
|
|
||||||
})
|
|
||||||
|
|
||||||
ws.Route(ws.GET("/configz").
|
|
||||||
To(func(request *restful.Request, response *restful.Response) {
|
|
||||||
conf.stripEmptyOptions()
|
|
||||||
response.WriteAsJson(conf.ToMap())
|
|
||||||
}).
|
|
||||||
Doc("Get system components configuration").
|
|
||||||
Produces(restful.MIME_JSON).
|
|
||||||
Writes(Config{}).
|
|
||||||
Returns(http.StatusOK, "ok", Config{}))
|
|
||||||
|
|
||||||
c.Add(ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertToMap simply converts config to map[string]bool
|
// convertToMap simply converts config to map[string]bool
|
||||||
// to hide sensitive information
|
// to hide sensitive information
|
||||||
func (conf *Config) ToMap() map[string]bool {
|
func (conf *Config) ToMap() map[string]bool {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/proxy"
|
"k8s.io/apimachinery/pkg/util/proxy"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||||
|
"k8s.io/klog"
|
||||||
clusterv1alpha1 "kubesphere.io/kubesphere/pkg/apis/cluster/v1alpha1"
|
clusterv1alpha1 "kubesphere.io/kubesphere/pkg/apis/cluster/v1alpha1"
|
||||||
"kubesphere.io/kubesphere/pkg/apiserver/request"
|
"kubesphere.io/kubesphere/pkg/apiserver/request"
|
||||||
"kubesphere.io/kubesphere/pkg/client/listers/cluster/v1alpha1"
|
"kubesphere.io/kubesphere/pkg/client/listers/cluster/v1alpha1"
|
||||||
@@ -13,27 +14,46 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultMultipleClusterAgentNamespace = "kubesphere-system"
|
|
||||||
|
|
||||||
// Dispatcher defines how to forward request to designated cluster based on cluster name
|
// Dispatcher defines how to forward request to designated cluster based on cluster name
|
||||||
type Dispatcher interface {
|
type Dispatcher interface {
|
||||||
Dispatch(w http.ResponseWriter, req *http.Request, handler http.Handler)
|
Dispatch(w http.ResponseWriter, req *http.Request, handler http.Handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
type clusterDispatch struct {
|
type clusterDispatch struct {
|
||||||
agentLister v1alpha1.AgentLister
|
agentLister v1alpha1.AgentLister
|
||||||
|
clusterLister v1alpha1.ClusterLister
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClusterDispatch(agentLister v1alpha1.AgentLister) Dispatcher {
|
func NewClusterDispatch(agentLister v1alpha1.AgentLister, clusterLister v1alpha1.ClusterLister) Dispatcher {
|
||||||
return &clusterDispatch{
|
return &clusterDispatch{
|
||||||
agentLister: agentLister,
|
agentLister: agentLister,
|
||||||
|
clusterLister: clusterLister,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clusterDispatch) Dispatch(w http.ResponseWriter, req *http.Request, handler http.Handler) {
|
func (c *clusterDispatch) Dispatch(w http.ResponseWriter, req *http.Request, handler http.Handler) {
|
||||||
|
|
||||||
info, _ := request.RequestInfoFrom(req.Context())
|
info, _ := request.RequestInfoFrom(req.Context())
|
||||||
if info.Cluster == "" { // fallback to host cluster if cluster name if empty
|
|
||||||
|
if len(info.Cluster) == 0 {
|
||||||
|
klog.Warningf("Request with empty cluster, %v", req.URL)
|
||||||
|
http.Error(w, fmt.Sprintf("Bad request, empty cluster"), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster, err := c.clusterLister.Get(info.Cluster)
|
||||||
|
if err != nil {
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
http.Error(w, fmt.Sprintf("cluster %s not found", info.Cluster), http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// request cluster is host cluster, no need go through agent
|
||||||
|
if isClusterHostCluster(cluster) {
|
||||||
|
req.URL.Path = strings.Replace(req.URL.Path, fmt.Sprintf("/clusters/%s", info.Cluster), "", 1)
|
||||||
handler.ServeHTTP(w, req)
|
handler.ServeHTTP(w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -74,3 +94,14 @@ func isAgentReady(agent *clusterv1alpha1.Agent) bool {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
func isClusterHostCluster(cluster *clusterv1alpha1.Cluster) bool {
|
||||||
|
for key, value := range cluster.Annotations {
|
||||||
|
if key == clusterv1alpha1.IsHostCluster && value == "true" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ type RequestInfoFactory struct {
|
|||||||
// /kapis/{api-group}/{version}/namespaces/{namespace}/{resource}
|
// /kapis/{api-group}/{version}/namespaces/{namespace}/{resource}
|
||||||
// /kapis/{api-group}/{version}/namespaces/{namespace}/{resource}/{resourceName}
|
// /kapis/{api-group}/{version}/namespaces/{namespace}/{resource}/{resourceName}
|
||||||
// With workspaces:
|
// With workspaces:
|
||||||
// /kapis/{api-group}/{version}/clusters/{cluster}/namespaces/{namespace}/{resource}
|
// /kapis/clusters/{cluster}/{api-group}/{version}/namespaces/{namespace}/{resource}
|
||||||
// /kapis/{api-group}/{version}/clusters/{cluster}/namespaces/{namespace}/{resource}/{resourceName}
|
// /kapis/clusters/{cluster}/{api-group}/{version}/namespaces/{namespace}/{resource}/{resourceName}
|
||||||
//
|
//
|
||||||
func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, error) {
|
func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, error) {
|
||||||
|
|
||||||
@@ -111,6 +111,16 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
|
|||||||
requestInfo.APIPrefix = currentParts[0]
|
requestInfo.APIPrefix = currentParts[0]
|
||||||
currentParts = currentParts[1:]
|
currentParts = currentParts[1:]
|
||||||
|
|
||||||
|
// URL forms: /clusters/{cluster}/*
|
||||||
|
if currentParts[0] == "clusters" {
|
||||||
|
if len(currentParts) > 1 {
|
||||||
|
requestInfo.Cluster = currentParts[1]
|
||||||
|
}
|
||||||
|
if len(currentParts) > 2 {
|
||||||
|
currentParts = currentParts[2:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !r.GrouplessAPIPrefixes.Has(requestInfo.APIPrefix) {
|
if !r.GrouplessAPIPrefixes.Has(requestInfo.APIPrefix) {
|
||||||
// one part (APIPrefix) has already been consumed, so this is actually "do we have four parts?"
|
// one part (APIPrefix) has already been consumed, so this is actually "do we have four parts?"
|
||||||
if len(currentParts) < 3 {
|
if len(currentParts) < 3 {
|
||||||
@@ -150,16 +160,6 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL forms: /clusters/{cluster}/*
|
|
||||||
if currentParts[0] == "clusters" {
|
|
||||||
if len(currentParts) > 1 {
|
|
||||||
requestInfo.Cluster = currentParts[1]
|
|
||||||
}
|
|
||||||
if len(currentParts) > 2 {
|
|
||||||
currentParts = currentParts[2:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// URL forms: /workspaces/{workspace}/*
|
// URL forms: /workspaces/{workspace}/*
|
||||||
if currentParts[0] == "workspaces" {
|
if currentParts[0] == "workspaces" {
|
||||||
if len(currentParts) > 1 {
|
if len(currentParts) > 1 {
|
||||||
|
|||||||
@@ -59,40 +59,18 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
|
|||||||
expectedKubernetesRequest: false,
|
expectedKubernetesRequest: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "list cluster roles",
|
name: "list clusterRoles of cluster gondor",
|
||||||
url: "/apis/rbac.authorization.k8s.io/v1/clusters/cluster1/clusterroles",
|
url: "/apis/clusters/gondor/rbac.authorization.k8s.io/v1/clusterroles",
|
||||||
method: http.MethodGet,
|
method: http.MethodGet,
|
||||||
expectedErr: nil,
|
expectedErr: nil,
|
||||||
expectedVerb: "list",
|
expectedVerb: "list",
|
||||||
expectedResource: "clusterroles",
|
expectedResource: "clusterroles",
|
||||||
expectedIsResourceRequest: true,
|
expectedIsResourceRequest: true,
|
||||||
expectedCluster: "cluster1",
|
expectedCluster: "gondor",
|
||||||
expectedKubernetesRequest: true,
|
expectedKubernetesRequest: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "list cluster nodes",
|
name: "list nodes",
|
||||||
url: "/api/v1/clusters/cluster1/nodes",
|
|
||||||
method: http.MethodGet,
|
|
||||||
expectedErr: nil,
|
|
||||||
expectedVerb: "list",
|
|
||||||
expectedResource: "nodes",
|
|
||||||
expectedIsResourceRequest: true,
|
|
||||||
expectedCluster: "cluster1",
|
|
||||||
expectedKubernetesRequest: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "list cluster nodes",
|
|
||||||
url: "/api/v1/clusters/cluster1/nodes",
|
|
||||||
method: http.MethodGet,
|
|
||||||
expectedErr: nil,
|
|
||||||
expectedVerb: "list",
|
|
||||||
expectedResource: "nodes",
|
|
||||||
expectedIsResourceRequest: true,
|
|
||||||
expectedCluster: "cluster1",
|
|
||||||
expectedKubernetesRequest: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "list cluster nodes",
|
|
||||||
url: "/api/v1/nodes",
|
url: "/api/v1/nodes",
|
||||||
method: http.MethodGet,
|
method: http.MethodGet,
|
||||||
expectedErr: nil,
|
expectedErr: nil,
|
||||||
@@ -103,15 +81,26 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
|
|||||||
expectedKubernetesRequest: true,
|
expectedKubernetesRequest: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "list roles",
|
name: "list nodes of cluster gondor",
|
||||||
url: "/apis/rbac.authorization.k8s.io/v1/clusters/cluster1/namespaces/namespace1/roles",
|
url: "/api/clusters/gondor/v1/nodes",
|
||||||
|
method: http.MethodGet,
|
||||||
|
expectedErr: nil,
|
||||||
|
expectedVerb: "list",
|
||||||
|
expectedResource: "nodes",
|
||||||
|
expectedIsResourceRequest: true,
|
||||||
|
expectedCluster: "gondor",
|
||||||
|
expectedKubernetesRequest: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "list roles of cluster gondor",
|
||||||
|
url: "/apis/clusters/gondor/rbac.authorization.k8s.io/v1/namespaces/namespace1/roles",
|
||||||
method: http.MethodGet,
|
method: http.MethodGet,
|
||||||
expectedErr: nil,
|
expectedErr: nil,
|
||||||
expectedVerb: "list",
|
expectedVerb: "list",
|
||||||
expectedResource: "roles",
|
expectedResource: "roles",
|
||||||
expectedIsResourceRequest: true,
|
expectedIsResourceRequest: true,
|
||||||
expectedNamespace: "namespace1",
|
expectedNamespace: "namespace1",
|
||||||
expectedCluster: "cluster1",
|
expectedCluster: "gondor",
|
||||||
expectedKubernetesRequest: true,
|
expectedKubernetesRequest: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -139,17 +128,41 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) {
|
|||||||
expectedKubernetesRequest: false,
|
expectedKubernetesRequest: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "list namespaces",
|
name: "list namespaces of cluster gondor",
|
||||||
url: "/kapis/resources.kubesphere.io/v1alpha3/clusters/cluster1/workspaces/workspace1/namespaces",
|
url: "/kapis/clusters/gondor/resources.kubesphere.io/v1alpha3/workspaces/workspace1/namespaces",
|
||||||
method: http.MethodGet,
|
method: http.MethodGet,
|
||||||
expectedErr: nil,
|
expectedErr: nil,
|
||||||
expectedVerb: "list",
|
expectedVerb: "list",
|
||||||
expectedResource: "namespaces",
|
expectedResource: "namespaces",
|
||||||
expectedIsResourceRequest: true,
|
expectedIsResourceRequest: true,
|
||||||
expectedWorkspace: "workspace1",
|
expectedWorkspace: "workspace1",
|
||||||
expectedCluster: "cluster1",
|
expectedCluster: "gondor",
|
||||||
expectedKubernetesRequest: false,
|
expectedKubernetesRequest: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "list clusters",
|
||||||
|
url: "/apis/cluster.kubesphere.io/v1alpha1/clusters",
|
||||||
|
method: http.MethodGet,
|
||||||
|
expectedErr: nil,
|
||||||
|
expectedVerb: "list",
|
||||||
|
expectedResource: "clusters",
|
||||||
|
expectedIsResourceRequest: true,
|
||||||
|
expectedWorkspace: "",
|
||||||
|
expectedCluster: "",
|
||||||
|
expectedKubernetesRequest: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get cluster gondor",
|
||||||
|
url: "/apis/cluster.kubesphere.io/v1alpha1/clusters/gondor",
|
||||||
|
method: http.MethodGet,
|
||||||
|
expectedErr: nil,
|
||||||
|
expectedVerb: "get",
|
||||||
|
expectedResource: "clusters",
|
||||||
|
expectedIsResourceRequest: true,
|
||||||
|
expectedWorkspace: "",
|
||||||
|
expectedCluster: "",
|
||||||
|
expectedKubernetesRequest: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "random query",
|
name: "random query",
|
||||||
url: "/foo/bar",
|
url: "/foo/bar",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/client-go/util/retry"
|
"k8s.io/client-go/util/retry"
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
@@ -87,6 +88,12 @@ func NewClusterController(
|
|||||||
DeleteFunc: c.addCluster,
|
DeleteFunc: c.addCluster,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
agentInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
|
AddFunc: nil,
|
||||||
|
UpdateFunc: nil,
|
||||||
|
DeleteFunc: nil,
|
||||||
|
})
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +148,7 @@ func (c *ClusterController) syncCluster(key string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
klog.V(4).Info("Finished syncing cluster.", "name", name, "duration", time.Since(startTime))
|
klog.V(4).Infof("Finished syncing cluster %s in %s", name, time.Since(startTime))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
cluster, err := c.clusterLister.Get(name)
|
cluster, err := c.clusterLister.Get(name)
|
||||||
@@ -209,6 +216,66 @@ func (c *ClusterController) syncCluster(key string) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// agent connection is ready, update cluster status
|
||||||
|
// set
|
||||||
|
if len(agent.Status.KubeConfig) != 0 && c.isAgentReady(agent) {
|
||||||
|
clientConfig, err := clientcmd.NewClientConfigFromBytes(agent.Status.KubeConfig)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Unable to create client config from kubeconfig bytes, %#v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := clientConfig.ClientConfig()
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Failed to get client config, %#v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
clientSet, err := kubernetes.NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Failed to create ClientSet from config, %#v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
version, err := clientSet.Discovery().ServerVersion()
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Failed to get kubernetes version, %#v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster.Status.KubernetesVersion = version.GitVersion
|
||||||
|
|
||||||
|
nodes, err := clientSet.CoreV1().Nodes().List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Failed to get cluster nodes, %#v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster.Status.NodeCount = len(nodes.Items)
|
||||||
|
}
|
||||||
|
|
||||||
|
agentReadyCondition := clusterv1alpha1.ClusterCondition{
|
||||||
|
Type: clusterv1alpha1.ClusterAgentAvailable,
|
||||||
|
LastUpdateTime: metav1.NewTime(time.Now()),
|
||||||
|
LastTransitionTime: metav1.NewTime(time.Now()),
|
||||||
|
Reason: "",
|
||||||
|
Message: "Cluster agent is available now.",
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.isAgentReady(agent) {
|
||||||
|
agentReadyCondition.Status = v1.ConditionTrue
|
||||||
|
} else {
|
||||||
|
agentReadyCondition.Status = v1.ConditionFalse
|
||||||
|
}
|
||||||
|
|
||||||
|
c.addClusterCondition(cluster, agentReadyCondition)
|
||||||
|
|
||||||
|
_, err = c.clusterClient.Update(cluster)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Failed to update cluster status, %#v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,14 +284,64 @@ func (c *ClusterController) addCluster(obj interface{}) {
|
|||||||
|
|
||||||
key, err := cache.MetaNamespaceKeyFunc(obj)
|
key, err := cache.MetaNamespaceKeyFunc(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("get cluster key %s/%s failed", cluster.Namespace, cluster.Name))
|
utilruntime.HandleError(fmt.Errorf("get cluster key %s failed", cluster.Name))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.queue.Add(key)
|
c.queue.Add(key)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClusterController) handleErr(err error, key interface{}) {
|
func (c *ClusterController) handleErr(err error, key interface{}) {
|
||||||
|
if err == nil {
|
||||||
|
c.queue.Forget(key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.queue.NumRequeues(key) < maxRetries {
|
||||||
|
klog.V(2).Infof("Error syncing virtualservice %s for service retrying, %#v", key, err)
|
||||||
|
c.queue.AddRateLimited(key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(4).Infof("Dropping service %s out of the queue.", key)
|
||||||
|
c.queue.Forget(key)
|
||||||
|
utilruntime.HandleError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClusterController) addAgent(obj interface{}) {
|
||||||
|
agent := obj.(*clusterv1alpha1.Agent)
|
||||||
|
key, err := cache.MetaNamespaceKeyFunc(obj)
|
||||||
|
if err != nil {
|
||||||
|
utilruntime.HandleError(fmt.Errorf("get agent key %s failed", agent.Name))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.queue.Add(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClusterController) isAgentReady(agent *clusterv1alpha1.Agent) bool {
|
||||||
|
for _, condition := range agent.Status.Conditions {
|
||||||
|
if condition.Type == clusterv1alpha1.AgentConnected && condition.Status == v1.ConditionTrue {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// addClusterCondition add condition
|
||||||
|
func (c *ClusterController) addClusterCondition(cluster *clusterv1alpha1.Cluster, condition clusterv1alpha1.ClusterCondition) {
|
||||||
|
if cluster.Status.Conditions == nil {
|
||||||
|
cluster.Status.Conditions = make([]clusterv1alpha1.ClusterCondition, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
newConditions := make([]clusterv1alpha1.ClusterCondition, 0)
|
||||||
|
for _, cond := range cluster.Status.Conditions {
|
||||||
|
if cond.Type == condition.Type {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newConditions = append(newConditions, cond)
|
||||||
|
}
|
||||||
|
|
||||||
|
newConditions = append(newConditions, condition)
|
||||||
|
cluster.Status.Conditions = newConditions
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ func (v *DestinationRuleController) processNextWorkItem() bool {
|
|||||||
func (v *DestinationRuleController) syncService(key string) error {
|
func (v *DestinationRuleController) syncService(key string) error {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
defer func() {
|
defer func() {
|
||||||
log.V(4).Info("Finished syncing service destinationrule.", "key", key, "duration", time.Since(startTime))
|
log.V(4).Infof("Finished syncing service destinationrule %s in %s.", key, time.Since(startTime))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
namespace, name, err := cache.SplitMetaNamespaceKey(key)
|
namespace, name, err := cache.SplitMetaNamespaceKey(key)
|
||||||
@@ -212,14 +212,14 @@ func (v *DestinationRuleController) syncService(key string) error {
|
|||||||
// delete the corresponding destinationrule if there is any, as the service has been deleted.
|
// delete the corresponding destinationrule if there is any, as the service has been deleted.
|
||||||
err = v.destinationRuleClient.NetworkingV1alpha3().DestinationRules(namespace).Delete(name, nil)
|
err = v.destinationRuleClient.NetworkingV1alpha3().DestinationRules(namespace).Delete(name, nil)
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
log.Error(err, "delete destination rule failed", "namespace", namespace, "name", name)
|
log.Errorf("delete destination rule failed %s/%s, error %v.", namespace, name, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete orphan service policy if there is any
|
// delete orphan service policy if there is any
|
||||||
err = v.servicemeshClient.ServicemeshV1alpha2().ServicePolicies(namespace).Delete(name, nil)
|
err = v.servicemeshClient.ServicemeshV1alpha2().ServicePolicies(namespace).Delete(name, nil)
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
log.Error(err, "delete orphan service policy failed", "namespace", namespace, "name", name)
|
log.Errorf("delete orphan service policy %s/%s failed, %#v", namespace, name, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ func (v *DestinationRuleController) syncService(key string) error {
|
|||||||
version := util.GetComponentVersion(&deployment.ObjectMeta)
|
version := util.GetComponentVersion(&deployment.ObjectMeta)
|
||||||
|
|
||||||
if len(version) == 0 {
|
if len(version) == 0 {
|
||||||
log.V(4).Info("Deployment doesn't have a version label", "key", types.NamespacedName{Namespace: deployment.Namespace, Name: deployment.Name}.String())
|
log.V(4).Infof("Deployment %s doesn't have a version label", types.NamespacedName{Namespace: deployment.Namespace, Name: deployment.Name}.String())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ func (v *VirtualServiceController) syncService(key string) error {
|
|||||||
appName := name
|
appName := name
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
log.V(4).Info("Finished syncing service virtualservice.", "namespace", namespace, "name", name, "duration", time.Since(startTime))
|
log.V(4).Infof("Finished syncing service virtualservice %s/%s in %s.", namespace, name, time.Since(startTime))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
service, err := v.serviceLister.Services(namespace).Get(name)
|
service, err := v.serviceLister.Services(namespace).Get(name)
|
||||||
|
|||||||
Reference in New Issue
Block a user