From 7121e3609ce3a744888afaa864973bc4b648fea9 Mon Sep 17 00:00:00 2001 From: zryfish Date: Sun, 29 Mar 2020 16:49:11 +0800 Subject: [PATCH] move agent crd to kubesphere (#1974) --- hack/generate_client.sh | 2 +- pkg/apis/addtoscheme_tower_v1alpha1.go | 9 + pkg/apis/tower/group.go | 1 + pkg/apis/tower/v1alpha1/agent_types.go | 116 +++++++++++ pkg/apis/tower/v1alpha1/doc.go | 8 + pkg/apis/tower/v1alpha1/register.go | 41 ++++ .../tower/v1alpha1/zz_generated.deepcopy.go | 137 +++++++++++++ pkg/apiserver/apiserver.go | 3 +- pkg/apiserver/dispatch/dispatch.go | 64 ++++-- pkg/apiserver/filters/dispatch.go | 7 +- pkg/apiserver/request/requestinfo.go | 2 - pkg/apiserver/request/requestinfo_test.go | 62 +++++- pkg/client/clientset/versioned/clientset.go | 14 ++ .../versioned/fake/clientset_generated.go | 7 + .../clientset/versioned/fake/register.go | 2 + .../clientset/versioned/scheme/register.go | 2 + .../versioned/typed/tower/v1alpha1/agent.go | 191 ++++++++++++++++++ .../versioned/typed/tower/v1alpha1/doc.go | 20 ++ .../typed/tower/v1alpha1/fake/doc.go | 20 ++ .../typed/tower/v1alpha1/fake/fake_agent.go | 140 +++++++++++++ .../tower/v1alpha1/fake/fake_tower_client.go | 40 ++++ .../tower/v1alpha1/generated_expansion.go | 21 ++ .../typed/tower/v1alpha1/tower_client.go | 89 ++++++++ .../informers/externalversions/factory.go | 6 + .../informers/externalversions/generic.go | 5 + .../externalversions/tower/interface.go | 46 +++++ .../externalversions/tower/v1alpha1/agent.go | 89 ++++++++ .../tower/v1alpha1/interface.go | 45 +++++ pkg/client/listers/tower/v1alpha1/agent.go | 94 +++++++++ .../tower/v1alpha1/expansion_generated.go | 27 +++ 30 files changed, 1278 insertions(+), 32 deletions(-) create mode 100644 pkg/apis/addtoscheme_tower_v1alpha1.go create mode 100644 pkg/apis/tower/group.go create mode 100644 pkg/apis/tower/v1alpha1/agent_types.go create mode 100644 pkg/apis/tower/v1alpha1/doc.go create mode 100644 pkg/apis/tower/v1alpha1/register.go create mode 100644 pkg/apis/tower/v1alpha1/zz_generated.deepcopy.go create mode 100644 pkg/client/clientset/versioned/typed/tower/v1alpha1/agent.go create mode 100644 pkg/client/clientset/versioned/typed/tower/v1alpha1/doc.go create mode 100644 pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/doc.go create mode 100644 pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/fake_agent.go create mode 100644 pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/fake_tower_client.go create mode 100644 pkg/client/clientset/versioned/typed/tower/v1alpha1/generated_expansion.go create mode 100644 pkg/client/clientset/versioned/typed/tower/v1alpha1/tower_client.go create mode 100644 pkg/client/informers/externalversions/tower/interface.go create mode 100644 pkg/client/informers/externalversions/tower/v1alpha1/agent.go create mode 100644 pkg/client/informers/externalversions/tower/v1alpha1/interface.go create mode 100644 pkg/client/listers/tower/v1alpha1/agent.go create mode 100644 pkg/client/listers/tower/v1alpha1/expansion_generated.go diff --git a/hack/generate_client.sh b/hack/generate_client.sh index 9d094b8b0..a7740811f 100755 --- a/hack/generate_client.sh +++ b/hack/generate_client.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -GV="network:v1alpha1 servicemesh:v1alpha2 tenant:v1alpha1 devops:v1alpha1" +GV="network:v1alpha1 servicemesh:v1alpha2 tenant:v1alpha1 devops:v1alpha1 tower:v1alpha1" rm -rf ./pkg/client ./hack/generate_group.sh "client,lister,informer" kubesphere.io/kubesphere/pkg/client kubesphere.io/kubesphere/pkg/apis "$GV" --output-base=./ -h "$PWD/hack/boilerplate.go.txt" diff --git a/pkg/apis/addtoscheme_tower_v1alpha1.go b/pkg/apis/addtoscheme_tower_v1alpha1.go new file mode 100644 index 000000000..e952df5a0 --- /dev/null +++ b/pkg/apis/addtoscheme_tower_v1alpha1.go @@ -0,0 +1,9 @@ +package apis + +import ( + "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" +) + +func init() { + AddToSchemes = append(AddToSchemes, v1alpha1.SchemeBuilder.AddToScheme) +} diff --git a/pkg/apis/tower/group.go b/pkg/apis/tower/group.go new file mode 100644 index 000000000..260171028 --- /dev/null +++ b/pkg/apis/tower/group.go @@ -0,0 +1 @@ +package tower diff --git a/pkg/apis/tower/v1alpha1/agent_types.go b/pkg/apis/tower/v1alpha1/agent_types.go new file mode 100644 index 000000000..f4e928ff4 --- /dev/null +++ b/pkg/apis/tower/v1alpha1/agent_types.go @@ -0,0 +1,116 @@ +/* + +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 v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// AgentSpec defines the desired state of Agent +type AgentSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Token used by agents to connect to proxy. + // +optional + Token string `json:"token,omitempty"` + + // Proxy address + // +optional + Proxy string `json:"proxy,omitempty"` + + // KubeAPIServerPort is the port which listens for forwarding kube-apiserver traffic + // +optional + KubernetesAPIServerPort uint16 `json:"kubernetesAPIServerPort,omitempty"` + + // KubeSphereAPIServerPort is the port which listens for forwarding kubesphere apigateway traffic + // +optional + KubeSphereAPIServerPort uint16 `json:"kubesphereAPIServerPort,omitempty"` + + // Indicates that the agent is paused. + // +optional + Paused bool +} + +type AgentConditionType string + +const ( + // Agent is initialized, and waiting for establishing to a proxy server + AgentInitialized AgentConditionType = "Initialized" + + // Agent has successfully connected to proxy server + AgentConnected AgentConditionType = "Connected" +) + +type AgentCondition struct { + // Type of AgentCondition + Type AgentConditionType `json:"type,omitempty"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // A human readable message indicating details about the transition. + Message string `json:"message,omitempty"` +} + +// AgentStatus defines the observed state of Agent +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. + Conditions []AgentCondition `json:"conditions,omitempty"` + + // Represents the connection quality, in ms + Ping uint64 `json:"ping,omitempty"` + + // Issued new kubeconfig by proxy server + KubeConfig []byte +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:openapi-gen=true + +// Agent is the Schema for the agents API +type Agent struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AgentSpec `json:"spec,omitempty"` + Status AgentStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AgentList contains a list of Agent +type AgentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Agent `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Agent{}, &AgentList{}) +} diff --git a/pkg/apis/tower/v1alpha1/doc.go b/pkg/apis/tower/v1alpha1/doc.go new file mode 100644 index 000000000..469552839 --- /dev/null +++ b/pkg/apis/tower/v1alpha1/doc.go @@ -0,0 +1,8 @@ +// Package v1alpha2 contains API Schema definitions for the tower v1alpha1 API group +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=kubesphere.io/tower/pkg/apis/tower +// +k8s:defaulter-gen=TypeMeta +// +groupName=tower.kubesphere.io + +package v1alpha1 diff --git a/pkg/apis/tower/v1alpha1/register.go b/pkg/apis/tower/v1alpha1/register.go new file mode 100644 index 000000000..e22fc7864 --- /dev/null +++ b/pkg/apis/tower/v1alpha1/register.go @@ -0,0 +1,41 @@ +/* + +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 v1alpha1 contains API Schema definitions for the tower v1alpha1 API group +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +k8s:defaulter-gen=TypeMeta +// +groupName=tower.kubesphere.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: "tower.kubesphere.io", Version: "v1alpha1"} + + // 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 +) + +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/pkg/apis/tower/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/tower/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..2cfab57f9 --- /dev/null +++ b/pkg/apis/tower/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,137 @@ +// +build !ignore_autogenerated + +/* + +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 v1alpha1 + +import ( + 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 *Agent) DeepCopyInto(out *Agent) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Agent. +func (in *Agent) DeepCopy() *Agent { + if in == nil { + return nil + } + out := new(Agent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Agent) 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 *AgentCondition) DeepCopyInto(out *AgentCondition) { + *out = *in + in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentCondition. +func (in *AgentCondition) DeepCopy() *AgentCondition { + if in == nil { + return nil + } + out := new(AgentCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AgentList) DeepCopyInto(out *AgentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Agent, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentList. +func (in *AgentList) DeepCopy() *AgentList { + if in == nil { + return nil + } + out := new(AgentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AgentList) 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 *AgentSpec) DeepCopyInto(out *AgentSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentSpec. +func (in *AgentSpec) DeepCopy() *AgentSpec { + if in == nil { + return nil + } + out := new(AgentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AgentStatus) DeepCopyInto(out *AgentStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]AgentCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentStatus. +func (in *AgentStatus) DeepCopy() *AgentStatus { + if in == nil { + return nil + } + out := new(AgentStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 7f83560d5..008bc4497 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -185,7 +185,7 @@ func (s *APIServer) buildHandlerChain() { handler := s.Server.Handler handler = filters.WithKubeAPIServer(handler, s.KubernetesClient.Config(), &errorResponder{}) - handler = filters.WithMultipleClusterDispatcher(handler, dispatch.DefaultClusterDispatch) + handler = filters.WithMultipleClusterDispatcher(handler, dispatch.NewClusterDispatch(s.InformerFactory.KubeSphereSharedInformerFactory().Tower().V1alpha1().Agents().Lister())) excludedPaths := []string{"/oauth/authorize", "/oauth/token"} pathAuthorizer, _ := path.NewAuthorizer(excludedPaths) @@ -275,6 +275,7 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error { ksGVRs := []schema.GroupVersionResource{ {Group: "tenant.kubesphere.io", Version: "v1alpha1", Resource: "workspaces"}, + {Group: "tower.kubesphere.io", Version: "v1alpha1", Resource: "agents"}, } devopsGVRs := []schema.GroupVersionResource{ diff --git a/pkg/apiserver/dispatch/dispatch.go b/pkg/apiserver/dispatch/dispatch.go index 766fe88f2..da9628b38 100644 --- a/pkg/apiserver/dispatch/dispatch.go +++ b/pkg/apiserver/dispatch/dispatch.go @@ -1,36 +1,76 @@ package dispatch import ( - "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" - "net/http" - + "fmt" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/util/proxy" + "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" + towerv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" + "kubesphere.io/kubesphere/pkg/apiserver/request" + "kubesphere.io/kubesphere/pkg/client/listers/tower/v1alpha1" + "net/http" + "strings" ) +const defaultMultipleClusterAgentNamespace = "kubesphere-system" + // Dispatcher defines how to forward request to designated cluster based on cluster name type Dispatcher interface { - Dispatch(w http.ResponseWriter, req *http.Request) + Dispatch(w http.ResponseWriter, req *http.Request, handler http.Handler) } -var DefaultClusterDispatch = newClusterDispatch() - type clusterDispatch struct { - transport *http.Transport + agentLister v1alpha1.AgentLister } -func newClusterDispatch() Dispatcher { - return &clusterDispatch{} +func NewClusterDispatch(agentLister v1alpha1.AgentLister) Dispatcher { + return &clusterDispatch{ + agentLister: agentLister, + } } -func (c *clusterDispatch) Dispatch(w http.ResponseWriter, req *http.Request) { +func (c *clusterDispatch) Dispatch(w http.ResponseWriter, req *http.Request, handler http.Handler) { + + info, _ := request.RequestInfoFrom(req.Context()) + if info.Cluster == "" { // fallback to host cluster if cluster name if empty + handler.ServeHTTP(w, req) + return + } + + agent, err := c.agentLister.Agents(defaultMultipleClusterAgentNamespace).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 + } + + if !isAgentReady(agent) { + http.Error(w, fmt.Sprintf("cluster agent is not ready"), http.StatusInternalServerError) + return + } u := *req.URL - // u.Host = someHost + u.Host = agent.Spec.Proxy + u.Path = strings.Replace(u.Path, fmt.Sprintf("/clusters/%s", info.Cluster), "", 1) - httpProxy := proxy.NewUpgradeAwareHandler(&u, c.transport, false, false, c) + httpProxy := proxy.NewUpgradeAwareHandler(&u, http.DefaultTransport, true, false, c) httpProxy.ServeHTTP(w, req) } func (c *clusterDispatch) Error(w http.ResponseWriter, req *http.Request, err error) { responsewriters.InternalError(w, req, err) } + +func isAgentReady(agent *towerv1alpha1.Agent) bool { + for _, condition := range agent.Status.Conditions { + if condition.Type == towerv1alpha1.AgentConnected && condition.Status == corev1.ConditionTrue { + return true + } + } + + return false +} diff --git a/pkg/apiserver/filters/dispatch.go b/pkg/apiserver/filters/dispatch.go index 1157f4b4c..842336b4f 100644 --- a/pkg/apiserver/filters/dispatch.go +++ b/pkg/apiserver/filters/dispatch.go @@ -7,7 +7,6 @@ import ( "kubesphere.io/kubesphere/pkg/apiserver/dispatch" "kubesphere.io/kubesphere/pkg/apiserver/request" "net/http" - "strings" ) // Multiple cluster dispatcher forward request to desired cluster based on request cluster name @@ -24,12 +23,10 @@ func WithMultipleClusterDispatcher(handler http.Handler, dispatch dispatch.Dispa return } - if info.Cluster == "host-cluster" || info.Cluster == "" { + if info.Cluster == "" { handler.ServeHTTP(w, req) } else { - // remove cluster path - req.URL.Path = strings.Replace(req.URL.Path, fmt.Sprintf("/clusters/%s", info.Cluster), "", 1) - dispatch.Dispatch(w, req) + dispatch.Dispatch(w, req, handler) } }) } diff --git a/pkg/apiserver/request/requestinfo.go b/pkg/apiserver/request/requestinfo.go index 8f0c53533..7a39a9786 100644 --- a/pkg/apiserver/request/requestinfo.go +++ b/pkg/apiserver/request/requestinfo.go @@ -126,8 +126,6 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er if currentParts[0] == "clusters" { requestInfo.Cluster = currentParts[1] currentParts = currentParts[2:] - } else if len(currentParts) > 0 { - requestInfo.Cluster = "host-cluster" } if currentParts[0] == "workspaces" { diff --git a/pkg/apiserver/request/requestinfo_test.go b/pkg/apiserver/request/requestinfo_test.go index 3742e180c..4348184cc 100644 --- a/pkg/apiserver/request/requestinfo_test.go +++ b/pkg/apiserver/request/requestinfo_test.go @@ -44,7 +44,8 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedIsResourceRequest bool expectedCluster string expectedWorkspace string - exceptedNamespace string + expectedNamespace string + expectedKubernetesRequest bool }{ { name: "login", @@ -55,6 +56,7 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedResource: "", expectedIsResourceRequest: false, expectedCluster: "", + expectedKubernetesRequest: false, }, { name: "list cluster roles", @@ -65,6 +67,7 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedResource: "clusterroles", expectedIsResourceRequest: true, expectedCluster: "cluster1", + expectedKubernetesRequest: true, }, { name: "list cluster nodes", @@ -75,6 +78,7 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedResource: "nodes", expectedIsResourceRequest: true, expectedCluster: "cluster1", + expectedKubernetesRequest: true, }, { name: "list cluster nodes", @@ -85,6 +89,7 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedResource: "nodes", expectedIsResourceRequest: true, expectedCluster: "cluster1", + expectedKubernetesRequest: true, }, { name: "list cluster nodes", @@ -94,7 +99,8 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedVerb: "list", expectedResource: "nodes", expectedIsResourceRequest: true, - expectedCluster: "host-cluster", + expectedCluster: "", + expectedKubernetesRequest: true, }, { name: "list roles", @@ -104,8 +110,9 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedVerb: "list", expectedResource: "roles", expectedIsResourceRequest: true, - exceptedNamespace: "namespace1", + expectedNamespace: "namespace1", expectedCluster: "cluster1", + expectedKubernetesRequest: true, }, { name: "list roles", @@ -115,7 +122,9 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedVerb: "list", expectedResource: "roles", expectedIsResourceRequest: true, - expectedCluster: "host-cluster", + expectedCluster: "", + expectedNamespace: "namespace1", + expectedKubernetesRequest: true, }, { name: "list namespaces", @@ -126,7 +135,8 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedResource: "namespaces", expectedIsResourceRequest: true, expectedWorkspace: "workspace1", - expectedCluster: "host-cluster", + expectedCluster: "", + expectedKubernetesRequest: false, }, { name: "list namespaces", @@ -138,6 +148,32 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { expectedIsResourceRequest: true, expectedWorkspace: "workspace1", expectedCluster: "cluster1", + expectedKubernetesRequest: false, + }, + { + name: "random query", + url: "/foo/bar", + method: http.MethodGet, + expectedErr: nil, + expectedVerb: "GET", + expectedResource: "", + expectedIsResourceRequest: false, + expectedWorkspace: "", + expectedCluster: "", + expectedKubernetesRequest: false, + }, + { + name: "kubesphere api without clusters", + url: "/kapis/foo/bar/", + method: http.MethodPost, + expectedErr: nil, + expectedVerb: "POST", + expectedResource: "", + expectedNamespace: "", + expectedWorkspace: "", + expectedCluster: "", + expectedIsResourceRequest: false, + expectedKubernetesRequest: false, }, } @@ -155,23 +191,27 @@ func TestRequestInfoFactory_NewRequestInfo(t *testing.T) { t.Errorf("%s: expected error %v, actual %v", test.name, test.expectedErr, err) } } else { - if test.expectedVerb != "" && test.expectedVerb != requestInfo.Verb { + if test.expectedVerb != requestInfo.Verb { t.Errorf("%s: expected verb %v, actual %+v", test.name, test.expectedVerb, requestInfo.Verb) } - if test.expectedResource != "" && test.expectedResource != requestInfo.Resource { + if test.expectedResource != requestInfo.Resource { t.Errorf("%s: expected resource %v, actual %+v", test.name, test.expectedResource, requestInfo.Resource) } if test.expectedIsResourceRequest != requestInfo.IsResourceRequest { t.Errorf("%s: expected is resource request %v, actual %+v", test.name, test.expectedIsResourceRequest, requestInfo.IsResourceRequest) } - if test.expectedCluster != "" && test.expectedCluster != requestInfo.Cluster { + if test.expectedCluster != requestInfo.Cluster { t.Errorf("%s: expected cluster %v, actual %+v", test.name, test.expectedCluster, requestInfo.Cluster) } - if test.expectedWorkspace != "" && test.expectedWorkspace != requestInfo.Workspace { + if test.expectedWorkspace != requestInfo.Workspace { t.Errorf("%s: expected workspace %v, actual %+v", test.name, test.expectedWorkspace, requestInfo.Workspace) } - if test.exceptedNamespace != "" && test.exceptedNamespace != requestInfo.Namespace { - t.Errorf("%s: expected namespace %v, actual %+v", test.name, test.exceptedNamespace, requestInfo.Namespace) + if test.expectedNamespace != requestInfo.Namespace { + t.Errorf("%s: expected namespace %v, actual %+v", test.name, test.expectedNamespace, requestInfo.Namespace) + } + + if test.expectedKubernetesRequest != requestInfo.IsKubernetesRequest { + t.Errorf("%s: expected kubernetes request %v, actual %+v", test.name, test.expectedKubernetesRequest, requestInfo.IsKubernetesRequest) } } } diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index cdf28675e..1b569b7d7 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -28,6 +28,7 @@ import ( networkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1" + towerv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tower/v1alpha1" ) type Interface interface { @@ -36,6 +37,7 @@ type Interface interface { NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface ServicemeshV1alpha2() servicemeshv1alpha2.ServicemeshV1alpha2Interface TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface + TowerV1alpha1() towerv1alpha1.TowerV1alpha1Interface } // Clientset contains the clients for groups. Each group has exactly one @@ -46,6 +48,7 @@ type Clientset struct { networkV1alpha1 *networkv1alpha1.NetworkV1alpha1Client servicemeshV1alpha2 *servicemeshv1alpha2.ServicemeshV1alpha2Client tenantV1alpha1 *tenantv1alpha1.TenantV1alpha1Client + towerV1alpha1 *towerv1alpha1.TowerV1alpha1Client } // DevopsV1alpha1 retrieves the DevopsV1alpha1Client @@ -68,6 +71,11 @@ func (c *Clientset) TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface { return c.tenantV1alpha1 } +// TowerV1alpha1 retrieves the TowerV1alpha1Client +func (c *Clientset) TowerV1alpha1() towerv1alpha1.TowerV1alpha1Interface { + return c.towerV1alpha1 +} + // Discovery retrieves the DiscoveryClient func (c *Clientset) Discovery() discovery.DiscoveryInterface { if c == nil { @@ -105,6 +113,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { if err != nil { return nil, err } + cs.towerV1alpha1, err = towerv1alpha1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) if err != nil { @@ -121,6 +133,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { cs.networkV1alpha1 = networkv1alpha1.NewForConfigOrDie(c) cs.servicemeshV1alpha2 = servicemeshv1alpha2.NewForConfigOrDie(c) cs.tenantV1alpha1 = tenantv1alpha1.NewForConfigOrDie(c) + cs.towerV1alpha1 = towerv1alpha1.NewForConfigOrDie(c) cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) return &cs @@ -133,6 +146,7 @@ func New(c rest.Interface) *Clientset { cs.networkV1alpha1 = networkv1alpha1.New(c) cs.servicemeshV1alpha2 = servicemeshv1alpha2.New(c) cs.tenantV1alpha1 = tenantv1alpha1.New(c) + cs.towerV1alpha1 = towerv1alpha1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 2eb0a0a07..a92d2679b 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -33,6 +33,8 @@ import ( fakeservicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2/fake" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1" faketenantv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1/fake" + towerv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tower/v1alpha1" + faketowerv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake" ) // NewSimpleClientset returns a clientset that will respond with the provided objects. @@ -101,3 +103,8 @@ func (c *Clientset) ServicemeshV1alpha2() servicemeshv1alpha2.ServicemeshV1alpha func (c *Clientset) TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface { return &faketenantv1alpha1.FakeTenantV1alpha1{Fake: &c.Fake} } + +// TowerV1alpha1 retrieves the TowerV1alpha1Client +func (c *Clientset) TowerV1alpha1() towerv1alpha1.TowerV1alpha1Interface { + return &faketowerv1alpha1.FakeTowerV1alpha1{Fake: &c.Fake} +} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index 36f2e736e..004d160de 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -28,6 +28,7 @@ import ( networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" + towerv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" ) var scheme = runtime.NewScheme() @@ -38,6 +39,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ networkv1alpha1.AddToScheme, servicemeshv1alpha2.AddToScheme, tenantv1alpha1.AddToScheme, + towerv1alpha1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 30434c545..6c6997a2a 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -28,6 +28,7 @@ import ( networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" + towerv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" ) var Scheme = runtime.NewScheme() @@ -38,6 +39,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ networkv1alpha1.AddToScheme, servicemeshv1alpha2.AddToScheme, tenantv1alpha1.AddToScheme, + towerv1alpha1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/typed/tower/v1alpha1/agent.go b/pkg/client/clientset/versioned/typed/tower/v1alpha1/agent.go new file mode 100644 index 000000000..c445c9142 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/tower/v1alpha1/agent.go @@ -0,0 +1,191 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "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" + v1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" + scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme" +) + +// AgentsGetter has a method to return a AgentInterface. +// A group's client should implement this interface. +type AgentsGetter interface { + Agents(namespace string) AgentInterface +} + +// AgentInterface has methods to work with Agent resources. +type AgentInterface interface { + Create(*v1alpha1.Agent) (*v1alpha1.Agent, error) + Update(*v1alpha1.Agent) (*v1alpha1.Agent, error) + UpdateStatus(*v1alpha1.Agent) (*v1alpha1.Agent, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.Agent, error) + List(opts v1.ListOptions) (*v1alpha1.AgentList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Agent, err error) + AgentExpansion +} + +// agents implements AgentInterface +type agents struct { + client rest.Interface + ns string +} + +// newAgents returns a Agents +func newAgents(c *TowerV1alpha1Client, namespace string) *agents { + return &agents{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the agent, and returns the corresponding agent object, and an error if there is any. +func (c *agents) Get(name string, options v1.GetOptions) (result *v1alpha1.Agent, err error) { + result = &v1alpha1.Agent{} + err = c.client.Get(). + Namespace(c.ns). + Resource("agents"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Agents that match those selectors. +func (c *agents) List(opts v1.ListOptions) (result *v1alpha1.AgentList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.AgentList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("agents"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested agents. +func (c *agents) Watch(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("agents"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a agent and creates it. Returns the server's representation of the agent, and an error, if there is any. +func (c *agents) Create(agent *v1alpha1.Agent) (result *v1alpha1.Agent, err error) { + result = &v1alpha1.Agent{} + err = c.client.Post(). + Namespace(c.ns). + Resource("agents"). + Body(agent). + Do(). + Into(result) + return +} + +// Update takes the representation of a agent and updates it. Returns the server's representation of the agent, and an error, if there is any. +func (c *agents) Update(agent *v1alpha1.Agent) (result *v1alpha1.Agent, err error) { + result = &v1alpha1.Agent{} + err = c.client.Put(). + Namespace(c.ns). + Resource("agents"). + Name(agent.Name). + Body(agent). + Do(). + 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 *agents) UpdateStatus(agent *v1alpha1.Agent) (result *v1alpha1.Agent, err error) { + result = &v1alpha1.Agent{} + err = c.client.Put(). + Namespace(c.ns). + Resource("agents"). + Name(agent.Name). + SubResource("status"). + Body(agent). + Do(). + Into(result) + return +} + +// Delete takes name of the agent and deletes it. Returns an error if one occurs. +func (c *agents) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("agents"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *agents) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("agents"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched agent. +func (c *agents) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Agent, err error) { + result = &v1alpha1.Agent{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("agents"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/tower/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/tower/v1alpha1/doc.go new file mode 100644 index 000000000..f2efa4141 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/tower/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/doc.go new file mode 100644 index 000000000..329c98fb5 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/fake_agent.go b/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/fake_agent.go new file mode 100644 index 000000000..f7755fc28 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/fake_agent.go @@ -0,0 +1,140 @@ +/* +Copyright 2019 The KubeSphere authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + 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" + v1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" +) + +// FakeAgents implements AgentInterface +type FakeAgents struct { + Fake *FakeTowerV1alpha1 + ns string +} + +var agentsResource = schema.GroupVersionResource{Group: "tower.kubesphere.io", Version: "v1alpha1", Resource: "agents"} + +var agentsKind = schema.GroupVersionKind{Group: "tower.kubesphere.io", Version: "v1alpha1", Kind: "Agent"} + +// Get takes name of the agent, and returns the corresponding agent object, and an error if there is any. +func (c *FakeAgents) Get(name string, options v1.GetOptions) (result *v1alpha1.Agent, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(agentsResource, c.ns, name), &v1alpha1.Agent{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Agent), err +} + +// List takes label and field selectors, and returns the list of Agents that match those selectors. +func (c *FakeAgents) List(opts v1.ListOptions) (result *v1alpha1.AgentList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(agentsResource, agentsKind, c.ns, opts), &v1alpha1.AgentList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.AgentList{ListMeta: obj.(*v1alpha1.AgentList).ListMeta} + for _, item := range obj.(*v1alpha1.AgentList).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 agents. +func (c *FakeAgents) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(agentsResource, c.ns, opts)) + +} + +// Create takes the representation of a agent and creates it. Returns the server's representation of the agent, and an error, if there is any. +func (c *FakeAgents) Create(agent *v1alpha1.Agent) (result *v1alpha1.Agent, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(agentsResource, c.ns, agent), &v1alpha1.Agent{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Agent), err +} + +// Update takes the representation of a agent and updates it. Returns the server's representation of the agent, and an error, if there is any. +func (c *FakeAgents) Update(agent *v1alpha1.Agent) (result *v1alpha1.Agent, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(agentsResource, c.ns, agent), &v1alpha1.Agent{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Agent), 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 *FakeAgents) UpdateStatus(agent *v1alpha1.Agent) (*v1alpha1.Agent, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(agentsResource, "status", c.ns, agent), &v1alpha1.Agent{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Agent), err +} + +// Delete takes name of the agent and deletes it. Returns an error if one occurs. +func (c *FakeAgents) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(agentsResource, c.ns, name), &v1alpha1.Agent{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeAgents) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(agentsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.AgentList{}) + return err +} + +// Patch applies the patch and returns the patched agent. +func (c *FakeAgents) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Agent, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(agentsResource, c.ns, name, pt, data, subresources...), &v1alpha1.Agent{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Agent), err +} diff --git a/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/fake_tower_client.go b/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/fake_tower_client.go new file mode 100644 index 000000000..5df0777d4 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/tower/v1alpha1/fake/fake_tower_client.go @@ -0,0 +1,40 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" + v1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tower/v1alpha1" +) + +type FakeTowerV1alpha1 struct { + *testing.Fake +} + +func (c *FakeTowerV1alpha1) Agents(namespace string) v1alpha1.AgentInterface { + return &FakeAgents{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeTowerV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/tower/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/tower/v1alpha1/generated_expansion.go new file mode 100644 index 000000000..4e8868cb6 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/tower/v1alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type AgentExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/tower/v1alpha1/tower_client.go b/pkg/client/clientset/versioned/typed/tower/v1alpha1/tower_client.go new file mode 100644 index 000000000..2d87fe8c7 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/tower/v1alpha1/tower_client.go @@ -0,0 +1,89 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + rest "k8s.io/client-go/rest" + v1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" + "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme" +) + +type TowerV1alpha1Interface interface { + RESTClient() rest.Interface + AgentsGetter +} + +// TowerV1alpha1Client is used to interact with features provided by the tower.kubesphere.io group. +type TowerV1alpha1Client struct { + restClient rest.Interface +} + +func (c *TowerV1alpha1Client) Agents(namespace string) AgentInterface { + return newAgents(c, namespace) +} + +// NewForConfig creates a new TowerV1alpha1Client for the given config. +func NewForConfig(c *rest.Config) (*TowerV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &TowerV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new TowerV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *TowerV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new TowerV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *TowerV1alpha1Client { + return &TowerV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.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 *TowerV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index 8134dd6ef..069b0a336 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -33,6 +33,7 @@ import ( network "kubesphere.io/kubesphere/pkg/client/informers/externalversions/network" servicemesh "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh" tenant "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant" + tower "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tower" ) // SharedInformerOption defines the functional option type for SharedInformerFactory. @@ -179,6 +180,7 @@ type SharedInformerFactory interface { Network() network.Interface Servicemesh() servicemesh.Interface Tenant() tenant.Interface + Tower() tower.Interface } func (f *sharedInformerFactory) Devops() devops.Interface { @@ -196,3 +198,7 @@ func (f *sharedInformerFactory) Servicemesh() servicemesh.Interface { func (f *sharedInformerFactory) Tenant() tenant.Interface { return tenant.New(f, f.namespace, f.tweakListOptions) } + +func (f *sharedInformerFactory) Tower() tower.Interface { + return tower.New(f, f.namespace, f.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index b4763dd37..1a81f88c0 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -27,6 +27,7 @@ import ( networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" v1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" + towerv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" ) // GenericInformer is type of SharedIndexInformer which will locate and delegate to other @@ -81,6 +82,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case tenantv1alpha1.SchemeGroupVersion.WithResource("workspaces"): return &genericInformer{resource: resource.GroupResource(), informer: f.Tenant().V1alpha1().Workspaces().Informer()}, nil + // Group=tower.kubesphere.io, Version=v1alpha1 + case towerv1alpha1.SchemeGroupVersion.WithResource("agents"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Tower().V1alpha1().Agents().Informer()}, nil + } return nil, fmt.Errorf("no informer found for %v", resource) diff --git a/pkg/client/informers/externalversions/tower/interface.go b/pkg/client/informers/externalversions/tower/interface.go new file mode 100644 index 000000000..f02645536 --- /dev/null +++ b/pkg/client/informers/externalversions/tower/interface.go @@ -0,0 +1,46 @@ +/* +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package tower + +import ( + internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tower/v1alpha1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.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} +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/tower/v1alpha1/agent.go b/pkg/client/informers/externalversions/tower/v1alpha1/agent.go new file mode 100644 index 000000000..98f84ce8c --- /dev/null +++ b/pkg/client/informers/externalversions/tower/v1alpha1/agent.go @@ -0,0 +1,89 @@ +/* +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + 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" + towerv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" + versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned" + internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "kubesphere.io/kubesphere/pkg/client/listers/tower/v1alpha1" +) + +// AgentInformer provides access to a shared informer and lister for +// Agents. +type AgentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.AgentLister +} + +type agentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewAgentInformer constructs a new informer for Agent 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 NewAgentInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredAgentInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredAgentInformer constructs a new informer for Agent 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 NewFilteredAgentInformer(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.TowerV1alpha1().Agents(namespace).List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.TowerV1alpha1().Agents(namespace).Watch(options) + }, + }, + &towerv1alpha1.Agent{}, + resyncPeriod, + indexers, + ) +} + +func (f *agentInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredAgentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *agentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&towerv1alpha1.Agent{}, f.defaultInformer) +} + +func (f *agentInformer) Lister() v1alpha1.AgentLister { + return v1alpha1.NewAgentLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/tower/v1alpha1/interface.go b/pkg/client/informers/externalversions/tower/v1alpha1/interface.go new file mode 100644 index 000000000..0beae5610 --- /dev/null +++ b/pkg/client/informers/externalversions/tower/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // Agents returns a AgentInformer. + Agents() AgentInformer +} + +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} +} + +// Agents returns a AgentInformer. +func (v *version) Agents() AgentInformer { + return &agentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/listers/tower/v1alpha1/agent.go b/pkg/client/listers/tower/v1alpha1/agent.go new file mode 100644 index 000000000..9f78cb328 --- /dev/null +++ b/pkg/client/listers/tower/v1alpha1/agent.go @@ -0,0 +1,94 @@ +/* +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" + v1alpha1 "kubesphere.io/kubesphere/pkg/apis/tower/v1alpha1" +) + +// AgentLister helps list Agents. +type AgentLister interface { + // List lists all Agents in the indexer. + List(selector labels.Selector) (ret []*v1alpha1.Agent, err error) + // Agents returns an object that can list and get Agents. + Agents(namespace string) AgentNamespaceLister + AgentListerExpansion +} + +// agentLister implements the AgentLister interface. +type agentLister struct { + indexer cache.Indexer +} + +// NewAgentLister returns a new AgentLister. +func NewAgentLister(indexer cache.Indexer) AgentLister { + return &agentLister{indexer: indexer} +} + +// List lists all Agents in the indexer. +func (s *agentLister) List(selector labels.Selector) (ret []*v1alpha1.Agent, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.Agent)) + }) + return ret, err +} + +// Agents returns an object that can list and get Agents. +func (s *agentLister) Agents(namespace string) AgentNamespaceLister { + return agentNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// AgentNamespaceLister helps list and get Agents. +type AgentNamespaceLister interface { + // List lists all Agents in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1alpha1.Agent, err error) + // Get retrieves the Agent from the indexer for a given namespace and name. + Get(name string) (*v1alpha1.Agent, error) + AgentNamespaceListerExpansion +} + +// agentNamespaceLister implements the AgentNamespaceLister +// interface. +type agentNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Agents in the indexer for a given namespace. +func (s agentNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Agent, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.Agent)) + }) + return ret, err +} + +// Get retrieves the Agent from the indexer for a given namespace and name. +func (s agentNamespaceLister) Get(name string) (*v1alpha1.Agent, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("agent"), name) + } + return obj.(*v1alpha1.Agent), nil +} diff --git a/pkg/client/listers/tower/v1alpha1/expansion_generated.go b/pkg/client/listers/tower/v1alpha1/expansion_generated.go new file mode 100644 index 000000000..d094cbfb6 --- /dev/null +++ b/pkg/client/listers/tower/v1alpha1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// AgentListerExpansion allows custom methods to be added to +// AgentLister. +type AgentListerExpansion interface{} + +// AgentNamespaceListerExpansion allows custom methods to be added to +// AgentNamespaceLister. +type AgentNamespaceListerExpansion interface{}