@@ -66,6 +66,7 @@ func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
|
||||
s.GenericServerRunOptions.AddFlags(fs, s.GenericServerRunOptions)
|
||||
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), s.KubernetesOptions)
|
||||
s.AuthenticationOptions.AddFlags(fss.FlagSet("authentication"), s.AuthenticationOptions)
|
||||
s.AuthorizationOptions.AddFlags(fss.FlagSet("authorization"), s.AuthorizationOptions)
|
||||
s.DevopsOptions.AddFlags(fss.FlagSet("devops"), s.DevopsOptions)
|
||||
s.SonarQubeOptions.AddFlags(fss.FlagSet("sonarqube"), s.SonarQubeOptions)
|
||||
s.LdapOptions.AddFlags(fss.FlagSet("ldap"), s.LdapOptions)
|
||||
|
||||
@@ -15,6 +15,7 @@ func (s *ServerRunOptions) Validate() []error {
|
||||
errors = append(errors, s.OpenPitrixOptions.Validate()...)
|
||||
errors = append(errors, s.NetworkOptions.Validate()...)
|
||||
errors = append(errors, s.LoggingOptions.Validate()...)
|
||||
errors = append(errors, s.AuthorizationOptions.Validate()...)
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
@@ -6,28 +6,17 @@ metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: (devel)
|
||||
creationTimestamp: null
|
||||
name: rolebindings.iam.kubesphere.io
|
||||
name: globalrolebindings.iam.kubesphere.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .scope
|
||||
name: Scope
|
||||
type: string
|
||||
- JSONPath: .roleRef.name
|
||||
name: RoleRef
|
||||
type: string
|
||||
- JSONPath: .subjects[*].name
|
||||
name: Subjects
|
||||
type: string
|
||||
group: iam.kubesphere.io
|
||||
names:
|
||||
categories:
|
||||
- iam
|
||||
kind: RoleBinding
|
||||
listKind: RoleBindingList
|
||||
plural: rolebindings
|
||||
singular: rolebinding
|
||||
kind: GlobalRoleBinding
|
||||
listKind: GlobalRoleBindingList
|
||||
plural: globalrolebindings
|
||||
singular: globalrolebinding
|
||||
scope: Cluster
|
||||
subresources: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: RoleBinding is the Schema for the rolebindings API
|
||||
@@ -43,10 +32,11 @@ spec:
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
description: Standard object's metadata.
|
||||
type: object
|
||||
roleRef:
|
||||
description: RoleRef contains information that points to the role being
|
||||
used
|
||||
description: RoleRef can only reference a ClusterRole in the global namespace.
|
||||
If the RoleRef cannot be resolved, the Authorizer must return an error.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup is the group for the resource being referenced
|
||||
@@ -62,15 +52,17 @@ spec:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
scope:
|
||||
type: string
|
||||
subjects:
|
||||
description: Subjects holds references to the users the role applies to.
|
||||
description: Subjects holds references to the objects the role applies to.
|
||||
items:
|
||||
description: or a value for non-objects such as user and group names.
|
||||
description: Subject contains a reference to the object or user identities
|
||||
a role binding applies to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of the referenced subject.
|
||||
Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced. Values defined by this
|
||||
@@ -81,15 +73,18 @@ spec:
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If the object kind
|
||||
is non-namespace, such as "User" or "Group", and this value is not
|
||||
empty the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- apiGroup
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- roleRef
|
||||
- scope
|
||||
type: object
|
||||
version: v1alpha2
|
||||
versions:
|
||||
156
config/crds/iam.kubesphere.io_globalroles.yaml
generated
Normal file
156
config/crds/iam.kubesphere.io_globalroles.yaml
generated
Normal file
@@ -0,0 +1,156 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: (devel)
|
||||
creationTimestamp: null
|
||||
name: globalroles.iam.kubesphere.io
|
||||
spec:
|
||||
group: iam.kubesphere.io
|
||||
names:
|
||||
categories:
|
||||
- iam
|
||||
kind: GlobalRole
|
||||
listKind: GlobalRoleList
|
||||
plural: globalroles
|
||||
singular: globalrole
|
||||
scope: Cluster
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
aggregationRule:
|
||||
description: AggregationRule is an optional field that describes how to
|
||||
build the Rules for this GlobalRole. If AggregationRule is set, then the
|
||||
Rules are controller managed and direct changes to Rules will be stomped
|
||||
by the controller.
|
||||
properties:
|
||||
roleSelectors:
|
||||
description: ClusterRoleSelectors holds a list of selectors which will
|
||||
be used to find ClusterRoles and create the rules. If any of the selectors
|
||||
match, then the ClusterRole's permissions will be added
|
||||
items:
|
||||
description: A label selector is a label query over a set of resources.
|
||||
The result of matchLabels and matchExpressions are ANDed. An empty
|
||||
label selector matches all objects. A null label selector matches
|
||||
no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that
|
||||
contains values, a key, and an operator that relates the key
|
||||
and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to
|
||||
a set of values. Valid operators are In, NotIn, Exists
|
||||
and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the
|
||||
operator is In or NotIn, the values array must be non-empty.
|
||||
If the operator is Exists or DoesNotExist, the values
|
||||
array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator
|
||||
is "In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
description: Standard object's metadata.
|
||||
type: object
|
||||
rules:
|
||||
description: Rules holds all the PolicyRules for this ClusterRole
|
||||
items:
|
||||
description: PolicyRule holds information that describes a policy rule,
|
||||
but does not contain information about who the rule applies to or which
|
||||
namespace the rule applies to.
|
||||
properties:
|
||||
apiGroups:
|
||||
description: APIGroups is the name of the APIGroup that contains the
|
||||
resources. If multiple API groups are specified, any action requested
|
||||
against one of the enumerated resources in any API group will be
|
||||
allowed.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
nonResourceURLs:
|
||||
description: NonResourceURLs is a set of partial urls that a user
|
||||
should have access to. *s are allowed, but only as the full, final
|
||||
step in the path Since non-resource URLs are not namespaced, this
|
||||
field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
|
||||
Rules can either apply to API resources (such as "pods" or "secrets")
|
||||
or non-resource URL paths (such as "/api"), but not both.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resourceNames:
|
||||
description: ResourceNames is an optional white list of names that
|
||||
the rule applies to. An empty set means that everything is allowed.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: Resources is a list of resources this rule applies to. ResourceAll
|
||||
represents all resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
verbs:
|
||||
description: Verbs is a list of Verbs that apply to ALL the ResourceKinds
|
||||
and AttributeRestrictions contained in this rule. VerbAll represents
|
||||
all kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- verbs
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- rules
|
||||
type: object
|
||||
version: v1alpha2
|
||||
versions:
|
||||
- name: v1alpha2
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
58
config/crds/iam.kubesphere.io_policyrules.yaml
generated
58
config/crds/iam.kubesphere.io_policyrules.yaml
generated
@@ -1,58 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: (devel)
|
||||
creationTimestamp: null
|
||||
name: policyrules.iam.kubesphere.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .scope
|
||||
name: Scope
|
||||
type: string
|
||||
group: iam.kubesphere.io
|
||||
names:
|
||||
categories:
|
||||
- iam
|
||||
kind: PolicyRule
|
||||
listKind: PolicyRuleList
|
||||
plural: policyrules
|
||||
singular: policyrule
|
||||
scope: Cluster
|
||||
subresources: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
rego:
|
||||
type: string
|
||||
scope:
|
||||
type: string
|
||||
required:
|
||||
- rego
|
||||
- scope
|
||||
type: object
|
||||
version: v1alpha2
|
||||
versions:
|
||||
- name: v1alpha2
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
87
config/crds/iam.kubesphere.io_roles.yaml
generated
87
config/crds/iam.kubesphere.io_roles.yaml
generated
@@ -1,87 +0,0 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: (devel)
|
||||
creationTimestamp: null
|
||||
name: roles.iam.kubesphere.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .target.scope
|
||||
name: Scope
|
||||
type: string
|
||||
- JSONPath: .target.name
|
||||
name: Target
|
||||
type: string
|
||||
group: iam.kubesphere.io
|
||||
names:
|
||||
categories:
|
||||
- iam
|
||||
kind: Role
|
||||
listKind: RoleList
|
||||
plural: roles
|
||||
singular: role
|
||||
scope: Cluster
|
||||
subresources: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
rules:
|
||||
items:
|
||||
description: RuleRef contains information that points to the role being
|
||||
used
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup is the group for the resource being referenced
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is the type of resource being referenced
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of resource being referenced
|
||||
type: string
|
||||
required:
|
||||
- apiGroup
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
target:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
scope:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- scope
|
||||
type: object
|
||||
required:
|
||||
- rules
|
||||
- target
|
||||
type: object
|
||||
version: v1alpha2
|
||||
versions:
|
||||
- name: v1alpha2
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
2
config/crds/iam.kubesphere.io_users.yaml
generated
2
config/crds/iam.kubesphere.io_users.yaml
generated
@@ -40,6 +40,7 @@ spec:
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
description: Standard object's metadata.
|
||||
type: object
|
||||
spec:
|
||||
description: UserSpec defines the desired state of User
|
||||
@@ -66,6 +67,7 @@ spec:
|
||||
description: The preferred written or spoken language for the user.
|
||||
type: string
|
||||
password:
|
||||
description: password will be encrypted by mutating admission webhook
|
||||
type: string
|
||||
required:
|
||||
- email
|
||||
|
||||
103
config/crds/iam.kubesphere.io_workspacerolebindings.yaml
generated
Normal file
103
config/crds/iam.kubesphere.io_workspacerolebindings.yaml
generated
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: (devel)
|
||||
creationTimestamp: null
|
||||
name: workspacerolebindings.iam.kubesphere.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .metadata.labels.kubesphere\.io/workspace
|
||||
name: Workspace
|
||||
type: string
|
||||
group: iam.kubesphere.io
|
||||
names:
|
||||
categories:
|
||||
- iam
|
||||
kind: WorkspaceRoleBinding
|
||||
listKind: WorkspaceRoleBindingList
|
||||
plural: workspacerolebindings
|
||||
singular: workspacerolebinding
|
||||
scope: Cluster
|
||||
subresources: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: RoleBinding is the Schema for the rolebindings API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
roleRef:
|
||||
description: RoleRef can only reference a ClusterRole in the global namespace.
|
||||
If the RoleRef cannot be resolved, the Authorizer must return an error.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup is the group for the resource being referenced
|
||||
type: string
|
||||
kind:
|
||||
description: Kind is the type of resource being referenced
|
||||
type: string
|
||||
name:
|
||||
description: Name is the name of resource being referenced
|
||||
type: string
|
||||
required:
|
||||
- apiGroup
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
subjects:
|
||||
description: Subjects holds references to the objects the role applies to.
|
||||
items:
|
||||
description: Subject contains a reference to the object or user identities
|
||||
a role binding applies to. This can either hold a direct API object
|
||||
reference, or a value for non-objects such as user and group names.
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup holds the API group of the referenced subject.
|
||||
Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
|
||||
for User and Group subjects.
|
||||
type: string
|
||||
kind:
|
||||
description: Kind of object being referenced. Values defined by this
|
||||
API group are "User", "Group", and "ServiceAccount". If the Authorizer
|
||||
does not recognized the kind value, the Authorizer should report
|
||||
an error.
|
||||
type: string
|
||||
name:
|
||||
description: Name of the object being referenced.
|
||||
type: string
|
||||
namespace:
|
||||
description: Namespace of the referenced object. If the object kind
|
||||
is non-namespace, such as "User" or "Group", and this value is not
|
||||
empty the Authorizer should report an error.
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- roleRef
|
||||
type: object
|
||||
version: v1alpha2
|
||||
versions:
|
||||
- name: v1alpha2
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
164
config/crds/iam.kubesphere.io_workspaceroles.yaml
generated
Normal file
164
config/crds/iam.kubesphere.io_workspaceroles.yaml
generated
Normal file
@@ -0,0 +1,164 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: (devel)
|
||||
creationTimestamp: null
|
||||
name: workspaceroles.iam.kubesphere.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .metadata.labels.kubesphere\.io/workspace
|
||||
name: Workspace
|
||||
type: string
|
||||
- JSONPath: .metadata.labels.kubesphere\.io/alias-name
|
||||
name: Alias
|
||||
type: string
|
||||
group: iam.kubesphere.io
|
||||
names:
|
||||
categories:
|
||||
- iam
|
||||
kind: WorkspaceRole
|
||||
listKind: WorkspaceRoleList
|
||||
plural: workspaceroles
|
||||
singular: workspacerole
|
||||
scope: Cluster
|
||||
subresources: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
aggregationRule:
|
||||
description: AggregationRule is an optional field that describes how to
|
||||
build the Rules for this WorkspaceRole. If AggregationRule is set, then
|
||||
the Rules are controller managed and direct changes to Rules will be stomped
|
||||
by the controller.
|
||||
properties:
|
||||
roleSelectors:
|
||||
description: ClusterRoleSelectors holds a list of selectors which will
|
||||
be used to find ClusterRoles and create the rules. If any of the selectors
|
||||
match, then the ClusterRole's permissions will be added
|
||||
items:
|
||||
description: A label selector is a label query over a set of resources.
|
||||
The result of matchLabels and matchExpressions are ANDed. An empty
|
||||
label selector matches all objects. A null label selector matches
|
||||
no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that
|
||||
contains values, a key, and an operator that relates the key
|
||||
and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to
|
||||
a set of values. Valid operators are In, NotIn, Exists
|
||||
and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the
|
||||
operator is In or NotIn, the values array must be non-empty.
|
||||
If the operator is Exists or DoesNotExist, the values
|
||||
array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator
|
||||
is "In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
description: Standard object's metadata.
|
||||
type: object
|
||||
rules:
|
||||
description: Rules holds all the PolicyRules for this ClusterRole
|
||||
items:
|
||||
description: PolicyRule holds information that describes a policy rule,
|
||||
but does not contain information about who the rule applies to or which
|
||||
namespace the rule applies to.
|
||||
properties:
|
||||
apiGroups:
|
||||
description: APIGroups is the name of the APIGroup that contains the
|
||||
resources. If multiple API groups are specified, any action requested
|
||||
against one of the enumerated resources in any API group will be
|
||||
allowed.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
nonResourceURLs:
|
||||
description: NonResourceURLs is a set of partial urls that a user
|
||||
should have access to. *s are allowed, but only as the full, final
|
||||
step in the path Since non-resource URLs are not namespaced, this
|
||||
field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
|
||||
Rules can either apply to API resources (such as "pods" or "secrets")
|
||||
or non-resource URL paths (such as "/api"), but not both.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resourceNames:
|
||||
description: ResourceNames is an optional white list of names that
|
||||
the rule applies to. An empty set means that everything is allowed.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
description: Resources is a list of resources this rule applies to. ResourceAll
|
||||
represents all resources.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
verbs:
|
||||
description: Verbs is a list of Verbs that apply to ALL the ResourceKinds
|
||||
and AttributeRestrictions contained in this rule. VerbAll represents
|
||||
all kinds.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- verbs
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- rules
|
||||
type: object
|
||||
version: v1alpha2
|
||||
versions:
|
||||
- name: v1alpha2
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
14
config/samples/iam_v1alpha2_globalrole.yaml
Normal file
14
config/samples/iam_v1alpha2_globalrole.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: iam.kubesphere.io/v1alpha2
|
||||
kind: GlobalRole
|
||||
metadata:
|
||||
labels:
|
||||
controller-tools.k8s.io: "1.0"
|
||||
name: global-admin
|
||||
rules:
|
||||
- apiGroups:
|
||||
- '*'
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
apiVersion: iam.kubesphere.io/v1alpha2
|
||||
kind: RoleBinding
|
||||
kind: GlobalRoleBinding
|
||||
metadata:
|
||||
labels:
|
||||
controller-tools.k8s.io: "1.0"
|
||||
name: cluster-admin
|
||||
scope: Global
|
||||
name: admin
|
||||
roleRef:
|
||||
apiGroup: iam.kubesphere.io/v1alpha2
|
||||
kind: Role
|
||||
name: cluster-admin
|
||||
kind: GlobalRole
|
||||
name: global-admin
|
||||
subjects:
|
||||
- apiGroup: iam.kubesphere.io/v1alpha2
|
||||
kind: User
|
||||
@@ -1,55 +0,0 @@
|
||||
apiVersion: iam.kubesphere.io/v1alpha2
|
||||
kind: PolicyRule
|
||||
metadata:
|
||||
labels:
|
||||
controller-tools.k8s.io: "1.0"
|
||||
name: always-allow
|
||||
scope: Global
|
||||
rego: 'package authz\ndefault allow = true'
|
||||
|
||||
---
|
||||
|
||||
apiVersion: iam.kubesphere.io/v1alpha2
|
||||
kind: PolicyRule
|
||||
metadata:
|
||||
labels:
|
||||
controller-tools.k8s.io: "1.0"
|
||||
name: always-deny
|
||||
scope: Global
|
||||
rego: |
|
||||
package authz
|
||||
default allow = false
|
||||
|
||||
---
|
||||
|
||||
apiVersion: iam.kubesphere.io/v1alpha2
|
||||
kind: PolicyRule
|
||||
metadata:
|
||||
labels:
|
||||
controller-tools.k8s.io: "1.0"
|
||||
name: cluster-manage
|
||||
scope: Global
|
||||
rego: |
|
||||
package authz
|
||||
default allow = false
|
||||
allow {
|
||||
input.Resource == 'clusters'
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
apiVersion: iam.kubesphere.io/v1alpha2
|
||||
kind: PolicyRule
|
||||
metadata:
|
||||
labels:
|
||||
controller-tools.k8s.io: "1.0"
|
||||
name: some-namespace-manage
|
||||
scope: Namespace
|
||||
rego: |
|
||||
package authz
|
||||
default allow = false
|
||||
allow {
|
||||
input.Resource == 'clusters'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
apiVersion: iam.kubesphere.io/v1alpha2
|
||||
kind: Role
|
||||
metadata:
|
||||
labels:
|
||||
controller-tools.k8s.io: "1.0"
|
||||
name: cluster-admin
|
||||
target:
|
||||
scope: Global
|
||||
name: ''
|
||||
rules:
|
||||
- apiGroup: iam.kubesphere.io/v1alpha2
|
||||
kind: PolicyRule
|
||||
name: always-allow
|
||||
|
||||
---
|
||||
|
||||
apiVersion: iam.kubesphere.io/v1alpha2
|
||||
kind: Role
|
||||
metadata:
|
||||
labels:
|
||||
controller-tools.k8s.io: "1.0"
|
||||
name: anonymous
|
||||
target:
|
||||
scope: Global
|
||||
name: ''
|
||||
rules:
|
||||
- apiGroup: iam.kubesphere.io/v1alpha2
|
||||
kind: PolicyRule
|
||||
name: always-deny
|
||||
|
||||
25
go.mod
25
go.mod
@@ -81,7 +81,7 @@ require (
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478
|
||||
google.golang.org/grpc v1.23.1
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1 // indirect
|
||||
@@ -141,10 +141,8 @@ replace (
|
||||
github.com/bitly/go-simplejson => github.com/bitly/go-simplejson v0.5.0
|
||||
github.com/blang/semver => github.com/blang/semver v3.5.0+incompatible
|
||||
github.com/bmizerany/assert => github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869
|
||||
github.com/cenkalti/backoff => github.com/cenkalti/backoff v2.2.1+incompatible
|
||||
github.com/cespare/xxhash => github.com/cespare/xxhash v1.1.0
|
||||
github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
|
||||
github.com/cheekybits/genny => github.com/cheekybits/genny v1.0.0
|
||||
github.com/client9/misspell => github.com/client9/misspell v0.3.4
|
||||
github.com/coreos/bbolt => github.com/coreos/bbolt v1.3.3
|
||||
github.com/coreos/etcd => github.com/coreos/etcd v3.3.17+incompatible
|
||||
@@ -158,14 +156,12 @@ replace (
|
||||
github.com/deckarep/golang-set => github.com/deckarep/golang-set v1.7.1
|
||||
github.com/denisenkom/go-mssqldb => github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289
|
||||
github.com/dgrijalva/jwt-go => github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/dgryski/go-sip13 => github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954
|
||||
github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker => github.com/docker/engine v1.4.2-0.20190822205725-ed20165a37b4
|
||||
github.com/docker/go-connections => github.com/docker/go-connections v0.3.0
|
||||
github.com/docker/go-units => github.com/docker/go-units v0.3.3
|
||||
github.com/docker/spdystream => github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c
|
||||
github.com/docopt/docopt-go => github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||
github.com/dustin/go-humanize => github.com/dustin/go-humanize v1.0.0
|
||||
github.com/elastic/go-elasticsearch/v5 => github.com/elastic/go-elasticsearch/v5 v5.6.1
|
||||
github.com/elastic/go-elasticsearch/v6 => github.com/elastic/go-elasticsearch/v6 v6.8.2
|
||||
github.com/elastic/go-elasticsearch/v7 => github.com/elastic/go-elasticsearch/v7 v7.3.0
|
||||
@@ -185,7 +181,6 @@ replace (
|
||||
github.com/ghodss/yaml => github.com/ghodss/yaml v1.0.0
|
||||
github.com/gliderlabs/ssh => github.com/gliderlabs/ssh v0.1.1
|
||||
github.com/globalsign/mgo => github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8
|
||||
github.com/go-acme/lego => github.com/go-acme/lego v2.5.0+incompatible
|
||||
github.com/go-kit/kit => github.com/go-kit/kit v0.8.0
|
||||
github.com/go-ldap/ldap => github.com/go-ldap/ldap v3.0.3+incompatible
|
||||
github.com/go-logfmt/logfmt => github.com/go-logfmt/logfmt v0.4.0
|
||||
@@ -238,7 +233,6 @@ replace (
|
||||
github.com/grpc-ecosystem/go-grpc-middleware => github.com/grpc-ecosystem/go-grpc-middleware v1.0.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus => github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.9.6
|
||||
github.com/hashicorp/go-syslog => github.com/hashicorp/go-syslog v1.0.0
|
||||
github.com/hashicorp/go-version => github.com/hashicorp/go-version v1.2.0
|
||||
github.com/hashicorp/golang-lru => github.com/hashicorp/golang-lru v0.5.3
|
||||
github.com/hashicorp/hcl => github.com/hashicorp/hcl v1.0.0
|
||||
@@ -247,7 +241,6 @@ replace (
|
||||
github.com/inconshreveable/mousetrap => github.com/inconshreveable/mousetrap v1.0.0
|
||||
github.com/jbenet/go-context => github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
||||
github.com/jessevdk/go-flags => github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/jimstudt/http-authentication => github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a
|
||||
github.com/jinzhu/gorm => github.com/jinzhu/gorm v1.9.2
|
||||
github.com/jinzhu/inflection => github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a
|
||||
github.com/jinzhu/now => github.com/jinzhu/now v1.0.0
|
||||
@@ -263,7 +256,6 @@ replace (
|
||||
github.com/kiali/kiali => github.com/kubesphere/kiali v0.15.1-0.20191210080139-edbbad1ef779
|
||||
github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.2.0
|
||||
github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0
|
||||
github.com/klauspost/cpuid => github.com/klauspost/cpuid v1.2.1
|
||||
github.com/koding/multiconfig => github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7
|
||||
github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.2
|
||||
github.com/kr/logfmt => github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515
|
||||
@@ -271,26 +263,18 @@ replace (
|
||||
github.com/kr/pty => github.com/kr/pty v1.1.5
|
||||
github.com/kr/text => github.com/kr/text v0.1.0
|
||||
github.com/kubernetes-sigs/application => github.com/kubesphere/application v0.0.0-20191210100950-18cc93526ab4
|
||||
github.com/kubernetes-sigs/federation-v2 => github.com/kubernetes-sigs/federation-v2 v0.0.10
|
||||
github.com/kubesphere/s2ioperator => github.com/kubesphere/s2ioperator v0.0.14
|
||||
github.com/kubesphere/sonargo => github.com/kubesphere/sonargo v0.0.2
|
||||
github.com/kylelemons/godebug => github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348
|
||||
github.com/leodido/go-urn => github.com/leodido/go-urn v1.1.0
|
||||
github.com/lib/pq => github.com/lib/pq v1.2.0
|
||||
github.com/liggitt/tabwriter => github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
|
||||
github.com/lithammer/dedent => github.com/lithammer/dedent v1.1.0
|
||||
github.com/lucas-clemente/quic-go => github.com/lucas-clemente/quic-go v0.11.1
|
||||
github.com/magiconair/properties => github.com/magiconair/properties v1.8.0
|
||||
github.com/mailru/easyjson => github.com/mailru/easyjson v0.7.0
|
||||
github.com/marten-seemann/qtls => github.com/marten-seemann/qtls v0.2.3
|
||||
github.com/mattn/go-colorable => github.com/mattn/go-colorable v0.1.2
|
||||
github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.8
|
||||
github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.0-20181025052659-b20a3daf6a39
|
||||
github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.11.0
|
||||
github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.1
|
||||
github.com/mholt/caddy => github.com/mholt/caddy v1.0.0
|
||||
github.com/mholt/certmagic => github.com/mholt/certmagic v0.5.1
|
||||
github.com/miekg/dns => github.com/miekg/dns v1.1.9
|
||||
github.com/mitchellh/go-homedir => github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/go-wordwrap => github.com/mitchellh/go-wordwrap v1.0.0
|
||||
github.com/mitchellh/mapstructure => github.com/mitchellh/mapstructure v1.1.2
|
||||
@@ -301,9 +285,6 @@ replace (
|
||||
github.com/munnerz/goautoneg => github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d
|
||||
github.com/mwitkow/go-conntrack => github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223
|
||||
github.com/mxk/go-flowrate => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
||||
github.com/naoina/go-stringutil => github.com/naoina/go-stringutil v0.1.0
|
||||
github.com/naoina/toml => github.com/naoina/toml v0.1.1
|
||||
github.com/oklog/ulid => github.com/oklog/ulid v1.3.1
|
||||
github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.1
|
||||
github.com/onsi/ginkgo => github.com/onsi/ginkgo v1.8.0
|
||||
github.com/onsi/gomega => github.com/onsi/gomega v1.5.0
|
||||
@@ -311,7 +292,6 @@ replace (
|
||||
github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0-rc1
|
||||
github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/openshift/api => github.com/openshift/api v0.0.0-20180801171038-322a19404e37
|
||||
github.com/openshift/build-machinery-go => github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160
|
||||
github.com/openshift/generic-admission-server => github.com/openshift/generic-admission-server v1.14.0
|
||||
github.com/opentracing/opentracing-go => github.com/opentracing/opentracing-go v1.1.0
|
||||
github.com/pborman/uuid => github.com/pborman/uuid v1.2.0
|
||||
@@ -333,7 +313,6 @@ replace (
|
||||
github.com/prometheus/common => github.com/prometheus/common v0.4.0
|
||||
github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.2
|
||||
github.com/prometheus/prometheus => github.com/prometheus/prometheus v1.8.2
|
||||
github.com/prometheus/tsdb => github.com/prometheus/tsdb v0.7.1
|
||||
github.com/rcrowley/go-metrics => github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a
|
||||
github.com/remyoudompheng/bigfft => github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446
|
||||
github.com/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af
|
||||
@@ -400,7 +379,6 @@ replace (
|
||||
gopkg.in/go-playground/assert.v1 => gopkg.in/go-playground/assert.v1 v1.2.1
|
||||
gopkg.in/go-playground/validator.v9 => gopkg.in/go-playground/validator.v9 v9.29.1
|
||||
gopkg.in/inf.v0 => gopkg.in/inf.v0 v0.9.1
|
||||
gopkg.in/mcuadros/go-syslog.v2 => gopkg.in/mcuadros/go-syslog.v2 v2.2.1
|
||||
gopkg.in/natefinch/lumberjack.v2 => gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/resty.v1 => gopkg.in/resty.v1 v1.12.0
|
||||
gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.3.1
|
||||
@@ -424,7 +402,6 @@ replace (
|
||||
k8s.io/apiserver => k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682
|
||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.17.3
|
||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20191114101535-6c5935290e33
|
||||
k8s.io/cluster-registry => k8s.io/cluster-registry v0.0.6
|
||||
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894
|
||||
k8s.io/component-base => k8s.io/component-base v0.0.0-20191114102325-35a9586014f7
|
||||
k8s.io/gengo => k8s.io/gengo v0.0.0-20191120174120-e74f70b9b27e
|
||||
|
||||
@@ -51,12 +51,14 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&User{},
|
||||
&UserList{},
|
||||
&Role{},
|
||||
&RoleList{},
|
||||
&RoleBinding{},
|
||||
&RoleBindingList{},
|
||||
&PolicyRule{},
|
||||
&PolicyRuleList{},
|
||||
&GlobalRole{},
|
||||
&GlobalRoleList{},
|
||||
&GlobalRoleBinding{},
|
||||
&GlobalRoleBindingList{},
|
||||
&WorkspaceRole{},
|
||||
&WorkspaceRoleList{},
|
||||
&WorkspaceRoleBinding{},
|
||||
&WorkspaceRoleBindingList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
||||
@@ -17,9 +17,39 @@ limitations under the License.
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
ResourceKindUser = "User"
|
||||
ResourcesSingularUser = "user"
|
||||
ResourcesPluralUser = "users"
|
||||
ResourceKindGlobalRoleBinding = "GlobalRoleBinding"
|
||||
ResourcesSingularGlobalRoleBinding = "globalrolebinding"
|
||||
ResourcesPluralGlobalRoleBinding = "globalrolebindings"
|
||||
ResourceKindGlobalRole = "GlobalRole"
|
||||
ResourcesSingularGlobalRole = "globalrole"
|
||||
ResourcesPluralGlobalRole = "globalroles"
|
||||
ResourceKindWorkspaceRoleBinding = "WorkspaceRoleBinding"
|
||||
ResourcesSingularWorkspaceRoleBinding = "workspacerolebinding"
|
||||
ResourcesPluralWorkspaceRoleBinding = "workspacerolebindings"
|
||||
ResourceKindWorkspaceRole = "WorkspaceRole"
|
||||
ResourcesSingularWorkspaceRole = "workspacerole"
|
||||
ResourcesPluralWorkspaceRole = "workspaceroles"
|
||||
ResourceKindClusterRole = "ClusterRole"
|
||||
ResourcesSingularClusterRole = "clusterrole"
|
||||
ResourcesPluralClusterRole = "clusterroles"
|
||||
ResourceKindRole = "Role"
|
||||
ResourcesSingularRole = "role"
|
||||
ResourcesPluralRole = "roles"
|
||||
RegoOverrideAnnotation = "iam.kubesphere.io/rego-override"
|
||||
GlobalScope = "Global"
|
||||
ClusterScope = "Cluster"
|
||||
WorkspaceScope = "Workspace"
|
||||
NamespaceScope = "Namespace"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@@ -30,7 +60,9 @@ import (
|
||||
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.state"
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
type User struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec UserSpec `json:"spec"`
|
||||
@@ -53,9 +85,9 @@ type UserSpec struct {
|
||||
// +optional
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
// +optional
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
EncryptedPassword string `json:"password"`
|
||||
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
// password will be encrypted by mutating admission webhook
|
||||
EncryptedPassword string `json:"password"`
|
||||
// Finalizers is an opaque list of values that must be empty to permanently remove object from storage.
|
||||
// +optional
|
||||
Finalizers []FinalizerName `json:"finalizers,omitempty"`
|
||||
@@ -102,7 +134,7 @@ type UserConditionType string
|
||||
// These are valid conditions of a user.
|
||||
const (
|
||||
// UserLoginFailure contains information about user login.
|
||||
UserLoginFailure UserConditionType = "UserLoginFailure"
|
||||
LoginFailure UserConditionType = "LoginFailure"
|
||||
)
|
||||
|
||||
type ConditionStatus string
|
||||
@@ -121,6 +153,8 @@ const (
|
||||
// UserList contains a list of User
|
||||
type UserList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []User `json:"items"`
|
||||
}
|
||||
@@ -129,128 +163,131 @@ type UserList struct {
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// +kubebuilder:printcolumn:name="Scope",type="string",JSONPath=".target.scope"
|
||||
// +kubebuilder:printcolumn:name="Target",type="string",JSONPath=".target.name"
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
type Role struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Target Target `json:"target"`
|
||||
Rules []RuleRef `json:"rules"`
|
||||
}
|
||||
|
||||
type Target struct {
|
||||
Scope Scope `json:"scope"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Scope string
|
||||
|
||||
const (
|
||||
GlobalScope Scope = "Global"
|
||||
ClusterScope Scope = "Cluster"
|
||||
WorkspaceScope Scope = "Workspace"
|
||||
NamespaceScope Scope = "Namespace"
|
||||
UserKind = "User"
|
||||
PolicyRuleKind = "PolicyRule"
|
||||
RoleKind = "Role"
|
||||
RoleBindingKind = "RoleBinding"
|
||||
)
|
||||
|
||||
// RuleRef contains information that points to the role being used
|
||||
type RuleRef struct {
|
||||
// APIGroup is the group for the resource being referenced
|
||||
APIGroup string `json:"apiGroup"`
|
||||
// Kind is the type of resource being referenced
|
||||
Kind string `json:"kind"`
|
||||
// Name is the name of resource being referenced
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// RoleList contains a list of Role
|
||||
type RoleList struct {
|
||||
type GlobalRole struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Role `json:"items"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// +kubebuilder:printcolumn:name="Scope",type="string",JSONPath=".scope"
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
type PolicyRule struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Scope Scope `json:"scope"`
|
||||
Rego string `json:"rego"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PolicyRuleList contains a list of PolicyRule
|
||||
type PolicyRuleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []PolicyRule `json:"items"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// RoleBinding is the Schema for the rolebindings API
|
||||
// +kubebuilder:printcolumn:name="Scope",type="string",JSONPath=".scope"
|
||||
// +kubebuilder:printcolumn:name="RoleRef",type="string",JSONPath=".roleRef.name"
|
||||
// +kubebuilder:printcolumn:name="Subjects",type="string",JSONPath=".subjects[*].name"
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
type RoleBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Scope Scope `json:"scope"`
|
||||
RoleRef RoleRef `json:"roleRef"`
|
||||
// Subjects holds references to the users the role applies to.
|
||||
// Standard object's metadata.
|
||||
// +optional
|
||||
Subjects []Subject `json:"subjects,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this ClusterRole
|
||||
Rules []rbacv1.PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"`
|
||||
|
||||
// AggregationRule is an optional field that describes how to build the Rules for this GlobalRole.
|
||||
// If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be
|
||||
// stomped by the controller.
|
||||
AggregationRule *AggregationRule `json:"aggregationRule,omitempty" protobuf:"bytes,3,opt,name=aggregationRule"`
|
||||
}
|
||||
|
||||
// RoleRef contains information that points to the role being used
|
||||
type RoleRef struct {
|
||||
// APIGroup is the group for the resource being referenced
|
||||
APIGroup string `json:"apiGroup"`
|
||||
// Kind is the type of resource being referenced
|
||||
Kind string `json:"kind"`
|
||||
// Name is the name of resource being referenced
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// or a value for non-objects such as user and group names.
|
||||
type Subject struct {
|
||||
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
|
||||
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
|
||||
Kind string `json:"kind"`
|
||||
// APIGroup holds the API group of the referenced subject.
|
||||
APIGroup string `json:"apiGroup"`
|
||||
// Name of the object being referenced.
|
||||
Name string `json:"name"`
|
||||
// AggregationRule describes how to locate ClusterRoles to aggregate into the ClusterRole
|
||||
type AggregationRule struct {
|
||||
// ClusterRoleSelectors holds a list of selectors which will be used to find ClusterRoles and create the rules.
|
||||
// If any of the selectors match, then the ClusterRole's permissions will be added
|
||||
// +optional
|
||||
RoleSelectors []metav1.LabelSelector `json:"roleSelectors,omitempty" protobuf:"bytes,1,rep,name=roleSelectors"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// RoleBindingList contains a list of RoleBinding
|
||||
type RoleBindingList struct {
|
||||
// GlobalRoleList contains a list of GlobalRole
|
||||
type GlobalRoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []RoleBinding `json:"items"`
|
||||
Items []GlobalRole `json:"items"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// GlobalRoleBinding is the Schema for the globalrolebindings API
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
type GlobalRoleBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// +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 ClusterRole in the global namespace.
|
||||
// If the RoleRef cannot be resolved, the Authorizer must return an error.
|
||||
RoleRef rbacv1.RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// +kubebuilder:printcolumn:name="Workspace",type="string",JSONPath=".metadata.labels.kubesphere\\.io/workspace"
|
||||
// +kubebuilder:printcolumn:name="Alias",type="string",JSONPath=".metadata.labels.kubesphere\\.io/alias-name"
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
type WorkspaceRole struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Rules holds all the PolicyRules for this ClusterRole
|
||||
Rules []rbacv1.PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"`
|
||||
// AggregationRule is an optional field that describes how to build the Rules for this WorkspaceRole.
|
||||
// If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be
|
||||
// stomped by the controller.
|
||||
AggregationRule *AggregationRule `json:"aggregationRule,omitempty" protobuf:"bytes,3,opt,name=aggregationRule"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// WorkspaceRoleList contains a list of WorkspaceRole
|
||||
type WorkspaceRoleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []WorkspaceRole `json:"items"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// WorkspaceRoleBinding is the Schema for the workspacerolebindings API
|
||||
// +kubebuilder:printcolumn:name="Workspace",type="string",JSONPath=".metadata.labels.kubesphere\\.io/workspace"
|
||||
// +kubebuilder:resource:categories="iam",scope="Cluster"
|
||||
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 ClusterRole in the global namespace.
|
||||
// If the RoleRef cannot be resolved, the Authorizer must return an error.
|
||||
RoleRef rbacv1.RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// WorkspaceRoleBindingList contains a list of WorkspaceRoleBinding
|
||||
type WorkspaceRoleBindingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []WorkspaceRoleBinding `json:"items"`
|
||||
}
|
||||
|
||||
type UserDetail struct {
|
||||
*User
|
||||
GlobalRole *Role `json:"globalRole"`
|
||||
GlobalRole *GlobalRole `json:"globalRole"`
|
||||
}
|
||||
|
||||
305
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
generated
305
pkg/apis/iam/v1alpha2/zz_generated.deepcopy.go
generated
@@ -21,91 +21,64 @@ limitations under the License.
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyRule) DeepCopyInto(out *PolicyRule) {
|
||||
func (in *AggregationRule) DeepCopyInto(out *AggregationRule) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyRule.
|
||||
func (in *PolicyRule) DeepCopy() *PolicyRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PolicyRule) 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 *PolicyRuleList) DeepCopyInto(out *PolicyRuleList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]PolicyRule, len(*in))
|
||||
if in.RoleSelectors != nil {
|
||||
in, out := &in.RoleSelectors, &out.RoleSelectors
|
||||
*out = make([]metav1.LabelSelector, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyRuleList.
|
||||
func (in *PolicyRuleList) DeepCopy() *PolicyRuleList {
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AggregationRule.
|
||||
func (in *AggregationRule) DeepCopy() *AggregationRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyRuleList)
|
||||
out := new(AggregationRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PolicyRuleList) 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 *Role) DeepCopyInto(out *Role) {
|
||||
func (in *GlobalRole) DeepCopyInto(out *GlobalRole) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Target = in.Target
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]RuleRef, len(*in))
|
||||
copy(*out, *in)
|
||||
*out = make([]v1.PolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.AggregationRule != nil {
|
||||
in, out := &in.AggregationRule, &out.AggregationRule
|
||||
*out = new(AggregationRule)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Role.
|
||||
func (in *Role) DeepCopy() *Role {
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRole.
|
||||
func (in *GlobalRole) DeepCopy() *GlobalRole {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Role)
|
||||
out := new(GlobalRole)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Role) DeepCopyObject() runtime.Object {
|
||||
func (in *GlobalRole) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
@@ -113,30 +86,30 @@ func (in *Role) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RoleBinding) DeepCopyInto(out *RoleBinding) {
|
||||
func (in *GlobalRoleBinding) DeepCopyInto(out *GlobalRoleBinding) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.RoleRef = in.RoleRef
|
||||
if in.Subjects != nil {
|
||||
in, out := &in.Subjects, &out.Subjects
|
||||
*out = make([]Subject, len(*in))
|
||||
*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 {
|
||||
// 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(RoleBinding)
|
||||
out := new(GlobalRoleBinding)
|
||||
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 {
|
||||
func (in *GlobalRoleBinding) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
@@ -144,31 +117,31 @@ func (in *RoleBinding) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RoleBindingList) DeepCopyInto(out *RoleBindingList) {
|
||||
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([]RoleBinding, len(*in))
|
||||
*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 RoleBindingList.
|
||||
func (in *RoleBindingList) DeepCopy() *RoleBindingList {
|
||||
// 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(RoleBindingList)
|
||||
out := new(GlobalRoleBindingList)
|
||||
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 {
|
||||
func (in *GlobalRoleBindingList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
@@ -176,97 +149,37 @@ func (in *RoleBindingList) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RoleList) DeepCopyInto(out *RoleList) {
|
||||
func (in *GlobalRoleList) DeepCopyInto(out *GlobalRoleList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Role, len(*in))
|
||||
*out = make([]GlobalRole, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleList.
|
||||
func (in *RoleList) DeepCopy() *RoleList {
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRoleList.
|
||||
func (in *GlobalRoleList) DeepCopy() *GlobalRoleList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RoleList)
|
||||
out := new(GlobalRoleList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *RoleList) DeepCopyObject() runtime.Object {
|
||||
func (in *GlobalRoleList) 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 *RoleRef) DeepCopyInto(out *RoleRef) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleRef.
|
||||
func (in *RoleRef) DeepCopy() *RoleRef {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RoleRef)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RuleRef) DeepCopyInto(out *RuleRef) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuleRef.
|
||||
func (in *RuleRef) DeepCopy() *RuleRef {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RuleRef)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Subject) DeepCopyInto(out *Subject) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subject.
|
||||
func (in *Subject) DeepCopy() *Subject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Subject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Target) DeepCopyInto(out *Target) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Target.
|
||||
func (in *Target) DeepCopy() *Target {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Target)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *User) DeepCopyInto(out *User) {
|
||||
*out = *in
|
||||
@@ -320,7 +233,7 @@ func (in *UserDetail) DeepCopyInto(out *UserDetail) {
|
||||
}
|
||||
if in.GlobalRole != nil {
|
||||
in, out := &in.GlobalRole, &out.GlobalRole
|
||||
*out = new(Role)
|
||||
*out = new(GlobalRole)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
@@ -413,3 +326,135 @@ func (in *UserStatus) DeepCopy() *UserStatus {
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkspaceRole) DeepCopyInto(out *WorkspaceRole) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
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])
|
||||
}
|
||||
}
|
||||
if in.AggregationRule != nil {
|
||||
in, out := &in.AggregationRule, &out.AggregationRule
|
||||
*out = new(AggregationRule)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceRole.
|
||||
func (in *WorkspaceRole) DeepCopy() *WorkspaceRole {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkspaceRole)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WorkspaceRole) 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 *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
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]WorkspaceRole, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceRoleList.
|
||||
func (in *WorkspaceRoleList) DeepCopy() *WorkspaceRoleList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkspaceRoleList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *WorkspaceRoleList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
179
pkg/apis/rbac/v1/evaluation_helpers.go
Normal file
179
pkg/apis/rbac/v1/evaluation_helpers.go
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes 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 v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func RoleRefGroupKind(roleRef rbacv1.RoleRef) schema.GroupKind {
|
||||
return schema.GroupKind{Group: roleRef.APIGroup, Kind: roleRef.Kind}
|
||||
}
|
||||
|
||||
func VerbMatches(rule *rbacv1.PolicyRule, requestedVerb string) bool {
|
||||
for _, ruleVerb := range rule.Verbs {
|
||||
if ruleVerb == rbacv1.VerbAll {
|
||||
return true
|
||||
}
|
||||
if ruleVerb == requestedVerb {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func APIGroupMatches(rule *rbacv1.PolicyRule, requestedGroup string) bool {
|
||||
for _, ruleGroup := range rule.APIGroups {
|
||||
if ruleGroup == rbacv1.APIGroupAll {
|
||||
return true
|
||||
}
|
||||
if ruleGroup == requestedGroup {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ResourceMatches(rule *rbacv1.PolicyRule, combinedRequestedResource, requestedSubresource string) bool {
|
||||
for _, ruleResource := range rule.Resources {
|
||||
// if everything is allowed, we match
|
||||
if ruleResource == rbacv1.ResourceAll {
|
||||
return true
|
||||
}
|
||||
// if we have an exact match, we match
|
||||
if ruleResource == combinedRequestedResource {
|
||||
return true
|
||||
}
|
||||
|
||||
// We can also match a */subresource.
|
||||
// if there isn't a subresource, then continue
|
||||
if len(requestedSubresource) == 0 {
|
||||
continue
|
||||
}
|
||||
// if the rule isn't in the format */subresource, then we don't match, continue
|
||||
if len(ruleResource) == len(requestedSubresource)+2 &&
|
||||
strings.HasPrefix(ruleResource, "*/") &&
|
||||
strings.HasSuffix(ruleResource, requestedSubresource) {
|
||||
return true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ResourceNameMatches(rule *rbacv1.PolicyRule, requestedName string) bool {
|
||||
if len(rule.ResourceNames) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, ruleName := range rule.ResourceNames {
|
||||
if ruleName == requestedName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func NonResourceURLMatches(rule *rbacv1.PolicyRule, requestedURL string) bool {
|
||||
for _, ruleURL := range rule.NonResourceURLs {
|
||||
if ruleURL == rbacv1.NonResourceAll {
|
||||
return true
|
||||
}
|
||||
if ruleURL == requestedURL {
|
||||
return true
|
||||
}
|
||||
if strings.HasSuffix(ruleURL, "*") && strings.HasPrefix(requestedURL, strings.TrimRight(ruleURL, "*")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// subjectsStrings returns users, groups, serviceaccounts, unknown for display purposes.
|
||||
func SubjectsStrings(subjects []rbacv1.Subject) ([]string, []string, []string, []string) {
|
||||
users := []string{}
|
||||
groups := []string{}
|
||||
sas := []string{}
|
||||
others := []string{}
|
||||
|
||||
for _, subject := range subjects {
|
||||
switch subject.Kind {
|
||||
case rbacv1.ServiceAccountKind:
|
||||
sas = append(sas, fmt.Sprintf("%s/%s", subject.Namespace, subject.Name))
|
||||
|
||||
case rbacv1.UserKind:
|
||||
users = append(users, subject.Name)
|
||||
|
||||
case rbacv1.GroupKind:
|
||||
groups = append(groups, subject.Name)
|
||||
|
||||
default:
|
||||
others = append(others, fmt.Sprintf("%s/%s/%s", subject.Kind, subject.Namespace, subject.Name))
|
||||
}
|
||||
}
|
||||
|
||||
return users, groups, sas, others
|
||||
}
|
||||
|
||||
func String(r rbacv1.PolicyRule) string {
|
||||
return "PolicyRule" + CompactString(r)
|
||||
}
|
||||
|
||||
// CompactString exposes a compact string representation for use in escalation error messages
|
||||
func CompactString(r rbacv1.PolicyRule) string {
|
||||
formatStringParts := []string{}
|
||||
formatArgs := []interface{}{}
|
||||
if len(r.APIGroups) > 0 {
|
||||
formatStringParts = append(formatStringParts, "APIGroups:%q")
|
||||
formatArgs = append(formatArgs, r.APIGroups)
|
||||
}
|
||||
if len(r.Resources) > 0 {
|
||||
formatStringParts = append(formatStringParts, "Resources:%q")
|
||||
formatArgs = append(formatArgs, r.Resources)
|
||||
}
|
||||
if len(r.NonResourceURLs) > 0 {
|
||||
formatStringParts = append(formatStringParts, "NonResourceURLs:%q")
|
||||
formatArgs = append(formatArgs, r.NonResourceURLs)
|
||||
}
|
||||
if len(r.ResourceNames) > 0 {
|
||||
formatStringParts = append(formatStringParts, "ResourceNames:%q")
|
||||
formatArgs = append(formatArgs, r.ResourceNames)
|
||||
}
|
||||
if len(r.Verbs) > 0 {
|
||||
formatStringParts = append(formatStringParts, "Verbs:%q")
|
||||
formatArgs = append(formatArgs, r.Verbs)
|
||||
}
|
||||
formatString := "{" + strings.Join(formatStringParts, ", ") + "}"
|
||||
return fmt.Sprintf(formatString, formatArgs...)
|
||||
}
|
||||
|
||||
type SortableRuleSlice []rbacv1.PolicyRule
|
||||
|
||||
func (s SortableRuleSlice) Len() int { return len(s) }
|
||||
func (s SortableRuleSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s SortableRuleSlice) Less(i, j int) bool {
|
||||
return strings.Compare(s[i].String(), s[j].String()) < 0
|
||||
}
|
||||
@@ -26,6 +26,7 @@ const (
|
||||
ResourceKindWorkspace = "Workspace"
|
||||
ResourceSingularWorkspace = "workspace"
|
||||
ResourcePluralWorkspace = "workspaces"
|
||||
WorkspaceLabel = "kubesphere.io/workspace"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
|
||||
@@ -11,13 +11,18 @@ import (
|
||||
unionauth "k8s.io/apiserver/pkg/authentication/request/union"
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||
"k8s.io/klog"
|
||||
clusterv1alpha1 "kubesphere.io/kubesphere/pkg/apis/cluster/v1alpha1"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authentication/authenticators/basic"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authentication/authenticators/jwttoken"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authentication/request/anonymous"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authentication/request/basictoken"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authentication/request/bearertoken"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authentication/token"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizerfactory"
|
||||
authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authorization/path"
|
||||
unionauthorizer "kubesphere.io/kubesphere/pkg/apiserver/authorization/union"
|
||||
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
|
||||
@@ -27,7 +32,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
configv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/config/v1alpha2"
|
||||
devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
|
||||
iamapi "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
|
||||
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/logging/v1alpha2"
|
||||
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
|
||||
networkv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/network/v1alpha2"
|
||||
@@ -94,7 +99,7 @@ type APIServer struct {
|
||||
// monitoring client set
|
||||
MonitoringClient monitoring.Interface
|
||||
|
||||
// openpitrix client
|
||||
//
|
||||
OpenpitrixClient openpitrix.Client
|
||||
|
||||
//
|
||||
@@ -143,11 +148,10 @@ func (s *APIServer) installKubeSphereAPIs() {
|
||||
urlruntime.Must(networkv1alpha2.AddToContainer(s.container, s.Config.NetworkOptions.WeaveScopeHost))
|
||||
urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes()))
|
||||
urlruntime.Must(resourcesv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.InformerFactory))
|
||||
urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.KubernetesClient, s.InformerFactory))
|
||||
urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.InformerFactory))
|
||||
urlruntime.Must(terminalv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.KubernetesClient.Config()))
|
||||
urlruntime.Must(iamv1alpha2.AddToContainer(s.container, im.NewOperator(s.KubernetesClient.KubeSphere(),
|
||||
s.InformerFactory.KubeSphereSharedInformerFactory()),
|
||||
am.NewAMOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory.KubeSphereSharedInformerFactory()),
|
||||
urlruntime.Must(iamapi.AddToContainer(s.container, im.NewOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory),
|
||||
am.NewAMOperator(s.InformerFactory),
|
||||
s.Config.AuthenticationOptions))
|
||||
urlruntime.Must(oauth.AddToContainer(s.container, token.NewJwtTokenIssuer(token.DefaultIssuerName, s.Config.AuthenticationOptions, s.CacheClient), s.Config.AuthenticationOptions))
|
||||
urlruntime.Must(servicemeshv1alpha2.AddToContainer(s.container))
|
||||
@@ -183,6 +187,13 @@ func (s *APIServer) buildHandlerChain() {
|
||||
requestInfoResolver := &request.RequestInfoFactory{
|
||||
APIPrefixes: sets.NewString("api", "apis", "kapis", "kapi"),
|
||||
GrouplessAPIPrefixes: sets.NewString("api", "kapi"),
|
||||
GlobalResources: []schema.GroupResource{
|
||||
{Group: iamv1alpha2.SchemeGroupVersion.Group, Resource: iamv1alpha2.ResourcesPluralUser},
|
||||
{Group: iamv1alpha2.SchemeGroupVersion.Group, Resource: iamv1alpha2.ResourcesPluralGlobalRole},
|
||||
{Group: iamv1alpha2.SchemeGroupVersion.Group, Resource: iamv1alpha2.ResourcesPluralGlobalRoleBinding},
|
||||
{Group: tenantv1alpha1.SchemeGroupVersion.Group, Resource: tenantv1alpha1.ResourcePluralWorkspace},
|
||||
{Group: clusterv1alpha1.SchemeGroupVersion.Group, Resource: clusterv1alpha1.ResourcesPluralCluster},
|
||||
},
|
||||
}
|
||||
|
||||
handler := s.Server.Handler
|
||||
@@ -193,16 +204,26 @@ func (s *APIServer) buildHandlerChain() {
|
||||
handler = filters.WithMultipleClusterDispatcher(handler, clusterDispatcher)
|
||||
}
|
||||
|
||||
excludedPaths := []string{"/oauth/*", "/kapis/config.kubesphere.io/*"}
|
||||
pathAuthorizer, _ := path.NewAuthorizer(excludedPaths)
|
||||
var authorizers authorizer.Authorizer
|
||||
|
||||
switch s.Config.AuthorizationOptions.Mode {
|
||||
case authorizationoptions.AlwaysAllow:
|
||||
authorizers = authorizerfactory.NewAlwaysAllowAuthorizer()
|
||||
case authorizationoptions.AlwaysDeny:
|
||||
authorizers = authorizerfactory.NewAlwaysDenyAuthorizer()
|
||||
default:
|
||||
fallthrough
|
||||
case authorizationoptions.RBAC:
|
||||
excludedPaths := []string{"/oauth/*", "/kapis/config.kubesphere.io/*"}
|
||||
pathAuthorizer, _ := path.NewAuthorizer(excludedPaths)
|
||||
authorizers = unionauthorizer.New(pathAuthorizer, authorizerfactory.NewOPAAuthorizer(am.NewAMOperator(s.InformerFactory)), authorizerfactory.NewRBACAuthorizer(am.NewAMOperator(s.InformerFactory)))
|
||||
}
|
||||
|
||||
// union authorizers are ordered, don't change the order here
|
||||
authorizers := unionauthorizer.New(pathAuthorizer, authorizerfactory.NewOPAAuthorizer(am.NewAMOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory.KubeSphereSharedInformerFactory())))
|
||||
handler = filters.WithAuthorization(handler, authorizers)
|
||||
|
||||
// authenticators are unordered
|
||||
authn := unionauth.New(anonymous.NewAuthenticator(),
|
||||
basictoken.New(basic.NewBasicAuthenticator(im.NewOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory.KubeSphereSharedInformerFactory()))),
|
||||
basictoken.New(basic.NewBasicAuthenticator(im.NewOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory))),
|
||||
bearertoken.New(jwttoken.NewTokenAuthenticator(token.NewJwtTokenIssuer(token.DefaultIssuerName, s.Config.AuthenticationOptions, s.CacheClient))))
|
||||
handler = filters.WithAuthentication(handler, authn)
|
||||
handler = filters.WithRequestInfo(handler, requestInfoResolver)
|
||||
@@ -283,9 +304,10 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error {
|
||||
ksGVRs := []schema.GroupVersionResource{
|
||||
{Group: "tenant.kubesphere.io", Version: "v1alpha1", Resource: "workspaces"},
|
||||
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "users"},
|
||||
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "roles"},
|
||||
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "rolebindings"},
|
||||
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "policyrules"},
|
||||
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "globalroles"},
|
||||
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "globalrolebindings"},
|
||||
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "workspaceroles"},
|
||||
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "workspacerolebindings"},
|
||||
{Group: "cluster.kubesphere.io", Version: "v1alpha1", Resource: "clusters"},
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,9 @@ type Attributes interface {
|
||||
// and false for non-resource endpoints like /api, /healthz
|
||||
IsResourceRequest() bool
|
||||
|
||||
// GetResourceScope returns the scope of the resource requested, if a request is for a REST object.
|
||||
GetResourceScope() string
|
||||
|
||||
// GetPath returns the path of the request
|
||||
GetPath() string
|
||||
}
|
||||
@@ -111,6 +114,7 @@ type AttributesRecord struct {
|
||||
KubernetesRequest bool
|
||||
ResourceRequest bool
|
||||
Path string
|
||||
ResourceScope string
|
||||
}
|
||||
|
||||
func (a AttributesRecord) GetUser() user.Info {
|
||||
@@ -169,6 +173,10 @@ func (a AttributesRecord) GetPath() string {
|
||||
return a.Path
|
||||
}
|
||||
|
||||
func (a AttributesRecord) GetResourceScope() string {
|
||||
return a.ResourceScope
|
||||
}
|
||||
|
||||
type Decision int
|
||||
|
||||
const (
|
||||
|
||||
49
pkg/apiserver/authorization/authorizerfactory/builtin.go
Normal file
49
pkg/apiserver/authorization/authorizerfactory/builtin.go
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 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 authorizerfactory
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
|
||||
)
|
||||
|
||||
// alwaysAllowAuthorizer is an implementation of authorizer.Attributes
|
||||
// which always says yes to an authorization request.
|
||||
// It is useful in tests and when using kubernetes in an open manner.
|
||||
type alwaysAllowAuthorizer struct{}
|
||||
|
||||
func (alwaysAllowAuthorizer) Authorize(authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
func NewAlwaysAllowAuthorizer() *alwaysAllowAuthorizer {
|
||||
return new(alwaysAllowAuthorizer)
|
||||
}
|
||||
|
||||
// alwaysDenyAuthorizer is an implementation of authorizer.Attributes
|
||||
// which always says no to an authorization request.
|
||||
// It is useful in unit tests to force an operation to be forbidden.
|
||||
type alwaysDenyAuthorizer struct{}
|
||||
|
||||
func (alwaysDenyAuthorizer) Authorize(a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) {
|
||||
return authorizer.DecisionNoOpinion, "Everything is forbidden.", nil
|
||||
}
|
||||
|
||||
func NewAlwaysDenyAuthorizer() *alwaysDenyAuthorizer {
|
||||
return new(alwaysDenyAuthorizer)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 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 authorizerfactory
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewAlwaysAllowAuthorizer(t *testing.T) {
|
||||
aaa := NewAlwaysAllowAuthorizer()
|
||||
if decision, _, _ := aaa.Authorize(nil); decision != authorizer.DecisionAllow {
|
||||
t.Errorf("AlwaysAllowAuthorizer.Authorize did not authorize successfully.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewAlwaysDenyAuthorizer(t *testing.T) {
|
||||
ada := NewAlwaysDenyAuthorizer()
|
||||
if decision, _, _ := ada.Authorize(nil); decision == authorizer.DecisionAllow {
|
||||
t.Errorf("AlwaysDenyAuthorizer.Authorize returned nil instead of error.")
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ package authorizerfactory
|
||||
import (
|
||||
"context"
|
||||
"github.com/open-policy-agent/opa/rego"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/klog"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
@@ -33,125 +34,140 @@ type opaAuthorizer struct {
|
||||
}
|
||||
|
||||
const (
|
||||
permissionUndefined = "permission undefined"
|
||||
defaultRegoQuery = "data.authz.allow"
|
||||
defaultRegoQuery = "data.authz.allow"
|
||||
)
|
||||
|
||||
// Make decision by request attributes
|
||||
func (o *opaAuthorizer) Authorize(attr authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
|
||||
// Make decisions based on the authorization policy of different levels of roles
|
||||
// Error returned when an internal error occurs
|
||||
// Reason must be returned when access is denied
|
||||
globalRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.GlobalScope, "", attr.GetUser().GetName())
|
||||
globalRole, err := o.am.GetGlobalRoleOfUser(attr.GetUser().GetName())
|
||||
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return authorizer.DecisionDeny, err.Error(), nil
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
return authorizer.DecisionDeny, "", err
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
|
||||
// check global role policy rules
|
||||
// check global policy rules
|
||||
if authorized, reason, err = o.makeDecision(globalRole, attr); authorized == authorizer.DecisionAllow {
|
||||
return authorized, reason, nil
|
||||
}
|
||||
|
||||
// it's not in cluster resource, permission denied
|
||||
if attr.GetCluster() == "" {
|
||||
return authorizer.DecisionDeny, permissionUndefined, nil
|
||||
// it's global resource, permission denied
|
||||
if attr.GetResourceScope() == iamv1alpha2.GlobalScope {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
clusterRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.ClusterScope, attr.GetCluster(), attr.GetUser().GetName())
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return authorizer.DecisionDeny, err.Error(), nil
|
||||
if attr.GetResourceScope() == iamv1alpha2.WorkspaceScope {
|
||||
workspaceRole, err := o.am.GetWorkspaceRoleOfUser(attr.GetUser().GetName(), attr.GetWorkspace())
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
return authorizer.DecisionDeny, "", err
|
||||
|
||||
// check workspace role policy rules
|
||||
if authorized, reason, err := o.makeDecision(workspaceRole, attr); authorized == authorizer.DecisionAllow {
|
||||
return authorized, reason, err
|
||||
} else if err != nil {
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
if attr.GetResourceScope() == iamv1alpha2.NamespaceScope {
|
||||
role, err := o.am.GetNamespaceRoleOfUser(attr.GetUser().GetName(), attr.GetNamespace())
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
// check namespace role policy rules
|
||||
if authorized, reason, err := o.makeDecision(role, attr); authorized == authorizer.DecisionAllow {
|
||||
return authorized, reason, err
|
||||
} else if err != nil {
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
clusterRole, err := o.am.GetClusterRoleOfUser(attr.GetUser().GetName(), attr.GetCluster())
|
||||
|
||||
if errors.IsNotFound(err) {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
|
||||
// check cluster role policy rules
|
||||
if authorized, reason, err := o.makeDecision(clusterRole, attr); authorized == authorizer.DecisionAllow {
|
||||
return authorized, reason, nil
|
||||
} else if err != nil {
|
||||
return authorizer.DecisionDeny, "", err
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
|
||||
// it's not in cluster resource, permission denied
|
||||
if attr.GetWorkspace() == "" && attr.GetNamespace() == "" {
|
||||
return authorizer.DecisionDeny, permissionUndefined, nil
|
||||
}
|
||||
|
||||
workspaceRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.WorkspaceScope, attr.GetWorkspace(), attr.GetUser().GetName())
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return authorizer.DecisionDeny, err.Error(), nil
|
||||
}
|
||||
return authorizer.DecisionDeny, "", err
|
||||
}
|
||||
|
||||
// check workspace role policy rules
|
||||
if authorized, reason, err := o.makeDecision(workspaceRole, attr); authorized == authorizer.DecisionAllow {
|
||||
return authorized, reason, err
|
||||
} else if err != nil {
|
||||
return authorizer.DecisionDeny, "", err
|
||||
}
|
||||
|
||||
// it's not in workspace resource, permission denied
|
||||
if attr.GetNamespace() == "" {
|
||||
return authorizer.DecisionDeny, permissionUndefined, nil
|
||||
}
|
||||
|
||||
namespaceRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.NamespaceScope, attr.GetNamespace(), attr.GetUser().GetName())
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return authorizer.DecisionDeny, err.Error(), nil
|
||||
}
|
||||
return authorizer.DecisionDeny, "", err
|
||||
}
|
||||
// check namespace role policy rules
|
||||
if authorized, reason, err := o.makeDecision(namespaceRole, attr); authorized == authorizer.DecisionAllow {
|
||||
return authorized, reason, err
|
||||
} else if err != nil {
|
||||
return authorizer.DecisionDeny, "", err
|
||||
}
|
||||
|
||||
return authorizer.DecisionDeny, permissionUndefined, nil
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
// Make decision base on role
|
||||
func (o *opaAuthorizer) makeDecision(role *iamv1alpha2.Role, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
func (o *opaAuthorizer) makeDecision(role interface{}, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
|
||||
for _, ruleRef := range role.Rules {
|
||||
rule, err := o.am.GetPolicyRule(ruleRef.Name)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
return authorizer.DecisionDeny, "", err
|
||||
regoPolicy := ""
|
||||
|
||||
// override
|
||||
if globalRole, ok := role.(*iamv1alpha2.GlobalRole); ok {
|
||||
if overrideRego, ok := globalRole.Annotations[iamv1alpha2.RegoOverrideAnnotation]; ok {
|
||||
regoPolicy = overrideRego
|
||||
}
|
||||
// Call the rego.New function to create an object that can be prepared or evaluated
|
||||
// After constructing a new rego.Rego object you can call PrepareForEval() to obtain an executable query
|
||||
query, err := rego.New(rego.Query(defaultRegoQuery), rego.Module("authz.rego", rule.Rego)).PrepareForEval(context.Background())
|
||||
|
||||
if err != nil {
|
||||
klog.Errorf("rule syntax error:%s", err)
|
||||
continue
|
||||
} else if workspaceRole, ok := role.(*iamv1alpha2.WorkspaceRole); ok {
|
||||
if overrideRego, ok := workspaceRole.Annotations[iamv1alpha2.RegoOverrideAnnotation]; ok {
|
||||
regoPolicy = overrideRego
|
||||
}
|
||||
|
||||
// The policy decision is contained in the results returned by the Eval() call. You can inspect the decision and handle it accordingly.
|
||||
results, err := query.Eval(context.Background(), rego.EvalInput(a))
|
||||
|
||||
if err != nil {
|
||||
klog.Errorf("rule syntax error:%s", err)
|
||||
continue
|
||||
} else if clusterRole, ok := role.(*rbacv1.ClusterRole); ok {
|
||||
if overrideRego, ok := clusterRole.Annotations[iamv1alpha2.RegoOverrideAnnotation]; ok {
|
||||
regoPolicy = overrideRego
|
||||
}
|
||||
|
||||
if len(results) > 0 && results[0].Expressions[0].Value == true {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
} else if role, ok := role.(*rbacv1.Role); ok {
|
||||
if overrideRego, ok := role.Annotations[iamv1alpha2.RegoOverrideAnnotation]; ok {
|
||||
regoPolicy = overrideRego
|
||||
}
|
||||
}
|
||||
|
||||
return authorizer.DecisionDeny, permissionUndefined, nil
|
||||
if regoPolicy == "" {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
// Call the rego.New function to create an object that can be prepared or evaluated
|
||||
// After constructing a new rego.Rego object you can call PrepareForEval() to obtain an executable query
|
||||
query, err := rego.New(rego.Query(defaultRegoQuery), rego.Module("authz.rego", regoPolicy)).PrepareForEval(context.Background())
|
||||
|
||||
if err != nil {
|
||||
klog.Errorf("syntax error:%s,refer: %s+v", err, role)
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
|
||||
// The policy decision is contained in the results returned by the Eval() call. You can inspect the decision and handle it accordingly.
|
||||
results, err := query.Eval(context.Background(), rego.EvalInput(a))
|
||||
|
||||
if err != nil {
|
||||
klog.Errorf("syntax error:%s,refer: %s+v", err, role)
|
||||
return authorizer.DecisionNoOpinion, "", err
|
||||
}
|
||||
|
||||
if len(results) > 0 && results[0].Expressions[0].Value == true {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
func NewOPAAuthorizer(am am.AccessManagementInterface) *opaAuthorizer {
|
||||
|
||||
@@ -20,209 +20,22 @@ package authorizerfactory
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
fakek8s "k8s.io/client-go/kubernetes/fake"
|
||||
iamvealpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
factory "kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam/am"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func prepare() (am.AccessManagementInterface, error) {
|
||||
rules := []*iamvealpha2.PolicyRule{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.PolicyRuleKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "always-allow",
|
||||
},
|
||||
Rego: "package authz\ndefault allow = true",
|
||||
}, {
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.PolicyRuleKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "always-deny",
|
||||
},
|
||||
Rego: "package authz\ndefault allow = false",
|
||||
}, {
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.PolicyRuleKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "manage-cluster1-resources",
|
||||
},
|
||||
Rego: `package authz
|
||||
default allow = false
|
||||
allow {
|
||||
resources_in_cluster1
|
||||
}
|
||||
resources_in_cluster1 {
|
||||
input.Cluster == "cluster1"
|
||||
}`,
|
||||
},
|
||||
}
|
||||
|
||||
roles := []*iamvealpha2.Role{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.RoleKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "global-admin",
|
||||
},
|
||||
Target: iamvealpha2.Target{
|
||||
Scope: iamvealpha2.GlobalScope,
|
||||
Name: "",
|
||||
},
|
||||
Rules: []iamvealpha2.RuleRef{
|
||||
{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.PolicyRuleKind,
|
||||
Name: "always-allow",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.RoleKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "anonymous",
|
||||
},
|
||||
Target: iamvealpha2.Target{
|
||||
Scope: iamvealpha2.GlobalScope,
|
||||
Name: "",
|
||||
},
|
||||
Rules: []iamvealpha2.RuleRef{
|
||||
{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.PolicyRuleKind,
|
||||
Name: "always-deny",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.RoleKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1-admin",
|
||||
},
|
||||
Target: iamvealpha2.Target{
|
||||
Scope: iamvealpha2.GlobalScope,
|
||||
Name: "",
|
||||
},
|
||||
Rules: []iamvealpha2.RuleRef{
|
||||
{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.PolicyRuleKind,
|
||||
Name: "manage-cluster1-resources",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
roleBindings := []*iamvealpha2.RoleBinding{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.RoleBindingKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "global-admin",
|
||||
},
|
||||
Scope: iamvealpha2.GlobalScope,
|
||||
RoleRef: iamvealpha2.RoleRef{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.RoleKind,
|
||||
Name: "global-admin",
|
||||
},
|
||||
Subjects: []iamvealpha2.Subject{
|
||||
{
|
||||
Kind: iamvealpha2.UserKind,
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Name: "admin",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.RoleBindingKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "anonymous",
|
||||
},
|
||||
Scope: iamvealpha2.GlobalScope,
|
||||
RoleRef: iamvealpha2.RoleRef{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.RoleKind,
|
||||
Name: "anonymous",
|
||||
},
|
||||
Subjects: []iamvealpha2.Subject{
|
||||
{
|
||||
Kind: iamvealpha2.UserKind,
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Name: user.Anonymous,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.RoleBindingKind,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1-admin",
|
||||
},
|
||||
Scope: iamvealpha2.GlobalScope,
|
||||
RoleRef: iamvealpha2.RoleRef{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.RoleKind,
|
||||
Name: "cluster1-admin",
|
||||
},
|
||||
Subjects: []iamvealpha2.Subject{
|
||||
{
|
||||
Kind: iamvealpha2.UserKind,
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Name: "tom",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
informerFactory := externalversions.NewSharedInformerFactory(ksClient, 0)
|
||||
|
||||
for _, rule := range rules {
|
||||
err := informerFactory.Iam().V1alpha2().PolicyRules().Informer().GetIndexer().Add(rule)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add rule:%s", err)
|
||||
}
|
||||
}
|
||||
for _, role := range roles {
|
||||
err := informerFactory.Iam().V1alpha2().Roles().Informer().GetIndexer().Add(role)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add role:%s", err)
|
||||
}
|
||||
}
|
||||
for _, roleBinding := range roleBindings {
|
||||
err := informerFactory.Iam().V1alpha2().RoleBindings().Informer().GetIndexer().Add(roleBinding)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add role binding:%s", err)
|
||||
}
|
||||
}
|
||||
|
||||
operator := am.NewAMOperator(ksClient, informerFactory)
|
||||
|
||||
return operator, nil
|
||||
}
|
||||
|
||||
func TestGlobalRole(t *testing.T) {
|
||||
|
||||
operator, err := prepare()
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -244,14 +57,8 @@ func TestGlobalRole(t *testing.T) {
|
||||
Extra: nil,
|
||||
},
|
||||
Verb: "list",
|
||||
Cluster: "",
|
||||
Workspace: "",
|
||||
Namespace: "",
|
||||
APIGroup: "",
|
||||
APIVersion: "v1",
|
||||
Resource: "nodes",
|
||||
Subresource: "",
|
||||
Name: "",
|
||||
KubernetesRequest: true,
|
||||
ResourceRequest: true,
|
||||
Path: "/api/v1/nodes",
|
||||
@@ -268,19 +75,13 @@ func TestGlobalRole(t *testing.T) {
|
||||
Extra: nil,
|
||||
},
|
||||
Verb: "list",
|
||||
Cluster: "",
|
||||
Workspace: "",
|
||||
Namespace: "",
|
||||
APIGroup: "",
|
||||
APIVersion: "v1",
|
||||
Resource: "nodes",
|
||||
Subresource: "",
|
||||
Name: "",
|
||||
KubernetesRequest: true,
|
||||
ResourceRequest: true,
|
||||
Path: "/api/v1/nodes",
|
||||
},
|
||||
expectedDecision: authorizer.DecisionDeny,
|
||||
expectedDecision: authorizer.DecisionNoOpinion,
|
||||
}, {
|
||||
name: "tom can list nodes in cluster1",
|
||||
request: authorizer.AttributesRecord{
|
||||
@@ -289,13 +90,8 @@ func TestGlobalRole(t *testing.T) {
|
||||
},
|
||||
Verb: "list",
|
||||
Cluster: "cluster1",
|
||||
Workspace: "",
|
||||
Namespace: "",
|
||||
APIGroup: "",
|
||||
APIVersion: "v1",
|
||||
Resource: "nodes",
|
||||
Subresource: "",
|
||||
Name: "",
|
||||
KubernetesRequest: true,
|
||||
ResourceRequest: true,
|
||||
Path: "/api/v1/clusters/cluster1/nodes",
|
||||
@@ -310,18 +106,13 @@ func TestGlobalRole(t *testing.T) {
|
||||
},
|
||||
Verb: "list",
|
||||
Cluster: "cluster2",
|
||||
Workspace: "",
|
||||
Namespace: "",
|
||||
APIGroup: "",
|
||||
APIVersion: "v1",
|
||||
Resource: "nodes",
|
||||
Subresource: "",
|
||||
Name: "",
|
||||
KubernetesRequest: true,
|
||||
ResourceRequest: true,
|
||||
Path: "/api/v1/clusters/cluster2/nodes",
|
||||
},
|
||||
expectedDecision: authorizer.DecisionDeny,
|
||||
expectedDecision: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -335,3 +126,127 @@ func TestGlobalRole(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func prepare() (am.AccessManagementInterface, error) {
|
||||
globalRoles := []*iamvealpha2.GlobalRole{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.ResourceKindGlobalRole,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "global-admin",
|
||||
Annotations: map[string]string{iamvealpha2.RegoOverrideAnnotation: "package authz\ndefault allow = true"},
|
||||
},
|
||||
}, {
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.ResourceKindGlobalRole,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "anonymous",
|
||||
Annotations: map[string]string{iamvealpha2.RegoOverrideAnnotation: "package authz\ndefault allow = false"},
|
||||
},
|
||||
}, {
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.ResourceKindGlobalRole,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1-admin",
|
||||
Annotations: map[string]string{iamvealpha2.RegoOverrideAnnotation: `package authz
|
||||
default allow = false
|
||||
allow {
|
||||
resources_in_cluster1
|
||||
}
|
||||
resources_in_cluster1 {
|
||||
input.Cluster == "cluster1"
|
||||
}`},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
roleBindings := []*iamvealpha2.GlobalRoleBinding{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.ResourceKindGlobalRoleBinding,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "global-admin",
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.ResourceKindGlobalRole,
|
||||
Name: "global-admin",
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: iamvealpha2.ResourceKindUser,
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Name: "admin",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.ResourceKindGlobalRoleBinding,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "anonymous",
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.ResourceKindGlobalRole,
|
||||
Name: "anonymous",
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: iamvealpha2.ResourceKindUser,
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Name: user.Anonymous,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: iamvealpha2.ResourceKindGlobalRoleBinding,
|
||||
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cluster1-admin",
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Kind: iamvealpha2.ResourceKindGlobalRole,
|
||||
Name: "cluster1-admin",
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: iamvealpha2.ResourceKindUser,
|
||||
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
|
||||
Name: "tom",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
factory := factory.NewInformerFactories(k8sClient, ksClient, nil, nil)
|
||||
for _, role := range globalRoles {
|
||||
err := factory.KubeSphereSharedInformerFactory().Iam().V1alpha2().GlobalRoles().Informer().GetIndexer().Add(role)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add role:%s", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
err := factory.KubeSphereSharedInformerFactory().Iam().V1alpha2().GlobalRoleBindings().Informer().GetIndexer().Add(roleBinding)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add role binding:%s", err)
|
||||
}
|
||||
}
|
||||
|
||||
operator := am.NewAMOperator(factory)
|
||||
|
||||
return operator, nil
|
||||
}
|
||||
|
||||
384
pkg/apiserver/authorization/authorizerfactory/rbac.go
Normal file
384
pkg/apiserver/authorization/authorizerfactory/rbac.go
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 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 authorizerfactory
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam/am"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
rbacv1helpers "kubesphere.io/kubesphere/pkg/apis/rbac/v1"
|
||||
)
|
||||
|
||||
type RBACAuthorizer struct {
|
||||
am am.AccessManagementInterface
|
||||
}
|
||||
|
||||
// authorizingVisitor short-circuits once allowed, and collects any resolution errors encountered
|
||||
type authorizingVisitor struct {
|
||||
requestAttributes authorizer.Attributes
|
||||
|
||||
allowed bool
|
||||
reason string
|
||||
errors []error
|
||||
}
|
||||
|
||||
func (v *authorizingVisitor) visit(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool {
|
||||
if rule != nil && ruleAllows(v.requestAttributes, rule) {
|
||||
v.allowed = true
|
||||
v.reason = fmt.Sprintf("RBAC: allowed by %s", source.String())
|
||||
return false
|
||||
}
|
||||
if err != nil {
|
||||
v.errors = append(v.errors, err)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type ruleAccumulator struct {
|
||||
rules []rbacv1.PolicyRule
|
||||
errors []error
|
||||
}
|
||||
|
||||
func (r *ruleAccumulator) visit(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool {
|
||||
if rule != nil {
|
||||
r.rules = append(r.rules, *rule)
|
||||
}
|
||||
if err != nil {
|
||||
r.errors = append(r.errors, err)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
ruleCheckingVisitor := &authorizingVisitor{requestAttributes: requestAttributes}
|
||||
|
||||
r.visitRulesFor(requestAttributes, ruleCheckingVisitor.visit)
|
||||
|
||||
if ruleCheckingVisitor.allowed {
|
||||
return authorizer.DecisionAllow, ruleCheckingVisitor.reason, nil
|
||||
}
|
||||
|
||||
// Build a detailed log of the denial.
|
||||
// Make the whole block conditional so we don't do a lot of string-building we won't use.
|
||||
if klog.V(4) {
|
||||
var operation string
|
||||
if requestAttributes.IsResourceRequest() {
|
||||
b := &bytes.Buffer{}
|
||||
b.WriteString(`"`)
|
||||
b.WriteString(requestAttributes.GetVerb())
|
||||
b.WriteString(`" resource "`)
|
||||
b.WriteString(requestAttributes.GetResource())
|
||||
if len(requestAttributes.GetAPIGroup()) > 0 {
|
||||
b.WriteString(`.`)
|
||||
b.WriteString(requestAttributes.GetAPIGroup())
|
||||
}
|
||||
if len(requestAttributes.GetSubresource()) > 0 {
|
||||
b.WriteString(`/`)
|
||||
b.WriteString(requestAttributes.GetSubresource())
|
||||
}
|
||||
b.WriteString(`"`)
|
||||
if len(requestAttributes.GetName()) > 0 {
|
||||
b.WriteString(` named "`)
|
||||
b.WriteString(requestAttributes.GetName())
|
||||
b.WriteString(`"`)
|
||||
}
|
||||
operation = b.String()
|
||||
} else {
|
||||
operation = fmt.Sprintf("%q nonResourceURL %q", requestAttributes.GetVerb(), requestAttributes.GetPath())
|
||||
}
|
||||
|
||||
var scope string
|
||||
if ns := requestAttributes.GetNamespace(); len(ns) > 0 {
|
||||
scope = fmt.Sprintf("in namespace %q", ns)
|
||||
} else if ws := requestAttributes.GetWorkspace(); len(ws) > 0 {
|
||||
scope = fmt.Sprintf("in workspace %q", ws)
|
||||
} else if cluster := requestAttributes.GetWorkspace(); len(cluster) > 0 {
|
||||
scope = fmt.Sprintf("in cluster %q", cluster)
|
||||
} else {
|
||||
scope = "global-wide"
|
||||
}
|
||||
|
||||
klog.Infof("RBAC: no rules authorize user %q with groups %q to %s %s", requestAttributes.GetUser().GetName(), requestAttributes.GetUser().GetGroups(), operation, scope)
|
||||
}
|
||||
|
||||
reason := ""
|
||||
if len(ruleCheckingVisitor.errors) > 0 {
|
||||
reason = fmt.Sprintf("RBAC: %v", utilerrors.NewAggregate(ruleCheckingVisitor.errors))
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, reason, nil
|
||||
}
|
||||
|
||||
func NewRBACAuthorizer(am am.AccessManagementInterface) *RBACAuthorizer {
|
||||
return &RBACAuthorizer{am: am}
|
||||
}
|
||||
|
||||
func ruleAllows(requestAttributes authorizer.Attributes, rule *rbacv1.PolicyRule) bool {
|
||||
if requestAttributes.IsResourceRequest() {
|
||||
combinedResource := requestAttributes.GetResource()
|
||||
if len(requestAttributes.GetSubresource()) > 0 {
|
||||
combinedResource = requestAttributes.GetResource() + "/" + requestAttributes.GetSubresource()
|
||||
}
|
||||
|
||||
return rbacv1helpers.VerbMatches(rule, requestAttributes.GetVerb()) &&
|
||||
rbacv1helpers.APIGroupMatches(rule, requestAttributes.GetAPIGroup()) &&
|
||||
rbacv1helpers.ResourceMatches(rule, combinedResource, requestAttributes.GetSubresource()) &&
|
||||
rbacv1helpers.ResourceNameMatches(rule, requestAttributes.GetName())
|
||||
}
|
||||
|
||||
return rbacv1helpers.VerbMatches(rule, requestAttributes.GetVerb()) &&
|
||||
rbacv1helpers.NonResourceURLMatches(rule, requestAttributes.GetPath())
|
||||
}
|
||||
|
||||
func (r *RBACAuthorizer) rulesFor(requestAttributes authorizer.Attributes) ([]rbacv1.PolicyRule, error) {
|
||||
visitor := &ruleAccumulator{}
|
||||
r.visitRulesFor(requestAttributes, visitor.visit)
|
||||
return visitor.rules, utilerrors.NewAggregate(visitor.errors)
|
||||
}
|
||||
|
||||
func (r *RBACAuthorizer) visitRulesFor(requestAttributes authorizer.Attributes, visitor func(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool) {
|
||||
if globalRoleBindings, err := r.am.ListGlobalRoleBindings(""); err != nil {
|
||||
if !visitor(nil, nil, err) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
sourceDescriber := &globalRoleBindingDescriber{}
|
||||
for _, globalRoleBinding := range globalRoleBindings {
|
||||
subjectIndex, applies := appliesTo(requestAttributes.GetUser(), globalRoleBinding.Subjects, "")
|
||||
if !applies {
|
||||
continue
|
||||
}
|
||||
rules, err := r.am.GetRoleReferenceRules(globalRoleBinding.RoleRef, "")
|
||||
if err != nil {
|
||||
if !visitor(nil, nil, err) {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
sourceDescriber.binding = globalRoleBinding
|
||||
sourceDescriber.subject = &globalRoleBinding.Subjects[subjectIndex]
|
||||
for i := range rules {
|
||||
if !visitor(sourceDescriber, &rules[i], nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if requestAttributes.GetResourceScope() == iamv1alpha2.WorkspaceScope {
|
||||
if workspaceRoleBindings, err := r.am.ListWorkspaceRoleBindings("", requestAttributes.GetWorkspace()); err != nil {
|
||||
if !visitor(nil, nil, err) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
sourceDescriber := &workspaceRoleBindingDescriber{}
|
||||
for _, workspaceRoleBinding := range workspaceRoleBindings {
|
||||
subjectIndex, applies := appliesTo(requestAttributes.GetUser(), workspaceRoleBinding.Subjects, "")
|
||||
if !applies {
|
||||
continue
|
||||
}
|
||||
rules, err := r.am.GetRoleReferenceRules(workspaceRoleBinding.RoleRef, "")
|
||||
if err != nil {
|
||||
if !visitor(nil, nil, err) {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
sourceDescriber.binding = workspaceRoleBinding
|
||||
sourceDescriber.subject = &workspaceRoleBinding.Subjects[subjectIndex]
|
||||
for i := range rules {
|
||||
if !visitor(sourceDescriber, &rules[i], nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if requestAttributes.GetResourceScope() == iamv1alpha2.NamespaceScope {
|
||||
if roleBindings, err := r.am.ListRoleBindings("", requestAttributes.GetNamespace()); err != nil {
|
||||
if !visitor(nil, nil, err) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
sourceDescriber := &roleBindingDescriber{}
|
||||
for _, roleBinding := range roleBindings {
|
||||
subjectIndex, applies := appliesTo(requestAttributes.GetUser(), roleBinding.Subjects, requestAttributes.GetNamespace())
|
||||
if !applies {
|
||||
continue
|
||||
}
|
||||
rules, err := r.am.GetRoleReferenceRules(roleBinding.RoleRef, requestAttributes.GetNamespace())
|
||||
if err != nil {
|
||||
if !visitor(nil, nil, err) {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
sourceDescriber.binding = roleBinding
|
||||
sourceDescriber.subject = &roleBinding.Subjects[subjectIndex]
|
||||
for i := range rules {
|
||||
if !visitor(sourceDescriber, &rules[i], nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if clusterRoleBindings, err := r.am.ListClusterRoleBindings(""); err != nil {
|
||||
if !visitor(nil, nil, err) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
sourceDescriber := &clusterRoleBindingDescriber{}
|
||||
for _, clusterRoleBinding := range clusterRoleBindings {
|
||||
subjectIndex, applies := appliesTo(requestAttributes.GetUser(), clusterRoleBinding.Subjects, "")
|
||||
if !applies {
|
||||
continue
|
||||
}
|
||||
rules, err := r.am.GetRoleReferenceRules(clusterRoleBinding.RoleRef, "")
|
||||
if err != nil {
|
||||
if !visitor(nil, nil, err) {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
sourceDescriber.binding = clusterRoleBinding
|
||||
sourceDescriber.subject = &clusterRoleBinding.Subjects[subjectIndex]
|
||||
for i := range rules {
|
||||
if !visitor(sourceDescriber, &rules[i], nil) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// appliesTo returns whether any of the bindingSubjects applies to the specified subject,
|
||||
// and if true, the index of the first subject that applies
|
||||
func appliesTo(user user.Info, bindingSubjects []rbacv1.Subject, namespace string) (int, bool) {
|
||||
for i, bindingSubject := range bindingSubjects {
|
||||
if appliesToUser(user, bindingSubject, namespace) {
|
||||
return i, true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func appliesToUser(user user.Info, subject rbacv1.Subject, namespace string) bool {
|
||||
switch subject.Kind {
|
||||
case rbacv1.UserKind:
|
||||
return user.GetName() == subject.Name
|
||||
|
||||
case rbacv1.GroupKind:
|
||||
return sliceutil.HasString(user.GetGroups(), subject.Name)
|
||||
|
||||
case rbacv1.ServiceAccountKind:
|
||||
// default the namespace to namespace we're working in if its available. This allows rolebindings that reference
|
||||
// SAs in th local namespace to avoid having to qualify them.
|
||||
saNamespace := namespace
|
||||
if len(subject.Namespace) > 0 {
|
||||
saNamespace = subject.Namespace
|
||||
}
|
||||
if len(saNamespace) == 0 {
|
||||
return false
|
||||
}
|
||||
// use a more efficient comparison for RBAC checking
|
||||
return serviceaccount.MatchesUsername(saNamespace, subject.Name, user.GetName())
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type globalRoleBindingDescriber struct {
|
||||
binding *iamv1alpha2.GlobalRoleBinding
|
||||
subject *rbacv1.Subject
|
||||
}
|
||||
|
||||
func (d *globalRoleBindingDescriber) String() string {
|
||||
return fmt.Sprintf("GlobalRoleBinding %q of %s %q to %s",
|
||||
d.binding.Name,
|
||||
d.binding.RoleRef.Kind,
|
||||
d.binding.RoleRef.Name,
|
||||
describeSubject(d.subject, ""),
|
||||
)
|
||||
}
|
||||
|
||||
type clusterRoleBindingDescriber struct {
|
||||
binding *rbacv1.ClusterRoleBinding
|
||||
subject *rbacv1.Subject
|
||||
}
|
||||
|
||||
func (d *clusterRoleBindingDescriber) String() string {
|
||||
return fmt.Sprintf("ClusterRoleBinding %q of %s %q to %s",
|
||||
d.binding.Name,
|
||||
d.binding.RoleRef.Kind,
|
||||
d.binding.RoleRef.Name,
|
||||
describeSubject(d.subject, ""),
|
||||
)
|
||||
}
|
||||
|
||||
type workspaceRoleBindingDescriber struct {
|
||||
binding *iamv1alpha2.WorkspaceRoleBinding
|
||||
subject *rbacv1.Subject
|
||||
}
|
||||
|
||||
func (d *workspaceRoleBindingDescriber) String() string {
|
||||
return fmt.Sprintf("GlobalRoleBinding %q of %s %q to %s",
|
||||
d.binding.Name,
|
||||
d.binding.RoleRef.Kind,
|
||||
d.binding.RoleRef.Name,
|
||||
describeSubject(d.subject, ""),
|
||||
)
|
||||
}
|
||||
|
||||
type roleBindingDescriber struct {
|
||||
binding *rbacv1.RoleBinding
|
||||
subject *rbacv1.Subject
|
||||
}
|
||||
|
||||
func (d *roleBindingDescriber) String() string {
|
||||
return fmt.Sprintf("RoleBinding %q of %s %q to %s",
|
||||
d.binding.Name+"/"+d.binding.Namespace,
|
||||
d.binding.RoleRef.Kind,
|
||||
d.binding.RoleRef.Name,
|
||||
describeSubject(d.subject, d.binding.Namespace),
|
||||
)
|
||||
}
|
||||
|
||||
func describeSubject(s *rbacv1.Subject, bindingNamespace string) string {
|
||||
switch s.Kind {
|
||||
case rbacv1.ServiceAccountKind:
|
||||
if len(s.Namespace) > 0 {
|
||||
return fmt.Sprintf("%s %q", s.Kind, s.Name+"/"+s.Namespace)
|
||||
}
|
||||
return fmt.Sprintf("%s %q", s.Kind, s.Name+"/"+bindingNamespace)
|
||||
default:
|
||||
return fmt.Sprintf("%s %q", s.Kind, s.Name)
|
||||
}
|
||||
}
|
||||
389
pkg/apiserver/authorization/authorizerfactory/rbac_test.go
Normal file
389
pkg/apiserver/authorization/authorizerfactory/rbac_test.go
Normal file
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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 authorizerfactory
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
fakeapp "github.com/kubernetes-sigs/application/pkg/client/clientset/versioned/fake"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
fakeistio "istio.io/client-go/pkg/clientset/versioned/fake"
|
||||
fakek8s "k8s.io/client-go/kubernetes/fake"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
|
||||
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam/am"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
)
|
||||
|
||||
// StaticRoles is a rule resolver that resolves from lists of role objects.
|
||||
type StaticRoles struct {
|
||||
roles []*rbacv1.Role
|
||||
roleBindings []*rbacv1.RoleBinding
|
||||
clusterRoles []*rbacv1.ClusterRole
|
||||
clusterRoleBindings []*rbacv1.ClusterRoleBinding
|
||||
}
|
||||
|
||||
func (r *StaticRoles) GetRole(namespace, name string) (*rbacv1.Role, error) {
|
||||
if len(namespace) == 0 {
|
||||
return nil, errors.New("must provide namespace when getting role")
|
||||
}
|
||||
for _, role := range r.roles {
|
||||
if role.Namespace == namespace && role.Name == name {
|
||||
return role, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("role not found")
|
||||
}
|
||||
|
||||
func (r *StaticRoles) GetClusterRole(name string) (*rbacv1.ClusterRole, error) {
|
||||
for _, clusterRole := range r.clusterRoles {
|
||||
if clusterRole.Name == name {
|
||||
return clusterRole, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("clusterrole not found")
|
||||
}
|
||||
|
||||
func (r *StaticRoles) ListRoleBindings(namespace string) ([]*rbacv1.RoleBinding, error) {
|
||||
if len(namespace) == 0 {
|
||||
return nil, errors.New("must provide namespace when listing role bindings")
|
||||
}
|
||||
|
||||
roleBindingList := []*rbacv1.RoleBinding{}
|
||||
for _, roleBinding := range r.roleBindings {
|
||||
if roleBinding.Namespace != namespace {
|
||||
continue
|
||||
}
|
||||
// TODO(ericchiang): need to implement label selectors?
|
||||
roleBindingList = append(roleBindingList, roleBinding)
|
||||
}
|
||||
return roleBindingList, nil
|
||||
}
|
||||
|
||||
func (r *StaticRoles) ListClusterRoleBindings() ([]*rbacv1.ClusterRoleBinding, error) {
|
||||
return r.clusterRoleBindings, nil
|
||||
}
|
||||
|
||||
// compute a hash of a policy rule so we can sort in a deterministic order
|
||||
func hashOf(p rbacv1.PolicyRule) string {
|
||||
hash := fnv.New32()
|
||||
writeStrings := func(slis ...[]string) {
|
||||
for _, sli := range slis {
|
||||
for _, s := range sli {
|
||||
io.WriteString(hash, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
writeStrings(p.Verbs, p.APIGroups, p.Resources, p.ResourceNames, p.NonResourceURLs)
|
||||
return string(hash.Sum(nil))
|
||||
}
|
||||
|
||||
// byHash sorts a set of policy rules by a hash of its fields
|
||||
type byHash []rbacv1.PolicyRule
|
||||
|
||||
func (b byHash) Len() int { return len(b) }
|
||||
func (b byHash) Less(i, j int) bool { return hashOf(b[i]) < hashOf(b[j]) }
|
||||
func (b byHash) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
|
||||
|
||||
func TestRBACAuthorizer(t *testing.T) {
|
||||
ruleReadPods := rbacv1.PolicyRule{
|
||||
Verbs: []string{"GET", "WATCH"},
|
||||
APIGroups: []string{"v1"},
|
||||
Resources: []string{"pods"},
|
||||
}
|
||||
ruleReadServices := rbacv1.PolicyRule{
|
||||
Verbs: []string{"GET", "WATCH"},
|
||||
APIGroups: []string{"v1"},
|
||||
Resources: []string{"services"},
|
||||
}
|
||||
ruleWriteNodes := rbacv1.PolicyRule{
|
||||
Verbs: []string{"PUT", "CREATE", "UPDATE"},
|
||||
APIGroups: []string{"v1"},
|
||||
Resources: []string{"nodes"},
|
||||
}
|
||||
ruleAdmin := rbacv1.PolicyRule{
|
||||
Verbs: []string{"*"},
|
||||
APIGroups: []string{"*"},
|
||||
Resources: []string{"*"},
|
||||
}
|
||||
|
||||
staticRoles1 := StaticRoles{
|
||||
roles: []*rbacv1.Role{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace1", Name: "readthings"},
|
||||
Rules: []rbacv1.PolicyRule{ruleReadPods, ruleReadServices},
|
||||
},
|
||||
},
|
||||
clusterRoles: []*rbacv1.ClusterRole{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "cluster-admin"},
|
||||
Rules: []rbacv1.PolicyRule{ruleAdmin},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "write-nodes"},
|
||||
Rules: []rbacv1.PolicyRule{ruleWriteNodes},
|
||||
},
|
||||
},
|
||||
roleBindings: []*rbacv1.RoleBinding{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace1"},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "foobar"},
|
||||
{Kind: rbacv1.GroupKind, Name: "group1"},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{APIGroup: rbacv1.GroupName, Kind: "Role", Name: "readthings"},
|
||||
},
|
||||
},
|
||||
clusterRoleBindings: []*rbacv1.ClusterRoleBinding{
|
||||
{
|
||||
Subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "admin"},
|
||||
{Kind: rbacv1.GroupKind, Name: "admin"},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{APIGroup: rbacv1.GroupName, Kind: "ClusterRole", Name: "cluster-admin"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
StaticRoles
|
||||
|
||||
// For a given context, what are the rules that apply?
|
||||
user user.Info
|
||||
namespace string
|
||||
effectiveRules []rbacv1.PolicyRule
|
||||
}{
|
||||
{
|
||||
StaticRoles: staticRoles1,
|
||||
user: &user.DefaultInfo{Name: "foobar"},
|
||||
namespace: "namespace1",
|
||||
effectiveRules: []rbacv1.PolicyRule{ruleReadPods, ruleReadServices},
|
||||
},
|
||||
{
|
||||
StaticRoles: staticRoles1,
|
||||
user: &user.DefaultInfo{Name: "foobar"},
|
||||
namespace: "namespace2",
|
||||
effectiveRules: nil,
|
||||
},
|
||||
{
|
||||
StaticRoles: staticRoles1,
|
||||
// Same as above but without a namespace. Only cluster rules should apply.
|
||||
user: &user.DefaultInfo{Name: "foobar", Groups: []string{"admin"}},
|
||||
effectiveRules: []rbacv1.PolicyRule{ruleAdmin},
|
||||
},
|
||||
{
|
||||
StaticRoles: staticRoles1,
|
||||
user: &user.DefaultInfo{},
|
||||
effectiveRules: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range tests {
|
||||
ruleResolver, err := newMockRBACAuthorizer(&tc.StaticRoles)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
scope := iamv1alpha2.ClusterScope
|
||||
|
||||
if tc.namespace != "" {
|
||||
scope = iamv1alpha2.NamespaceScope
|
||||
}
|
||||
|
||||
rules, err := ruleResolver.rulesFor(authorizer.AttributesRecord{
|
||||
User: tc.user,
|
||||
Namespace: tc.namespace,
|
||||
ResourceScope: scope,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("case %d: GetEffectivePolicyRules(context)=%v", i, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Sort for deep equals
|
||||
sort.Sort(byHash(rules))
|
||||
sort.Sort(byHash(tc.effectiveRules))
|
||||
|
||||
if diff := cmp.Diff(rules, tc.effectiveRules); diff != "" {
|
||||
t.Errorf("case %d: %s", i, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newMockRBACAuthorizer(staticRoles *StaticRoles) (*RBACAuthorizer, error) {
|
||||
|
||||
ksClient := fakeks.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
istioClient := fakeistio.NewSimpleClientset()
|
||||
appClient := fakeapp.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, istioClient, appClient)
|
||||
|
||||
k8sInformerFactory := fakeInformerFactory.KubernetesSharedInformerFactory()
|
||||
|
||||
for _, role := range staticRoles.roles {
|
||||
err := k8sInformerFactory.Rbac().V1().Roles().Informer().GetIndexer().Add(role)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, roleBinding := range staticRoles.roleBindings {
|
||||
err := k8sInformerFactory.Rbac().V1().RoleBindings().Informer().GetIndexer().Add(roleBinding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, clusterRole := range staticRoles.clusterRoles {
|
||||
err := k8sInformerFactory.Rbac().V1().ClusterRoles().Informer().GetIndexer().Add(clusterRole)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, clusterRoleBinding := range staticRoles.clusterRoleBindings {
|
||||
err := k8sInformerFactory.Rbac().V1().ClusterRoleBindings().Informer().GetIndexer().Add(clusterRoleBinding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return NewRBACAuthorizer(am.NewAMOperator(fakeInformerFactory)), nil
|
||||
}
|
||||
|
||||
func TestAppliesTo(t *testing.T) {
|
||||
tests := []struct {
|
||||
subjects []rbacv1.Subject
|
||||
user user.Info
|
||||
namespace string
|
||||
appliesTo bool
|
||||
index int
|
||||
testCase string
|
||||
}{
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "foobar"},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "foobar"},
|
||||
appliesTo: true,
|
||||
index: 0,
|
||||
testCase: "single subject that matches username",
|
||||
},
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "barfoo"},
|
||||
{Kind: rbacv1.UserKind, Name: "foobar"},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "foobar"},
|
||||
appliesTo: true,
|
||||
index: 1,
|
||||
testCase: "multiple subjects, one that matches username",
|
||||
},
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "barfoo"},
|
||||
{Kind: rbacv1.UserKind, Name: "foobar"},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "zimzam"},
|
||||
appliesTo: false,
|
||||
testCase: "multiple subjects, none that match username",
|
||||
},
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "barfoo"},
|
||||
{Kind: rbacv1.GroupKind, Name: "foobar"},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "zimzam", Groups: []string{"foobar"}},
|
||||
appliesTo: true,
|
||||
index: 1,
|
||||
testCase: "multiple subjects, one that match group",
|
||||
},
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "barfoo"},
|
||||
{Kind: rbacv1.GroupKind, Name: "foobar"},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "zimzam", Groups: []string{"foobar"}},
|
||||
namespace: "namespace1",
|
||||
appliesTo: true,
|
||||
index: 1,
|
||||
testCase: "multiple subjects, one that match group, should ignore namespace",
|
||||
},
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "barfoo"},
|
||||
{Kind: rbacv1.GroupKind, Name: "foobar"},
|
||||
{Kind: rbacv1.ServiceAccountKind, Namespace: "kube-system", Name: "default"},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "system:serviceaccount:kube-system:default"},
|
||||
namespace: "default",
|
||||
appliesTo: true,
|
||||
index: 2,
|
||||
testCase: "multiple subjects with a service account that matches",
|
||||
},
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.UserKind, Name: "*"},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "foobar"},
|
||||
namespace: "default",
|
||||
appliesTo: false,
|
||||
testCase: "* user subject name doesn't match all users",
|
||||
},
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.GroupKind, Name: user.AllAuthenticated},
|
||||
{Kind: rbacv1.GroupKind, Name: user.AllUnauthenticated},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "foobar", Groups: []string{user.AllAuthenticated}},
|
||||
namespace: "default",
|
||||
appliesTo: true,
|
||||
index: 0,
|
||||
testCase: "binding to all authenticated and unauthenticated subjects matches authenticated user",
|
||||
},
|
||||
{
|
||||
subjects: []rbacv1.Subject{
|
||||
{Kind: rbacv1.GroupKind, Name: user.AllAuthenticated},
|
||||
{Kind: rbacv1.GroupKind, Name: user.AllUnauthenticated},
|
||||
},
|
||||
user: &user.DefaultInfo{Name: "system:anonymous", Groups: []string{user.AllUnauthenticated}},
|
||||
namespace: "default",
|
||||
appliesTo: true,
|
||||
index: 1,
|
||||
testCase: "binding to all authenticated and unauthenticated subjects matches anonymous user",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
gotIndex, got := appliesTo(tc.user, tc.subjects, tc.namespace)
|
||||
if got != tc.appliesTo {
|
||||
t.Errorf("case %q want appliesTo=%t, got appliesTo=%t", tc.testCase, tc.appliesTo, got)
|
||||
}
|
||||
if gotIndex != tc.index {
|
||||
t.Errorf("case %q want index %d, got %d", tc.testCase, tc.index, gotIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
54
pkg/apiserver/authorization/options/authorization_options.go
Normal file
54
pkg/apiserver/authorization/options/authorization_options.go
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 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 options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
)
|
||||
|
||||
type AuthorizationOptions struct {
|
||||
Mode string `json:"mode" yaml:"mode"`
|
||||
}
|
||||
|
||||
func NewAuthorizationOptions() *AuthorizationOptions {
|
||||
return &AuthorizationOptions{Mode: RBAC}
|
||||
}
|
||||
|
||||
var (
|
||||
AlwaysDeny = "AlwaysDeny"
|
||||
AlwaysAllow = "AlwaysAllow"
|
||||
RBAC = "RBAC"
|
||||
)
|
||||
|
||||
func (o *AuthorizationOptions) AddFlags(fs *pflag.FlagSet, s *AuthorizationOptions) {
|
||||
fs.StringVar(&o.Mode, "authorization", s.Mode, "Authorization setting, allowed values: AlwaysDeny, AlwaysAllow, RBAC.")
|
||||
}
|
||||
|
||||
func (o AuthorizationOptions) Validate() []error {
|
||||
errs := make([]error, 0)
|
||||
if !sliceutil.HasString([]string{AlwaysAllow, AlwaysDeny, RBAC}, o.Mode) {
|
||||
err := fmt.Errorf("authorization mode %s not support", o.Mode)
|
||||
klog.Error(err)
|
||||
errs = append(errs, err)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
|
||||
authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
||||
@@ -59,19 +60,20 @@ const (
|
||||
|
||||
// Config defines everything needed for apiserver to deal with external services
|
||||
type Config struct {
|
||||
DevopsOptions *jenkins.Options `json:"devops,omitempty" yaml:"devops,omitempty" mapstructure:"devops"`
|
||||
SonarQubeOptions *sonarqube.Options `json:"sonarqube,omitempty" yaml:"sonarQube,omitempty" mapstructure:"sonarqube"`
|
||||
KubernetesOptions *k8s.KubernetesOptions `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty" mapstructure:"kubernetes"`
|
||||
ServiceMeshOptions *servicemesh.Options `json:"servicemesh,omitempty" yaml:"servicemesh,omitempty" mapstructure:"servicemesh"`
|
||||
NetworkOptions *network.Options `json:"network,omitempty" yaml:"network,omitempty" mapstructure:"network"`
|
||||
LdapOptions *ldap.Options `json:"-" yaml:"ldap,omitempty" mapstructure:"ldap"`
|
||||
RedisOptions *cache.Options `json:"-" yaml:"redis,omitempty" mapstructure:"redis"`
|
||||
S3Options *s3.Options `json:"s3,omitempty" yaml:"s3,omitempty" mapstructure:"s3"`
|
||||
OpenPitrixOptions *openpitrix.Options `json:"openpitrix,omitempty" yaml:"openpitrix,omitempty" mapstructure:"openpitrix"`
|
||||
MonitoringOptions *prometheus.Options `json:"monitoring,omitempty" yaml:"monitoring,omitempty" mapstructure:"monitoring"`
|
||||
LoggingOptions *elasticsearch.Options `json:"logging,omitempty" yaml:"logging,omitempty" mapstructure:"logging"`
|
||||
AuthenticationOptions *authoptions.AuthenticationOptions `json:"-" yaml:"authentication,omitempty" mapstructure:"authentication"`
|
||||
MultiClusterOptions *multicluster.Options `json:"multicluster,omitempty" yaml:"multicluster,omitempty" mapstructure:"multicluster"`
|
||||
DevopsOptions *jenkins.Options `json:"devops,omitempty" yaml:"devops,omitempty" mapstructure:"devops"`
|
||||
SonarQubeOptions *sonarqube.Options `json:"sonarqube,omitempty" yaml:"sonarQube,omitempty" mapstructure:"sonarqube"`
|
||||
KubernetesOptions *k8s.KubernetesOptions `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty" mapstructure:"kubernetes"`
|
||||
ServiceMeshOptions *servicemesh.Options `json:"servicemesh,omitempty" yaml:"servicemesh,omitempty" mapstructure:"servicemesh"`
|
||||
NetworkOptions *network.Options `json:"network,omitempty" yaml:"network,omitempty" mapstructure:"network"`
|
||||
LdapOptions *ldap.Options `json:"-,omitempty" yaml:"ldap,omitempty" mapstructure:"ldap"`
|
||||
RedisOptions *cache.Options `json:"redis,omitempty" yaml:"redis,omitempty" mapstructure:"redis"`
|
||||
S3Options *s3.Options `json:"s3,omitempty" yaml:"s3,omitempty" mapstructure:"s3"`
|
||||
OpenPitrixOptions *openpitrix.Options `json:"openpitrix,omitempty" yaml:"openpitrix,omitempty" mapstructure:"openpitrix"`
|
||||
MonitoringOptions *prometheus.Options `json:"monitoring,omitempty" yaml:"monitoring,omitempty" mapstructure:"monitoring"`
|
||||
LoggingOptions *elasticsearch.Options `json:"logging,omitempty" yaml:"logging,omitempty" mapstructure:"logging"`
|
||||
AuthenticationOptions *authoptions.AuthenticationOptions `json:"authentication,omitempty" yaml:"authentication,omitempty" mapstructure:"authentication"`
|
||||
AuthorizationOptions *authorizationoptions.AuthorizationOptions `json:"authorization,omitempty" yaml:"authorization,omitempty" mapstructure:"authorization"`
|
||||
MultiClusterOptions *multicluster.Options `json:"multicluster,omitempty" yaml:"multicluster,omitempty" mapstructure:"multicluster"`
|
||||
// Options used for enabling components, not actually used now. Once we switch Alerting/Notification API to kubesphere,
|
||||
// we can add these options to kubesphere command lines
|
||||
AlertingOptions *alerting.Options `json:"alerting,omitempty" yaml:"alerting,omitempty" mapstructure:"alerting"`
|
||||
@@ -95,6 +97,8 @@ func New() *Config {
|
||||
NotificationOptions: notification.NewNotificationOptions(),
|
||||
LoggingOptions: elasticsearch.NewElasticSearchOptions(),
|
||||
AuthenticationOptions: authoptions.NewAuthenticateOptions(),
|
||||
AuthorizationOptions: authorizationoptions.NewAuthorizationOptions(),
|
||||
MultiClusterOptions: multicluster.NewOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,5 +213,4 @@ func (conf *Config) stripEmptyOptions() {
|
||||
if conf.MultiClusterOptions != nil && !conf.MultiClusterOptions.Enable {
|
||||
conf.MultiClusterOptions = nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"io/ioutil"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth"
|
||||
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
|
||||
authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
||||
@@ -99,6 +100,7 @@ func newTestConfig() (*Config, error) {
|
||||
NotificationOptions: ¬ification.Options{
|
||||
Endpoint: "http://notification.kubesphere-alerting-system.svc:9200",
|
||||
},
|
||||
AuthorizationOptions: authorizationoptions.NewAuthorizationOptions(),
|
||||
AuthenticationOptions: &authoptions.AuthenticationOptions{
|
||||
AuthenticateRateLimiterMaxTries: 5,
|
||||
AuthenticateRateLimiterDuration: 30 * time.Minute,
|
||||
|
||||
@@ -59,6 +59,7 @@ func getAuthorizerAttributes(ctx context.Context) (authorizer.Attributes, error)
|
||||
}
|
||||
|
||||
// Start with common attributes that apply to resource and non-resource requests
|
||||
attribs.ResourceScope = requestInfo.ResourceScope
|
||||
attribs.ResourceRequest = requestInfo.IsResourceRequest
|
||||
attribs.Path = requestInfo.Path
|
||||
attribs.Verb = requestInfo.Verb
|
||||
|
||||
@@ -7,7 +7,9 @@ const (
|
||||
FieldName = "name"
|
||||
FieldUID = "uid"
|
||||
FieldCreationTimeStamp = "creationTimestamp"
|
||||
FieldCreateTime = "createTime"
|
||||
FieldLastUpdateTimestamp = "lastUpdateTimestamp"
|
||||
FieldUpdateTime = "updateTime"
|
||||
FieldLabel = "label"
|
||||
FieldAnnotation = "annotation"
|
||||
FieldNamespace = "namespace"
|
||||
@@ -18,6 +20,8 @@ const (
|
||||
|
||||
var SortableFields = []Field{
|
||||
FieldCreationTimeStamp,
|
||||
FieldCreateTime,
|
||||
FieldUpdateTime,
|
||||
FieldLastUpdateTimestamp,
|
||||
FieldName,
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package query
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -26,7 +28,9 @@ type Query struct {
|
||||
Ascending bool
|
||||
|
||||
//
|
||||
Filters []Filter
|
||||
Filters map[Field]Value
|
||||
|
||||
LabelSelector string
|
||||
}
|
||||
|
||||
type Pagination struct {
|
||||
@@ -47,17 +51,27 @@ func newPagination(limit int, offset int) *Pagination {
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Query) Selector() labels.Selector {
|
||||
if selector, err := labels.Parse(q.LabelSelector); err != nil {
|
||||
return labels.Everything()
|
||||
} else {
|
||||
return selector
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pagination) GetValidPagination(total int) (startIndex, endIndex int) {
|
||||
|
||||
// no pagination
|
||||
if p.Limit == NoPagination.Limit {
|
||||
return 0, total
|
||||
}
|
||||
|
||||
if p.Limit < 0 || p.Offset < 0 || total == 0 {
|
||||
// out of range
|
||||
if p.Limit < 0 || p.Offset < 0 || p.Offset > total {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
startIndex = p.Limit * p.Offset
|
||||
startIndex = p.Offset
|
||||
endIndex = startIndex + p.Limit
|
||||
|
||||
if endIndex > total {
|
||||
@@ -72,7 +86,7 @@ func New() *Query {
|
||||
Pagination: NoPagination,
|
||||
SortBy: "",
|
||||
Ascending: false,
|
||||
Filters: []Filter{},
|
||||
Filters: map[Field]Value{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,35 +98,36 @@ type Filter struct {
|
||||
func ParseQueryParameter(request *restful.Request) *Query {
|
||||
query := New()
|
||||
|
||||
limit, err := strconv.Atoi(request.QueryParameter("limit"))
|
||||
limit, err := strconv.Atoi(request.QueryParameter(ParameterLimit))
|
||||
// equivalent to undefined, use the default value
|
||||
if err != nil {
|
||||
limit = -1
|
||||
}
|
||||
page, err := strconv.Atoi(request.QueryParameter("page"))
|
||||
page, err := strconv.Atoi(request.QueryParameter(ParameterPage))
|
||||
// equivalent to undefined, use the default value
|
||||
if err != nil {
|
||||
page = 1
|
||||
}
|
||||
|
||||
query.Pagination = newPagination(limit, page-1)
|
||||
query.Pagination = newPagination(limit, (page-1)*limit)
|
||||
|
||||
query.SortBy = Field(defaultString(request.QueryParameter("sortBy"), FieldCreationTimeStamp))
|
||||
query.SortBy = Field(defaultString(request.QueryParameter(ParameterOrderBy), FieldCreationTimeStamp))
|
||||
|
||||
ascending, err := strconv.ParseBool(defaultString(request.QueryParameter("ascending"), "false"))
|
||||
ascending, err := strconv.ParseBool(defaultString(request.QueryParameter(ParameterAscending), "false"))
|
||||
if err != nil {
|
||||
query.Ascending = false
|
||||
} else {
|
||||
query.Ascending = ascending
|
||||
}
|
||||
|
||||
for _, field := range ComparableFields {
|
||||
f := request.QueryParameter(string(field))
|
||||
if len(f) != 0 {
|
||||
query.Filters = append(query.Filters, Filter{
|
||||
Field: field,
|
||||
Value: Value(f),
|
||||
})
|
||||
query.LabelSelector = request.QueryParameter(ParameterLabelSelector)
|
||||
|
||||
for key, values := range request.Request.URL.Query() {
|
||||
if !sliceutil.HasString([]string{ParameterPage, ParameterLimit, ParameterOrderBy, ParameterAscending, ParameterLabelSelector}, key) {
|
||||
// support multiple query condition
|
||||
for _, value := range values {
|
||||
query.Filters[Field(key)] = Value(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,24 +16,15 @@ func TestParseQueryParameter(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
"test normal case",
|
||||
"label=app.kubernetes.io/name:book&name=foo&status=Running&page=1&limit=10&ascending=true",
|
||||
"label=app.kubernetes.io/name=book&name=foo&status=Running&page=1&limit=10&ascending=true",
|
||||
&Query{
|
||||
Pagination: newPagination(10, 0),
|
||||
SortBy: FieldCreationTimeStamp,
|
||||
Ascending: true,
|
||||
Filters: []Filter{
|
||||
{
|
||||
FieldName,
|
||||
Value("foo"),
|
||||
},
|
||||
{
|
||||
FieldLabel,
|
||||
Value("app.kubernetes.io/name:book"),
|
||||
},
|
||||
{
|
||||
FieldStatus,
|
||||
Value("Running"),
|
||||
},
|
||||
Filters: map[Field]Value{
|
||||
FieldLabel: Value("app.kubernetes.io/name=book"),
|
||||
FieldName: Value("foo"),
|
||||
FieldStatus: Value("Running"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -44,7 +35,10 @@ func TestParseQueryParameter(t *testing.T) {
|
||||
Pagination: NoPagination,
|
||||
SortBy: FieldCreationTimeStamp,
|
||||
Ascending: false,
|
||||
Filters: []Filter{},
|
||||
Filters: map[Field]Value{
|
||||
Field("xxxx"): Value("xxxx"),
|
||||
Field("dsfsw"): Value("xxxx"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -61,6 +55,7 @@ func TestParseQueryParameter(t *testing.T) {
|
||||
got := ParseQueryParameter(request)
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/validation/path"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -46,11 +48,15 @@ type RequestInfo struct {
|
||||
|
||||
// Cluster of requested resource, this is empty in single-cluster environment
|
||||
Cluster string
|
||||
|
||||
// Scope of requested resource.
|
||||
ResourceScope string
|
||||
}
|
||||
|
||||
type RequestInfoFactory struct {
|
||||
APIPrefixes sets.String
|
||||
GrouplessAPIPrefixes sets.String
|
||||
GlobalResources []schema.GroupResource
|
||||
}
|
||||
|
||||
// NewRequestInfo returns the information from the http request. If error is not nil, RequestInfo holds the information as best it is known before the failure
|
||||
@@ -188,6 +194,8 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
|
||||
// parsing successful, so we now know the proper value for .Parts
|
||||
requestInfo.Parts = currentParts
|
||||
|
||||
requestInfo.ResourceScope = r.resolveResourceScope(requestInfo)
|
||||
|
||||
// parts look like: resource/resourceName/subresource/other/stuff/we/don't/interpret
|
||||
switch {
|
||||
case len(requestInfo.Parts) >= 3 && !specialVerbsNoSubresources.Has(requestInfo.Verb):
|
||||
@@ -264,3 +272,21 @@ func splitPath(path string) []string {
|
||||
}
|
||||
return strings.Split(path, "/")
|
||||
}
|
||||
|
||||
func (r *RequestInfoFactory) resolveResourceScope(request RequestInfo) string {
|
||||
for _, globalResource := range r.GlobalResources {
|
||||
if globalResource.Group == request.APIGroup &&
|
||||
globalResource.Resource == request.Resource {
|
||||
return iamv1alpha2.GlobalScope
|
||||
}
|
||||
}
|
||||
if request.Namespace != "" {
|
||||
return iamv1alpha2.NamespaceScope
|
||||
}
|
||||
|
||||
if request.Workspace != "" {
|
||||
return iamv1alpha2.WorkspaceScope
|
||||
}
|
||||
|
||||
return iamv1alpha2.ClusterScope
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// FakeGlobalRoles implements GlobalRoleInterface
|
||||
type FakeGlobalRoles struct {
|
||||
Fake *FakeIamV1alpha2
|
||||
}
|
||||
|
||||
var globalrolesResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "globalroles"}
|
||||
|
||||
var globalrolesKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "GlobalRole"}
|
||||
|
||||
// Get takes name of the globalRole, and returns the corresponding globalRole object, and an error if there is any.
|
||||
func (c *FakeGlobalRoles) Get(name string, options v1.GetOptions) (result *v1alpha2.GlobalRole, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(globalrolesResource, name), &v1alpha2.GlobalRole{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRole), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of GlobalRoles that match those selectors.
|
||||
func (c *FakeGlobalRoles) List(opts v1.ListOptions) (result *v1alpha2.GlobalRoleList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(globalrolesResource, globalrolesKind, opts), &v1alpha2.GlobalRoleList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha2.GlobalRoleList{ListMeta: obj.(*v1alpha2.GlobalRoleList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha2.GlobalRoleList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested globalRoles.
|
||||
func (c *FakeGlobalRoles) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(globalrolesResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a globalRole and creates it. Returns the server's representation of the globalRole, and an error, if there is any.
|
||||
func (c *FakeGlobalRoles) Create(globalRole *v1alpha2.GlobalRole) (result *v1alpha2.GlobalRole, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(globalrolesResource, globalRole), &v1alpha2.GlobalRole{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRole), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a globalRole and updates it. Returns the server's representation of the globalRole, and an error, if there is any.
|
||||
func (c *FakeGlobalRoles) Update(globalRole *v1alpha2.GlobalRole) (result *v1alpha2.GlobalRole, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(globalrolesResource, globalRole), &v1alpha2.GlobalRole{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRole), err
|
||||
}
|
||||
|
||||
// Delete takes name of the globalRole and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeGlobalRoles) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(globalrolesResource, name), &v1alpha2.GlobalRole{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeGlobalRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(globalrolesResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha2.GlobalRoleList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched globalRole.
|
||||
func (c *FakeGlobalRoles) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRole, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(globalrolesResource, name, pt, data, subresources...), &v1alpha2.GlobalRole{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRole), err
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// FakeGlobalRoleBindings implements GlobalRoleBindingInterface
|
||||
type FakeGlobalRoleBindings struct {
|
||||
Fake *FakeIamV1alpha2
|
||||
}
|
||||
|
||||
var globalrolebindingsResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "globalrolebindings"}
|
||||
|
||||
var globalrolebindingsKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "GlobalRoleBinding"}
|
||||
|
||||
// Get takes name of the globalRoleBinding, and returns the corresponding globalRoleBinding object, and an error if there is any.
|
||||
func (c *FakeGlobalRoleBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.GlobalRoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(globalrolebindingsResource, name), &v1alpha2.GlobalRoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRoleBinding), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of GlobalRoleBindings that match those selectors.
|
||||
func (c *FakeGlobalRoleBindings) List(opts v1.ListOptions) (result *v1alpha2.GlobalRoleBindingList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(globalrolebindingsResource, globalrolebindingsKind, opts), &v1alpha2.GlobalRoleBindingList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha2.GlobalRoleBindingList{ListMeta: obj.(*v1alpha2.GlobalRoleBindingList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha2.GlobalRoleBindingList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested globalRoleBindings.
|
||||
func (c *FakeGlobalRoleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(globalrolebindingsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a globalRoleBinding and creates it. Returns the server's representation of the globalRoleBinding, and an error, if there is any.
|
||||
func (c *FakeGlobalRoleBindings) Create(globalRoleBinding *v1alpha2.GlobalRoleBinding) (result *v1alpha2.GlobalRoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(globalrolebindingsResource, globalRoleBinding), &v1alpha2.GlobalRoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRoleBinding), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a globalRoleBinding and updates it. Returns the server's representation of the globalRoleBinding, and an error, if there is any.
|
||||
func (c *FakeGlobalRoleBindings) Update(globalRoleBinding *v1alpha2.GlobalRoleBinding) (result *v1alpha2.GlobalRoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(globalrolebindingsResource, globalRoleBinding), &v1alpha2.GlobalRoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRoleBinding), err
|
||||
}
|
||||
|
||||
// Delete takes name of the globalRoleBinding and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeGlobalRoleBindings) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(globalrolebindingsResource, name), &v1alpha2.GlobalRoleBinding{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeGlobalRoleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(globalrolebindingsResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha2.GlobalRoleBindingList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched globalRoleBinding.
|
||||
func (c *FakeGlobalRoleBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(globalrolebindingsResource, name, pt, data, subresources...), &v1alpha2.GlobalRoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRoleBinding), err
|
||||
}
|
||||
@@ -28,22 +28,26 @@ type FakeIamV1alpha2 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeIamV1alpha2) PolicyRules() v1alpha2.PolicyRuleInterface {
|
||||
return &FakePolicyRules{c}
|
||||
func (c *FakeIamV1alpha2) GlobalRoles() v1alpha2.GlobalRoleInterface {
|
||||
return &FakeGlobalRoles{c}
|
||||
}
|
||||
|
||||
func (c *FakeIamV1alpha2) Roles() v1alpha2.RoleInterface {
|
||||
return &FakeRoles{c}
|
||||
}
|
||||
|
||||
func (c *FakeIamV1alpha2) RoleBindings() v1alpha2.RoleBindingInterface {
|
||||
return &FakeRoleBindings{c}
|
||||
func (c *FakeIamV1alpha2) GlobalRoleBindings() v1alpha2.GlobalRoleBindingInterface {
|
||||
return &FakeGlobalRoleBindings{c}
|
||||
}
|
||||
|
||||
func (c *FakeIamV1alpha2) Users() v1alpha2.UserInterface {
|
||||
return &FakeUsers{c}
|
||||
}
|
||||
|
||||
func (c *FakeIamV1alpha2) WorkspaceRoles() v1alpha2.WorkspaceRoleInterface {
|
||||
return &FakeWorkspaceRoles{c}
|
||||
}
|
||||
|
||||
func (c *FakeIamV1alpha2) WorkspaceRoleBindings() v1alpha2.WorkspaceRoleBindingInterface {
|
||||
return &FakeWorkspaceRoleBindings{c}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeIamV1alpha2) RESTClient() rest.Interface {
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// FakePolicyRules implements PolicyRuleInterface
|
||||
type FakePolicyRules struct {
|
||||
Fake *FakeIamV1alpha2
|
||||
}
|
||||
|
||||
var policyrulesResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "policyrules"}
|
||||
|
||||
var policyrulesKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "PolicyRule"}
|
||||
|
||||
// Get takes name of the policyRule, and returns the corresponding policyRule object, and an error if there is any.
|
||||
func (c *FakePolicyRules) Get(name string, options v1.GetOptions) (result *v1alpha2.PolicyRule, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(policyrulesResource, name), &v1alpha2.PolicyRule{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.PolicyRule), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PolicyRules that match those selectors.
|
||||
func (c *FakePolicyRules) List(opts v1.ListOptions) (result *v1alpha2.PolicyRuleList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(policyrulesResource, policyrulesKind, opts), &v1alpha2.PolicyRuleList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha2.PolicyRuleList{ListMeta: obj.(*v1alpha2.PolicyRuleList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha2.PolicyRuleList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested policyRules.
|
||||
func (c *FakePolicyRules) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(policyrulesResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a policyRule and creates it. Returns the server's representation of the policyRule, and an error, if there is any.
|
||||
func (c *FakePolicyRules) Create(policyRule *v1alpha2.PolicyRule) (result *v1alpha2.PolicyRule, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(policyrulesResource, policyRule), &v1alpha2.PolicyRule{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.PolicyRule), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a policyRule and updates it. Returns the server's representation of the policyRule, and an error, if there is any.
|
||||
func (c *FakePolicyRules) Update(policyRule *v1alpha2.PolicyRule) (result *v1alpha2.PolicyRule, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(policyrulesResource, policyRule), &v1alpha2.PolicyRule{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.PolicyRule), err
|
||||
}
|
||||
|
||||
// Delete takes name of the policyRule and deletes it. Returns an error if one occurs.
|
||||
func (c *FakePolicyRules) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(policyrulesResource, name), &v1alpha2.PolicyRule{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakePolicyRules) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(policyrulesResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha2.PolicyRuleList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched policyRule.
|
||||
func (c *FakePolicyRules) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.PolicyRule, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(policyrulesResource, name, pt, data, subresources...), &v1alpha2.PolicyRule{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.PolicyRule), err
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// FakeRoles implements RoleInterface
|
||||
type FakeRoles struct {
|
||||
Fake *FakeIamV1alpha2
|
||||
}
|
||||
|
||||
var rolesResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "roles"}
|
||||
|
||||
var rolesKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "Role"}
|
||||
|
||||
// Get takes name of the role, and returns the corresponding role object, and an error if there is any.
|
||||
func (c *FakeRoles) Get(name string, options v1.GetOptions) (result *v1alpha2.Role, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(rolesResource, name), &v1alpha2.Role{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Role), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Roles that match those selectors.
|
||||
func (c *FakeRoles) List(opts v1.ListOptions) (result *v1alpha2.RoleList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(rolesResource, rolesKind, opts), &v1alpha2.RoleList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha2.RoleList{ListMeta: obj.(*v1alpha2.RoleList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha2.RoleList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested roles.
|
||||
func (c *FakeRoles) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(rolesResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a role and creates it. Returns the server's representation of the role, and an error, if there is any.
|
||||
func (c *FakeRoles) Create(role *v1alpha2.Role) (result *v1alpha2.Role, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(rolesResource, role), &v1alpha2.Role{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Role), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a role and updates it. Returns the server's representation of the role, and an error, if there is any.
|
||||
func (c *FakeRoles) Update(role *v1alpha2.Role) (result *v1alpha2.Role, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(rolesResource, role), &v1alpha2.Role{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Role), err
|
||||
}
|
||||
|
||||
// Delete takes name of the role and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeRoles) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(rolesResource, name), &v1alpha2.Role{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(rolesResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha2.RoleList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched role.
|
||||
func (c *FakeRoles) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Role, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(rolesResource, name, pt, data, subresources...), &v1alpha2.Role{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Role), err
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// FakeRoleBindings implements RoleBindingInterface
|
||||
type FakeRoleBindings struct {
|
||||
Fake *FakeIamV1alpha2
|
||||
}
|
||||
|
||||
var rolebindingsResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "rolebindings"}
|
||||
|
||||
var rolebindingsKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "RoleBinding"}
|
||||
|
||||
// Get takes name of the roleBinding, and returns the corresponding roleBinding object, and an error if there is any.
|
||||
func (c *FakeRoleBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.RoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(rolebindingsResource, name), &v1alpha2.RoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.RoleBinding), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of RoleBindings that match those selectors.
|
||||
func (c *FakeRoleBindings) List(opts v1.ListOptions) (result *v1alpha2.RoleBindingList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(rolebindingsResource, rolebindingsKind, opts), &v1alpha2.RoleBindingList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha2.RoleBindingList{ListMeta: obj.(*v1alpha2.RoleBindingList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha2.RoleBindingList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested roleBindings.
|
||||
func (c *FakeRoleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(rolebindingsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a roleBinding and creates it. Returns the server's representation of the roleBinding, and an error, if there is any.
|
||||
func (c *FakeRoleBindings) Create(roleBinding *v1alpha2.RoleBinding) (result *v1alpha2.RoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(rolebindingsResource, roleBinding), &v1alpha2.RoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.RoleBinding), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a roleBinding and updates it. Returns the server's representation of the roleBinding, and an error, if there is any.
|
||||
func (c *FakeRoleBindings) Update(roleBinding *v1alpha2.RoleBinding) (result *v1alpha2.RoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(rolebindingsResource, roleBinding), &v1alpha2.RoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.RoleBinding), err
|
||||
}
|
||||
|
||||
// Delete takes name of the roleBinding and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeRoleBindings) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(rolebindingsResource, name), &v1alpha2.RoleBinding{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeRoleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(rolebindingsResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha2.RoleBindingList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched roleBinding.
|
||||
func (c *FakeRoleBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.RoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(rolebindingsResource, name, pt, data, subresources...), &v1alpha2.RoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.RoleBinding), err
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// FakeWorkspaceRoles implements WorkspaceRoleInterface
|
||||
type FakeWorkspaceRoles struct {
|
||||
Fake *FakeIamV1alpha2
|
||||
}
|
||||
|
||||
var workspacerolesResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "workspaceroles"}
|
||||
|
||||
var workspacerolesKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "WorkspaceRole"}
|
||||
|
||||
// Get takes name of the workspaceRole, and returns the corresponding workspaceRole object, and an error if there is any.
|
||||
func (c *FakeWorkspaceRoles) Get(name string, options v1.GetOptions) (result *v1alpha2.WorkspaceRole, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(workspacerolesResource, name), &v1alpha2.WorkspaceRole{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRole), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of WorkspaceRoles that match those selectors.
|
||||
func (c *FakeWorkspaceRoles) List(opts v1.ListOptions) (result *v1alpha2.WorkspaceRoleList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(workspacerolesResource, workspacerolesKind, opts), &v1alpha2.WorkspaceRoleList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha2.WorkspaceRoleList{ListMeta: obj.(*v1alpha2.WorkspaceRoleList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha2.WorkspaceRoleList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested workspaceRoles.
|
||||
func (c *FakeWorkspaceRoles) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(workspacerolesResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a workspaceRole and creates it. Returns the server's representation of the workspaceRole, and an error, if there is any.
|
||||
func (c *FakeWorkspaceRoles) Create(workspaceRole *v1alpha2.WorkspaceRole) (result *v1alpha2.WorkspaceRole, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(workspacerolesResource, workspaceRole), &v1alpha2.WorkspaceRole{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRole), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a workspaceRole and updates it. Returns the server's representation of the workspaceRole, and an error, if there is any.
|
||||
func (c *FakeWorkspaceRoles) Update(workspaceRole *v1alpha2.WorkspaceRole) (result *v1alpha2.WorkspaceRole, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(workspacerolesResource, workspaceRole), &v1alpha2.WorkspaceRole{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRole), err
|
||||
}
|
||||
|
||||
// Delete takes name of the workspaceRole and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeWorkspaceRoles) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(workspacerolesResource, name), &v1alpha2.WorkspaceRole{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeWorkspaceRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(workspacerolesResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha2.WorkspaceRoleList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched workspaceRole.
|
||||
func (c *FakeWorkspaceRoles) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.WorkspaceRole, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(workspacerolesResource, name, pt, data, subresources...), &v1alpha2.WorkspaceRole{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRole), err
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// FakeWorkspaceRoleBindings implements WorkspaceRoleBindingInterface
|
||||
type FakeWorkspaceRoleBindings struct {
|
||||
Fake *FakeIamV1alpha2
|
||||
}
|
||||
|
||||
var workspacerolebindingsResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "workspacerolebindings"}
|
||||
|
||||
var workspacerolebindingsKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "WorkspaceRoleBinding"}
|
||||
|
||||
// Get takes name of the workspaceRoleBinding, and returns the corresponding workspaceRoleBinding object, and an error if there is any.
|
||||
func (c *FakeWorkspaceRoleBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(workspacerolebindingsResource, name), &v1alpha2.WorkspaceRoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRoleBinding), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of WorkspaceRoleBindings that match those selectors.
|
||||
func (c *FakeWorkspaceRoleBindings) List(opts v1.ListOptions) (result *v1alpha2.WorkspaceRoleBindingList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(workspacerolebindingsResource, workspacerolebindingsKind, opts), &v1alpha2.WorkspaceRoleBindingList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha2.WorkspaceRoleBindingList{ListMeta: obj.(*v1alpha2.WorkspaceRoleBindingList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha2.WorkspaceRoleBindingList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested workspaceRoleBindings.
|
||||
func (c *FakeWorkspaceRoleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(workspacerolebindingsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a workspaceRoleBinding and creates it. Returns the server's representation of the workspaceRoleBinding, and an error, if there is any.
|
||||
func (c *FakeWorkspaceRoleBindings) Create(workspaceRoleBinding *v1alpha2.WorkspaceRoleBinding) (result *v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(workspacerolebindingsResource, workspaceRoleBinding), &v1alpha2.WorkspaceRoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRoleBinding), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a workspaceRoleBinding and updates it. Returns the server's representation of the workspaceRoleBinding, and an error, if there is any.
|
||||
func (c *FakeWorkspaceRoleBindings) Update(workspaceRoleBinding *v1alpha2.WorkspaceRoleBinding) (result *v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(workspacerolebindingsResource, workspaceRoleBinding), &v1alpha2.WorkspaceRoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRoleBinding), err
|
||||
}
|
||||
|
||||
// Delete takes name of the workspaceRoleBinding and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeWorkspaceRoleBindings) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(workspacerolebindingsResource, name), &v1alpha2.WorkspaceRoleBinding{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeWorkspaceRoleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(workspacerolebindingsResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha2.WorkspaceRoleBindingList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched workspaceRoleBinding.
|
||||
func (c *FakeWorkspaceRoleBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(workspacerolebindingsResource, name, pt, data, subresources...), &v1alpha2.WorkspaceRoleBinding{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRoleBinding), err
|
||||
}
|
||||
@@ -18,10 +18,12 @@ limitations under the License.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
type PolicyRuleExpansion interface{}
|
||||
type GlobalRoleExpansion interface{}
|
||||
|
||||
type RoleExpansion interface{}
|
||||
|
||||
type RoleBindingExpansion interface{}
|
||||
type GlobalRoleBindingExpansion interface{}
|
||||
|
||||
type UserExpansion interface{}
|
||||
|
||||
type WorkspaceRoleExpansion interface{}
|
||||
|
||||
type WorkspaceRoleBindingExpansion interface{}
|
||||
|
||||
@@ -29,42 +29,42 @@ import (
|
||||
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// PolicyRulesGetter has a method to return a PolicyRuleInterface.
|
||||
// GlobalRolesGetter has a method to return a GlobalRoleInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PolicyRulesGetter interface {
|
||||
PolicyRules() PolicyRuleInterface
|
||||
type GlobalRolesGetter interface {
|
||||
GlobalRoles() GlobalRoleInterface
|
||||
}
|
||||
|
||||
// PolicyRuleInterface has methods to work with PolicyRule resources.
|
||||
type PolicyRuleInterface interface {
|
||||
Create(*v1alpha2.PolicyRule) (*v1alpha2.PolicyRule, error)
|
||||
Update(*v1alpha2.PolicyRule) (*v1alpha2.PolicyRule, error)
|
||||
// GlobalRoleInterface has methods to work with GlobalRole resources.
|
||||
type GlobalRoleInterface interface {
|
||||
Create(*v1alpha2.GlobalRole) (*v1alpha2.GlobalRole, error)
|
||||
Update(*v1alpha2.GlobalRole) (*v1alpha2.GlobalRole, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha2.PolicyRule, error)
|
||||
List(opts v1.ListOptions) (*v1alpha2.PolicyRuleList, error)
|
||||
Get(name string, options v1.GetOptions) (*v1alpha2.GlobalRole, error)
|
||||
List(opts v1.ListOptions) (*v1alpha2.GlobalRoleList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.PolicyRule, err error)
|
||||
PolicyRuleExpansion
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRole, err error)
|
||||
GlobalRoleExpansion
|
||||
}
|
||||
|
||||
// policyRules implements PolicyRuleInterface
|
||||
type policyRules struct {
|
||||
// globalRoles implements GlobalRoleInterface
|
||||
type globalRoles struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newPolicyRules returns a PolicyRules
|
||||
func newPolicyRules(c *IamV1alpha2Client) *policyRules {
|
||||
return &policyRules{
|
||||
// newGlobalRoles returns a GlobalRoles
|
||||
func newGlobalRoles(c *IamV1alpha2Client) *globalRoles {
|
||||
return &globalRoles{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the policyRule, and returns the corresponding policyRule object, and an error if there is any.
|
||||
func (c *policyRules) Get(name string, options v1.GetOptions) (result *v1alpha2.PolicyRule, err error) {
|
||||
result = &v1alpha2.PolicyRule{}
|
||||
// Get takes name of the globalRole, and returns the corresponding globalRole object, and an error if there is any.
|
||||
func (c *globalRoles) Get(name string, options v1.GetOptions) (result *v1alpha2.GlobalRole, err error) {
|
||||
result = &v1alpha2.GlobalRole{}
|
||||
err = c.client.Get().
|
||||
Resource("policyrules").
|
||||
Resource("globalroles").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
@@ -72,15 +72,15 @@ func (c *policyRules) Get(name string, options v1.GetOptions) (result *v1alpha2.
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PolicyRules that match those selectors.
|
||||
func (c *policyRules) List(opts v1.ListOptions) (result *v1alpha2.PolicyRuleList, err error) {
|
||||
// List takes label and field selectors, and returns the list of GlobalRoles that match those selectors.
|
||||
func (c *globalRoles) List(opts v1.ListOptions) (result *v1alpha2.GlobalRoleList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha2.PolicyRuleList{}
|
||||
result = &v1alpha2.GlobalRoleList{}
|
||||
err = c.client.Get().
|
||||
Resource("policyrules").
|
||||
Resource("globalroles").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
@@ -88,47 +88,47 @@ func (c *policyRules) List(opts v1.ListOptions) (result *v1alpha2.PolicyRuleList
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested policyRules.
|
||||
func (c *policyRules) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
// Watch returns a watch.Interface that watches the requested globalRoles.
|
||||
func (c *globalRoles) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("policyrules").
|
||||
Resource("globalroles").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a policyRule and creates it. Returns the server's representation of the policyRule, and an error, if there is any.
|
||||
func (c *policyRules) Create(policyRule *v1alpha2.PolicyRule) (result *v1alpha2.PolicyRule, err error) {
|
||||
result = &v1alpha2.PolicyRule{}
|
||||
// Create takes the representation of a globalRole and creates it. Returns the server's representation of the globalRole, and an error, if there is any.
|
||||
func (c *globalRoles) Create(globalRole *v1alpha2.GlobalRole) (result *v1alpha2.GlobalRole, err error) {
|
||||
result = &v1alpha2.GlobalRole{}
|
||||
err = c.client.Post().
|
||||
Resource("policyrules").
|
||||
Body(policyRule).
|
||||
Resource("globalroles").
|
||||
Body(globalRole).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a policyRule and updates it. Returns the server's representation of the policyRule, and an error, if there is any.
|
||||
func (c *policyRules) Update(policyRule *v1alpha2.PolicyRule) (result *v1alpha2.PolicyRule, err error) {
|
||||
result = &v1alpha2.PolicyRule{}
|
||||
// Update takes the representation of a globalRole and updates it. Returns the server's representation of the globalRole, and an error, if there is any.
|
||||
func (c *globalRoles) Update(globalRole *v1alpha2.GlobalRole) (result *v1alpha2.GlobalRole, err error) {
|
||||
result = &v1alpha2.GlobalRole{}
|
||||
err = c.client.Put().
|
||||
Resource("policyrules").
|
||||
Name(policyRule.Name).
|
||||
Body(policyRule).
|
||||
Resource("globalroles").
|
||||
Name(globalRole.Name).
|
||||
Body(globalRole).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the policyRule and deletes it. Returns an error if one occurs.
|
||||
func (c *policyRules) Delete(name string, options *v1.DeleteOptions) error {
|
||||
// Delete takes name of the globalRole and deletes it. Returns an error if one occurs.
|
||||
func (c *globalRoles) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("policyrules").
|
||||
Resource("globalroles").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
@@ -136,13 +136,13 @@ func (c *policyRules) Delete(name string, options *v1.DeleteOptions) error {
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *policyRules) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
func (c *globalRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("policyrules").
|
||||
Resource("globalroles").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
@@ -150,11 +150,11 @@ func (c *policyRules) DeleteCollection(options *v1.DeleteOptions, listOptions v1
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched policyRule.
|
||||
func (c *policyRules) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.PolicyRule, err error) {
|
||||
result = &v1alpha2.PolicyRule{}
|
||||
// Patch applies the patch and returns the patched globalRole.
|
||||
func (c *globalRoles) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRole, err error) {
|
||||
result = &v1alpha2.GlobalRole{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("policyrules").
|
||||
Resource("globalroles").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// GlobalRoleBindingsGetter has a method to return a GlobalRoleBindingInterface.
|
||||
// A group's client should implement this interface.
|
||||
type GlobalRoleBindingsGetter interface {
|
||||
GlobalRoleBindings() GlobalRoleBindingInterface
|
||||
}
|
||||
|
||||
// GlobalRoleBindingInterface has methods to work with GlobalRoleBinding resources.
|
||||
type GlobalRoleBindingInterface interface {
|
||||
Create(*v1alpha2.GlobalRoleBinding) (*v1alpha2.GlobalRoleBinding, error)
|
||||
Update(*v1alpha2.GlobalRoleBinding) (*v1alpha2.GlobalRoleBinding, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha2.GlobalRoleBinding, error)
|
||||
List(opts v1.ListOptions) (*v1alpha2.GlobalRoleBindingList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRoleBinding, err error)
|
||||
GlobalRoleBindingExpansion
|
||||
}
|
||||
|
||||
// globalRoleBindings implements GlobalRoleBindingInterface
|
||||
type globalRoleBindings struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newGlobalRoleBindings returns a GlobalRoleBindings
|
||||
func newGlobalRoleBindings(c *IamV1alpha2Client) *globalRoleBindings {
|
||||
return &globalRoleBindings{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the globalRoleBinding, and returns the corresponding globalRoleBinding object, and an error if there is any.
|
||||
func (c *globalRoleBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.GlobalRoleBinding, err error) {
|
||||
result = &v1alpha2.GlobalRoleBinding{}
|
||||
err = c.client.Get().
|
||||
Resource("globalrolebindings").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of GlobalRoleBindings that match those selectors.
|
||||
func (c *globalRoleBindings) List(opts v1.ListOptions) (result *v1alpha2.GlobalRoleBindingList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha2.GlobalRoleBindingList{}
|
||||
err = c.client.Get().
|
||||
Resource("globalrolebindings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested globalRoleBindings.
|
||||
func (c *globalRoleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("globalrolebindings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a globalRoleBinding and creates it. Returns the server's representation of the globalRoleBinding, and an error, if there is any.
|
||||
func (c *globalRoleBindings) Create(globalRoleBinding *v1alpha2.GlobalRoleBinding) (result *v1alpha2.GlobalRoleBinding, err error) {
|
||||
result = &v1alpha2.GlobalRoleBinding{}
|
||||
err = c.client.Post().
|
||||
Resource("globalrolebindings").
|
||||
Body(globalRoleBinding).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a globalRoleBinding and updates it. Returns the server's representation of the globalRoleBinding, and an error, if there is any.
|
||||
func (c *globalRoleBindings) Update(globalRoleBinding *v1alpha2.GlobalRoleBinding) (result *v1alpha2.GlobalRoleBinding, err error) {
|
||||
result = &v1alpha2.GlobalRoleBinding{}
|
||||
err = c.client.Put().
|
||||
Resource("globalrolebindings").
|
||||
Name(globalRoleBinding.Name).
|
||||
Body(globalRoleBinding).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the globalRoleBinding and deletes it. Returns an error if one occurs.
|
||||
func (c *globalRoleBindings) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("globalrolebindings").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *globalRoleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("globalrolebindings").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched globalRoleBinding.
|
||||
func (c *globalRoleBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRoleBinding, err error) {
|
||||
result = &v1alpha2.GlobalRoleBinding{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("globalrolebindings").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -26,10 +26,11 @@ import (
|
||||
|
||||
type IamV1alpha2Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
PolicyRulesGetter
|
||||
RolesGetter
|
||||
RoleBindingsGetter
|
||||
GlobalRolesGetter
|
||||
GlobalRoleBindingsGetter
|
||||
UsersGetter
|
||||
WorkspaceRolesGetter
|
||||
WorkspaceRoleBindingsGetter
|
||||
}
|
||||
|
||||
// IamV1alpha2Client is used to interact with features provided by the iam.kubesphere.io group.
|
||||
@@ -37,22 +38,26 @@ type IamV1alpha2Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *IamV1alpha2Client) PolicyRules() PolicyRuleInterface {
|
||||
return newPolicyRules(c)
|
||||
func (c *IamV1alpha2Client) GlobalRoles() GlobalRoleInterface {
|
||||
return newGlobalRoles(c)
|
||||
}
|
||||
|
||||
func (c *IamV1alpha2Client) Roles() RoleInterface {
|
||||
return newRoles(c)
|
||||
}
|
||||
|
||||
func (c *IamV1alpha2Client) RoleBindings() RoleBindingInterface {
|
||||
return newRoleBindings(c)
|
||||
func (c *IamV1alpha2Client) GlobalRoleBindings() GlobalRoleBindingInterface {
|
||||
return newGlobalRoleBindings(c)
|
||||
}
|
||||
|
||||
func (c *IamV1alpha2Client) Users() UserInterface {
|
||||
return newUsers(c)
|
||||
}
|
||||
|
||||
func (c *IamV1alpha2Client) WorkspaceRoles() WorkspaceRoleInterface {
|
||||
return newWorkspaceRoles(c)
|
||||
}
|
||||
|
||||
func (c *IamV1alpha2Client) WorkspaceRoleBindings() WorkspaceRoleBindingInterface {
|
||||
return newWorkspaceRoleBindings(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new IamV1alpha2Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*IamV1alpha2Client, error) {
|
||||
config := *c
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// RolesGetter has a method to return a RoleInterface.
|
||||
// A group's client should implement this interface.
|
||||
type RolesGetter interface {
|
||||
Roles() RoleInterface
|
||||
}
|
||||
|
||||
// RoleInterface has methods to work with Role resources.
|
||||
type RoleInterface interface {
|
||||
Create(*v1alpha2.Role) (*v1alpha2.Role, error)
|
||||
Update(*v1alpha2.Role) (*v1alpha2.Role, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha2.Role, error)
|
||||
List(opts v1.ListOptions) (*v1alpha2.RoleList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Role, err error)
|
||||
RoleExpansion
|
||||
}
|
||||
|
||||
// roles implements RoleInterface
|
||||
type roles struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newRoles returns a Roles
|
||||
func newRoles(c *IamV1alpha2Client) *roles {
|
||||
return &roles{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the role, and returns the corresponding role object, and an error if there is any.
|
||||
func (c *roles) Get(name string, options v1.GetOptions) (result *v1alpha2.Role, err error) {
|
||||
result = &v1alpha2.Role{}
|
||||
err = c.client.Get().
|
||||
Resource("roles").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Roles that match those selectors.
|
||||
func (c *roles) List(opts v1.ListOptions) (result *v1alpha2.RoleList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha2.RoleList{}
|
||||
err = c.client.Get().
|
||||
Resource("roles").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested roles.
|
||||
func (c *roles) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("roles").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a role and creates it. Returns the server's representation of the role, and an error, if there is any.
|
||||
func (c *roles) Create(role *v1alpha2.Role) (result *v1alpha2.Role, err error) {
|
||||
result = &v1alpha2.Role{}
|
||||
err = c.client.Post().
|
||||
Resource("roles").
|
||||
Body(role).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a role and updates it. Returns the server's representation of the role, and an error, if there is any.
|
||||
func (c *roles) Update(role *v1alpha2.Role) (result *v1alpha2.Role, err error) {
|
||||
result = &v1alpha2.Role{}
|
||||
err = c.client.Put().
|
||||
Resource("roles").
|
||||
Name(role.Name).
|
||||
Body(role).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the role and deletes it. Returns an error if one occurs.
|
||||
func (c *roles) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("roles").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *roles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("roles").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched role.
|
||||
func (c *roles) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Role, err error) {
|
||||
result = &v1alpha2.Role{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("roles").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// RoleBindingsGetter has a method to return a RoleBindingInterface.
|
||||
// A group's client should implement this interface.
|
||||
type RoleBindingsGetter interface {
|
||||
RoleBindings() RoleBindingInterface
|
||||
}
|
||||
|
||||
// RoleBindingInterface has methods to work with RoleBinding resources.
|
||||
type RoleBindingInterface interface {
|
||||
Create(*v1alpha2.RoleBinding) (*v1alpha2.RoleBinding, error)
|
||||
Update(*v1alpha2.RoleBinding) (*v1alpha2.RoleBinding, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha2.RoleBinding, error)
|
||||
List(opts v1.ListOptions) (*v1alpha2.RoleBindingList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.RoleBinding, err error)
|
||||
RoleBindingExpansion
|
||||
}
|
||||
|
||||
// roleBindings implements RoleBindingInterface
|
||||
type roleBindings struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newRoleBindings returns a RoleBindings
|
||||
func newRoleBindings(c *IamV1alpha2Client) *roleBindings {
|
||||
return &roleBindings{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the roleBinding, and returns the corresponding roleBinding object, and an error if there is any.
|
||||
func (c *roleBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.RoleBinding, err error) {
|
||||
result = &v1alpha2.RoleBinding{}
|
||||
err = c.client.Get().
|
||||
Resource("rolebindings").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of RoleBindings that match those selectors.
|
||||
func (c *roleBindings) List(opts v1.ListOptions) (result *v1alpha2.RoleBindingList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha2.RoleBindingList{}
|
||||
err = c.client.Get().
|
||||
Resource("rolebindings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested roleBindings.
|
||||
func (c *roleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("rolebindings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a roleBinding and creates it. Returns the server's representation of the roleBinding, and an error, if there is any.
|
||||
func (c *roleBindings) Create(roleBinding *v1alpha2.RoleBinding) (result *v1alpha2.RoleBinding, err error) {
|
||||
result = &v1alpha2.RoleBinding{}
|
||||
err = c.client.Post().
|
||||
Resource("rolebindings").
|
||||
Body(roleBinding).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a roleBinding and updates it. Returns the server's representation of the roleBinding, and an error, if there is any.
|
||||
func (c *roleBindings) Update(roleBinding *v1alpha2.RoleBinding) (result *v1alpha2.RoleBinding, err error) {
|
||||
result = &v1alpha2.RoleBinding{}
|
||||
err = c.client.Put().
|
||||
Resource("rolebindings").
|
||||
Name(roleBinding.Name).
|
||||
Body(roleBinding).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the roleBinding and deletes it. Returns an error if one occurs.
|
||||
func (c *roleBindings) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("rolebindings").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *roleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("rolebindings").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched roleBinding.
|
||||
func (c *roleBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.RoleBinding, err error) {
|
||||
result = &v1alpha2.RoleBinding{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("rolebindings").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// WorkspaceRolesGetter has a method to return a WorkspaceRoleInterface.
|
||||
// A group's client should implement this interface.
|
||||
type WorkspaceRolesGetter interface {
|
||||
WorkspaceRoles() WorkspaceRoleInterface
|
||||
}
|
||||
|
||||
// WorkspaceRoleInterface has methods to work with WorkspaceRole resources.
|
||||
type WorkspaceRoleInterface interface {
|
||||
Create(*v1alpha2.WorkspaceRole) (*v1alpha2.WorkspaceRole, error)
|
||||
Update(*v1alpha2.WorkspaceRole) (*v1alpha2.WorkspaceRole, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha2.WorkspaceRole, error)
|
||||
List(opts v1.ListOptions) (*v1alpha2.WorkspaceRoleList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.WorkspaceRole, err error)
|
||||
WorkspaceRoleExpansion
|
||||
}
|
||||
|
||||
// workspaceRoles implements WorkspaceRoleInterface
|
||||
type workspaceRoles struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newWorkspaceRoles returns a WorkspaceRoles
|
||||
func newWorkspaceRoles(c *IamV1alpha2Client) *workspaceRoles {
|
||||
return &workspaceRoles{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the workspaceRole, and returns the corresponding workspaceRole object, and an error if there is any.
|
||||
func (c *workspaceRoles) Get(name string, options v1.GetOptions) (result *v1alpha2.WorkspaceRole, err error) {
|
||||
result = &v1alpha2.WorkspaceRole{}
|
||||
err = c.client.Get().
|
||||
Resource("workspaceroles").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of WorkspaceRoles that match those selectors.
|
||||
func (c *workspaceRoles) List(opts v1.ListOptions) (result *v1alpha2.WorkspaceRoleList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha2.WorkspaceRoleList{}
|
||||
err = c.client.Get().
|
||||
Resource("workspaceroles").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested workspaceRoles.
|
||||
func (c *workspaceRoles) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("workspaceroles").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a workspaceRole and creates it. Returns the server's representation of the workspaceRole, and an error, if there is any.
|
||||
func (c *workspaceRoles) Create(workspaceRole *v1alpha2.WorkspaceRole) (result *v1alpha2.WorkspaceRole, err error) {
|
||||
result = &v1alpha2.WorkspaceRole{}
|
||||
err = c.client.Post().
|
||||
Resource("workspaceroles").
|
||||
Body(workspaceRole).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a workspaceRole and updates it. Returns the server's representation of the workspaceRole, and an error, if there is any.
|
||||
func (c *workspaceRoles) Update(workspaceRole *v1alpha2.WorkspaceRole) (result *v1alpha2.WorkspaceRole, err error) {
|
||||
result = &v1alpha2.WorkspaceRole{}
|
||||
err = c.client.Put().
|
||||
Resource("workspaceroles").
|
||||
Name(workspaceRole.Name).
|
||||
Body(workspaceRole).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the workspaceRole and deletes it. Returns an error if one occurs.
|
||||
func (c *workspaceRoles) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("workspaceroles").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *workspaceRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("workspaceroles").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched workspaceRole.
|
||||
func (c *workspaceRoles) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.WorkspaceRole, err error) {
|
||||
result = &v1alpha2.WorkspaceRole{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("workspaceroles").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// WorkspaceRoleBindingsGetter has a method to return a WorkspaceRoleBindingInterface.
|
||||
// A group's client should implement this interface.
|
||||
type WorkspaceRoleBindingsGetter interface {
|
||||
WorkspaceRoleBindings() WorkspaceRoleBindingInterface
|
||||
}
|
||||
|
||||
// WorkspaceRoleBindingInterface has methods to work with WorkspaceRoleBinding resources.
|
||||
type WorkspaceRoleBindingInterface interface {
|
||||
Create(*v1alpha2.WorkspaceRoleBinding) (*v1alpha2.WorkspaceRoleBinding, error)
|
||||
Update(*v1alpha2.WorkspaceRoleBinding) (*v1alpha2.WorkspaceRoleBinding, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha2.WorkspaceRoleBinding, error)
|
||||
List(opts v1.ListOptions) (*v1alpha2.WorkspaceRoleBindingList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.WorkspaceRoleBinding, err error)
|
||||
WorkspaceRoleBindingExpansion
|
||||
}
|
||||
|
||||
// workspaceRoleBindings implements WorkspaceRoleBindingInterface
|
||||
type workspaceRoleBindings struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newWorkspaceRoleBindings returns a WorkspaceRoleBindings
|
||||
func newWorkspaceRoleBindings(c *IamV1alpha2Client) *workspaceRoleBindings {
|
||||
return &workspaceRoleBindings{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the workspaceRoleBinding, and returns the corresponding workspaceRoleBinding object, and an error if there is any.
|
||||
func (c *workspaceRoleBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
result = &v1alpha2.WorkspaceRoleBinding{}
|
||||
err = c.client.Get().
|
||||
Resource("workspacerolebindings").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of WorkspaceRoleBindings that match those selectors.
|
||||
func (c *workspaceRoleBindings) List(opts v1.ListOptions) (result *v1alpha2.WorkspaceRoleBindingList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha2.WorkspaceRoleBindingList{}
|
||||
err = c.client.Get().
|
||||
Resource("workspacerolebindings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested workspaceRoleBindings.
|
||||
func (c *workspaceRoleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Resource("workspacerolebindings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a workspaceRoleBinding and creates it. Returns the server's representation of the workspaceRoleBinding, and an error, if there is any.
|
||||
func (c *workspaceRoleBindings) Create(workspaceRoleBinding *v1alpha2.WorkspaceRoleBinding) (result *v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
result = &v1alpha2.WorkspaceRoleBinding{}
|
||||
err = c.client.Post().
|
||||
Resource("workspacerolebindings").
|
||||
Body(workspaceRoleBinding).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a workspaceRoleBinding and updates it. Returns the server's representation of the workspaceRoleBinding, and an error, if there is any.
|
||||
func (c *workspaceRoleBindings) Update(workspaceRoleBinding *v1alpha2.WorkspaceRoleBinding) (result *v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
result = &v1alpha2.WorkspaceRoleBinding{}
|
||||
err = c.client.Put().
|
||||
Resource("workspacerolebindings").
|
||||
Name(workspaceRoleBinding.Name).
|
||||
Body(workspaceRoleBinding).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the workspaceRoleBinding and deletes it. Returns an error if one occurs.
|
||||
func (c *workspaceRoleBindings) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("workspacerolebindings").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *workspaceRoleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("workspacerolebindings").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched workspaceRoleBinding.
|
||||
func (c *workspaceRoleBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
result = &v1alpha2.WorkspaceRoleBinding{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("workspacerolebindings").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -79,14 +79,16 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Devops().V1alpha3().Pipelines().Informer()}, nil
|
||||
|
||||
// Group=iam.kubesphere.io, Version=v1alpha2
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("policyrules"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().PolicyRules().Informer()}, nil
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("roles"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().Roles().Informer()}, nil
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("rolebindings"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().RoleBindings().Informer()}, nil
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("globalroles"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().GlobalRoles().Informer()}, nil
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("globalrolebindings"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().GlobalRoleBindings().Informer()}, nil
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("users"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().Users().Informer()}, nil
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("workspaceroles"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().WorkspaceRoles().Informer()}, nil
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("workspacerolebindings"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().WorkspaceRoleBindings().Informer()}, nil
|
||||
|
||||
// Group=network.kubesphere.io, Version=v1alpha1
|
||||
case networkv1alpha1.SchemeGroupVersion.WithResource("namespacenetworkpolicies"):
|
||||
|
||||
@@ -31,58 +31,58 @@ import (
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// PolicyRuleInformer provides access to a shared informer and lister for
|
||||
// PolicyRules.
|
||||
type PolicyRuleInformer interface {
|
||||
// GlobalRoleInformer provides access to a shared informer and lister for
|
||||
// GlobalRoles.
|
||||
type GlobalRoleInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha2.PolicyRuleLister
|
||||
Lister() v1alpha2.GlobalRoleLister
|
||||
}
|
||||
|
||||
type policyRuleInformer struct {
|
||||
type globalRoleInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewPolicyRuleInformer constructs a new informer for PolicyRule type.
|
||||
// NewGlobalRoleInformer constructs a new informer for GlobalRole 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 NewPolicyRuleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredPolicyRuleInformer(client, resyncPeriod, indexers, nil)
|
||||
func NewGlobalRoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredGlobalRoleInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredPolicyRuleInformer constructs a new informer for PolicyRule type.
|
||||
// NewFilteredGlobalRoleInformer constructs a new informer for GlobalRole 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 NewFilteredPolicyRuleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
func NewFilteredGlobalRoleInformer(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.IamV1alpha2().PolicyRules().List(options)
|
||||
return client.IamV1alpha2().GlobalRoles().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IamV1alpha2().PolicyRules().Watch(options)
|
||||
return client.IamV1alpha2().GlobalRoles().Watch(options)
|
||||
},
|
||||
},
|
||||
&iamv1alpha2.PolicyRule{},
|
||||
&iamv1alpha2.GlobalRole{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *policyRuleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredPolicyRuleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
func (f *globalRoleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredGlobalRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *policyRuleInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&iamv1alpha2.PolicyRule{}, f.defaultInformer)
|
||||
func (f *globalRoleInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&iamv1alpha2.GlobalRole{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *policyRuleInformer) Lister() v1alpha2.PolicyRuleLister {
|
||||
return v1alpha2.NewPolicyRuleLister(f.Informer().GetIndexer())
|
||||
func (f *globalRoleInformer) Lister() v1alpha2.GlobalRoleLister {
|
||||
return v1alpha2.NewGlobalRoleLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -31,58 +31,58 @@ import (
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// RoleInformer provides access to a shared informer and lister for
|
||||
// Roles.
|
||||
type RoleInformer interface {
|
||||
// GlobalRoleBindingInformer provides access to a shared informer and lister for
|
||||
// GlobalRoleBindings.
|
||||
type GlobalRoleBindingInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha2.RoleLister
|
||||
Lister() v1alpha2.GlobalRoleBindingLister
|
||||
}
|
||||
|
||||
type roleInformer struct {
|
||||
type globalRoleBindingInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewRoleInformer constructs a new informer for Role type.
|
||||
// NewGlobalRoleBindingInformer constructs a new informer for GlobalRoleBinding 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 NewRoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredRoleInformer(client, resyncPeriod, indexers, nil)
|
||||
func NewGlobalRoleBindingInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredGlobalRoleBindingInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredRoleInformer constructs a new informer for Role type.
|
||||
// NewFilteredGlobalRoleBindingInformer constructs a new informer for GlobalRoleBinding 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 NewFilteredRoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
func NewFilteredGlobalRoleBindingInformer(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.IamV1alpha2().Roles().List(options)
|
||||
return client.IamV1alpha2().GlobalRoleBindings().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IamV1alpha2().Roles().Watch(options)
|
||||
return client.IamV1alpha2().GlobalRoleBindings().Watch(options)
|
||||
},
|
||||
},
|
||||
&iamv1alpha2.Role{},
|
||||
&iamv1alpha2.GlobalRoleBinding{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *roleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
func (f *globalRoleBindingInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredGlobalRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *roleInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&iamv1alpha2.Role{}, f.defaultInformer)
|
||||
func (f *globalRoleBindingInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&iamv1alpha2.GlobalRoleBinding{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *roleInformer) Lister() v1alpha2.RoleLister {
|
||||
return v1alpha2.NewRoleLister(f.Informer().GetIndexer())
|
||||
func (f *globalRoleBindingInformer) Lister() v1alpha2.GlobalRoleBindingLister {
|
||||
return v1alpha2.NewGlobalRoleBindingLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -24,14 +24,16 @@ import (
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// PolicyRules returns a PolicyRuleInformer.
|
||||
PolicyRules() PolicyRuleInformer
|
||||
// Roles returns a RoleInformer.
|
||||
Roles() RoleInformer
|
||||
// RoleBindings returns a RoleBindingInformer.
|
||||
RoleBindings() RoleBindingInformer
|
||||
// GlobalRoles returns a GlobalRoleInformer.
|
||||
GlobalRoles() GlobalRoleInformer
|
||||
// GlobalRoleBindings returns a GlobalRoleBindingInformer.
|
||||
GlobalRoleBindings() GlobalRoleBindingInformer
|
||||
// Users returns a UserInformer.
|
||||
Users() UserInformer
|
||||
// WorkspaceRoles returns a WorkspaceRoleInformer.
|
||||
WorkspaceRoles() WorkspaceRoleInformer
|
||||
// WorkspaceRoleBindings returns a WorkspaceRoleBindingInformer.
|
||||
WorkspaceRoleBindings() WorkspaceRoleBindingInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
@@ -45,22 +47,27 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// PolicyRules returns a PolicyRuleInformer.
|
||||
func (v *version) PolicyRules() PolicyRuleInformer {
|
||||
return &policyRuleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
// GlobalRoles returns a GlobalRoleInformer.
|
||||
func (v *version) GlobalRoles() GlobalRoleInformer {
|
||||
return &globalRoleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// Roles returns a RoleInformer.
|
||||
func (v *version) Roles() RoleInformer {
|
||||
return &roleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// RoleBindings returns a RoleBindingInformer.
|
||||
func (v *version) RoleBindings() RoleBindingInformer {
|
||||
return &roleBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
// GlobalRoleBindings returns a GlobalRoleBindingInformer.
|
||||
func (v *version) GlobalRoleBindings() GlobalRoleBindingInformer {
|
||||
return &globalRoleBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// Users returns a UserInformer.
|
||||
func (v *version) Users() UserInformer {
|
||||
return &userInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// WorkspaceRoles returns a WorkspaceRoleInformer.
|
||||
func (v *version) WorkspaceRoles() WorkspaceRoleInformer {
|
||||
return &workspaceRoleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// WorkspaceRoleBindings returns a WorkspaceRoleBindingInformer.
|
||||
func (v *version) WorkspaceRoleBindings() WorkspaceRoleBindingInformer {
|
||||
return &workspaceRoleBindingInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
@@ -31,58 +31,58 @@ import (
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// RoleBindingInformer provides access to a shared informer and lister for
|
||||
// RoleBindings.
|
||||
type RoleBindingInformer interface {
|
||||
// WorkspaceRoleInformer provides access to a shared informer and lister for
|
||||
// WorkspaceRoles.
|
||||
type WorkspaceRoleInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha2.RoleBindingLister
|
||||
Lister() v1alpha2.WorkspaceRoleLister
|
||||
}
|
||||
|
||||
type roleBindingInformer struct {
|
||||
type workspaceRoleInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewRoleBindingInformer constructs a new informer for RoleBinding type.
|
||||
// NewWorkspaceRoleInformer constructs a new informer for WorkspaceRole 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 NewRoleBindingInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredRoleBindingInformer(client, resyncPeriod, indexers, nil)
|
||||
func NewWorkspaceRoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredWorkspaceRoleInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredRoleBindingInformer constructs a new informer for RoleBinding type.
|
||||
// NewFilteredWorkspaceRoleInformer constructs a new informer for WorkspaceRole 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 NewFilteredRoleBindingInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
func NewFilteredWorkspaceRoleInformer(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.IamV1alpha2().RoleBindings().List(options)
|
||||
return client.IamV1alpha2().WorkspaceRoles().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IamV1alpha2().RoleBindings().Watch(options)
|
||||
return client.IamV1alpha2().WorkspaceRoles().Watch(options)
|
||||
},
|
||||
},
|
||||
&iamv1alpha2.RoleBinding{},
|
||||
&iamv1alpha2.WorkspaceRole{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *roleBindingInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
func (f *workspaceRoleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredWorkspaceRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *roleBindingInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&iamv1alpha2.RoleBinding{}, f.defaultInformer)
|
||||
func (f *workspaceRoleInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&iamv1alpha2.WorkspaceRole{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *roleBindingInformer) Lister() v1alpha2.RoleBindingLister {
|
||||
return v1alpha2.NewRoleBindingLister(f.Informer().GetIndexer())
|
||||
func (f *workspaceRoleInformer) Lister() v1alpha2.WorkspaceRoleLister {
|
||||
return v1alpha2.NewWorkspaceRoleLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// WorkspaceRoleBindingInformer provides access to a shared informer and lister for
|
||||
// WorkspaceRoleBindings.
|
||||
type WorkspaceRoleBindingInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha2.WorkspaceRoleBindingLister
|
||||
}
|
||||
|
||||
type workspaceRoleBindingInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewWorkspaceRoleBindingInformer constructs a new informer for WorkspaceRoleBinding 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 NewWorkspaceRoleBindingInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredWorkspaceRoleBindingInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredWorkspaceRoleBindingInformer constructs a new informer for WorkspaceRoleBinding 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 NewFilteredWorkspaceRoleBindingInformer(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.IamV1alpha2().WorkspaceRoleBindings().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.IamV1alpha2().WorkspaceRoleBindings().Watch(options)
|
||||
},
|
||||
},
|
||||
&iamv1alpha2.WorkspaceRoleBinding{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *workspaceRoleBindingInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredWorkspaceRoleBindingInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *workspaceRoleBindingInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&iamv1alpha2.WorkspaceRoleBinding{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *workspaceRoleBindingInformer) Lister() v1alpha2.WorkspaceRoleBindingLister {
|
||||
return v1alpha2.NewWorkspaceRoleBindingLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -18,18 +18,22 @@ limitations under the License.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
// PolicyRuleListerExpansion allows custom methods to be added to
|
||||
// PolicyRuleLister.
|
||||
type PolicyRuleListerExpansion interface{}
|
||||
// GlobalRoleListerExpansion allows custom methods to be added to
|
||||
// GlobalRoleLister.
|
||||
type GlobalRoleListerExpansion interface{}
|
||||
|
||||
// RoleListerExpansion allows custom methods to be added to
|
||||
// RoleLister.
|
||||
type RoleListerExpansion interface{}
|
||||
|
||||
// RoleBindingListerExpansion allows custom methods to be added to
|
||||
// RoleBindingLister.
|
||||
type RoleBindingListerExpansion interface{}
|
||||
// GlobalRoleBindingListerExpansion allows custom methods to be added to
|
||||
// GlobalRoleBindingLister.
|
||||
type GlobalRoleBindingListerExpansion interface{}
|
||||
|
||||
// UserListerExpansion allows custom methods to be added to
|
||||
// UserLister.
|
||||
type UserListerExpansion interface{}
|
||||
|
||||
// WorkspaceRoleListerExpansion allows custom methods to be added to
|
||||
// WorkspaceRoleLister.
|
||||
type WorkspaceRoleListerExpansion interface{}
|
||||
|
||||
// WorkspaceRoleBindingListerExpansion allows custom methods to be added to
|
||||
// WorkspaceRoleBindingLister.
|
||||
type WorkspaceRoleBindingListerExpansion interface{}
|
||||
|
||||
@@ -25,41 +25,41 @@ import (
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// PolicyRuleLister helps list PolicyRules.
|
||||
type PolicyRuleLister interface {
|
||||
// List lists all PolicyRules in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.PolicyRule, err error)
|
||||
// Get retrieves the PolicyRule from the index for a given name.
|
||||
Get(name string) (*v1alpha2.PolicyRule, error)
|
||||
PolicyRuleListerExpansion
|
||||
// GlobalRoleLister helps list GlobalRoles.
|
||||
type GlobalRoleLister interface {
|
||||
// List lists all GlobalRoles in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.GlobalRole, err error)
|
||||
// Get retrieves the GlobalRole from the index for a given name.
|
||||
Get(name string) (*v1alpha2.GlobalRole, error)
|
||||
GlobalRoleListerExpansion
|
||||
}
|
||||
|
||||
// policyRuleLister implements the PolicyRuleLister interface.
|
||||
type policyRuleLister struct {
|
||||
// globalRoleLister implements the GlobalRoleLister interface.
|
||||
type globalRoleLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewPolicyRuleLister returns a new PolicyRuleLister.
|
||||
func NewPolicyRuleLister(indexer cache.Indexer) PolicyRuleLister {
|
||||
return &policyRuleLister{indexer: indexer}
|
||||
// NewGlobalRoleLister returns a new GlobalRoleLister.
|
||||
func NewGlobalRoleLister(indexer cache.Indexer) GlobalRoleLister {
|
||||
return &globalRoleLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all PolicyRules in the indexer.
|
||||
func (s *policyRuleLister) List(selector labels.Selector) (ret []*v1alpha2.PolicyRule, err error) {
|
||||
// List lists all GlobalRoles in the indexer.
|
||||
func (s *globalRoleLister) List(selector labels.Selector) (ret []*v1alpha2.GlobalRole, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha2.PolicyRule))
|
||||
ret = append(ret, m.(*v1alpha2.GlobalRole))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the PolicyRule from the index for a given name.
|
||||
func (s *policyRuleLister) Get(name string) (*v1alpha2.PolicyRule, error) {
|
||||
// Get retrieves the GlobalRole from the index for a given name.
|
||||
func (s *globalRoleLister) Get(name string) (*v1alpha2.GlobalRole, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha2.Resource("policyrule"), name)
|
||||
return nil, errors.NewNotFound(v1alpha2.Resource("globalrole"), name)
|
||||
}
|
||||
return obj.(*v1alpha2.PolicyRule), nil
|
||||
return obj.(*v1alpha2.GlobalRole), nil
|
||||
}
|
||||
65
pkg/client/listers/iam/v1alpha2/globalrolebinding.go
Normal file
65
pkg/client/listers/iam/v1alpha2/globalrolebinding.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// GlobalRoleBindingLister helps list GlobalRoleBindings.
|
||||
type GlobalRoleBindingLister interface {
|
||||
// List lists all GlobalRoleBindings in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.GlobalRoleBinding, err error)
|
||||
// Get retrieves the GlobalRoleBinding from the index for a given name.
|
||||
Get(name string) (*v1alpha2.GlobalRoleBinding, error)
|
||||
GlobalRoleBindingListerExpansion
|
||||
}
|
||||
|
||||
// globalRoleBindingLister implements the GlobalRoleBindingLister interface.
|
||||
type globalRoleBindingLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewGlobalRoleBindingLister returns a new GlobalRoleBindingLister.
|
||||
func NewGlobalRoleBindingLister(indexer cache.Indexer) GlobalRoleBindingLister {
|
||||
return &globalRoleBindingLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all GlobalRoleBindings in the indexer.
|
||||
func (s *globalRoleBindingLister) List(selector labels.Selector) (ret []*v1alpha2.GlobalRoleBinding, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha2.GlobalRoleBinding))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the GlobalRoleBinding from the index for a given name.
|
||||
func (s *globalRoleBindingLister) Get(name string) (*v1alpha2.GlobalRoleBinding, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha2.Resource("globalrolebinding"), name)
|
||||
}
|
||||
return obj.(*v1alpha2.GlobalRoleBinding), nil
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// RoleLister helps list Roles.
|
||||
type RoleLister interface {
|
||||
// List lists all Roles in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.Role, err error)
|
||||
// Get retrieves the Role from the index for a given name.
|
||||
Get(name string) (*v1alpha2.Role, error)
|
||||
RoleListerExpansion
|
||||
}
|
||||
|
||||
// roleLister implements the RoleLister interface.
|
||||
type roleLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewRoleLister returns a new RoleLister.
|
||||
func NewRoleLister(indexer cache.Indexer) RoleLister {
|
||||
return &roleLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all Roles in the indexer.
|
||||
func (s *roleLister) List(selector labels.Selector) (ret []*v1alpha2.Role, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha2.Role))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the Role from the index for a given name.
|
||||
func (s *roleLister) Get(name string) (*v1alpha2.Role, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha2.Resource("role"), name)
|
||||
}
|
||||
return obj.(*v1alpha2.Role), nil
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// RoleBindingLister helps list RoleBindings.
|
||||
type RoleBindingLister interface {
|
||||
// List lists all RoleBindings in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.RoleBinding, err error)
|
||||
// Get retrieves the RoleBinding from the index for a given name.
|
||||
Get(name string) (*v1alpha2.RoleBinding, error)
|
||||
RoleBindingListerExpansion
|
||||
}
|
||||
|
||||
// roleBindingLister implements the RoleBindingLister interface.
|
||||
type roleBindingLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewRoleBindingLister returns a new RoleBindingLister.
|
||||
func NewRoleBindingLister(indexer cache.Indexer) RoleBindingLister {
|
||||
return &roleBindingLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all RoleBindings in the indexer.
|
||||
func (s *roleBindingLister) List(selector labels.Selector) (ret []*v1alpha2.RoleBinding, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha2.RoleBinding))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the RoleBinding from the index for a given name.
|
||||
func (s *roleBindingLister) Get(name string) (*v1alpha2.RoleBinding, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha2.Resource("rolebinding"), name)
|
||||
}
|
||||
return obj.(*v1alpha2.RoleBinding), nil
|
||||
}
|
||||
65
pkg/client/listers/iam/v1alpha2/workspacerole.go
Normal file
65
pkg/client/listers/iam/v1alpha2/workspacerole.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// WorkspaceRoleLister helps list WorkspaceRoles.
|
||||
type WorkspaceRoleLister interface {
|
||||
// List lists all WorkspaceRoles in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.WorkspaceRole, err error)
|
||||
// Get retrieves the WorkspaceRole from the index for a given name.
|
||||
Get(name string) (*v1alpha2.WorkspaceRole, error)
|
||||
WorkspaceRoleListerExpansion
|
||||
}
|
||||
|
||||
// workspaceRoleLister implements the WorkspaceRoleLister interface.
|
||||
type workspaceRoleLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewWorkspaceRoleLister returns a new WorkspaceRoleLister.
|
||||
func NewWorkspaceRoleLister(indexer cache.Indexer) WorkspaceRoleLister {
|
||||
return &workspaceRoleLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all WorkspaceRoles in the indexer.
|
||||
func (s *workspaceRoleLister) List(selector labels.Selector) (ret []*v1alpha2.WorkspaceRole, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha2.WorkspaceRole))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the WorkspaceRole from the index for a given name.
|
||||
func (s *workspaceRoleLister) Get(name string) (*v1alpha2.WorkspaceRole, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha2.Resource("workspacerole"), name)
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRole), nil
|
||||
}
|
||||
65
pkg/client/listers/iam/v1alpha2/workspacerolebinding.go
Normal file
65
pkg/client/listers/iam/v1alpha2/workspacerolebinding.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2019 The KubeSphere authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
)
|
||||
|
||||
// WorkspaceRoleBindingLister helps list WorkspaceRoleBindings.
|
||||
type WorkspaceRoleBindingLister interface {
|
||||
// List lists all WorkspaceRoleBindings in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.WorkspaceRoleBinding, err error)
|
||||
// Get retrieves the WorkspaceRoleBinding from the index for a given name.
|
||||
Get(name string) (*v1alpha2.WorkspaceRoleBinding, error)
|
||||
WorkspaceRoleBindingListerExpansion
|
||||
}
|
||||
|
||||
// workspaceRoleBindingLister implements the WorkspaceRoleBindingLister interface.
|
||||
type workspaceRoleBindingLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewWorkspaceRoleBindingLister returns a new WorkspaceRoleBindingLister.
|
||||
func NewWorkspaceRoleBindingLister(indexer cache.Indexer) WorkspaceRoleBindingLister {
|
||||
return &workspaceRoleBindingLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all WorkspaceRoleBindings in the indexer.
|
||||
func (s *workspaceRoleBindingLister) List(selector labels.Selector) (ret []*v1alpha2.WorkspaceRoleBinding, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha2.WorkspaceRoleBinding))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the WorkspaceRoleBinding from the index for a given name.
|
||||
func (s *workspaceRoleBindingLister) Get(name string) (*v1alpha2.WorkspaceRoleBinding, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha2.Resource("workspacerolebinding"), name)
|
||||
}
|
||||
return obj.(*v1alpha2.WorkspaceRoleBinding), nil
|
||||
}
|
||||
@@ -1,14 +1,20 @@
|
||||
package v1alpha2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam/am"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam/im"
|
||||
"strings"
|
||||
resources "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type iamHandler struct {
|
||||
@@ -23,18 +29,6 @@ func newIAMHandler(im im.IdentityManagementInterface, am am.AccessManagementInte
|
||||
}
|
||||
}
|
||||
|
||||
func (h *iamHandler) CreateUser(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (h *iamHandler) DeleteUser(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (h *iamHandler) ModifyUser(request *restful.Request, response *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (h *iamHandler) DescribeUser(req *restful.Request, resp *restful.Response) {
|
||||
username := req.PathParameter("user")
|
||||
user, err := h.im.DescribeUser(username)
|
||||
@@ -43,108 +37,196 @@ func (h *iamHandler) DescribeUser(req *restful.Request, resp *restful.Response)
|
||||
return
|
||||
}
|
||||
|
||||
globalRole, err := h.am.GetRoleOfUserInTargetScope(iamv1alpha2.GlobalScope, "", username)
|
||||
globalRole, err := h.am.GetGlobalRoleOfUser(username)
|
||||
|
||||
if err != nil {
|
||||
api.HandleInternalError(resp, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
result := iamv1alpha2.UserDetail{User: user, GlobalRole: globalRole}
|
||||
|
||||
resp.WriteEntity(result)
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListUsers(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListUserRoles(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListRoles(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListRolesOfUser(req *restful.Request, resp *restful.Response) {
|
||||
username := req.PathParameter("user")
|
||||
|
||||
var roles []iamv1alpha2.Role
|
||||
var err error
|
||||
|
||||
if strings.HasSuffix(req.Request.URL.Path, "workspaceroles") {
|
||||
roles, err = h.am.ListRolesOfUser(iamv1alpha2.WorkspaceScope, username)
|
||||
} else if strings.HasSuffix(req.Request.URL.Path, "clusterroles") {
|
||||
roles, err = h.am.ListRolesOfUser(iamv1alpha2.ClusterScope, username)
|
||||
} else if strings.HasSuffix(req.Request.URL.Path, "namespaceroles") {
|
||||
roles, err = h.am.ListRolesOfUser(iamv1alpha2.NamespaceScope, username)
|
||||
}
|
||||
|
||||
queryParam := query.ParseQueryParameter(req)
|
||||
result, err := h.im.ListUsers(queryParam)
|
||||
if err != nil {
|
||||
api.HandleInternalError(resp, req, err)
|
||||
return
|
||||
}
|
||||
for i, item := range result.Items {
|
||||
user := item.(*iamv1alpha2.User)
|
||||
user = user.DeepCopy()
|
||||
role, err := h.am.GetGlobalRoleOfUser(user.Name)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
klog.Error(err)
|
||||
api.HandleInternalError(resp, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
result := iamv1alpha2.RoleList{
|
||||
TypeMeta: v1.TypeMeta{
|
||||
Kind: "List",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ListMeta: v1.ListMeta{},
|
||||
Items: roles,
|
||||
if user.Annotations == nil {
|
||||
user.Annotations = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
if role != nil {
|
||||
user.Annotations["iam.kubesphere.io/global-role"] = role.Name
|
||||
} else {
|
||||
user.Annotations["iam.kubesphere.io/global-role"] = ""
|
||||
}
|
||||
|
||||
result.Items[i] = user
|
||||
}
|
||||
|
||||
resp.WriteEntity(result)
|
||||
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListRoles(req *restful.Request, resp *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
queryParam := query.ParseQueryParameter(req)
|
||||
result, err := h.am.ListRoles(namespace, queryParam)
|
||||
if err != nil {
|
||||
api.HandleInternalError(resp, req, err)
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(result)
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListClusterRoles(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
queryParam := query.ParseQueryParameter(req)
|
||||
result, err := h.am.ListClusterRoles(queryParam)
|
||||
if err != nil {
|
||||
api.HandleInternalError(resp, req, err)
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(result)
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListGlobalRoles(req *restful.Request, resp *restful.Response) {
|
||||
queryParam := query.ParseQueryParameter(req)
|
||||
result, err := h.am.ListGlobalRoles(queryParam)
|
||||
if err != nil {
|
||||
api.HandleInternalError(resp, req, err)
|
||||
return
|
||||
}
|
||||
resp.WriteEntity(result)
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListRoleUsers(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// List users by namespace
|
||||
func (h *iamHandler) ListNamespaceUsers(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
queryParam := query.ParseQueryParameter(req)
|
||||
namespace := req.PathParameter("namespace")
|
||||
|
||||
func (h *iamHandler) ListClusterRoleUsers(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
roleBindings, err := h.am.ListRoleBindings("", namespace)
|
||||
|
||||
func (h *iamHandler) ListClusterRoleRules(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
if err != nil {
|
||||
api.HandleInternalError(resp, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListRoleRules(req *restful.Request, resp *restful.Response) {
|
||||
panic("implement me")
|
||||
users := make([]runtime.Object, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
for _, subject := range roleBinding.Subjects {
|
||||
if subject.Kind == iamv1alpha2.ResourceKindUser {
|
||||
user, err := h.im.DescribeUser(subject.Name)
|
||||
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
klog.Errorf("orphan subject: %+v", subject)
|
||||
continue
|
||||
}
|
||||
api.HandleInternalError(resp, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
user = user.DeepCopy()
|
||||
|
||||
if user.Annotations == nil {
|
||||
user.Annotations = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
user.Annotations["iam.kubesphere.io/role"] = roleBinding.RoleRef.Name
|
||||
|
||||
users = append(users, user)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result := resources.DefaultList(users, queryParam, func(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
return resources.DefaultObjectMetaCompare(left.(*corev1.Namespace).ObjectMeta, right.(*corev1.Namespace).ObjectMeta, field)
|
||||
}, func(object runtime.Object, filter query.Filter) bool {
|
||||
user := object.(*iamv1alpha2.User).ObjectMeta
|
||||
return resources.DefaultObjectMetaFilter(user, filter)
|
||||
})
|
||||
|
||||
resp.WriteEntity(result)
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListWorkspaceRoles(request *restful.Request, response *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
queryParam := query.ParseQueryParameter(request)
|
||||
workspace := request.PathParameter("workspace")
|
||||
queryParam.Filters[query.FieldLabel] = query.Value(fmt.Sprintf("%s:%s", tenantv1alpha1.WorkspaceLabel, workspace))
|
||||
|
||||
func (h *iamHandler) DescribeWorkspaceRole(request *restful.Request, response *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListWorkspaceRoleRules(request *restful.Request, response *restful.Response) {
|
||||
panic("implement me")
|
||||
result, err := h.am.ListWorkspaceRoles(queryParam)
|
||||
if err != nil {
|
||||
api.HandleInternalError(response, request, err)
|
||||
return
|
||||
}
|
||||
response.WriteEntity(result)
|
||||
}
|
||||
|
||||
func (h *iamHandler) ListWorkspaceUsers(request *restful.Request, response *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
queryParam := query.ParseQueryParameter(request)
|
||||
workspace := request.PathParameter("workspace")
|
||||
|
||||
func (h *iamHandler) InviteUser(request *restful.Request, response *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
roleBindings, err := h.am.ListWorkspaceRoleBindings("", workspace)
|
||||
|
||||
func (h *iamHandler) RemoveUser(request *restful.Request, response *restful.Response) {
|
||||
panic("implement me")
|
||||
}
|
||||
if err != nil {
|
||||
api.HandleInternalError(response, request, err)
|
||||
return
|
||||
}
|
||||
|
||||
func (h *iamHandler) DescribeWorkspaceUser(request *restful.Request, response *restful.Response) {
|
||||
panic("implement me")
|
||||
users := make([]runtime.Object, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
for _, subject := range roleBinding.Subjects {
|
||||
if subject.Kind == iamv1alpha2.ResourceKindUser {
|
||||
user, err := h.im.DescribeUser(subject.Name)
|
||||
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
klog.Errorf("orphan subject: %+v", subject)
|
||||
continue
|
||||
}
|
||||
api.HandleInternalError(response, request, err)
|
||||
return
|
||||
}
|
||||
|
||||
user = user.DeepCopy()
|
||||
|
||||
if user.Annotations == nil {
|
||||
user.Annotations = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
user.Annotations["iam.kubesphere.io/workspace-role"] = roleBinding.RoleRef.Name
|
||||
|
||||
users = append(users, user)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result := resources.DefaultList(users, queryParam, func(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
return resources.DefaultObjectMetaCompare(left.(*corev1.Namespace).ObjectMeta, right.(*corev1.Namespace).ObjectMeta, field)
|
||||
}, func(object runtime.Object, filter query.Filter) bool {
|
||||
user := object.(*iamv1alpha2.User).ObjectMeta
|
||||
return resources.DefaultObjectMetaFilter(user, filter)
|
||||
})
|
||||
|
||||
response.WriteEntity(result)
|
||||
}
|
||||
|
||||
@@ -29,97 +29,69 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam/am"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam/im"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const groupName = "iam.kubesphere.io"
|
||||
const (
|
||||
GroupName = "iam.kubesphere.io"
|
||||
)
|
||||
|
||||
var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha2"}
|
||||
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
|
||||
|
||||
func AddToContainer(container *restful.Container, im im.IdentityManagementInterface, am am.AccessManagementInterface, options *authoptions.AuthenticationOptions) error {
|
||||
ws := runtime.NewWebService(GroupVersion)
|
||||
|
||||
handler := newIAMHandler(im, am, options)
|
||||
|
||||
// global resource
|
||||
ws.Route(ws.GET("/users").
|
||||
To(handler.ListUsers).
|
||||
Doc("List all users.").
|
||||
Returns(http.StatusOK, api.StatusOK, api.ListResult{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
// global resource
|
||||
ws.Route(ws.GET("/users/{user}").
|
||||
To(handler.DescribeUser).
|
||||
Doc("Retrieve user details.").
|
||||
Param(ws.PathParameter("user", "username")).
|
||||
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.UserDetail{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
ws.Route(ws.GET("/users/{user}/workspaceroles").
|
||||
To(handler.ListRolesOfUser).
|
||||
Doc("Retrieve user roles in workspaces.").
|
||||
Param(ws.PathParameter("user", "username")).
|
||||
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
ws.Route(ws.GET("/users/{user}/clusterroles").
|
||||
To(handler.ListRolesOfUser).
|
||||
Doc("Retrieve user roles in clusters.").
|
||||
Param(ws.PathParameter("user", "username")).
|
||||
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
ws.Route(ws.GET("/users/{user}/namespaceroles").
|
||||
To(handler.ListRolesOfUser).
|
||||
Doc("Retrieve user roles in namespaces.").
|
||||
Param(ws.PathParameter("user", "username")).
|
||||
Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/roles").
|
||||
To(handler.ListRoles).
|
||||
Doc("Retrieve the roles that are assigned to the user in the specified namespace.").
|
||||
Param(ws.PathParameter("namespace", "kubernetes namespace")).
|
||||
// global resource
|
||||
ws.Route(ws.GET("/globalroles").
|
||||
To(handler.ListGlobalRoles).
|
||||
Doc("List all cluster roles.").
|
||||
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
ws.Route(ws.GET("/clusterroles").
|
||||
To(handler.ListClusterRoles).
|
||||
Doc("List all cluster roles.").
|
||||
Doc("List cluster roles.").
|
||||
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
// TODO merge
|
||||
//ws.Route(ws.GET("/namespaces/{namespace}/roles/{role}/users"))
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/users").
|
||||
To(handler.ListNamespaceUsers).
|
||||
Doc("List all users in the specified namespace.").
|
||||
Param(ws.PathParameter("namespace", "kubernetes namespace")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
ws.Route(ws.GET("/clusterroles/{clusterrole}/users").
|
||||
To(handler.ListClusterRoleUsers).
|
||||
Doc("List all users that are bound to the specified cluster role.").
|
||||
Param(ws.PathParameter("clusterrole", "cluster role name")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
ws.Route(ws.GET("/workspaces/{workspace}/roles").
|
||||
To(handler.ListWorkspaceRoles).
|
||||
Doc("List all workspace roles.").
|
||||
Param(ws.PathParameter("workspace", "workspace name")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
ws.Route(ws.GET("/workspaces/{workspace}/members").
|
||||
ws.Route(ws.GET("/workspaces/{workspace}/users").
|
||||
To(handler.ListWorkspaceUsers).
|
||||
Doc("List all members in the specified workspace.").
|
||||
Param(ws.PathParameter("workspace", "workspace name")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
// TODO re-design
|
||||
ws.Route(ws.POST("/workspaces/{workspace}/members").
|
||||
To(handler.InviteUser).
|
||||
Doc("Invite a member to the specified workspace.").
|
||||
ws.Route(ws.GET("/workspaces/{workspace}/workspaceroles").
|
||||
To(handler.ListWorkspaceRoles).
|
||||
Doc("List all workspace roles.").
|
||||
Param(ws.PathParameter("workspace", "workspace name")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
ws.Route(ws.DELETE("/workspaces/{workspace}/members/{member}").
|
||||
To(handler.RemoveUser).
|
||||
Doc("Remove the specified member from the workspace.").
|
||||
Param(ws.PathParameter("workspace", "workspace name")).
|
||||
Param(ws.PathParameter("member", "username")).
|
||||
Returns(http.StatusOK, api.StatusOK, errors.Error{}).
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/users").
|
||||
To(handler.ListNamespaceUsers).
|
||||
Doc("List all users in the specified namespace.").
|
||||
Param(ws.PathParameter("namespace", "kubernetes namespace")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/roles").
|
||||
To(handler.ListRoles).
|
||||
Doc("List all roles in the specified namespace.").
|
||||
Param(ws.PathParameter("namespace", "namespace")).
|
||||
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag}))
|
||||
|
||||
container.Add(ws)
|
||||
|
||||
@@ -71,7 +71,7 @@ func AddToContainer(c *restful.Container, client kubernetes.Interface, factory i
|
||||
Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}).
|
||||
Doc("Cluster level resources").
|
||||
Param(webservice.PathParameter("resources", "cluster level resource type, e.g. nodes,workspaces,storageclasses,clusterroles.")).
|
||||
Param(webservice.PathParameter("resources", "cluster level resource type, e.g. nodes,workspaces,storageclasses,clusterrole.")).
|
||||
Param(webservice.QueryParameter(params.ConditionsParam, "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").
|
||||
Required(false).
|
||||
DataFormat("key=value,key~value").
|
||||
|
||||
@@ -9,20 +9,20 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/components"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
|
||||
resourcev1alpha2 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource"
|
||||
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
|
||||
"kubesphere.io/kubesphere/pkg/server/params"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
resourceGetterV1alpha3 *resourcev1alpha3.ResourceGetter
|
||||
resourceGetterV1alpha3 *resource.ResourceGetter
|
||||
resourcesGetterV1alpha2 *resourcev1alpha2.ResourceGetter
|
||||
componentsGetter components.ComponentsGetter
|
||||
}
|
||||
|
||||
func New(factory informers.InformerFactory) *Handler {
|
||||
return &Handler{
|
||||
resourceGetterV1alpha3: resourcev1alpha3.NewResourceGetter(factory),
|
||||
resourceGetterV1alpha3: resource.NewResourceGetter(factory),
|
||||
resourcesGetterV1alpha2: resourcev1alpha2.NewResourceGetter(factory),
|
||||
componentsGetter: components.NewComponentsGetter(factory.KubernetesSharedInformerFactory()),
|
||||
}
|
||||
@@ -41,7 +41,7 @@ func (h *Handler) handleListResources(request *restful.Request, response *restfu
|
||||
return
|
||||
}
|
||||
|
||||
if err != resourcev1alpha3.ErrResourceNotSupported {
|
||||
if err != resource.ErrResourceNotSupported {
|
||||
klog.Error(err)
|
||||
api.HandleInternalError(response, nil, err)
|
||||
return
|
||||
@@ -63,20 +63,20 @@ func (h *Handler) fallback(resourceType string, namespace string, q *query.Query
|
||||
orderBy := string(q.SortBy)
|
||||
limit, offset := q.Pagination.Limit, q.Pagination.Offset
|
||||
reverse := !q.Ascending
|
||||
conditions := ¶ms.Conditions{}
|
||||
for _, filter := range q.Filters {
|
||||
switch filter.Field {
|
||||
conditions := ¶ms.Conditions{Match: make(map[string]string, 0), Fuzzy: make(map[string]string, 0)}
|
||||
for field, value := range q.Filters {
|
||||
switch field {
|
||||
case query.FieldName:
|
||||
conditions.Match[v1alpha2.Name] = string(filter.Value)
|
||||
conditions.Match[v1alpha2.Name] = string(value)
|
||||
break
|
||||
case query.FieldCreationTimeStamp:
|
||||
conditions.Match[v1alpha2.CreateTime] = string(filter.Value)
|
||||
conditions.Match[v1alpha2.CreateTime] = string(value)
|
||||
break
|
||||
case query.FieldLastUpdateTimestamp:
|
||||
conditions.Match[v1alpha2.UpdateTime] = string(filter.Value)
|
||||
conditions.Match[v1alpha2.UpdateTime] = string(value)
|
||||
break
|
||||
case query.FieldLabel:
|
||||
values := strings.SplitN(string(filter.Value), ":", 2)
|
||||
values := strings.SplitN(string(value), ":", 2)
|
||||
if len(values) == 2 {
|
||||
conditions.Match[values[0]] = values[1]
|
||||
} else {
|
||||
@@ -84,7 +84,7 @@ func (h *Handler) fallback(resourceType string, namespace string, q *query.Query
|
||||
}
|
||||
break
|
||||
case query.FieldAnnotation:
|
||||
values := strings.SplitN(string(filter.Value), ":", 2)
|
||||
values := strings.SplitN(string(value), ":", 2)
|
||||
if len(values) == 2 {
|
||||
conditions.Match[v1alpha2.Annotation] = values[1]
|
||||
} else {
|
||||
@@ -92,13 +92,15 @@ func (h *Handler) fallback(resourceType string, namespace string, q *query.Query
|
||||
}
|
||||
break
|
||||
case query.FieldStatus:
|
||||
conditions.Match[v1alpha2.Status] = string(filter.Value)
|
||||
conditions.Match[v1alpha2.Status] = string(value)
|
||||
break
|
||||
case query.FieldOwnerReference:
|
||||
conditions.Match[v1alpha2.Owner] = string(filter.Value)
|
||||
conditions.Match[v1alpha2.Owner] = string(value)
|
||||
break
|
||||
default:
|
||||
conditions.Match[string(field)] = string(value)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
result, err := h.resourcesGetterV1alpha2.ListResources(namespace, resourceType, conditions, orderBy, reverse, limit, offset)
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
fakeks "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -92,7 +92,7 @@ func listResources(namespace, resourceType string, query *query.Query, h *Handle
|
||||
return result, nil
|
||||
}
|
||||
|
||||
if err != resourcev1alpha3.ErrResourceNotSupported {
|
||||
if err != resource.ErrResourceNotSupported {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -5,25 +5,26 @@ import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/request"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/tenant"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
)
|
||||
|
||||
type tenantHandler struct {
|
||||
tenant tenant.Interface
|
||||
}
|
||||
|
||||
func newTenantHandler(k8sClient k8s.Client, factory informers.InformerFactory) *tenantHandler {
|
||||
func newTenantHandler(factory informers.InformerFactory) *tenantHandler {
|
||||
|
||||
return &tenantHandler{
|
||||
tenant: tenant.New(k8sClient, factory),
|
||||
tenant: tenant.New(factory),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *tenantHandler) ListWorkspaces(req *restful.Request, resp *restful.Response) {
|
||||
user, ok := request.UserFrom(req.Request.Context())
|
||||
queryParam := query.ParseQueryParameter(req)
|
||||
|
||||
if !ok {
|
||||
err := errors.New("cannot obtain user info")
|
||||
@@ -32,7 +33,7 @@ func (h *tenantHandler) ListWorkspaces(req *restful.Request, resp *restful.Respo
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.tenant.ListWorkspaces(user)
|
||||
result, err := h.tenant.ListWorkspaces(user, queryParam)
|
||||
|
||||
if err != nil {
|
||||
api.HandleInternalError(resp, nil, err)
|
||||
@@ -44,6 +45,7 @@ func (h *tenantHandler) ListWorkspaces(req *restful.Request, resp *restful.Respo
|
||||
|
||||
func (h *tenantHandler) ListNamespaces(req *restful.Request, resp *restful.Response) {
|
||||
user, ok := request.UserFrom(req.Request.Context())
|
||||
queryParam := query.ParseQueryParameter(req)
|
||||
|
||||
if !ok {
|
||||
err := errors.New("cannot obtain user info")
|
||||
@@ -54,7 +56,7 @@ func (h *tenantHandler) ListNamespaces(req *restful.Request, resp *restful.Respo
|
||||
|
||||
workspace := req.PathParameter("workspace")
|
||||
|
||||
result, err := h.tenant.ListNamespaces(user, workspace)
|
||||
result, err := h.tenant.ListNamespaces(user, workspace, queryParam)
|
||||
|
||||
if err != nil {
|
||||
api.HandleInternalError(resp, nil, err)
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@@ -37,9 +36,9 @@ const (
|
||||
|
||||
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
|
||||
|
||||
func AddToContainer(c *restful.Container, k8sClient k8s.Client, factory informers.InformerFactory) error {
|
||||
func AddToContainer(c *restful.Container, factory informers.InformerFactory) error {
|
||||
ws := runtime.NewWebService(GroupVersion)
|
||||
handler := newTenantHandler(k8sClient, factory)
|
||||
handler := newTenantHandler(factory)
|
||||
|
||||
ws.Route(ws.GET("/workspaces").
|
||||
To(handler.ListWorkspaces).
|
||||
|
||||
@@ -19,103 +19,81 @@ package am
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
k8sinformers "k8s.io/client-go/informers"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type AccessManagementInterface interface {
|
||||
ListRolesOfUser(scope iamv1alpha2.Scope, username string) ([]iamv1alpha2.Role, error)
|
||||
GetRoleOfUserInTargetScope(scope iamv1alpha2.Scope, target string, username string) (*iamv1alpha2.Role, error)
|
||||
GetPolicyRule(name string) (*iamv1alpha2.PolicyRule, error)
|
||||
GetGlobalRoleOfUser(username string) (*iamv1alpha2.GlobalRole, error)
|
||||
GetWorkspaceRoleOfUser(username, workspace string) (*iamv1alpha2.WorkspaceRole, error)
|
||||
GetClusterRoleOfUser(username, cluster string) (*rbacv1.ClusterRole, error)
|
||||
GetNamespaceRoleOfUser(username, namespace string) (*rbacv1.Role, error)
|
||||
ListRoles(username string, query *query.Query) (*api.ListResult, error)
|
||||
ListClusterRoles(query *query.Query) (*api.ListResult, error)
|
||||
ListWorkspaceRoles(query *query.Query) (*api.ListResult, error)
|
||||
ListGlobalRoles(query *query.Query) (*api.ListResult, error)
|
||||
|
||||
ListGlobalRoleBindings(username string) ([]*iamv1alpha2.GlobalRoleBinding, error)
|
||||
ListClusterRoleBindings(username string) ([]*rbacv1.ClusterRoleBinding, error)
|
||||
ListWorkspaceRoleBindings(username, workspace string) ([]*iamv1alpha2.WorkspaceRoleBinding, error)
|
||||
ListRoleBindings(username, namespace string) ([]*rbacv1.RoleBinding, error)
|
||||
|
||||
GetRoleReferenceRules(roleRef rbacv1.RoleRef, bindingNamespace string) ([]rbacv1.PolicyRule, error)
|
||||
}
|
||||
|
||||
type amOperator struct {
|
||||
informers informers.SharedInformerFactory
|
||||
ksClient kubesphere.Interface
|
||||
ksinformer ksinformers.SharedInformerFactory
|
||||
k8sinformer k8sinformers.SharedInformerFactory
|
||||
resourceGetter *resourcev1alpha3.ResourceGetter
|
||||
}
|
||||
|
||||
func NewAMOperator(ksClient kubesphere.Interface, informers informers.SharedInformerFactory) AccessManagementInterface {
|
||||
func NewAMOperator(factory informers.InformerFactory) AccessManagementInterface {
|
||||
return &amOperator{
|
||||
informers: informers,
|
||||
ksClient: ksClient,
|
||||
ksinformer: factory.KubeSphereSharedInformerFactory(),
|
||||
k8sinformer: factory.KubernetesSharedInformerFactory(),
|
||||
resourceGetter: resourcev1alpha3.NewResourceGetter(factory),
|
||||
}
|
||||
}
|
||||
|
||||
func containsUser(subjets []iamv1alpha2.Subject, username string) bool {
|
||||
for _, sub := range subjets {
|
||||
if sub.Kind == iamv1alpha2.UserKind && sub.Name == username {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (am *amOperator) GetGlobalRoleOfUser(username string) (*iamv1alpha2.GlobalRole, error) {
|
||||
|
||||
func (am *amOperator) ListRolesOfUser(scope iamv1alpha2.Scope, username string) ([]iamv1alpha2.Role, error) {
|
||||
|
||||
lister := am.informers.Iam().V1alpha2().RoleBindings().Lister()
|
||||
|
||||
roleBindings, err := lister.List(labels.Everything())
|
||||
roleBindings, err := am.ksinformer.Iam().V1alpha2().GlobalRoleBindings().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roleBindingsInScope := filterRoleBindingByScope(roleBindings, scope)
|
||||
userRoleBindings := make([]*iamv1alpha2.GlobalRoleBinding, 0)
|
||||
|
||||
roles := make([]iamv1alpha2.Role, 0)
|
||||
|
||||
for _, roleBinding := range roleBindingsInScope {
|
||||
if containsUser(roleBinding.Subjects, username) {
|
||||
role, err := am.informers.
|
||||
Iam().V1alpha2().Roles().Lister().Get(roleBinding.RoleRef.Name)
|
||||
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles = append(roles, *role)
|
||||
for _, roleBinding := range roleBindings {
|
||||
if contains(roleBinding.Subjects, username) {
|
||||
userRoleBindings = append(userRoleBindings, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
func filterRoleBindingByScope(roles []*iamv1alpha2.RoleBinding, scope iamv1alpha2.Scope) []*iamv1alpha2.RoleBinding {
|
||||
result := make([]*iamv1alpha2.RoleBinding, 0)
|
||||
for _, role := range roles {
|
||||
if role.Scope == scope {
|
||||
result = append(result, role)
|
||||
if len(userRoleBindings) > 0 {
|
||||
role, err := am.ksinformer.Iam().V1alpha2().GlobalRoles().Lister().Get(userRoleBindings[0].RoleRef.Name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (am *amOperator) GetPolicyRule(name string) (*iamv1alpha2.PolicyRule, error) {
|
||||
lister := am.informers.Iam().V1alpha2().PolicyRules().Lister()
|
||||
return lister.Get(name)
|
||||
}
|
||||
|
||||
// Users can only bind one role at each level
|
||||
func (am *amOperator) GetRoleOfUserInTargetScope(scope iamv1alpha2.Scope, target, username string) (*iamv1alpha2.Role, error) {
|
||||
roles, err := am.ListRolesOfUser(scope, username)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
for _, role := range roles {
|
||||
if role.Target.Name == target {
|
||||
return &role, nil
|
||||
if len(roleBindings) > 1 {
|
||||
klog.Warningf("conflict global role binding, username: %s", username)
|
||||
}
|
||||
return role, nil
|
||||
}
|
||||
|
||||
err = &errors.StatusError{ErrStatus: metav1.Status{
|
||||
@@ -124,11 +102,273 @@ func (am *amOperator) GetRoleOfUserInTargetScope(scope iamv1alpha2.Scope, target
|
||||
Reason: metav1.StatusReasonNotFound,
|
||||
Details: &metav1.StatusDetails{
|
||||
Group: iamv1alpha2.SchemeGroupVersion.Group,
|
||||
Kind: iamv1alpha2.RoleBindingKind,
|
||||
Kind: iamv1alpha2.ResourceKindGlobalRoleBinding,
|
||||
},
|
||||
Message: fmt.Sprintf("role bind not found in %s %s scope", target, scope),
|
||||
Message: fmt.Sprintf("global role binding not found for %s", username),
|
||||
}}
|
||||
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (am *amOperator) GetWorkspaceRoleOfUser(username, workspace string) (*iamv1alpha2.WorkspaceRole, error) {
|
||||
|
||||
roleBindings, err := am.ksinformer.Iam().V1alpha2().WorkspaceRoleBindings().Lister().List(labels.SelectorFromValidatedSet(labels.Set{tenantv1alpha1.WorkspaceLabel: workspace}))
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userRoleBindings := make([]*iamv1alpha2.WorkspaceRoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
if contains(roleBinding.Subjects, username) {
|
||||
userRoleBindings = append(userRoleBindings, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
if len(userRoleBindings) > 0 {
|
||||
role, err := am.ksinformer.Iam().V1alpha2().WorkspaceRoles().Lister().Get(userRoleBindings[0].RoleRef.Name)
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(roleBindings) > 1 {
|
||||
klog.Warningf("conflict workspace role binding, username: %s", username)
|
||||
}
|
||||
|
||||
return role, nil
|
||||
}
|
||||
|
||||
err = &errors.StatusError{ErrStatus: metav1.Status{
|
||||
Status: metav1.StatusFailure,
|
||||
Code: http.StatusNotFound,
|
||||
Reason: metav1.StatusReasonNotFound,
|
||||
Details: &metav1.StatusDetails{
|
||||
Group: iamv1alpha2.SchemeGroupVersion.Group,
|
||||
Kind: iamv1alpha2.ResourceKindWorkspaceRoleBinding,
|
||||
},
|
||||
Message: fmt.Sprintf("workspace role binding not found for %s", username),
|
||||
}}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (am *amOperator) GetNamespaceRoleOfUser(username, namespace string) (*rbacv1.Role, error) {
|
||||
roleBindings, err := am.k8sinformer.Rbac().V1().RoleBindings().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userRoleBindings := make([]*rbacv1.RoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
if contains(roleBinding.Subjects, username) {
|
||||
userRoleBindings = append(userRoleBindings, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
if len(userRoleBindings) > 0 {
|
||||
role, err := am.k8sinformer.Rbac().V1().Roles().Lister().Roles(namespace).Get(userRoleBindings[0].RoleRef.Name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
if len(roleBindings) > 1 {
|
||||
klog.Warningf("conflict role binding, username: %s", username)
|
||||
}
|
||||
return role, nil
|
||||
}
|
||||
|
||||
err = &errors.StatusError{ErrStatus: metav1.Status{
|
||||
Status: metav1.StatusFailure,
|
||||
Code: http.StatusNotFound,
|
||||
Reason: metav1.StatusReasonNotFound,
|
||||
Details: &metav1.StatusDetails{
|
||||
Group: rbacv1.SchemeGroupVersion.Group,
|
||||
Kind: "RoleBinding",
|
||||
},
|
||||
Message: fmt.Sprintf("role binding not found for %s in %s", username, namespace),
|
||||
}}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get federated clusterrole of user if cluster is not empty, if cluster is empty means current cluster
|
||||
func (am *amOperator) GetClusterRoleOfUser(username, cluster string) (*rbacv1.ClusterRole, error) {
|
||||
roleBindings, err := am.k8sinformer.Rbac().V1().ClusterRoleBindings().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userRoleBindings := make([]*rbacv1.ClusterRoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
if contains(roleBinding.Subjects, username) {
|
||||
userRoleBindings = append(userRoleBindings, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
if len(userRoleBindings) > 0 {
|
||||
role, err := am.k8sinformer.Rbac().V1().ClusterRoles().Lister().Get(userRoleBindings[0].RoleRef.Name)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
if len(roleBindings) > 1 {
|
||||
klog.Warningf("conflict cluster role binding, username: %s", username)
|
||||
}
|
||||
return role, nil
|
||||
}
|
||||
err = &errors.StatusError{ErrStatus: metav1.Status{
|
||||
Status: metav1.StatusFailure,
|
||||
Code: http.StatusNotFound,
|
||||
Reason: metav1.StatusReasonNotFound,
|
||||
Details: &metav1.StatusDetails{
|
||||
Group: rbacv1.SchemeGroupVersion.Group,
|
||||
Kind: "ClusterRoleBinding",
|
||||
},
|
||||
Message: fmt.Sprintf("cluster role binding not found for %s in %s", username, cluster),
|
||||
}}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (am *amOperator) ListWorkspaceRoleBindings(username, workspace string) ([]*iamv1alpha2.WorkspaceRoleBinding, error) {
|
||||
roleBindings, err := am.ksinformer.Iam().V1alpha2().WorkspaceRoleBindings().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*iamv1alpha2.WorkspaceRoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
inSpecifiedWorkspace := workspace == "" || roleBinding.Labels[tenantv1alpha1.WorkspaceLabel] == workspace
|
||||
if contains(roleBinding.Subjects, username) && inSpecifiedWorkspace {
|
||||
result = append(result, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (am *amOperator) ListClusterRoleBindings(username string) ([]*rbacv1.ClusterRoleBinding, error) {
|
||||
|
||||
roleBindings, err := am.k8sinformer.Rbac().V1().ClusterRoleBindings().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*rbacv1.ClusterRoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
if contains(roleBinding.Subjects, username) {
|
||||
result = append(result, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (am *amOperator) ListGlobalRoleBindings(username string) ([]*iamv1alpha2.GlobalRoleBinding, error) {
|
||||
roleBindings, err := am.ksinformer.Iam().V1alpha2().GlobalRoleBindings().Lister().List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*iamv1alpha2.GlobalRoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
if contains(roleBinding.Subjects, username) {
|
||||
result = append(result, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (am *amOperator) ListRoleBindings(username, namespace string) ([]*rbacv1.RoleBinding, error) {
|
||||
|
||||
roleBindings, err := am.k8sinformer.Rbac().V1().RoleBindings().Lister().RoleBindings(namespace).List(labels.Everything())
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*rbacv1.RoleBinding, 0)
|
||||
|
||||
for _, roleBinding := range roleBindings {
|
||||
if contains(roleBinding.Subjects, username) {
|
||||
result = append(result, roleBinding)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func contains(subjects []rbacv1.Subject, username string) bool {
|
||||
for _, subject := range subjects {
|
||||
if subject.Kind == rbacv1.UserKind && (username == "" || subject.Name == username) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (am *amOperator) ListRoles(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
return am.resourceGetter.List("roles", namespace, query)
|
||||
}
|
||||
|
||||
func (am *amOperator) ListClusterRoles(query *query.Query) (*api.ListResult, error) {
|
||||
return am.resourceGetter.List("clusterroles", "", query)
|
||||
}
|
||||
|
||||
func (am *amOperator) ListWorkspaceRoles(queryParam *query.Query) (*api.ListResult, error) {
|
||||
return am.resourceGetter.List(iamv1alpha2.ResourcesPluralWorkspaceRole, "", queryParam)
|
||||
}
|
||||
|
||||
func (am *amOperator) ListGlobalRoles(query *query.Query) (*api.ListResult, error) {
|
||||
return am.resourceGetter.List(iamv1alpha2.ResourcesPluralGlobalRole, "", query)
|
||||
}
|
||||
|
||||
// GetRoleReferenceRules attempts to resolve the RoleBinding or ClusterRoleBinding.
|
||||
func (am *amOperator) GetRoleReferenceRules(roleRef rbacv1.RoleRef, bindingNamespace string) ([]rbacv1.PolicyRule, error) {
|
||||
switch roleRef.Kind {
|
||||
case iamv1alpha2.ResourceKindRole:
|
||||
role, err := am.k8sinformer.Rbac().V1().Roles().Lister().Roles(bindingNamespace).Get(roleRef.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return role.Rules, nil
|
||||
case iamv1alpha2.ResourceKindClusterRole:
|
||||
clusterRole, err := am.k8sinformer.Rbac().V1().ClusterRoles().Lister().Get(roleRef.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clusterRole.Rules, nil
|
||||
case iamv1alpha2.ResourceKindGlobalRole:
|
||||
globalRole, err := am.ksinformer.Iam().V1alpha2().GlobalRoles().Lister().Get(roleRef.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return globalRole.Rules, nil
|
||||
case iamv1alpha2.ResourceKindWorkspaceRole:
|
||||
workspaceRole, err := am.ksinformer.Iam().V1alpha2().WorkspaceRoles().Lister().Get(roleRef.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return workspaceRole.Rules, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported role reference kind: %q", roleRef.Kind)
|
||||
}
|
||||
}
|
||||
|
||||
179
pkg/models/iam/am/rbac/evaluation_helpers.go
Normal file
179
pkg/models/iam/am/rbac/evaluation_helpers.go
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes 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 authorizerfactory
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func RoleRefGroupKind(roleRef rbacv1.RoleRef) schema.GroupKind {
|
||||
return schema.GroupKind{Group: roleRef.APIGroup, Kind: roleRef.Kind}
|
||||
}
|
||||
|
||||
func VerbMatches(rule *rbacv1.PolicyRule, requestedVerb string) bool {
|
||||
for _, ruleVerb := range rule.Verbs {
|
||||
if ruleVerb == rbacv1.VerbAll {
|
||||
return true
|
||||
}
|
||||
if ruleVerb == requestedVerb {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func APIGroupMatches(rule *rbacv1.PolicyRule, requestedGroup string) bool {
|
||||
for _, ruleGroup := range rule.APIGroups {
|
||||
if ruleGroup == rbacv1.APIGroupAll {
|
||||
return true
|
||||
}
|
||||
if ruleGroup == requestedGroup {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ResourceMatches(rule *rbacv1.PolicyRule, combinedRequestedResource, requestedSubresource string) bool {
|
||||
for _, ruleResource := range rule.Resources {
|
||||
// if everything is allowed, we match
|
||||
if ruleResource == rbacv1.ResourceAll {
|
||||
return true
|
||||
}
|
||||
// if we have an exact match, we match
|
||||
if ruleResource == combinedRequestedResource {
|
||||
return true
|
||||
}
|
||||
|
||||
// We can also match a */subresource.
|
||||
// if there isn't a subresource, then continue
|
||||
if len(requestedSubresource) == 0 {
|
||||
continue
|
||||
}
|
||||
// if the rule isn't in the format */subresource, then we don't match, continue
|
||||
if len(ruleResource) == len(requestedSubresource)+2 &&
|
||||
strings.HasPrefix(ruleResource, "*/") &&
|
||||
strings.HasSuffix(ruleResource, requestedSubresource) {
|
||||
return true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ResourceNameMatches(rule *rbacv1.PolicyRule, requestedName string) bool {
|
||||
if len(rule.ResourceNames) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, ruleName := range rule.ResourceNames {
|
||||
if ruleName == requestedName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func NonResourceURLMatches(rule *rbacv1.PolicyRule, requestedURL string) bool {
|
||||
for _, ruleURL := range rule.NonResourceURLs {
|
||||
if ruleURL == rbacv1.NonResourceAll {
|
||||
return true
|
||||
}
|
||||
if ruleURL == requestedURL {
|
||||
return true
|
||||
}
|
||||
if strings.HasSuffix(ruleURL, "*") && strings.HasPrefix(requestedURL, strings.TrimRight(ruleURL, "*")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// subjectsStrings returns users, groups, serviceaccounts, unknown for display purposes.
|
||||
func SubjectsStrings(subjects []rbacv1.Subject) ([]string, []string, []string, []string) {
|
||||
users := []string{}
|
||||
groups := []string{}
|
||||
sas := []string{}
|
||||
others := []string{}
|
||||
|
||||
for _, subject := range subjects {
|
||||
switch subject.Kind {
|
||||
case rbacv1.ServiceAccountKind:
|
||||
sas = append(sas, fmt.Sprintf("%s/%s", subject.Namespace, subject.Name))
|
||||
|
||||
case rbacv1.UserKind:
|
||||
users = append(users, subject.Name)
|
||||
|
||||
case rbacv1.GroupKind:
|
||||
groups = append(groups, subject.Name)
|
||||
|
||||
default:
|
||||
others = append(others, fmt.Sprintf("%s/%s/%s", subject.Kind, subject.Namespace, subject.Name))
|
||||
}
|
||||
}
|
||||
|
||||
return users, groups, sas, others
|
||||
}
|
||||
|
||||
func String(r rbacv1.PolicyRule) string {
|
||||
return "PolicyRule" + CompactString(r)
|
||||
}
|
||||
|
||||
// CompactString exposes a compact string representation for use in escalation error messages
|
||||
func CompactString(r rbacv1.PolicyRule) string {
|
||||
formatStringParts := []string{}
|
||||
formatArgs := []interface{}{}
|
||||
if len(r.APIGroups) > 0 {
|
||||
formatStringParts = append(formatStringParts, "APIGroups:%q")
|
||||
formatArgs = append(formatArgs, r.APIGroups)
|
||||
}
|
||||
if len(r.Resources) > 0 {
|
||||
formatStringParts = append(formatStringParts, "Resources:%q")
|
||||
formatArgs = append(formatArgs, r.Resources)
|
||||
}
|
||||
if len(r.NonResourceURLs) > 0 {
|
||||
formatStringParts = append(formatStringParts, "NonResourceURLs:%q")
|
||||
formatArgs = append(formatArgs, r.NonResourceURLs)
|
||||
}
|
||||
if len(r.ResourceNames) > 0 {
|
||||
formatStringParts = append(formatStringParts, "ResourceNames:%q")
|
||||
formatArgs = append(formatArgs, r.ResourceNames)
|
||||
}
|
||||
if len(r.Verbs) > 0 {
|
||||
formatStringParts = append(formatStringParts, "Verbs:%q")
|
||||
formatArgs = append(formatArgs, r.Verbs)
|
||||
}
|
||||
formatString := "{" + strings.Join(formatStringParts, ", ") + "}"
|
||||
return fmt.Sprintf(formatString, formatArgs...)
|
||||
}
|
||||
|
||||
type SortableRuleSlice []rbacv1.PolicyRule
|
||||
|
||||
func (s SortableRuleSlice) Len() int { return len(s) }
|
||||
func (s SortableRuleSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s SortableRuleSlice) Less(i, j int) bool {
|
||||
return strings.Compare(s[i].String(), s[j].String()) < 0
|
||||
}
|
||||
@@ -19,11 +19,20 @@ package im
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
kubesphereclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
|
||||
)
|
||||
|
||||
type IdentityManagementInterface interface {
|
||||
CreateUser(user *iamv1alpha2.User) (*iamv1alpha2.User, error)
|
||||
ListUsers(query *query.Query) (*api.ListResult, error)
|
||||
DeleteUser(username string) error
|
||||
ModifyUser(user *iamv1alpha2.User) (*iamv1alpha2.User, error)
|
||||
DescribeUser(username string) (*iamv1alpha2.User, error)
|
||||
@@ -36,3 +45,75 @@ var (
|
||||
UserAlreadyExists = errors.New("user already exists")
|
||||
UserNotExists = errors.New("user not exists")
|
||||
)
|
||||
|
||||
func NewOperator(ksClient kubesphereclient.Interface, factory informers.InformerFactory) IdentityManagementInterface {
|
||||
|
||||
return &defaultIMOperator{
|
||||
ksClient: ksClient,
|
||||
resourceGetter: resourcev1alpha3.NewResourceGetter(factory),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type defaultIMOperator struct {
|
||||
ksClient kubesphereclient.Interface
|
||||
resourceGetter *resourcev1alpha3.ResourceGetter
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) ModifyUser(user *iamv1alpha2.User) (*iamv1alpha2.User, error) {
|
||||
return im.ksClient.IamV1alpha2().Users().Update(user)
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) Authenticate(username, password string) (*iamv1alpha2.User, error) {
|
||||
|
||||
user, err := im.DescribeUser(username)
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
if checkPasswordHash(password, user.Spec.EncryptedPassword) {
|
||||
return user, nil
|
||||
}
|
||||
return nil, AuthFailedIncorrectPassword
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) ListUsers(query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
result, err := im.resourceGetter.List(iamv1alpha2.ResourcesPluralUser, "", query)
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func checkPasswordHash(password, hash string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) DescribeUser(username string) (*iamv1alpha2.User, error) {
|
||||
user, err := im.resourceGetter.Get(iamv1alpha2.ResourcesPluralUser, "", username)
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return user.(*iamv1alpha2.User), nil
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) DeleteUser(username string) error {
|
||||
return im.ksClient.IamV1alpha2().Users().Delete(username, metav1.NewDeleteOptions(0))
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) CreateUser(user *iamv1alpha2.User) (*iamv1alpha2.User, error) {
|
||||
user, err := im.ksClient.IamV1alpha2().Users().Create(user)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 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 im
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
kubesphereclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
)
|
||||
|
||||
func NewOperator(ksClient kubesphereclient.Interface, informer informers.SharedInformerFactory) IdentityManagementInterface {
|
||||
|
||||
return &defaultIMOperator{
|
||||
ksClient: ksClient,
|
||||
informer: informer,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type defaultIMOperator struct {
|
||||
ksClient kubesphereclient.Interface
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) ModifyUser(user *iamv1alpha2.User) (*iamv1alpha2.User, error) {
|
||||
return im.ksClient.IamV1alpha2().Users().Update(user)
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) Authenticate(username, password string) (*iamv1alpha2.User, error) {
|
||||
|
||||
user, err := im.ksClient.IamV1alpha2().Users().Get(username, metav1.GetOptions{})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if checkPasswordHash(password, user.Spec.EncryptedPassword) {
|
||||
return user, nil
|
||||
}
|
||||
return nil, AuthFailedIncorrectPassword
|
||||
}
|
||||
|
||||
func checkPasswordHash(password, hash string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) DescribeUser(username string) (*iamv1alpha2.User, error) {
|
||||
user, err := im.ksClient.IamV1alpha2().Users().Get(username, metav1.GetOptions{})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) DeleteUser(username string) error {
|
||||
return im.ksClient.IamV1alpha2().Users().Delete(username, metav1.NewDeleteOptions(0))
|
||||
}
|
||||
|
||||
func (im *defaultIMOperator) CreateUser(user *iamv1alpha2.User) (*iamv1alpha2.User, error) {
|
||||
user, err := im.ksClient.IamV1alpha2().Users().Create(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
@@ -19,7 +19,10 @@
|
||||
package im
|
||||
|
||||
import (
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/ldap"
|
||||
)
|
||||
|
||||
@@ -31,7 +34,6 @@ func NewLDAPOperator(ldapClient ldap.Interface) IdentityManagementInterface {
|
||||
return &ldapOperator{
|
||||
ldapClient: ldapClient,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (im *ldapOperator) ModifyUser(user *iamv1alpha2.User) (*iamv1alpha2.User, error) {
|
||||
@@ -78,3 +80,14 @@ func (im *ldapOperator) CreateUser(user *iamv1alpha2.User) (*iamv1alpha2.User, e
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (im *ldapOperator) ListUsers(query *query.Query) (*api.ListResult, error) {
|
||||
result, err := im.ldapClient.List(query)
|
||||
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -81,6 +81,13 @@ func ObjectMetaExactlyMath(key, value string, item metav1.ObjectMeta) bool {
|
||||
if !strings.Contains(item.Name, value) && !FuzzyMatch(item.Labels, "", value) && !FuzzyMatch(item.Annotations, "", value) {
|
||||
return false
|
||||
}
|
||||
case Owner:
|
||||
for _, ownerReference := range item.OwnerReferences {
|
||||
if strings.Compare(string(ownerReference.UID), value) == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
default:
|
||||
// label not exist or value not equal
|
||||
if val, ok := item.Labels[key]; !ok || val != value {
|
||||
@@ -109,13 +116,6 @@ func ObjectMetaFuzzyMath(key, value string, item metav1.ObjectMeta) bool {
|
||||
if !strings.Contains(item.Labels[Chart], value) && !strings.Contains(item.Labels[Release], value) {
|
||||
return false
|
||||
}
|
||||
case Owner:
|
||||
for _, ownerReference := range item.OwnerReferences {
|
||||
if strings.Compare(string(ownerReference.UID), value) == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
default:
|
||||
if !FuzzyMatch(item.Labels, key, value) {
|
||||
return false
|
||||
|
||||
@@ -115,7 +115,7 @@ func (r *ResourceGetter) ListResources(namespace, resource string, conditions *p
|
||||
|
||||
// none namespace resource
|
||||
if namespace != "" && sliceutil.HasString(clusterResources, resource) {
|
||||
err = fmt.Errorf("namespaced resource %s not found", resource)
|
||||
err = fmt.Errorf("resource %s is not supported", resource)
|
||||
klog.Errorln(err)
|
||||
return nil, err
|
||||
}
|
||||
@@ -123,7 +123,7 @@ func (r *ResourceGetter) ListResources(namespace, resource string, conditions *p
|
||||
if searcher, ok := r.resourcesGetters[resource]; ok {
|
||||
result, err = searcher.Search(namespace, conditions, orderBy, reverse)
|
||||
} else {
|
||||
err = fmt.Errorf("namespaced resource %s not found", resource)
|
||||
err = fmt.Errorf("resource %s is not supported", resource)
|
||||
klog.Errorln(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ package application
|
||||
import (
|
||||
appv1beta1 "github.com/kubernetes-sigs/application/pkg/apis/app/v1beta1"
|
||||
"github.com/kubernetes-sigs/application/pkg/client/informers/externalversions"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"time"
|
||||
)
|
||||
|
||||
type applicationsGetter struct {
|
||||
@@ -40,7 +40,7 @@ func (d *applicationsGetter) Get(namespace, name string) (runtime.Object, error)
|
||||
}
|
||||
|
||||
func (d *applicationsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
all, err := d.informer.App().V1beta1().Applications().Lister().Applications(namespace).List(labels.Everything())
|
||||
all, err := d.informer.App().V1beta1().Applications().Lister().Applications(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -64,8 +64,14 @@ func (d *applicationsGetter) compare(left runtime.Object, right runtime.Object,
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftApplication.ObjectMeta, rightApplication.ObjectMeta, field)
|
||||
switch field {
|
||||
case query.FieldUpdateTime:
|
||||
fallthrough
|
||||
case query.FieldLastUpdateTimestamp:
|
||||
return lastUpdateTime(leftApplication).After(lastUpdateTime(rightApplication))
|
||||
default:
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftApplication.ObjectMeta, rightApplication.ObjectMeta, field)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *applicationsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
@@ -76,3 +82,13 @@ func (d *applicationsGetter) filter(object runtime.Object, filter query.Filter)
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(application.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func lastUpdateTime(application *appv1beta1.Application) time.Time {
|
||||
lut := application.CreationTimestamp.Time
|
||||
for _, condition := range application.Status.Conditions {
|
||||
if condition.LastUpdateTime.After(lut) {
|
||||
lut = condition.LastUpdateTime.Time
|
||||
}
|
||||
}
|
||||
return lut
|
||||
}
|
||||
|
||||
@@ -59,12 +59,7 @@ func TestListApplications(t *testing.T) {
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: []query.Filter{
|
||||
{
|
||||
Field: query.FieldNamespace,
|
||||
Value: query.Value("bar2"),
|
||||
},
|
||||
},
|
||||
Filters: map[query.Field]query.Value{query.FieldNamespace: query.Value("bar2")},
|
||||
},
|
||||
api.ListResult{
|
||||
Items: []interface{}{
|
||||
|
||||
79
pkg/models/resources/v1alpha3/clusterrole/clusterroles.go
Normal file
79
pkg/models/resources/v1alpha3/clusterrole/clusterroles.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
|
||||
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 clusterrole
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type rolesGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &rolesGetter{sharedInformers: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *rolesGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Rbac().V1().ClusterRoles().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (d *rolesGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
all, err := d.sharedInformers.Rbac().V1().ClusterRoles().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, deploy := range all {
|
||||
result = append(result, deploy)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *rolesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftRole, ok := left.(*rbacv1.ClusterRole)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightRole, ok := right.(*rbacv1.ClusterRole)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRole.ObjectMeta, rightRole.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *rolesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*rbacv1.ClusterRole)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(role.ObjectMeta, filter)
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package clusterrole
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListClusterRoles(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
bar1 = &rbacv1.ClusterRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
},
|
||||
}
|
||||
|
||||
roles = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, role := range roles {
|
||||
informer.Rbac().V1().ClusterRoles().Informer().GetIndexer().Add(role)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package configmap
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
@@ -40,7 +39,7 @@ func (d *configmapsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
}
|
||||
|
||||
func (d *configmapsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
all, err := d.informer.Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).List(labels.Everything())
|
||||
all, err := d.informer.Core().V1().ConfigMaps().Lister().ConfigMaps(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -30,12 +30,7 @@ func TestListConfigMaps(t *testing.T) {
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: []query.Filter{
|
||||
{
|
||||
Field: query.FieldNamespace,
|
||||
Value: query.Value("default"),
|
||||
},
|
||||
},
|
||||
Filters: map[query.Field]query.Value{query.FieldNamespace: query.Value("default")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{foo3, foo2, foo1},
|
||||
|
||||
@@ -26,8 +26,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"k8s.io/api/apps/v1"
|
||||
)
|
||||
|
||||
@@ -51,7 +49,7 @@ func (d *deploymentsGetter) Get(namespace, name string) (runtime.Object, error)
|
||||
|
||||
func (d *deploymentsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
// first retrieves all deployments within given namespace
|
||||
all, err := d.sharedInformers.Apps().V1().Deployments().Lister().Deployments(namespace).List(labels.Everything())
|
||||
all, err := d.sharedInformers.Apps().V1().Deployments().Lister().Deployments(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -77,6 +75,8 @@ func (d *deploymentsGetter) compare(left runtime.Object, right runtime.Object, f
|
||||
}
|
||||
|
||||
switch field {
|
||||
case query.FieldUpdateTime:
|
||||
fallthrough
|
||||
case query.FieldLastUpdateTimestamp:
|
||||
return lastUpdateTime(leftDeployment).After(lastUpdateTime(rightDeployment))
|
||||
default:
|
||||
|
||||
@@ -30,12 +30,7 @@ func TestListDeployments(t *testing.T) {
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: []query.Filter{
|
||||
{
|
||||
Field: query.FieldName,
|
||||
Value: query.Value("foo2"),
|
||||
},
|
||||
},
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
|
||||
79
pkg/models/resources/v1alpha3/globalrole/globalroles.go
Normal file
79
pkg/models/resources/v1alpha3/globalrole/globalroles.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
|
||||
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 globalrole
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type globalrolesGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &globalrolesGetter{sharedInformers: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Iam().V1alpha2().GlobalRoles().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
all, err := d.sharedInformers.Iam().V1alpha2().GlobalRoles().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, deploy := range all {
|
||||
result = append(result, deploy)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftRole, ok := left.(*iamv1alpha2.GlobalRole)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightRole, ok := right.(*iamv1alpha2.GlobalRole)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRole.ObjectMeta, rightRole.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *globalrolesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*iamv1alpha2.GlobalRole)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(role.ObjectMeta, filter)
|
||||
}
|
||||
94
pkg/models/resources/v1alpha3/globalrole/globalroles_test.go
Normal file
94
pkg/models/resources/v1alpha3/globalrole/globalroles_test.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package globalrole
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListGlobalRoles(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &iamv1alpha2.GlobalRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &iamv1alpha2.GlobalRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
bar1 = &iamv1alpha2.GlobalRole{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
},
|
||||
}
|
||||
|
||||
roles = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, role := range roles {
|
||||
informer.Iam().V1alpha2().GlobalRoles().Informer().GetIndexer().Add(role)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
@@ -22,13 +22,13 @@ type CompareFunc func(runtime.Object, runtime.Object, query.Field) bool
|
||||
|
||||
type FilterFunc func(runtime.Object, query.Filter) bool
|
||||
|
||||
func DefaultList(objects []runtime.Object, query *query.Query, compareFunc CompareFunc, filterFunc FilterFunc) *api.ListResult {
|
||||
func DefaultList(objects []runtime.Object, q *query.Query, compareFunc CompareFunc, filterFunc FilterFunc) *api.ListResult {
|
||||
// selected matched ones
|
||||
var filtered []runtime.Object
|
||||
for _, object := range objects {
|
||||
selected := true
|
||||
for _, filter := range query.Filters {
|
||||
if !filterFunc(object, filter) {
|
||||
for field, value := range q.Filters {
|
||||
if !filterFunc(object, query.Filter{Field: field, Value: value}) {
|
||||
selected = false
|
||||
break
|
||||
}
|
||||
@@ -41,14 +41,14 @@ func DefaultList(objects []runtime.Object, query *query.Query, compareFunc Compa
|
||||
|
||||
// sort by sortBy field
|
||||
sort.Slice(filtered, func(i, j int) bool {
|
||||
if !query.Ascending {
|
||||
return compareFunc(filtered[i], filtered[j], query.SortBy)
|
||||
if !q.Ascending {
|
||||
return compareFunc(filtered[i], filtered[j], q.SortBy)
|
||||
}
|
||||
return !compareFunc(filtered[i], filtered[j], query.SortBy)
|
||||
return !compareFunc(filtered[i], filtered[j], q.SortBy)
|
||||
})
|
||||
|
||||
total := len(filtered)
|
||||
start, end := query.Pagination.GetValidPagination(total)
|
||||
start, end := q.Pagination.GetValidPagination(total)
|
||||
|
||||
return &api.ListResult{
|
||||
TotalItems: len(filtered),
|
||||
@@ -63,6 +63,8 @@ func DefaultObjectMetaCompare(left, right metav1.ObjectMeta, sortBy query.Field)
|
||||
case query.FieldName:
|
||||
return strings.Compare(left.Name, right.Name) > 0
|
||||
// ?sortBy=creationTimestamp
|
||||
case query.FieldCreateTime:
|
||||
fallthrough
|
||||
case query.FieldCreationTimeStamp:
|
||||
// compare by name if creation timestamp is equal
|
||||
if left.CreationTimestamp.Equal(&right.CreationTimestamp) {
|
||||
@@ -104,29 +106,43 @@ func DefaultObjectMetaFilter(item metav1.ObjectMeta, filter query.Filter) bool {
|
||||
return false
|
||||
// /namespaces?page=1&limit=10&annotation=openpitrix_runtime
|
||||
case query.FieldAnnotation:
|
||||
return containsAnyValue(item.Annotations, string(filter.Value))
|
||||
return labelMatch(item.Annotations, string(filter.Value))
|
||||
// /namespaces?page=1&limit=10&label=kubesphere.io/workspace:system-workspace
|
||||
case query.FieldLabel:
|
||||
return containsAnyValue(item.Labels, string(filter.Value))
|
||||
return labelMatch(item.Labels, string(filter.Value))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Filter format <key:><value>,if the key is defined, the key must match exactly, value match according to strings.Contains.
|
||||
func containsAnyValue(keyValues map[string]string, filter string) bool {
|
||||
fields := strings.SplitN(filter, ":", 2)
|
||||
var keyFilter, valueFilter string
|
||||
// Filter format (key!?=)?value,if the key is defined, the key must match exactly, value match according to strings.Contains.
|
||||
func labelMatch(labels map[string]string, filter string) bool {
|
||||
fields := strings.SplitN(filter, "=", 2)
|
||||
var key, value string
|
||||
var opposite bool
|
||||
if len(fields) == 2 {
|
||||
keyFilter = fields[0]
|
||||
valueFilter = fields[1]
|
||||
} else {
|
||||
valueFilter = fields[0]
|
||||
}
|
||||
for key, value := range keyValues {
|
||||
if (key == keyFilter || keyFilter == "") && strings.Contains(value, valueFilter) {
|
||||
return true
|
||||
key = fields[0]
|
||||
if strings.HasSuffix(key, "!") {
|
||||
key = strings.TrimSuffix(key, "!")
|
||||
opposite = true
|
||||
}
|
||||
value = fields[1]
|
||||
} else {
|
||||
value = fields[0]
|
||||
}
|
||||
for k, v := range labels {
|
||||
if opposite {
|
||||
if (key == "" || k == key) && !strings.Contains(v, value) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if (key == "" || k == key) && strings.Contains(v, value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
if opposite && labels[key] == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package namespace
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
@@ -24,7 +23,7 @@ func (n namespaceGetter) Get(_, name string) (runtime.Object, error) {
|
||||
}
|
||||
|
||||
func (n namespaceGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
ns, err := n.informers.Core().V1().Namespaces().Lister().List(labels.Everything())
|
||||
ns, err := n.informers.Core().V1().Namespaces().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
115
pkg/models/resources/v1alpha3/pod/pods.go
Normal file
115
pkg/models/resources/v1alpha3/pod/pods.go
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
|
||||
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 pod
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type podsGetter struct {
|
||||
informer informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &podsGetter{informer: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *podsGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.informer.Core().V1().Pods().Lister().Pods(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (d *podsGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
all, err := d.informer.Core().V1().Pods().Lister().Pods(namespace).List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, app := range all {
|
||||
result = append(result, app)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *podsGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftPod, ok := left.(*corev1.Pod)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightPod, ok := right.(*corev1.Pod)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftPod.ObjectMeta, rightPod.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *podsGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
pod, ok := object.(*corev1.Pod)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch filter.Field {
|
||||
case "nodeName":
|
||||
if pod.Spec.NodeName != string(filter.Value) {
|
||||
return false
|
||||
}
|
||||
case "pvcName":
|
||||
if !d.podBindPVC(pod, string(filter.Value)) {
|
||||
return false
|
||||
}
|
||||
case "serviceName":
|
||||
if !d.podBelongToService(pod, string(filter.Value)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return v1alpha3.DefaultObjectMetaFilter(pod.ObjectMeta, filter)
|
||||
}
|
||||
|
||||
func (s *podsGetter) podBindPVC(item *corev1.Pod, pvcName string) bool {
|
||||
for _, v := range item.Spec.Volumes {
|
||||
if v.VolumeSource.PersistentVolumeClaim != nil &&
|
||||
v.VolumeSource.PersistentVolumeClaim.ClaimName == pvcName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *podsGetter) podBelongToService(item *corev1.Pod, serviceName string) bool {
|
||||
service, err := s.informer.Core().V1().Services().Lister().Services(item.Namespace).Get(serviceName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
|
||||
if selector.Empty() || !selector.Matches(labels.Set(item.Labels)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
91
pkg/models/resources/v1alpha3/pod/pods_test.go
Normal file
91
pkg/models/resources/v1alpha3/pod/pods_test.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package pod
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListPods(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"default",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldNamespace: query.Value("default")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{foo3, foo2, foo1},
|
||||
TotalItems: len(pods),
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
foo2 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
foo3 = &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo3",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
pods = []interface{}{foo1, foo2, foo3}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, pod := range pods {
|
||||
informer.Core().V1().Pods().Informer().GetIndexer().Add(pod)
|
||||
}
|
||||
|
||||
return New(informer)
|
||||
}
|
||||
@@ -1,15 +1,45 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 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 resource
|
||||
|
||||
import (
|
||||
"errors"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/application"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/clusterrole"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/configmap"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/deployment"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/globalrole"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/namespace"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/pod"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/role"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/user"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspace"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/workspacerole"
|
||||
)
|
||||
|
||||
var ErrResourceNotSupported = errors.New("resource is not supported")
|
||||
@@ -23,7 +53,15 @@ func NewResourceGetter(factory informers.InformerFactory) *ResourceGetter {
|
||||
|
||||
getters[schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}] = deployment.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"}] = namespace.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"}] = configmap.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}] = pod.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[schema.GroupVersionResource{Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"}] = application.New(factory.ApplicationSharedInformerFactory())
|
||||
getters[tenantv1alpha1.SchemeGroupVersion.WithResource(tenantv1alpha1.ResourcePluralWorkspace)] = workspace.New(factory.KubeSphereSharedInformerFactory())
|
||||
getters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralGlobalRole)] = globalrole.New(factory.KubeSphereSharedInformerFactory())
|
||||
getters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralWorkspaceRole)] = workspacerole.New(factory.KubeSphereSharedInformerFactory())
|
||||
getters[iamv1alpha2.SchemeGroupVersion.WithResource(iamv1alpha2.ResourcesPluralUser)] = user.New(factory.KubeSphereSharedInformerFactory())
|
||||
getters[rbacv1.SchemeGroupVersion.WithResource("roles")] = role.New(factory.KubernetesSharedInformerFactory())
|
||||
getters[rbacv1.SchemeGroupVersion.WithResource("clusterroles")] = clusterrole.New(factory.KubernetesSharedInformerFactory())
|
||||
|
||||
return &ResourceGetter{
|
||||
getters: getters,
|
||||
@@ -38,11 +76,10 @@ func (r *ResourceGetter) tryResource(resource string) v1alpha3.Interface {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ResourceGetter) Get(resource, namespace, name string) (interface{}, error) {
|
||||
func (r *ResourceGetter) Get(resource, namespace, name string) (runtime.Object, error) {
|
||||
getter := r.tryResource(resource)
|
||||
if getter == nil {
|
||||
return nil, ErrResourceNotSupported
|
||||
|
||||
@@ -55,7 +55,7 @@ func TestResourceGetter(t *testing.T) {
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: []query.Filter{},
|
||||
Filters: map[query.Field]query.Value{},
|
||||
},
|
||||
ExpectError: nil,
|
||||
ExpectResponse: &api.ListResult{
|
||||
|
||||
79
pkg/models/resources/v1alpha3/role/roles.go
Normal file
79
pkg/models/resources/v1alpha3/role/roles.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
|
||||
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 role
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/informers"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type rolesGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &rolesGetter{sharedInformers: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *rolesGetter) Get(namespace, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Rbac().V1().Roles().Lister().Roles(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (d *rolesGetter) List(namespace string, query *query.Query) (*api.ListResult, error) {
|
||||
all, err := d.sharedInformers.Rbac().V1().Roles().Lister().Roles(namespace).List(query.Selector())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, deploy := range all {
|
||||
result = append(result, deploy)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *rolesGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftRole, ok := left.(*rbacv1.Role)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightRole, ok := right.(*rbacv1.Role)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRole.ObjectMeta, rightRole.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *rolesGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*rbacv1.Role)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(role.ObjectMeta, filter)
|
||||
}
|
||||
97
pkg/models/resources/v1alpha3/role/roles_test.go
Normal file
97
pkg/models/resources/v1alpha3/role/roles_test.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListRoles(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &rbacv1.Role{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &rbacv1.Role{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
bar1 = &rbacv1.Role{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
Namespace: "bar",
|
||||
},
|
||||
}
|
||||
|
||||
roles = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, role := range roles {
|
||||
informer.Rbac().V1().Roles().Informer().GetIndexer().Add(role)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
79
pkg/models/resources/v1alpha3/user/users.go
Normal file
79
pkg/models/resources/v1alpha3/user/users.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
|
||||
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 user
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type usersGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &usersGetter{sharedInformers: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *usersGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Iam().V1alpha2().Users().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (d *usersGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
all, err := d.sharedInformers.Iam().V1alpha2().Users().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, deploy := range all {
|
||||
result = append(result, deploy)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *usersGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftRole, ok := left.(*iamv1alpha2.User)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightRole, ok := right.(*iamv1alpha2.User)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRole.ObjectMeta, rightRole.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *usersGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*iamv1alpha2.User)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(role.ObjectMeta, filter)
|
||||
}
|
||||
94
pkg/models/resources/v1alpha3/user/users_test.go
Normal file
94
pkg/models/resources/v1alpha3/user/users_test.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListUsers(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &iamv1alpha2.User{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &iamv1alpha2.User{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
bar1 = &iamv1alpha2.User{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
},
|
||||
}
|
||||
|
||||
users = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, user := range users {
|
||||
informer.Iam().V1alpha2().Users().Informer().GetIndexer().Add(user)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
79
pkg/models/resources/v1alpha3/workspace/workspaces.go
Normal file
79
pkg/models/resources/v1alpha3/workspace/workspaces.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
|
||||
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 workspace
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
)
|
||||
|
||||
type workspaceGetter struct {
|
||||
sharedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
func New(sharedInformers informers.SharedInformerFactory) v1alpha3.Interface {
|
||||
return &workspaceGetter{sharedInformers: sharedInformers}
|
||||
}
|
||||
|
||||
func (d *workspaceGetter) Get(_, name string) (runtime.Object, error) {
|
||||
return d.sharedInformers.Tenant().V1alpha1().Workspaces().Lister().Get(name)
|
||||
}
|
||||
|
||||
func (d *workspaceGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
|
||||
|
||||
all, err := d.sharedInformers.Tenant().V1alpha1().Workspaces().Lister().List(query.Selector())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []runtime.Object
|
||||
for _, deploy := range all {
|
||||
result = append(result, deploy)
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultList(result, query, d.compare, d.filter), nil
|
||||
}
|
||||
|
||||
func (d *workspaceGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
|
||||
|
||||
leftRole, ok := left.(*tenantv1alpha1.Workspace)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rightRole, ok := right.(*tenantv1alpha1.Workspace)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaCompare(leftRole.ObjectMeta, rightRole.ObjectMeta, field)
|
||||
}
|
||||
|
||||
func (d *workspaceGetter) filter(object runtime.Object, filter query.Filter) bool {
|
||||
role, ok := object.(*tenantv1alpha1.Workspace)
|
||||
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return v1alpha3.DefaultObjectMetaFilter(role.ObjectMeta, filter)
|
||||
}
|
||||
94
pkg/models/resources/v1alpha3/workspace/workspaces_test.go
Normal file
94
pkg/models/resources/v1alpha3/workspace/workspaces_test.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package workspace
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"kubesphere.io/kubesphere/pkg/api"
|
||||
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListWorkspaces(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
namespace string
|
||||
query *query.Query
|
||||
expected *api.ListResult
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
"test name filter",
|
||||
"bar",
|
||||
&query.Query{
|
||||
Pagination: &query.Pagination{
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
},
|
||||
SortBy: query.FieldName,
|
||||
Ascending: false,
|
||||
Filters: map[query.Field]query.Value{query.FieldName: query.Value("foo2")},
|
||||
},
|
||||
&api.ListResult{
|
||||
Items: []interface{}{
|
||||
foo2,
|
||||
},
|
||||
TotalItems: 1,
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
getter := prepare()
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
|
||||
got, err := getter.List(test.namespace, test.query)
|
||||
|
||||
if test.expectedErr != nil && err != test.expectedErr {
|
||||
t.Errorf("expected error, got nothing")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, test.expected); diff != "" {
|
||||
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
foo1 = &tenantv1alpha1.Workspace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
},
|
||||
}
|
||||
|
||||
foo2 = &tenantv1alpha1.Workspace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
},
|
||||
}
|
||||
bar1 = &tenantv1alpha1.Workspace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar1",
|
||||
},
|
||||
}
|
||||
|
||||
workspaces = []interface{}{foo1, foo2, bar1}
|
||||
)
|
||||
|
||||
func prepare() v1alpha3.Interface {
|
||||
client := fake.NewSimpleClientset()
|
||||
informer := informers.NewSharedInformerFactory(client, 0)
|
||||
|
||||
for _, workspace := range workspaces {
|
||||
informer.Tenant().V1alpha1().Workspaces().Informer().GetIndexer().Add(workspace)
|
||||
}
|
||||
return New(informer)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user