Merge pull request #2770 from wansir/tenant
fix workspacetemplate patch API not working
This commit is contained in:
@@ -21,7 +21,6 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/klog"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha2"
|
||||
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
|
||||
"kubesphere.io/kubesphere/pkg/controller/application"
|
||||
"kubesphere.io/kubesphere/pkg/controller/certificatesigningrequest"
|
||||
@@ -159,9 +158,9 @@ func addControllers(
|
||||
kubernetesInformer.Apps().V1().StatefulSets())
|
||||
|
||||
var fedUserCache, fedGlobalRoleBindingCache, fedGlobalRoleCache,
|
||||
fedWorkspaceCache, fedWorkspaceRoleCache, fedWorkspaceRoleBindingCache cache.Store
|
||||
fedWorkspaceRoleCache, fedWorkspaceRoleBindingCache cache.Store
|
||||
var fedUserCacheController, fedGlobalRoleBindingCacheController, fedGlobalRoleCacheController,
|
||||
fedWorkspaceCacheController, fedWorkspaceRoleCacheController, fedWorkspaceRoleBindingCacheController cache.Controller
|
||||
fedWorkspaceRoleCacheController, fedWorkspaceRoleBindingCacheController cache.Controller
|
||||
|
||||
if multiClusterEnabled {
|
||||
fedUserClient, err := util.NewResourceClient(client.Config(), &iamv1alpha2.FedUserResource)
|
||||
@@ -179,11 +178,6 @@ func addControllers(
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
fedWorkspaceClient, err := util.NewResourceClient(client.Config(), &tenantv1alpha2.FedWorkspaceResource)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
fedWorkspaceRoleClient, err := util.NewResourceClient(client.Config(), &iamv1alpha2.FedWorkspaceRoleResource)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
@@ -198,14 +192,12 @@ func addControllers(
|
||||
fedUserCache, fedUserCacheController = util.NewResourceInformer(fedUserClient, "", &iamv1alpha2.FedUserResource, func(object runtime.Object) {})
|
||||
fedGlobalRoleCache, fedGlobalRoleCacheController = util.NewResourceInformer(fedGlobalRoleClient, "", &iamv1alpha2.FedGlobalRoleResource, func(object runtime.Object) {})
|
||||
fedGlobalRoleBindingCache, fedGlobalRoleBindingCacheController = util.NewResourceInformer(fedGlobalRoleBindingClient, "", &iamv1alpha2.FedGlobalRoleBindingResource, func(object runtime.Object) {})
|
||||
fedWorkspaceCache, fedWorkspaceCacheController = util.NewResourceInformer(fedWorkspaceClient, "", &tenantv1alpha2.FedWorkspaceResource, func(object runtime.Object) {})
|
||||
fedWorkspaceRoleCache, fedWorkspaceRoleCacheController = util.NewResourceInformer(fedWorkspaceRoleClient, "", &iamv1alpha2.FedWorkspaceRoleResource, func(object runtime.Object) {})
|
||||
fedWorkspaceRoleBindingCache, fedWorkspaceRoleBindingCacheController = util.NewResourceInformer(fedWorkspaceRoleBindingClient, "", &iamv1alpha2.FedWorkspaceRoleBindingResource, func(object runtime.Object) {})
|
||||
|
||||
go fedUserCacheController.Run(stopCh)
|
||||
go fedGlobalRoleCacheController.Run(stopCh)
|
||||
go fedGlobalRoleBindingCacheController.Run(stopCh)
|
||||
go fedWorkspaceCacheController.Run(stopCh)
|
||||
go fedWorkspaceRoleCacheController.Run(stopCh)
|
||||
go fedWorkspaceRoleBindingCacheController.Run(stopCh)
|
||||
}
|
||||
@@ -255,7 +247,8 @@ func addControllers(
|
||||
kubesphereInformer.Tenant().V1alpha1().Workspaces(),
|
||||
kubesphereInformer.Iam().V1alpha2().RoleBases(),
|
||||
kubesphereInformer.Iam().V1alpha2().WorkspaceRoles(),
|
||||
fedWorkspaceCache, fedWorkspaceCacheController, multiClusterEnabled)
|
||||
kubesphereInformer.Types().V1beta1().FederatedWorkspaces(),
|
||||
multiClusterEnabled)
|
||||
|
||||
var clusterController manager.Runnable
|
||||
if multiClusterEnabled {
|
||||
|
||||
@@ -18,30 +18,13 @@ package v1alpha2
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
typesv1alpha1 "kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
|
||||
)
|
||||
|
||||
const (
|
||||
ResourceKindWorkspaceTemplate = "WorkspaceTemplate"
|
||||
ResourceSingularWorkspaceTemplate = "workspacetemplate"
|
||||
ResourcePluralWorkspaceTemplate = "workspacetemplates"
|
||||
ResourcesPluralFedWorkspace = "federatedworkspaces"
|
||||
ResourcesSingularFedWorkspace = "federatedworkspace"
|
||||
FedWorkspaceKind = "FederatedWorkspace"
|
||||
fedResourceGroup = "types.kubefed.io"
|
||||
fedResourceVersion = "v1beta1"
|
||||
)
|
||||
|
||||
var (
|
||||
FedWorkspaceResource = metav1.APIResource{
|
||||
Name: ResourcesPluralFedWorkspace,
|
||||
SingularName: ResourcesSingularFedWorkspace,
|
||||
Namespaced: false,
|
||||
Group: fedResourceGroup,
|
||||
Version: fedResourceVersion,
|
||||
Kind: FedWorkspaceKind,
|
||||
}
|
||||
)
|
||||
|
||||
// +genclient
|
||||
@@ -54,42 +37,7 @@ var (
|
||||
type WorkspaceTemplate struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec WorkspaceTemplateSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
type WorkspaceTemplateSpec struct {
|
||||
Template Template `json:"template"`
|
||||
Placement Placement `json:"placement"`
|
||||
Overrides []Override `json:"overrides,omitempty"`
|
||||
}
|
||||
|
||||
type Template struct {
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec v1alpha1.WorkspaceSpec `json:"spec"`
|
||||
}
|
||||
|
||||
type Placement struct {
|
||||
Clusters []Cluster `json:"clusters,omitempty"`
|
||||
ClusterSelector *ClusterSelector `json:"clusterSelector,omitempty"`
|
||||
}
|
||||
|
||||
type ClusterSelector struct {
|
||||
MatchLabels map[string]string `json:"matchLabels,omitempty"`
|
||||
}
|
||||
|
||||
type Cluster struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Override struct {
|
||||
ClusterName string `json:"clusterName"`
|
||||
ClusterOverrides []ClusterOverride `json:"clusterOverrides"`
|
||||
}
|
||||
|
||||
type ClusterOverride struct {
|
||||
Path string `json:"path"`
|
||||
Op string `json:"op,omitempty"`
|
||||
Value runtime.RawExtension `json:"value"`
|
||||
Spec typesv1alpha1.FederatedWorkspaceSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@@ -105,9 +53,3 @@ type WorkspaceTemplateList struct {
|
||||
func init() {
|
||||
SchemeBuilder.Register(&WorkspaceTemplate{}, &WorkspaceTemplateList{})
|
||||
}
|
||||
|
||||
type FederatedWorkspace struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec WorkspaceTemplateSpec `json:"spec"`
|
||||
}
|
||||
|
||||
167
pkg/apis/tenant/v1alpha2/zz_generated.deepcopy.go
generated
167
pkg/apis/tenant/v1alpha2/zz_generated.deepcopy.go
generated
@@ -24,148 +24,6 @@ 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 *Cluster) DeepCopyInto(out *Cluster) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
|
||||
func (in *Cluster) DeepCopy() *Cluster {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Cluster)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterOverride) DeepCopyInto(out *ClusterOverride) {
|
||||
*out = *in
|
||||
in.Value.DeepCopyInto(&out.Value)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterOverride.
|
||||
func (in *ClusterOverride) DeepCopy() *ClusterOverride {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterOverride)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterSelector) DeepCopyInto(out *ClusterSelector) {
|
||||
*out = *in
|
||||
if in.MatchLabels != nil {
|
||||
in, out := &in.MatchLabels, &out.MatchLabels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSelector.
|
||||
func (in *ClusterSelector) DeepCopy() *ClusterSelector {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterSelector)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FederatedWorkspace) DeepCopyInto(out *FederatedWorkspace) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FederatedWorkspace.
|
||||
func (in *FederatedWorkspace) DeepCopy() *FederatedWorkspace {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FederatedWorkspace)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Override) DeepCopyInto(out *Override) {
|
||||
*out = *in
|
||||
if in.ClusterOverrides != nil {
|
||||
in, out := &in.ClusterOverrides, &out.ClusterOverrides
|
||||
*out = make([]ClusterOverride, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Override.
|
||||
func (in *Override) DeepCopy() *Override {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Override)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Placement) DeepCopyInto(out *Placement) {
|
||||
*out = *in
|
||||
if in.Clusters != nil {
|
||||
in, out := &in.Clusters, &out.Clusters
|
||||
*out = make([]Cluster, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ClusterSelector != nil {
|
||||
in, out := &in.ClusterSelector, &out.ClusterSelector
|
||||
*out = new(ClusterSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Placement.
|
||||
func (in *Placement) DeepCopy() *Placement {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Placement)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Template) DeepCopyInto(out *Template) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Template.
|
||||
func (in *Template) DeepCopy() *Template {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Template)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkspaceTemplate) DeepCopyInto(out *WorkspaceTemplate) {
|
||||
*out = *in
|
||||
@@ -225,28 +83,3 @@ func (in *WorkspaceTemplateList) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkspaceTemplateSpec) DeepCopyInto(out *WorkspaceTemplateSpec) {
|
||||
*out = *in
|
||||
in.Template.DeepCopyInto(&out.Template)
|
||||
in.Placement.DeepCopyInto(&out.Placement)
|
||||
if in.Overrides != nil {
|
||||
in, out := &in.Overrides, &out.Overrides
|
||||
*out = make([]Override, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceTemplateSpec.
|
||||
func (in *WorkspaceTemplateSpec) DeepCopy() *WorkspaceTemplateSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkspaceTemplateSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ const (
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +genclient:nonNamespaced
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type FederatedWorkspace struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -45,7 +47,8 @@ type FederatedWorkspaceSpec struct {
|
||||
}
|
||||
|
||||
type WorkspaceTemplate struct {
|
||||
Spec workspacev1alpha1.WorkspaceSpec `json:"spec,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec workspacev1alpha1.WorkspaceSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
1
pkg/apis/types/v1beta1/zz_generated.deepcopy.go
generated
1
pkg/apis/types/v1beta1/zz_generated.deepcopy.go
generated
@@ -2039,6 +2039,7 @@ func (in *UserTemplate) DeepCopy() *UserTemplate {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkspaceTemplate) DeepCopyInto(out *WorkspaceTemplate) {
|
||||
*out = *in
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import (
|
||||
// FakeFederatedWorkspaces implements FederatedWorkspaceInterface
|
||||
type FakeFederatedWorkspaces struct {
|
||||
Fake *FakeTypesV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var federatedworkspacesResource = schema.GroupVersionResource{Group: "types.kubefed.io", Version: "v1beta1", Resource: "federatedworkspaces"}
|
||||
@@ -41,8 +40,7 @@ var federatedworkspacesKind = schema.GroupVersionKind{Group: "types.kubefed.io",
|
||||
// Get takes name of the federatedWorkspace, and returns the corresponding federatedWorkspace object, and an error if there is any.
|
||||
func (c *FakeFederatedWorkspaces) Get(name string, options v1.GetOptions) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(federatedworkspacesResource, c.ns, name), &v1beta1.FederatedWorkspace{})
|
||||
|
||||
Invokes(testing.NewRootGetAction(federatedworkspacesResource, name), &v1beta1.FederatedWorkspace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -52,8 +50,7 @@ func (c *FakeFederatedWorkspaces) Get(name string, options v1.GetOptions) (resul
|
||||
// List takes label and field selectors, and returns the list of FederatedWorkspaces that match those selectors.
|
||||
func (c *FakeFederatedWorkspaces) List(opts v1.ListOptions) (result *v1beta1.FederatedWorkspaceList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(federatedworkspacesResource, federatedworkspacesKind, c.ns, opts), &v1beta1.FederatedWorkspaceList{})
|
||||
|
||||
Invokes(testing.NewRootListAction(federatedworkspacesResource, federatedworkspacesKind, opts), &v1beta1.FederatedWorkspaceList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -74,15 +71,13 @@ func (c *FakeFederatedWorkspaces) List(opts v1.ListOptions) (result *v1beta1.Fed
|
||||
// Watch returns a watch.Interface that watches the requested federatedWorkspaces.
|
||||
func (c *FakeFederatedWorkspaces) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(federatedworkspacesResource, c.ns, opts))
|
||||
|
||||
InvokesWatch(testing.NewRootWatchAction(federatedworkspacesResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a federatedWorkspace and creates it. Returns the server's representation of the federatedWorkspace, and an error, if there is any.
|
||||
func (c *FakeFederatedWorkspaces) Create(federatedWorkspace *v1beta1.FederatedWorkspace) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(federatedworkspacesResource, c.ns, federatedWorkspace), &v1beta1.FederatedWorkspace{})
|
||||
|
||||
Invokes(testing.NewRootCreateAction(federatedworkspacesResource, federatedWorkspace), &v1beta1.FederatedWorkspace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -92,8 +87,7 @@ func (c *FakeFederatedWorkspaces) Create(federatedWorkspace *v1beta1.FederatedWo
|
||||
// Update takes the representation of a federatedWorkspace and updates it. Returns the server's representation of the federatedWorkspace, and an error, if there is any.
|
||||
func (c *FakeFederatedWorkspaces) Update(federatedWorkspace *v1beta1.FederatedWorkspace) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(federatedworkspacesResource, c.ns, federatedWorkspace), &v1beta1.FederatedWorkspace{})
|
||||
|
||||
Invokes(testing.NewRootUpdateAction(federatedworkspacesResource, federatedWorkspace), &v1beta1.FederatedWorkspace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -104,8 +98,7 @@ func (c *FakeFederatedWorkspaces) Update(federatedWorkspace *v1beta1.FederatedWo
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeFederatedWorkspaces) UpdateStatus(federatedWorkspace *v1beta1.FederatedWorkspace) (*v1beta1.FederatedWorkspace, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(federatedworkspacesResource, "status", c.ns, federatedWorkspace), &v1beta1.FederatedWorkspace{})
|
||||
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(federatedworkspacesResource, "status", federatedWorkspace), &v1beta1.FederatedWorkspace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -115,14 +108,13 @@ func (c *FakeFederatedWorkspaces) UpdateStatus(federatedWorkspace *v1beta1.Feder
|
||||
// Delete takes name of the federatedWorkspace and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeFederatedWorkspaces) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(federatedworkspacesResource, c.ns, name), &v1beta1.FederatedWorkspace{})
|
||||
|
||||
Invokes(testing.NewRootDeleteAction(federatedworkspacesResource, name), &v1beta1.FederatedWorkspace{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeFederatedWorkspaces) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(federatedworkspacesResource, c.ns, listOptions)
|
||||
action := testing.NewRootDeleteCollectionAction(federatedworkspacesResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.FederatedWorkspaceList{})
|
||||
return err
|
||||
@@ -131,8 +123,7 @@ func (c *FakeFederatedWorkspaces) DeleteCollection(options *v1.DeleteOptions, li
|
||||
// Patch applies the patch and returns the patched federatedWorkspace.
|
||||
func (c *FakeFederatedWorkspaces) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(federatedworkspacesResource, c.ns, name, pt, data, subresources...), &v1beta1.FederatedWorkspace{})
|
||||
|
||||
Invokes(testing.NewRootPatchSubresourceAction(federatedworkspacesResource, name, pt, data, subresources...), &v1beta1.FederatedWorkspace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -88,8 +88,8 @@ func (c *FakeTypesV1beta1) FederatedUsers(namespace string) v1beta1.FederatedUse
|
||||
return &FakeFederatedUsers{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeTypesV1beta1) FederatedWorkspaces(namespace string) v1beta1.FederatedWorkspaceInterface {
|
||||
return &FakeFederatedWorkspaces{c, namespace}
|
||||
func (c *FakeTypesV1beta1) FederatedWorkspaces() v1beta1.FederatedWorkspaceInterface {
|
||||
return &FakeFederatedWorkspaces{c}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
// FederatedWorkspacesGetter has a method to return a FederatedWorkspaceInterface.
|
||||
// A group's client should implement this interface.
|
||||
type FederatedWorkspacesGetter interface {
|
||||
FederatedWorkspaces(namespace string) FederatedWorkspaceInterface
|
||||
FederatedWorkspaces() FederatedWorkspaceInterface
|
||||
}
|
||||
|
||||
// FederatedWorkspaceInterface has methods to work with FederatedWorkspace resources.
|
||||
@@ -52,14 +52,12 @@ type FederatedWorkspaceInterface interface {
|
||||
// federatedWorkspaces implements FederatedWorkspaceInterface
|
||||
type federatedWorkspaces struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newFederatedWorkspaces returns a FederatedWorkspaces
|
||||
func newFederatedWorkspaces(c *TypesV1beta1Client, namespace string) *federatedWorkspaces {
|
||||
func newFederatedWorkspaces(c *TypesV1beta1Client) *federatedWorkspaces {
|
||||
return &federatedWorkspaces{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +65,6 @@ func newFederatedWorkspaces(c *TypesV1beta1Client, namespace string) *federatedW
|
||||
func (c *federatedWorkspaces) Get(name string, options v1.GetOptions) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
result = &v1beta1.FederatedWorkspace{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
@@ -84,7 +81,6 @@ func (c *federatedWorkspaces) List(opts v1.ListOptions) (result *v1beta1.Federat
|
||||
}
|
||||
result = &v1beta1.FederatedWorkspaceList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
@@ -101,7 +97,6 @@ func (c *federatedWorkspaces) Watch(opts v1.ListOptions) (watch.Interface, error
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
@@ -112,7 +107,6 @@ func (c *federatedWorkspaces) Watch(opts v1.ListOptions) (watch.Interface, error
|
||||
func (c *federatedWorkspaces) Create(federatedWorkspace *v1beta1.FederatedWorkspace) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
result = &v1beta1.FederatedWorkspace{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
Body(federatedWorkspace).
|
||||
Do().
|
||||
@@ -124,7 +118,6 @@ func (c *federatedWorkspaces) Create(federatedWorkspace *v1beta1.FederatedWorksp
|
||||
func (c *federatedWorkspaces) Update(federatedWorkspace *v1beta1.FederatedWorkspace) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
result = &v1beta1.FederatedWorkspace{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
Name(federatedWorkspace.Name).
|
||||
Body(federatedWorkspace).
|
||||
@@ -139,7 +132,6 @@ func (c *federatedWorkspaces) Update(federatedWorkspace *v1beta1.FederatedWorksp
|
||||
func (c *federatedWorkspaces) UpdateStatus(federatedWorkspace *v1beta1.FederatedWorkspace) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
result = &v1beta1.FederatedWorkspace{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
Name(federatedWorkspace.Name).
|
||||
SubResource("status").
|
||||
@@ -152,7 +144,6 @@ func (c *federatedWorkspaces) UpdateStatus(federatedWorkspace *v1beta1.Federated
|
||||
// Delete takes name of the federatedWorkspace and deletes it. Returns an error if one occurs.
|
||||
func (c *federatedWorkspaces) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
Name(name).
|
||||
Body(options).
|
||||
@@ -167,7 +158,6 @@ func (c *federatedWorkspaces) DeleteCollection(options *v1.DeleteOptions, listOp
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
@@ -180,7 +170,6 @@ func (c *federatedWorkspaces) DeleteCollection(options *v1.DeleteOptions, listOp
|
||||
func (c *federatedWorkspaces) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.FederatedWorkspace, err error) {
|
||||
result = &v1beta1.FederatedWorkspace{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("federatedworkspaces").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
|
||||
@@ -109,8 +109,8 @@ func (c *TypesV1beta1Client) FederatedUsers(namespace string) FederatedUserInter
|
||||
return newFederatedUsers(c, namespace)
|
||||
}
|
||||
|
||||
func (c *TypesV1beta1Client) FederatedWorkspaces(namespace string) FederatedWorkspaceInterface {
|
||||
return newFederatedWorkspaces(c, namespace)
|
||||
func (c *TypesV1beta1Client) FederatedWorkspaces() FederatedWorkspaceInterface {
|
||||
return newFederatedWorkspaces(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new TypesV1beta1Client for the given config.
|
||||
|
||||
@@ -41,33 +41,32 @@ type FederatedWorkspaceInformer interface {
|
||||
type federatedWorkspaceInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewFederatedWorkspaceInformer constructs a new informer for FederatedWorkspace 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 NewFederatedWorkspaceInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredFederatedWorkspaceInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
func NewFederatedWorkspaceInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredFederatedWorkspaceInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredFederatedWorkspaceInformer constructs a new informer for FederatedWorkspace 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 NewFilteredFederatedWorkspaceInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
func NewFilteredFederatedWorkspaceInformer(client versioned.Interface, 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.TypesV1beta1().FederatedWorkspaces(namespace).List(options)
|
||||
return client.TypesV1beta1().FederatedWorkspaces().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.TypesV1beta1().FederatedWorkspaces(namespace).Watch(options)
|
||||
return client.TypesV1beta1().FederatedWorkspaces().Watch(options)
|
||||
},
|
||||
},
|
||||
&typesv1beta1.FederatedWorkspace{},
|
||||
@@ -77,7 +76,7 @@ func NewFilteredFederatedWorkspaceInformer(client versioned.Interface, namespace
|
||||
}
|
||||
|
||||
func (f *federatedWorkspaceInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredFederatedWorkspaceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
return NewFilteredFederatedWorkspaceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *federatedWorkspaceInformer) Informer() cache.SharedIndexInformer {
|
||||
|
||||
@@ -146,5 +146,5 @@ func (v *version) FederatedUsers() FederatedUserInformer {
|
||||
|
||||
// FederatedWorkspaces returns a FederatedWorkspaceInformer.
|
||||
func (v *version) FederatedWorkspaces() FederatedWorkspaceInformer {
|
||||
return &federatedWorkspaceInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
return &federatedWorkspaceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,3 @@ type FederatedUserNamespaceListerExpansion interface{}
|
||||
// FederatedWorkspaceListerExpansion allows custom methods to be added to
|
||||
// FederatedWorkspaceLister.
|
||||
type FederatedWorkspaceListerExpansion interface{}
|
||||
|
||||
// FederatedWorkspaceNamespaceListerExpansion allows custom methods to be added to
|
||||
// FederatedWorkspaceNamespaceLister.
|
||||
type FederatedWorkspaceNamespaceListerExpansion interface{}
|
||||
|
||||
@@ -29,8 +29,8 @@ import (
|
||||
type FederatedWorkspaceLister interface {
|
||||
// List lists all FederatedWorkspaces in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1beta1.FederatedWorkspace, err error)
|
||||
// FederatedWorkspaces returns an object that can list and get FederatedWorkspaces.
|
||||
FederatedWorkspaces(namespace string) FederatedWorkspaceNamespaceLister
|
||||
// Get retrieves the FederatedWorkspace from the index for a given name.
|
||||
Get(name string) (*v1beta1.FederatedWorkspace, error)
|
||||
FederatedWorkspaceListerExpansion
|
||||
}
|
||||
|
||||
@@ -52,38 +52,9 @@ func (s *federatedWorkspaceLister) List(selector labels.Selector) (ret []*v1beta
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// FederatedWorkspaces returns an object that can list and get FederatedWorkspaces.
|
||||
func (s *federatedWorkspaceLister) FederatedWorkspaces(namespace string) FederatedWorkspaceNamespaceLister {
|
||||
return federatedWorkspaceNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// FederatedWorkspaceNamespaceLister helps list and get FederatedWorkspaces.
|
||||
type FederatedWorkspaceNamespaceLister interface {
|
||||
// List lists all FederatedWorkspaces in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1beta1.FederatedWorkspace, err error)
|
||||
// Get retrieves the FederatedWorkspace from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1beta1.FederatedWorkspace, error)
|
||||
FederatedWorkspaceNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// federatedWorkspaceNamespaceLister implements the FederatedWorkspaceNamespaceLister
|
||||
// interface.
|
||||
type federatedWorkspaceNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all FederatedWorkspaces in the indexer for a given namespace.
|
||||
func (s federatedWorkspaceNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.FederatedWorkspace, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.FederatedWorkspace))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the FederatedWorkspace from the indexer for a given namespace and name.
|
||||
func (s federatedWorkspaceNamespaceLister) Get(name string) (*v1beta1.FederatedWorkspace, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
// Get retrieves the FederatedWorkspace from the index for a given name.
|
||||
func (s *federatedWorkspaceLister) Get(name string) (*v1beta1.FederatedWorkspace, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -94,11 +94,11 @@ func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface
|
||||
}
|
||||
klog.Info("Setting up event handlers")
|
||||
globalRoleInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: ctl.enqueueClusterRole,
|
||||
AddFunc: ctl.enqueueGlobalRole,
|
||||
UpdateFunc: func(old, new interface{}) {
|
||||
ctl.enqueueClusterRole(new)
|
||||
ctl.enqueueGlobalRole(new)
|
||||
},
|
||||
DeleteFunc: ctl.enqueueClusterRole,
|
||||
DeleteFunc: ctl.enqueueGlobalRole,
|
||||
})
|
||||
return ctl
|
||||
}
|
||||
@@ -129,7 +129,7 @@ func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) enqueueClusterRole(obj interface{}) {
|
||||
func (c *Controller) enqueueGlobalRole(obj interface{}) {
|
||||
var key string
|
||||
var err error
|
||||
if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
|
||||
|
||||
@@ -293,14 +293,6 @@ func (r *ReconcileNamespace) initRoles(namespace *corev1.Namespace) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ReconcileNamespace) resetNamespaceOwner(namespace *corev1.Namespace) error {
|
||||
namespace = namespace.DeepCopy()
|
||||
delete(namespace.Annotations, constants.CreatorAnnotationKey)
|
||||
err := r.Update(context.Background(), namespace)
|
||||
klog.V(4).Infof("update namespace after creator has been deleted")
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ReconcileNamespace) initCreatorRoleBinding(namespace *corev1.Namespace) error {
|
||||
creator := namespace.Annotations[constants.CreatorAnnotationKey]
|
||||
if creator == "" {
|
||||
@@ -308,21 +300,14 @@ func (r *ReconcileNamespace) initCreatorRoleBinding(namespace *corev1.Namespace)
|
||||
}
|
||||
|
||||
var user iamv1alpha2.User
|
||||
err := r.Get(context.Background(), types.NamespacedName{Name: creator}, &user)
|
||||
if err != nil {
|
||||
// skip if user has been deleted
|
||||
if err := r.Get(context.Background(), types.NamespacedName{Name: creator}, &user); err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return r.resetNamespaceOwner(namespace)
|
||||
return nil
|
||||
}
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// skip if user has been deleted
|
||||
if !user.DeletionTimestamp.IsZero() {
|
||||
return r.resetNamespaceOwner(namespace)
|
||||
}
|
||||
|
||||
creatorRoleBinding := &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-%s", creator, iamv1alpha2.NamespaceAdmin),
|
||||
@@ -342,8 +327,8 @@ func (r *ReconcileNamespace) initCreatorRoleBinding(namespace *corev1.Namespace)
|
||||
},
|
||||
},
|
||||
}
|
||||
err = r.Client.Create(context.Background(), creatorRoleBinding)
|
||||
if err != nil {
|
||||
|
||||
if err := r.Client.Create(context.Background(), creatorRoleBinding); err != nil {
|
||||
if errors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -105,11 +105,11 @@ func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface
|
||||
}
|
||||
klog.Info("Setting up event handlers")
|
||||
workspaceRoleInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: ctl.enqueueClusterRole,
|
||||
AddFunc: ctl.enqueueWorkspaceRole,
|
||||
UpdateFunc: func(old, new interface{}) {
|
||||
ctl.enqueueClusterRole(new)
|
||||
ctl.enqueueWorkspaceRole(new)
|
||||
},
|
||||
DeleteFunc: ctl.enqueueClusterRole,
|
||||
DeleteFunc: ctl.enqueueWorkspaceRole,
|
||||
})
|
||||
return ctl
|
||||
}
|
||||
@@ -146,7 +146,7 @@ func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) enqueueClusterRole(obj interface{}) {
|
||||
func (c *Controller) enqueueWorkspaceRole(obj interface{}) {
|
||||
var key string
|
||||
var err error
|
||||
if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
|
||||
|
||||
@@ -18,15 +18,12 @@ package workspacetemplate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
@@ -40,13 +37,16 @@ import (
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha2"
|
||||
typesv1beta1 "kubesphere.io/kubesphere/pkg/apis/types/v1beta1"
|
||||
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
iamv1alpha2informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/iam/v1alpha2"
|
||||
tenantv1alpha1informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant/v1alpha1"
|
||||
tenantv1alpha2informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant/v1alpha2"
|
||||
typesv1beta1informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/types/v1beta1"
|
||||
iamv1alpha2listers "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
|
||||
tenantv1alpha1listers "kubesphere.io/kubesphere/pkg/client/listers/tenant/v1alpha1"
|
||||
tenantv1alpha2listers "kubesphere.io/kubesphere/pkg/client/listers/tenant/v1alpha2"
|
||||
typesv1beta1listers "kubesphere.io/kubesphere/pkg/client/listers/types/v1beta1"
|
||||
"reflect"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"time"
|
||||
@@ -61,23 +61,24 @@ const (
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
k8sClient kubernetes.Interface
|
||||
ksClient kubesphere.Interface
|
||||
workspaceTemplateInformer tenantv1alpha2informers.WorkspaceTemplateInformer
|
||||
workspaceTemplateLister tenantv1alpha2listers.WorkspaceTemplateLister
|
||||
workspaceTemplateSynced cache.InformerSynced
|
||||
workspaceRoleInformer iamv1alpha2informers.WorkspaceRoleInformer
|
||||
workspaceRoleLister iamv1alpha2listers.WorkspaceRoleLister
|
||||
workspaceRoleSynced cache.InformerSynced
|
||||
roleBaseInformer iamv1alpha2informers.RoleBaseInformer
|
||||
roleBaseLister iamv1alpha2listers.RoleBaseLister
|
||||
roleBaseSynced cache.InformerSynced
|
||||
workspaceInformer tenantv1alpha1informers.WorkspaceInformer
|
||||
workspaceLister tenantv1alpha1listers.WorkspaceLister
|
||||
workspaceSynced cache.InformerSynced
|
||||
fedWorkspaceCache cache.Store
|
||||
fedWorkspaceCacheController cache.Controller
|
||||
multiClusterEnabled bool
|
||||
k8sClient kubernetes.Interface
|
||||
ksClient kubesphere.Interface
|
||||
workspaceTemplateInformer tenantv1alpha2informers.WorkspaceTemplateInformer
|
||||
workspaceTemplateLister tenantv1alpha2listers.WorkspaceTemplateLister
|
||||
workspaceTemplateSynced cache.InformerSynced
|
||||
workspaceRoleInformer iamv1alpha2informers.WorkspaceRoleInformer
|
||||
workspaceRoleLister iamv1alpha2listers.WorkspaceRoleLister
|
||||
workspaceRoleSynced cache.InformerSynced
|
||||
roleBaseInformer iamv1alpha2informers.RoleBaseInformer
|
||||
roleBaseLister iamv1alpha2listers.RoleBaseLister
|
||||
roleBaseSynced cache.InformerSynced
|
||||
workspaceInformer tenantv1alpha1informers.WorkspaceInformer
|
||||
workspaceLister tenantv1alpha1listers.WorkspaceLister
|
||||
workspaceSynced cache.InformerSynced
|
||||
federatedWorkspaceInformer typesv1beta1informers.FederatedWorkspaceInformer
|
||||
federatedWorkspaceLister typesv1beta1listers.FederatedWorkspaceLister
|
||||
federatedWorkspaceSynced cache.InformerSynced
|
||||
multiClusterEnabled bool
|
||||
// workqueue is a rate limited work queue. This is used to queue work to be
|
||||
// processed instead of performing it as soon as a change happens. This
|
||||
// means we can ensure we only process a fixed amount of resources at a
|
||||
@@ -89,9 +90,13 @@ type Controller struct {
|
||||
recorder record.EventRecorder
|
||||
}
|
||||
|
||||
func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface, workspaceTemplateInformer tenantv1alpha2informers.WorkspaceTemplateInformer,
|
||||
workspaceInformer tenantv1alpha1informers.WorkspaceInformer, roleBaseInformer iamv1alpha2informers.RoleBaseInformer, workspaceRoleInformer iamv1alpha2informers.WorkspaceRoleInformer,
|
||||
fedWorkspaceCache cache.Store, fedWorkspaceCacheController cache.Controller, multiClusterEnabled bool) *Controller {
|
||||
func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface,
|
||||
workspaceTemplateInformer tenantv1alpha2informers.WorkspaceTemplateInformer,
|
||||
workspaceInformer tenantv1alpha1informers.WorkspaceInformer,
|
||||
roleBaseInformer iamv1alpha2informers.RoleBaseInformer,
|
||||
workspaceRoleInformer iamv1alpha2informers.WorkspaceRoleInformer,
|
||||
federatedWorkspaceInformer typesv1beta1informers.FederatedWorkspaceInformer,
|
||||
multiClusterEnabled bool) *Controller {
|
||||
// Create event broadcaster
|
||||
// Add sample-controller types to the default Kubernetes Scheme so Events can be
|
||||
// logged for sample-controller types.
|
||||
@@ -102,33 +107,34 @@ func NewController(k8sClient kubernetes.Interface, ksClient kubesphere.Interface
|
||||
eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: k8sClient.CoreV1().Events("")})
|
||||
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerName})
|
||||
ctl := &Controller{
|
||||
k8sClient: k8sClient,
|
||||
ksClient: ksClient,
|
||||
workspaceTemplateInformer: workspaceTemplateInformer,
|
||||
workspaceTemplateLister: workspaceTemplateInformer.Lister(),
|
||||
workspaceTemplateSynced: workspaceTemplateInformer.Informer().HasSynced,
|
||||
workspaceInformer: workspaceInformer,
|
||||
workspaceLister: workspaceInformer.Lister(),
|
||||
workspaceSynced: workspaceInformer.Informer().HasSynced,
|
||||
workspaceRoleInformer: workspaceRoleInformer,
|
||||
workspaceRoleLister: workspaceRoleInformer.Lister(),
|
||||
workspaceRoleSynced: workspaceRoleInformer.Informer().HasSynced,
|
||||
roleBaseInformer: roleBaseInformer,
|
||||
roleBaseLister: roleBaseInformer.Lister(),
|
||||
roleBaseSynced: roleBaseInformer.Informer().HasSynced,
|
||||
fedWorkspaceCache: fedWorkspaceCache,
|
||||
fedWorkspaceCacheController: fedWorkspaceCacheController,
|
||||
multiClusterEnabled: multiClusterEnabled,
|
||||
workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "WorkspaceTemplate"),
|
||||
recorder: recorder,
|
||||
k8sClient: k8sClient,
|
||||
ksClient: ksClient,
|
||||
workspaceTemplateInformer: workspaceTemplateInformer,
|
||||
workspaceTemplateLister: workspaceTemplateInformer.Lister(),
|
||||
workspaceTemplateSynced: workspaceTemplateInformer.Informer().HasSynced,
|
||||
workspaceInformer: workspaceInformer,
|
||||
workspaceLister: workspaceInformer.Lister(),
|
||||
workspaceSynced: workspaceInformer.Informer().HasSynced,
|
||||
workspaceRoleInformer: workspaceRoleInformer,
|
||||
workspaceRoleLister: workspaceRoleInformer.Lister(),
|
||||
workspaceRoleSynced: workspaceRoleInformer.Informer().HasSynced,
|
||||
roleBaseInformer: roleBaseInformer,
|
||||
roleBaseLister: roleBaseInformer.Lister(),
|
||||
roleBaseSynced: roleBaseInformer.Informer().HasSynced,
|
||||
federatedWorkspaceInformer: federatedWorkspaceInformer,
|
||||
federatedWorkspaceLister: federatedWorkspaceInformer.Lister(),
|
||||
federatedWorkspaceSynced: federatedWorkspaceInformer.Informer().HasSynced,
|
||||
multiClusterEnabled: multiClusterEnabled,
|
||||
workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "WorkspaceTemplate"),
|
||||
recorder: recorder,
|
||||
}
|
||||
klog.Info("Setting up event handlers")
|
||||
workspaceTemplateInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: ctl.enqueueClusterRole,
|
||||
AddFunc: ctl.enqueueWorkspaceTemplate,
|
||||
UpdateFunc: func(old, new interface{}) {
|
||||
ctl.enqueueClusterRole(new)
|
||||
ctl.enqueueWorkspaceTemplate(new)
|
||||
},
|
||||
DeleteFunc: ctl.enqueueClusterRole,
|
||||
DeleteFunc: ctl.enqueueWorkspaceTemplate,
|
||||
})
|
||||
return ctl
|
||||
}
|
||||
@@ -146,7 +152,7 @@ func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error {
|
||||
synced := make([]cache.InformerSynced, 0)
|
||||
synced = append(synced, c.workspaceTemplateSynced, c.workspaceSynced, c.workspaceRoleSynced, c.roleBaseSynced)
|
||||
if c.multiClusterEnabled {
|
||||
synced = append(synced, c.fedWorkspaceCacheController.HasSynced)
|
||||
synced = append(synced, c.federatedWorkspaceSynced)
|
||||
}
|
||||
if ok := cache.WaitForCacheSync(stopCh, synced...); !ok {
|
||||
return fmt.Errorf("failed to wait for caches to sync")
|
||||
@@ -164,7 +170,7 @@ func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) enqueueClusterRole(obj interface{}) {
|
||||
func (c *Controller) enqueueWorkspaceTemplate(obj interface{}) {
|
||||
var key string
|
||||
var err error
|
||||
if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
|
||||
@@ -236,7 +242,6 @@ func (c *Controller) processNextWorkItem() bool {
|
||||
// converge the two. It then updates the Status block of the Foo resource
|
||||
// with the current status of the resource.
|
||||
func (c *Controller) reconcile(key string) error {
|
||||
|
||||
workspaceTemplate, err := c.workspaceTemplateLister.Get(key)
|
||||
if err != nil {
|
||||
// The user may no longer exist, in which case we stop
|
||||
@@ -280,91 +285,45 @@ func (c *Controller) Start(stopCh <-chan struct{}) error {
|
||||
}
|
||||
|
||||
func (c *Controller) multiClusterSync(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error {
|
||||
|
||||
obj, exist, err := c.fedWorkspaceCache.GetByKey(workspaceTemplate.Name)
|
||||
if !exist {
|
||||
return c.createFederatedWorkspace(workspaceTemplate)
|
||||
}
|
||||
// multi cluster environment, synchronize workspaces with kubefed
|
||||
federatedWorkspace, err := c.federatedWorkspaceLister.Get(workspaceTemplate.Name)
|
||||
if err != nil {
|
||||
// create federatedworkspace if not found
|
||||
if errors.IsNotFound(err) {
|
||||
return c.createFederatedWorkspace(workspaceTemplate)
|
||||
}
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
var fedWorkspace tenantv1alpha2.FederatedWorkspace
|
||||
|
||||
if err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.(*unstructured.Unstructured).Object, &fedWorkspace); err != nil {
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(fedWorkspace.Spec, workspaceTemplate.Spec) {
|
||||
|
||||
fedWorkspace.Spec = workspaceTemplate.Spec
|
||||
|
||||
return c.updateFederatedWorkspace(&fedWorkspace)
|
||||
// update spec
|
||||
if !reflect.DeepEqual(federatedWorkspace.Spec, workspaceTemplate.Spec) {
|
||||
federatedWorkspace.Spec = workspaceTemplate.Spec
|
||||
if err := c.updateFederatedWorkspace(federatedWorkspace); err != nil {
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) createFederatedWorkspace(workspaceTemplate *tenantv1alpha2.WorkspaceTemplate) error {
|
||||
federatedWorkspace := &tenantv1alpha2.FederatedWorkspace{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: tenantv1alpha2.FedWorkspaceKind,
|
||||
APIVersion: tenantv1alpha2.FedWorkspaceResource.Group + "/" + tenantv1alpha2.FedWorkspaceResource.Version,
|
||||
},
|
||||
federatedWorkspace := &typesv1beta1.FederatedWorkspace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: workspaceTemplate.Name,
|
||||
},
|
||||
Spec: workspaceTemplate.Spec,
|
||||
}
|
||||
|
||||
err := controllerutil.SetControllerReference(workspaceTemplate, federatedWorkspace, scheme.Scheme)
|
||||
if err != nil {
|
||||
if err := controllerutil.SetControllerReference(workspaceTemplate, federatedWorkspace, scheme.Scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := json.Marshal(federatedWorkspace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cli := c.k8sClient.(*kubernetes.Clientset)
|
||||
err = cli.RESTClient().Post().
|
||||
AbsPath(fmt.Sprintf("/apis/%s/%s/%s", tenantv1alpha2.FedWorkspaceResource.Group,
|
||||
tenantv1alpha2.FedWorkspaceResource.Version, tenantv1alpha2.FedWorkspaceResource.Name)).
|
||||
Body(data).
|
||||
Do().Error()
|
||||
|
||||
if err != nil {
|
||||
if _, err := c.ksClient.TypesV1beta1().FederatedWorkspaces().Create(federatedWorkspace); err != nil {
|
||||
if errors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) updateFederatedWorkspace(fedWorkspace *tenantv1alpha2.FederatedWorkspace) error {
|
||||
|
||||
data, err := json.Marshal(fedWorkspace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cli := c.k8sClient.(*kubernetes.Clientset)
|
||||
err = cli.RESTClient().Put().
|
||||
AbsPath(fmt.Sprintf("/apis/%s/%s/%s/%s", tenantv1alpha2.FedWorkspaceResource.Group,
|
||||
tenantv1alpha2.FedWorkspaceResource.Version, tenantv1alpha2.FedWorkspaceResource.Name,
|
||||
fedWorkspace.Name)).
|
||||
Body(data).
|
||||
Do().Error()
|
||||
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -539,3 +498,12 @@ func (r *Controller) initManagerRoleBinding(workspace *tenantv1alpha2.WorkspaceT
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) updateFederatedWorkspace(workspace *typesv1beta1.FederatedWorkspace) error {
|
||||
_, err := c.ksClient.TypesV1beta1().FederatedWorkspaces().Update(workspace)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -492,18 +493,15 @@ func (h *tenantHandler) PatchNamespace(request *restful.Request, response *restf
|
||||
|
||||
func (h *tenantHandler) PatchWorkspace(request *restful.Request, response *restful.Response) {
|
||||
workspaceName := request.PathParameter("workspace")
|
||||
|
||||
var workspace tenantv1alpha2.WorkspaceTemplate
|
||||
err := request.ReadEntity(&workspace)
|
||||
var data json.RawMessage
|
||||
err := request.ReadEntity(&data)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
api.HandleBadRequest(response, request, err)
|
||||
return
|
||||
}
|
||||
|
||||
workspace.Name = workspaceName
|
||||
|
||||
patched, err := h.tenant.PatchWorkspace(&workspace)
|
||||
patched, err := h.tenant.PatchWorkspace(workspaceName, data)
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
|
||||
@@ -76,7 +76,7 @@ type Interface interface {
|
||||
DeleteNamespace(workspace, namespace string) error
|
||||
UpdateNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error)
|
||||
PatchNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error)
|
||||
PatchWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error)
|
||||
PatchWorkspace(workspace string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error)
|
||||
ListClusters(info user.Info) (*api.ListResult, error)
|
||||
}
|
||||
|
||||
@@ -369,16 +369,8 @@ func (t *tenantOperator) PatchNamespace(workspace string, namespace *corev1.Name
|
||||
return t.k8sclient.CoreV1().Namespaces().Patch(namespace.Name, types.MergePatchType, data)
|
||||
}
|
||||
|
||||
func (t *tenantOperator) PatchWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
|
||||
_, err := t.DescribeWorkspace(workspace.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := json.Marshal(workspace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return t.ksclient.TenantV1alpha2().WorkspaceTemplates().Patch(workspace.Name, types.MergePatchType, data)
|
||||
func (t *tenantOperator) PatchWorkspace(workspace string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error) {
|
||||
return t.ksclient.TenantV1alpha2().WorkspaceTemplates().Patch(workspace, types.MergePatchType, data)
|
||||
}
|
||||
|
||||
func (t *tenantOperator) CreateWorkspace(workspace *tenantv1alpha2.WorkspaceTemplate) (*tenantv1alpha2.WorkspaceTemplate, error) {
|
||||
|
||||
Reference in New Issue
Block a user