add kubesphereversion field for cluser.status

Signed-off-by: yuswift <yuswiftli@yunify.com>

adopt reviews from @LinuxSuRen
This commit is contained in:
yuswift
2021-04-07 11:19:26 +08:00
parent 828d2c6d37
commit 3b00fc6d5e
3 changed files with 161 additions and 139 deletions

View File

@@ -1,6 +1,6 @@
--- ---
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
@@ -8,19 +8,6 @@ metadata:
creationTimestamp: null creationTimestamp: null
name: clusters.cluster.kubesphere.io name: clusters.cluster.kubesphere.io
spec: spec:
additionalPrinterColumns:
- JSONPath: .spec.joinFederation
name: Federated
type: boolean
- JSONPath: .spec.provider
name: Provider
type: string
- JSONPath: .spec.enable
name: Active
type: boolean
- JSONPath: .status.kubernetesVersion
name: Version
type: string
group: cluster.kubesphere.io group: cluster.kubesphere.io
names: names:
kind: Cluster kind: Cluster
@@ -28,143 +15,129 @@ spec:
plural: clusters plural: clusters
singular: cluster singular: cluster
scope: Cluster scope: Cluster
subresources: {} versions:
validation: - additionalPrinterColumns:
openAPIV3Schema: - jsonPath: .spec.joinFederation
description: Cluster is the schema for the clusters API name: Federated
properties: type: boolean
apiVersion: - jsonPath: .spec.provider
description: 'APIVersion defines the versioned schema of this representation name: Provider
of an object. Servers should convert recognized schemas to the latest type: string
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - jsonPath: .spec.enable
type: string name: Active
kind: type: boolean
description: 'Kind is a string value representing the REST resource this - jsonPath: .status.kubernetesVersion
object represents. Servers may infer this from the endpoint the client name: Version
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 name: v1alpha1
metadata: schema:
type: object openAPIV3Schema:
spec: description: Cluster is the schema for the clusters API
properties: properties:
connection: apiVersion:
description: Connection holds info to connect to the member cluster description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
properties: type: string
kubeconfig: kind:
description: KubeConfig content used to connect to cluster api server description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
Should provide this field explicitly if connection type is direct. type: string
Will be populated by ks-proxy if connection type is proxy. metadata:
format: byte type: object
type: string spec:
kubernetesAPIEndpoint: properties:
description: 'Kubernetes API Server endpoint. Example: https://10.10.0.1:6443 connection:
Should provide this field explicitly if connection type is direct. description: Connection holds info to connect to the member cluster
Will be populated by ks-apiserver if connection type is proxy.'
type: string
kubernetesAPIServerPort:
description: KubeAPIServerPort is the port which listens for forwarding
kube-apiserver traffic Only applicable when connection type is
proxy.
type: integer
kubesphereAPIEndpoint:
description: 'KubeSphere API Server endpoint. Example: http://10.10.0.11:8080
Should provide this field explicitly if connection type is direct.
Will be populated by ks-apiserver if connection type is proxy.'
type: string
kubesphereAPIServerPort:
description: KubeSphereAPIServerPort is the port which listens for
forwarding kubesphere apigateway traffic Only applicable when
connection type is proxy.
type: integer
token:
description: Token used by agents of member cluster to connect to
host cluster proxy. This field is populated by apiserver only
if connection type is proxy.
type: string
type:
description: type defines how host cluster will connect to host
cluster ConnectionTypeDirect means direct connection, this requires kubeconfig
and kubesphere apiserver endpoint provided ConnectionTypeProxy
means using kubesphere proxy, no kubeconfig or kubesphere apiserver
endpoint required
type: string
type: object
enable:
description: Desired state of the cluster
type: boolean
joinFederation:
description: Join cluster as a kubefed cluster
type: boolean
provider:
description: Provider of the cluster, this field is just for description
type: string
type: object
status:
properties:
conditions:
description: Represents the latest available observations of a cluster's
current state.
items:
properties: properties:
lastTransitionTime: kubeconfig:
description: Last time the condition transitioned from one status description: KubeConfig content used to connect to cluster api server Should provide this field explicitly if connection type is direct. Will be populated by ks-proxy if connection type is proxy.
to another. format: byte
format: date-time
type: string type: string
lastUpdateTime: kubernetesAPIEndpoint:
description: The last time this condition was updated. description: 'Kubernetes API Server endpoint. Example: https://10.10.0.1:6443 Should provide this field explicitly if connection type is direct. Will be populated by ks-apiserver if connection type is proxy.'
format: date-time
type: string type: string
message: kubernetesAPIServerPort:
description: A human readable message indicating details about description: KubeAPIServerPort is the port which listens for forwarding kube-apiserver traffic Only applicable when connection type is proxy.
the transition. type: integer
kubesphereAPIEndpoint:
description: 'KubeSphere API Server endpoint. Example: http://10.10.0.11:8080 Should provide this field explicitly if connection type is direct. Will be populated by ks-apiserver if connection type is proxy.'
type: string type: string
reason: kubesphereAPIServerPort:
description: The reason for the condition's last transition. description: KubeSphereAPIServerPort is the port which listens for forwarding kubesphere apigateway traffic Only applicable when connection type is proxy.
type: string type: integer
status: token:
description: Status of the condition, one of True, False, Unknown. description: Token used by agents of member cluster to connect to host cluster proxy. This field is populated by apiserver only if connection type is proxy.
type: string type: string
type: type:
description: Type of the condition description: type defines how host cluster will connect to host cluster ConnectionTypeDirect means direct connection, this requires kubeconfig and kubesphere apiserver endpoint provided ConnectionTypeProxy means using kubesphere proxy, no kubeconfig or kubesphere apiserver endpoint required
type: string type: string
required:
- status
- type
type: object type: object
type: array enable:
configz: description: Desired state of the cluster
additionalProperties:
type: boolean type: boolean
description: Configz is status of components enabled in the member cluster. joinFederation:
This is synchronized with member cluster every amount of time, like description: Join cluster as a kubefed cluster
5 minutes. type: boolean
type: object provider:
kubernetesVersion: description: Provider of the cluster, this field is just for description
description: GitVersion of the kubernetes cluster, this field is populated
by cluster controller
type: string
nodeCount:
description: Count of the kubernetes cluster nodes This field may not
reflect the instant status of the cluster.
type: integer
region:
description: Region is the name of the region in which all of the nodes
in the cluster exist. e.g. 'us-east1'.
type: string
zones:
description: Zones are the names of availability zones in which the
nodes of the cluster exist, e.g. 'us-east1-a'.
items:
type: string type: string
type: array type: object
type: object status:
type: object properties:
version: v1alpha1 conditions:
versions: description: Represents the latest available observations of a cluster's current state.
- name: v1alpha1 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
configz:
additionalProperties:
type: boolean
description: Configz is status of components enabled in the member cluster. This is synchronized with member cluster every amount of time, like 5 minutes.
type: object
kubernetesVersion:
description: GitVersion of the kubernetes cluster, this field is populated by cluster controller
type: string
kubesphereVersion:
description: GitVersion of the /kapis/version api response, this field is populated by cluster controller
type: string
nodeCount:
description: Count of the kubernetes cluster nodes This field may not reflect the instant status of the cluster.
type: integer
region:
description: Region is the name of the region in which all of the nodes in the cluster exist. e.g. 'us-east1'.
type: string
zones:
description: Zones are the names of availability zones in which the nodes of the cluster exist, e.g. 'us-east1-a'.
items:
type: string
type: array
type: object
type: object
served: true served: true
storage: true storage: true
subresources: {}
status: status:
acceptedNames: acceptedNames:
kind: "" kind: ""

