Add iam v1beta1 APIs (#5502)
update iam v1beta1 types && deprecate iam v1alpha2 apis Signed-off-by: wenhaozhou <wenhaozhou@yunify.com>
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
Copyright 2023.
|
||||
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
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.
|
||||
|
||||
// CategorySpec defines the desired state of Category
|
||||
type CategorySpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
DisplayName map[string]string `json:"displayName,omitempty"`
|
||||
Description map[string]string `json:"description,omitempty"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// Category is the Schema for the categories API
|
||||
type Category struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec CategorySpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// CategoryList contains a list of Category
|
||||
type CategoryList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Category `json:"items"`
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
Copyright 2023.
|
||||
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/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.
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// ClusterRole is the Schema for the clusterroles API
|
||||
type ClusterRole struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// AggregationRoleTemplates means which RoleTemplates are composed this Role
|
||||
AggregationRoleTemplates AggregationRoleTemplates `json:"aggregationRoleTemplates,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this WorkspaceRole
|
||||
Rules rbacv1.PolicyRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// ClusterRoleList contains a list of ClusterRole
|
||||
type ClusterRoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ClusterRole `json:"items"`
|
||||
}
|
||||
23
staging/src/kubesphere.io/api/iam/v1beta1/doc.go
Normal file
23
staging/src/kubesphere.io/api/iam/v1beta1/doc.go
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v1beta1 contains API Schema definitions for the iam v1beta1 API group
|
||||
// +k8s:openapi-gen=true
|
||||
// +kubebuilder:object:generate=true
|
||||
// +k8s:conversion-gen=kubesphere.io/api/iam
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=iam.kubesphere.io
|
||||
package v1beta1
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
Copyright 2023.
|
||||
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/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.
|
||||
|
||||
type AggregationRoleTemplates struct {
|
||||
// TemplateNames select rules from RoleTemplate`s rules by RoleTemplate name
|
||||
TemplateNames []string `json:"templateNames,omitempty"`
|
||||
|
||||
// Selector select rules from RoleTemplate`s rules by labels
|
||||
Selector metav1.LabelSelector `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// GlobalRole is the Schema for the globalroles API
|
||||
type GlobalRole struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// AggregationRoleTemplates means which RoleTemplates are composed this Role
|
||||
AggregationRoleTemplates AggregationRoleTemplates `json:"aggregationRoleTemplates,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this WorkspaceRole
|
||||
Rules rbacv1.PolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// GlobalRoleList contains a list of GlobalRole
|
||||
type GlobalRoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []GlobalRole `json:"items"`
|
||||
}
|
||||
@@ -18,7 +18,6 @@ limitations under the License.
|
||||
// +k8s:openapi-gen=true
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=iam.kubesphere.io
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
@@ -58,6 +57,14 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
&GlobalRoleList{},
|
||||
&RoleTemplate{},
|
||||
&RoleTemplateList{},
|
||||
&RoleBinding{},
|
||||
&RoleBindingList{},
|
||||
&ClusterRoleBinding{},
|
||||
&ClusterRoleBindingList{},
|
||||
&WorkspaceRoleBinding{},
|
||||
&WorkspaceRoleBindingList{},
|
||||
&GlobalRoleBinding{},
|
||||
&GlobalRoleBindingList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
Copyright 2023.
|
||||
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/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.
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Namspaced
|
||||
|
||||
// Role is the Schema for the roles API
|
||||
type Role struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// AggregationRoleTemplates means which RoleTemplates are composed this Role
|
||||
AggregationRoleTemplates AggregationRoleTemplates `json:"aggregationRoleTemplates,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this WorkspaceRole
|
||||
Rules rbacv1.PolicyRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// RoleList contains a list of Role
|
||||
type RoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Role `json:"items"`
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
Copyright 2023.
|
||||
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/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.
|
||||
|
||||
// RoleTemplateSpec defines the desired state of RoleTemplate
|
||||
type RoleTemplateSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
// DisplayName represent the name displays at console, this field
|
||||
DisplayName map[string]string `json:"displayName,omitempty"`
|
||||
Description map[string]string `json:"description,omitempty"`
|
||||
Rules []rbacv1.PolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// RoleTemplate is the Schema for the roletemplates API
|
||||
type RoleTemplate struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec RoleTemplateSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// RoleTemplateList contains a list of RoleTemplate
|
||||
type RoleTemplateList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []RoleTemplate `json:"items"`
|
||||
}
|
||||
291
staging/src/kubesphere.io/api/iam/v1beta1/types.go
Normal file
291
staging/src/kubesphere.io/api/iam/v1beta1/types.go
Normal file
@@ -0,0 +1,291 @@
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
UserReferenceLabel = "iam.kubesphere.io/user-ref"
|
||||
ResourcesPluralUser = "users"
|
||||
)
|
||||
|
||||
// CategorySpec defines the desired state of Category
|
||||
type CategorySpec struct {
|
||||
DisplayName map[string]string `json:"displayName,omitempty"`
|
||||
Description map[string]string `json:"description,omitempty"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// Category is the Schema for the categories API
|
||||
type Category struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec CategorySpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// CategoryList contains a list of Category
|
||||
type CategoryList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Category `json:"items"`
|
||||
}
|
||||
|
||||
// AggregationRoleTemplates indicates which roleTemplate the role is composed of.
|
||||
// If the aggregation selector is not empty, the templateNames will be overwritten by the templates list by selector.
|
||||
type AggregationRoleTemplates struct {
|
||||
// TemplateNames select rules from RoleTemplate`s rules by RoleTemplate name
|
||||
TemplateNames []string `json:"templateNames,omitempty"`
|
||||
|
||||
// Selector select rules from RoleTemplate`s rules by labels
|
||||
Selector metav1.LabelSelector `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// GlobalRole is the Schema for the globalroles API
|
||||
type GlobalRole struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// AggregationRoleTemplates means which RoleTemplates are composed this Role
|
||||
AggregationRoleTemplates AggregationRoleTemplates `json:"aggregationRoleTemplates,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this WorkspaceRole
|
||||
Rules []rbacv1.PolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
|
||||
// GlobalRoleList contains a list of GlobalRole
|
||||
type GlobalRoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []GlobalRole `json:"items"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
|
||||
// GlobalRoleBinding is the Schema for the globalrolebindings API
|
||||
type GlobalRoleBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Subjects holds references to the objects the role applies to.
|
||||
// +optional
|
||||
Subjects []rbacv1.Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"`
|
||||
|
||||
// RoleRef can only reference a GlobalRole.
|
||||
// If the RoleRef cannot be resolved, the Authorizer must return an error.
|
||||
RoleRef rbacv1.RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// GlobalRoleBindingList contains a list of GlobalRoleBinding
|
||||
type GlobalRoleBindingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []GlobalRoleBinding `json:"items"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
//+kubebuilder:printcolumn:name="Workspace",type="string",JSONPath=".metadata.labels.kubesphere\\.io/workspace"
|
||||
//+kubebuilder:printcolumn:name="Alias",type="string",JSONPath=".metadata.annotations.kubesphere\\.io/alias-name"
|
||||
|
||||
// WorkspaceRole is the Schema for the workspaceroles API
|
||||
type WorkspaceRole struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// AggregationRoleTemplates means which RoleTemplates are composed this Role
|
||||
AggregationRoleTemplates AggregationRoleTemplates `json:"aggregationRoleTemplates,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this WorkspaceRole
|
||||
Rules []rbacv1.PolicyRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// WorkspaceRoleList contains a list of WorkspaceRole
|
||||
type WorkspaceRoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []WorkspaceRole `json:"items"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:printcolumn:name="Workspace",type="string",JSONPath=".metadata.labels.kubesphere\\.io/workspace"
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
|
||||
// WorkspaceRoleBinding is the Schema for the workspacerolebindings API
|
||||
type WorkspaceRoleBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Subjects holds references to the objects the role applies to.
|
||||
// +optional
|
||||
Subjects []rbacv1.Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"`
|
||||
|
||||
// RoleRef can only reference a WorkspaceRole.
|
||||
// If the RoleRef cannot be resolved, the Authorizer must return an error.
|
||||
RoleRef rbacv1.RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
|
||||
// WorkspaceRoleBindingList contains a list of WorkspaceRoleBinding
|
||||
type WorkspaceRoleBindingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []WorkspaceRoleBinding `json:"items"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Namespaced
|
||||
|
||||
// Role is the Schema for the roles API
|
||||
type Role struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// AggregationRoleTemplates means which RoleTemplates are composed this Role
|
||||
AggregationRoleTemplates AggregationRoleTemplates `json:"aggregationRoleTemplates,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this WorkspaceRole
|
||||
Rules []rbacv1.PolicyRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Namespaced
|
||||
|
||||
// RoleList contains a list of Role
|
||||
type RoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Role `json:"items"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Namespaced
|
||||
|
||||
type RoleBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Subjects holds references to the objects the role applies to.
|
||||
// +optional
|
||||
Subjects []rbacv1.Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"`
|
||||
|
||||
// RoleRef can only reference a WorkspaceRole.
|
||||
// If the RoleRef cannot be resolved, the Authorizer must return an error.
|
||||
RoleRef rbacv1.RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Namespaced
|
||||
|
||||
type RoleBindingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []RoleBinding `json:"items"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// ClusterRole is the Schema for the clusterroles API
|
||||
type ClusterRole struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// AggregationRoleTemplates means which RoleTemplates are composed this Role
|
||||
AggregationRoleTemplates AggregationRoleTemplates `json:"aggregationRoleTemplates,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this WorkspaceRole
|
||||
Rules []rbacv1.PolicyRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// ClusterRoleList contains a list of ClusterRole
|
||||
type ClusterRoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ClusterRole `json:"items"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
type ClusterRoleBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Subjects holds references to the objects the role applies to.
|
||||
// +optional
|
||||
Subjects []rbacv1.Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"`
|
||||
|
||||
// RoleRef can only reference a WorkspaceRole.
|
||||
// If the RoleRef cannot be resolved, the Authorizer must return an error.
|
||||
RoleRef rbacv1.RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
type ClusterRoleBindingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ClusterRoleBinding `json:"items"`
|
||||
}
|
||||
|
||||
// RoleTemplateSpec defines the desired state of RoleTemplate
|
||||
type RoleTemplateSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
// DisplayName represent the name displays at console, this field
|
||||
DisplayName map[string]string `json:"displayName,omitempty"`
|
||||
Description map[string]string `json:"description,omitempty"`
|
||||
Rules []rbacv1.PolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:categories=iam,scope=Cluster
|
||||
// +kubebuilder:storageversion
|
||||
// RoleTemplate is the Schema for the roletemplates API
|
||||
type RoleTemplate struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec RoleTemplateSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
|
||||
// RoleTemplateList contains a list of RoleTemplate
|
||||
type RoleTemplateList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []RoleTemplate `json:"items"`
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
Copyright 2023.
|
||||
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/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.
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:resource:categories=iam,scope=Cluster
|
||||
//+kubebuilder:printcolumn:name="Workspace",type="string",JSONPath=".metadata.labels.kubesphere\\.io/workspace"
|
||||
//+kubebuilder:printcolumn:name="Alias",type="string",JSONPath=".metadata.annotations.kubesphere\\.io/alias-name"
|
||||
|
||||
// WorkspaceRole is the Schema for the workspaceroles API
|
||||
type WorkspaceRole struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// AggregationRoleTemplates means which RoleTemplates are composed this Role
|
||||
AggregationRoleTemplates AggregationRoleTemplates `json:"aggregationRoleTemplates,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this WorkspaceRole
|
||||
Rules rbacv1.PolicyRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// WorkspaceRoleList contains a list of WorkspaceRole
|
||||
type WorkspaceRoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []WorkspaceRole `json:"items"`
|
||||
}
|
||||
@@ -23,7 +23,7 @@ package v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/api/rbac/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
@@ -140,7 +140,13 @@ func (in *ClusterRole) DeepCopyInto(out *ClusterRole) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.AggregationRoleTemplates.DeepCopyInto(&out.AggregationRoleTemplates)
|
||||
in.Rules.DeepCopyInto(&out.Rules)
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]v1.PolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRole.
|
||||
@@ -161,6 +167,69 @@ func (in *ClusterRole) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterRoleBinding) DeepCopyInto(out *ClusterRoleBinding) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
if in.Subjects != nil {
|
||||
in, out := &in.Subjects, &out.Subjects
|
||||
*out = make([]v1.Subject, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.RoleRef = in.RoleRef
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRoleBinding.
|
||||
func (in *ClusterRoleBinding) DeepCopy() *ClusterRoleBinding {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterRoleBinding)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterRoleBinding) 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 *ClusterRoleBindingList) DeepCopyInto(out *ClusterRoleBindingList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ClusterRoleBinding, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRoleBindingList.
|
||||
func (in *ClusterRoleBindingList) DeepCopy() *ClusterRoleBindingList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterRoleBindingList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterRoleBindingList) 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 *ClusterRoleList) DeepCopyInto(out *ClusterRoleList) {
|
||||
*out = *in
|
||||
@@ -199,7 +268,13 @@ func (in *GlobalRole) DeepCopyInto(out *GlobalRole) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.AggregationRoleTemplates.DeepCopyInto(&out.AggregationRoleTemplates)
|
||||
in.Rules.DeepCopyInto(&out.Rules)
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]v1.PolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRole.
|
||||
@@ -220,6 +295,69 @@ func (in *GlobalRole) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GlobalRoleBinding) DeepCopyInto(out *GlobalRoleBinding) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
if in.Subjects != nil {
|
||||
in, out := &in.Subjects, &out.Subjects
|
||||
*out = make([]v1.Subject, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.RoleRef = in.RoleRef
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRoleBinding.
|
||||
func (in *GlobalRoleBinding) DeepCopy() *GlobalRoleBinding {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(GlobalRoleBinding)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *GlobalRoleBinding) 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 *GlobalRoleBindingList) DeepCopyInto(out *GlobalRoleBindingList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]GlobalRoleBinding, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRoleBindingList.
|
||||
func (in *GlobalRoleBindingList) DeepCopy() *GlobalRoleBindingList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(GlobalRoleBindingList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *GlobalRoleBindingList) 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 *GlobalRoleList) DeepCopyInto(out *GlobalRoleList) {
|
||||
*out = *in
|
||||
@@ -258,7 +396,13 @@ func (in *Role) DeepCopyInto(out *Role) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.AggregationRoleTemplates.DeepCopyInto(&out.AggregationRoleTemplates)
|
||||
in.Rules.DeepCopyInto(&out.Rules)
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]v1.PolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Role.
|
||||
@@ -279,6 +423,69 @@ func (in *Role) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RoleBinding) DeepCopyInto(out *RoleBinding) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
if in.Subjects != nil {
|
||||
in, out := &in.Subjects, &out.Subjects
|
||||
*out = make([]v1.Subject, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.RoleRef = in.RoleRef
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleBinding.
|
||||
func (in *RoleBinding) DeepCopy() *RoleBinding {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RoleBinding)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *RoleBinding) 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 *RoleBindingList) DeepCopyInto(out *RoleBindingList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]RoleBinding, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleBindingList.
|
||||
func (in *RoleBindingList) DeepCopy() *RoleBindingList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RoleBindingList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *RoleBindingList) 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 *RoleList) DeepCopyInto(out *RoleList) {
|
||||
*out = *in
|
||||
@@ -411,7 +618,13 @@ func (in *WorkspaceRole) DeepCopyInto(out *WorkspaceRole) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.AggregationRoleTemplates.DeepCopyInto(&out.AggregationRoleTemplates)
|
||||
in.Rules.DeepCopyInto(&out.Rules)
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]v1.PolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceRole.
|
||||
@@ -432,6 +645,69 @@ func (in *WorkspaceRole) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkspaceRoleBinding) DeepCopyInto(out *WorkspaceRoleBinding) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
if in.Subjects != nil {
|
||||
in, out := &in.Subjects, &out.Subjects
|
||||
*out = make([]v1.Subject, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.RoleRef = in.RoleRef
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceRoleBinding.
|
||||
func (in *WorkspaceRoleBinding) DeepCopy() *WorkspaceRoleBinding {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkspaceRoleBinding)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WorkspaceRoleBinding) 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 *WorkspaceRoleBindingList) DeepCopyInto(out *WorkspaceRoleBindingList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]WorkspaceRoleBinding, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceRoleBindingList.
|
||||
func (in *WorkspaceRoleBindingList) DeepCopy() *WorkspaceRoleBindingList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkspaceRoleBindingList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WorkspaceRoleBindingList) 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 *WorkspaceRoleList) DeepCopyInto(out *WorkspaceRoleList) {
|
||||
*out = *in
|
||||
|
||||
Reference in New Issue
Block a user