Merge pull request #2018 from wansir/dev

migrate legacy API
This commit is contained in:
KubeSphere CI Bot
2020-04-29 10:42:26 +08:00
committed by GitHub
136 changed files with 6101 additions and 7501 deletions

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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:

View 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: []

View File

@@ -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: []

View File

@@ -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: []

View File

@@ -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

View 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: []

View 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: []

View 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:
- '*'

View File

@@ -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

View File

@@ -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'
}

View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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"`
}

View File

@@ -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
}

View 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
}

View File

@@ -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!

View File

@@ -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"},
}

View File

@@ -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 (

View 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)
}

View File

@@ -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.")
}
}

View File

@@ -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 {

View File

@@ -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
}

View 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)
}
}

View 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)
}
}
}

View 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
}

View File

@@ -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
}
}

View File

@@ -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: &notification.Options{
Endpoint: "http://notification.kubesphere-alerting-system.svc:9200",
},
AuthorizationOptions: authorizationoptions.NewAuthorizationOptions(),
AuthenticationOptions: &authoptions.AuthenticationOptions{
AuthenticateRateLimiterMaxTries: 5,
AuthenticateRateLimiterDuration: 30 * time.Minute,

View File

@@ -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

View File

@@ -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,
}

View File

@@ -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)
}
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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{}

View File

@@ -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).

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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"):

View File

@@ -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())
}

View File

@@ -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())
}

View File

@@ -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}
}

View File

@@ -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())
}

View File

@@ -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())
}

View File

@@ -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{}

View File

@@ -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
}

View 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
}

View File

@@ -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
}

View File

@@ -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
}

View 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
}

View 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
}

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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").

View File

@@ -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 := &params.Conditions{}
for _, filter := range q.Filters {
switch filter.Field {
conditions := &params.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)

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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).

View File

@@ -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)
}
}

View 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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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{}{

View 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)
}

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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},

View File

@@ -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:

View File

@@ -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{}{

View 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)
}

View 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)
}

View File

@@ -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
}

View File

@@ -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
}

View 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
}

View 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)
}

View File

@@ -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

View File

@@ -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{

View 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)
}

View 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)
}

View 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)
}

View 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)
}

View 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)
}

View 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