View File

@@ -136,6 +136,9 @@ type ClusterStatus struct {
// GitVersion of the kubernetes cluster, this field is populated by cluster controller // GitVersion of the kubernetes cluster, this field is populated by cluster controller
KubernetesVersion string `json:"kubernetesVersion,omitempty"` KubernetesVersion string `json:"kubernetesVersion,omitempty"`
// GitVersion of the /kapis/version api response, this field is populated by cluster controller
KubeSphereVersion string `json:"kubeSphereVersion,omitempty"`
// Count of the kubernetes cluster nodes // Count of the kubernetes cluster nodes
// This field may not reflect the instant status of the cluster. // This field may not reflect the instant status of the cluster.
NodeCount int `json:"nodeCount,omitempty"` NodeCount int `json:"nodeCount,omitempty"`

View File

@@ -51,6 +51,7 @@ import (
clusterclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/cluster/v1alpha1" clusterclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/cluster/v1alpha1"
clusterinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/cluster/v1alpha1" clusterinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/cluster/v1alpha1"
clusterlister "kubesphere.io/kubesphere/pkg/client/listers/cluster/v1alpha1" clusterlister "kubesphere.io/kubesphere/pkg/client/listers/cluster/v1alpha1"
"kubesphere.io/kubesphere/pkg/version"
) )
// Cluster controller only runs under multicluster mode. Cluster controller is following below steps, // Cluster controller only runs under multicluster mode. Cluster controller is following below steps,
@@ -582,6 +583,13 @@ func (c *clusterController) syncCluster(key string) error {
cluster.Status.Configz = configz cluster.Status.Configz = configz
} }
v, err := c.tryFetchKubeSphereVersion(clusterDt.config.Host, clusterDt.transport)
if err != nil {
klog.Errorf("failed to get KubeSphere version, err: %#v", err)
} else {
cluster.Status.KubeSphereVersion = v
}
// label cluster host cluster if configz["multicluster"]==true // label cluster host cluster if configz["multicluster"]==true
if mc, ok := configz[configzMultiCluster]; ok && mc && c.checkIfClusterIsHostCluster(nodes) { if mc, ok := configz[configzMultiCluster]; ok && mc && c.checkIfClusterIsHostCluster(nodes) {
if cluster.Labels == nil { if cluster.Labels == nil {
@@ -660,6 +668,44 @@ func (c *clusterController) tryToFetchKubeSphereComponents(host string, transpor
return configz, nil return configz, nil
} }
//
func (c *clusterController) tryFetchKubeSphereVersion(host string, transport http.RoundTripper) (string, error) {
client := http.Client{
Transport: transport,
Timeout: 5 * time.Second,
}
response, err := client.Get(fmt.Sprintf(proxyFormat, host, "kapis/version"))
if err != nil {
return "", err
}
if response.StatusCode != http.StatusOK {
klog.V(4).Infof("Response status code isn't 200.")
return "", fmt.Errorf("response code %d", response.StatusCode)
}
info := version.Info{}
decoder := json.NewDecoder(response.Body)
err = decoder.Decode(&info)
if err != nil {
return "", err
}
// currently, we kubesphere v2.1 can not be joined as a member cluster and it will never be reconciled,
// so we don't consider that situation
// for kubesphere v3.0.0, the gitVersion is always v0.0.0, so we return v3.0.0
if info.GitVersion == "v0.0.0" {
return "v3.0.0", nil
}
if len(info.GitVersion) == 0 {
return "unknown", nil
}
return info.GitVersion, nil
}
func (c *clusterController) addCluster(obj interface{}) { func (c *clusterController) addCluster(obj interface{}) {
cluster := obj.(*clusterv1alpha1.Cluster) cluster := obj.(*clusterv1alpha1.Cluster)