未验证 提交 25e95c4c 编写于 作者: K KubeSphere CI Bot 提交者: GitHub

Merge pull request #2018 from wansir/dev

migrate legacy API
......@@ -66,6 +66,7 @@ func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
s.GenericServerRunOptions.AddFlags(fs, s.GenericServerRunOptions)
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), s.KubernetesOptions)
s.AuthenticationOptions.AddFlags(fss.FlagSet("authentication"), s.AuthenticationOptions)
s.AuthorizationOptions.AddFlags(fss.FlagSet("authorization"), s.AuthorizationOptions)
s.DevopsOptions.AddFlags(fss.FlagSet("devops"), s.DevopsOptions)
s.SonarQubeOptions.AddFlags(fss.FlagSet("sonarqube"), s.SonarQubeOptions)
s.LdapOptions.AddFlags(fss.FlagSet("ldap"), s.LdapOptions)
......
......@@ -15,6 +15,7 @@ func (s *ServerRunOptions) Validate() []error {
errors = append(errors, s.OpenPitrixOptions.Validate()...)
errors = append(errors, s.NetworkOptions.Validate()...)
errors = append(errors, s.LoggingOptions.Validate()...)
errors = append(errors, s.AuthorizationOptions.Validate()...)
return errors
}
......@@ -6,28 +6,17 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: (devel)
creationTimestamp: null
name: rolebindings.iam.kubesphere.io
name: globalrolebindings.iam.kubesphere.io
spec:
additionalPrinterColumns:
- JSONPath: .scope
name: Scope
type: string
- JSONPath: .roleRef.name
name: RoleRef
type: string
- JSONPath: .subjects[*].name
name: Subjects
type: string
group: iam.kubesphere.io
names:
categories:
- iam
kind: RoleBinding
listKind: RoleBindingList
plural: rolebindings
singular: rolebinding
kind: GlobalRoleBinding
listKind: GlobalRoleBindingList
plural: globalrolebindings
singular: globalrolebinding
scope: Cluster
subresources: {}
validation:
openAPIV3Schema:
description: RoleBinding is the Schema for the rolebindings API
......@@ -43,10 +32,11 @@ spec:
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
description: Standard object's metadata.
type: object
roleRef:
description: RoleRef contains information that points to the role being
used
description: RoleRef can only reference a ClusterRole in the global namespace.
If the RoleRef cannot be resolved, the Authorizer must return an error.
properties:
apiGroup:
description: APIGroup is the group for the resource being referenced
......@@ -62,15 +52,17 @@ spec:
- kind
- name
type: object
scope:
type: string
subjects:
description: Subjects holds references to the users the role applies to.
description: Subjects holds references to the objects the role applies to.
items:
description: or a value for non-objects such as user and group names.
description: Subject contains a reference to the object or user identities
a role binding applies to. This can either hold a direct API object
reference, or a value for non-objects such as user and group names.
properties:
apiGroup:
description: APIGroup holds the API group of the referenced subject.
Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io"
for User and Group subjects.
type: string
kind:
description: Kind of object being referenced. Values defined by this
......@@ -81,15 +73,18 @@ spec:
name:
description: Name of the object being referenced.
type: string
namespace:
description: Namespace of the referenced object. If the object kind
is non-namespace, such as "User" or "Group", and this value is not
empty the Authorizer should report an error.
type: string
required:
- apiGroup
- kind
- name
type: object
type: array
required:
- roleRef
- scope
type: object
version: v1alpha2
versions:
......
---
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: []
---
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: []
......@@ -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
......
......@@ -6,27 +6,25 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: (devel)
creationTimestamp: null
name: roles.iam.kubesphere.io
name: workspacerolebindings.iam.kubesphere.io
spec:
additionalPrinterColumns:
- JSONPath: .target.scope
name: Scope
type: string
- JSONPath: .target.name
name: Target
- JSONPath: .metadata.labels.kubesphere\.io/workspace
name: Workspace
type: string
group: iam.kubesphere.io
names:
categories:
- iam
kind: Role
listKind: RoleList
plural: roles
singular: role
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
......@@ -40,39 +38,57 @@ spec:
type: string
metadata:
type: object
rules:
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: RuleRef contains information that points to the role being
used
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 is the group for the resource being referenced
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 is the type of resource being referenced
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 is the name of resource being referenced
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
target:
properties:
name:
type: string
scope:
type: string
required:
- name
- scope
type: object
required:
- rules
- target
- roleRef
type: object
version: v1alpha2
versions:
......
---
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: []
apiVersion: iam.kubesphere.io/v1alpha2
kind: GlobalRole
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: global-admin
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
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
......
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'
}
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
......@@ -81,7 +81,7 @@ require (
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/xanzy/ssh-agent v0.2.1 // indirect
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
golang.org/x/net v0.0.0-20190923162816-aa69164e4478
google.golang.org/grpc v1.23.1
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
gopkg.in/go-playground/validator.v9 v9.29.1 // indirect
......@@ -141,10 +141,8 @@ replace (
github.com/bitly/go-simplejson => github.com/bitly/go-simplejson v0.5.0
github.com/blang/semver => github.com/blang/semver v3.5.0+incompatible
github.com/bmizerany/assert => github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869
github.com/cenkalti/backoff => github.com/cenkalti/backoff v2.2.1+incompatible
github.com/cespare/xxhash => github.com/cespare/xxhash v1.1.0
github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
github.com/cheekybits/genny => github.com/cheekybits/genny v1.0.0
github.com/client9/misspell => github.com/client9/misspell v0.3.4
github.com/coreos/bbolt => github.com/coreos/bbolt v1.3.3
github.com/coreos/etcd => github.com/coreos/etcd v3.3.17+incompatible
......@@ -158,14 +156,12 @@ replace (
github.com/deckarep/golang-set => github.com/deckarep/golang-set v1.7.1
github.com/denisenkom/go-mssqldb => github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289
github.com/dgrijalva/jwt-go => github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dgryski/go-sip13 => github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954
github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible
github.com/docker/docker => github.com/docker/engine v1.4.2-0.20190822205725-ed20165a37b4
github.com/docker/go-connections => github.com/docker/go-connections v0.3.0
github.com/docker/go-units => github.com/docker/go-units v0.3.3
github.com/docker/spdystream => github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c
github.com/docopt/docopt-go => github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
github.com/dustin/go-humanize => github.com/dustin/go-humanize v1.0.0
github.com/elastic/go-elasticsearch/v5 => github.com/elastic/go-elasticsearch/v5 v5.6.1
github.com/elastic/go-elasticsearch/v6 => github.com/elastic/go-elasticsearch/v6 v6.8.2
github.com/elastic/go-elasticsearch/v7 => github.com/elastic/go-elasticsearch/v7 v7.3.0
......@@ -185,7 +181,6 @@ replace (
github.com/ghodss/yaml => github.com/ghodss/yaml v1.0.0
github.com/gliderlabs/ssh => github.com/gliderlabs/ssh v0.1.1
github.com/globalsign/mgo => github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8
github.com/go-acme/lego => github.com/go-acme/lego v2.5.0+incompatible
github.com/go-kit/kit => github.com/go-kit/kit v0.8.0
github.com/go-ldap/ldap => github.com/go-ldap/ldap v3.0.3+incompatible
github.com/go-logfmt/logfmt => github.com/go-logfmt/logfmt v0.4.0
......@@ -238,7 +233,6 @@ replace (
github.com/grpc-ecosystem/go-grpc-middleware => github.com/grpc-ecosystem/go-grpc-middleware v1.0.0
github.com/grpc-ecosystem/go-grpc-prometheus => github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.9.6
github.com/hashicorp/go-syslog => github.com/hashicorp/go-syslog v1.0.0
github.com/hashicorp/go-version => github.com/hashicorp/go-version v1.2.0
github.com/hashicorp/golang-lru => github.com/hashicorp/golang-lru v0.5.3
github.com/hashicorp/hcl => github.com/hashicorp/hcl v1.0.0
......@@ -247,7 +241,6 @@ replace (
github.com/inconshreveable/mousetrap => github.com/inconshreveable/mousetrap v1.0.0
github.com/jbenet/go-context => github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
github.com/jessevdk/go-flags => github.com/jessevdk/go-flags v1.4.0
github.com/jimstudt/http-authentication => github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a
github.com/jinzhu/gorm => github.com/jinzhu/gorm v1.9.2
github.com/jinzhu/inflection => github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a
github.com/jinzhu/now => github.com/jinzhu/now v1.0.0
......@@ -263,7 +256,6 @@ replace (
github.com/kiali/kiali => github.com/kubesphere/kiali v0.15.1-0.20191210080139-edbbad1ef779
github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.2.0
github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0
github.com/klauspost/cpuid => github.com/klauspost/cpuid v1.2.1
github.com/koding/multiconfig => github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7
github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.2
github.com/kr/logfmt => github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515
......@@ -271,26 +263,18 @@ replace (
github.com/kr/pty => github.com/kr/pty v1.1.5
github.com/kr/text => github.com/kr/text v0.1.0
github.com/kubernetes-sigs/application => github.com/kubesphere/application v0.0.0-20191210100950-18cc93526ab4
github.com/kubernetes-sigs/federation-v2 => github.com/kubernetes-sigs/federation-v2 v0.0.10
github.com/kubesphere/s2ioperator => github.com/kubesphere/s2ioperator v0.0.14
github.com/kubesphere/sonargo => github.com/kubesphere/sonargo v0.0.2
github.com/kylelemons/godebug => github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348
github.com/leodido/go-urn => github.com/leodido/go-urn v1.1.0
github.com/lib/pq => github.com/lib/pq v1.2.0
github.com/liggitt/tabwriter => github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
github.com/lithammer/dedent => github.com/lithammer/dedent v1.1.0
github.com/lucas-clemente/quic-go => github.com/lucas-clemente/quic-go v0.11.1
github.com/magiconair/properties => github.com/magiconair/properties v1.8.0
github.com/mailru/easyjson => github.com/mailru/easyjson v0.7.0
github.com/marten-seemann/qtls => github.com/marten-seemann/qtls v0.2.3
github.com/mattn/go-colorable => github.com/mattn/go-colorable v0.1.2
github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.8
github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.0-20181025052659-b20a3daf6a39
github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.11.0
github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/mholt/caddy => github.com/mholt/caddy v1.0.0
github.com/mholt/certmagic => github.com/mholt/certmagic v0.5.1
github.com/miekg/dns => github.com/miekg/dns v1.1.9
github.com/mitchellh/go-homedir => github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/go-wordwrap => github.com/mitchellh/go-wordwrap v1.0.0
github.com/mitchellh/mapstructure => github.com/mitchellh/mapstructure v1.1.2
......@@ -301,9 +285,6 @@ replace (
github.com/munnerz/goautoneg => github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d
github.com/mwitkow/go-conntrack => github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223
github.com/mxk/go-flowrate => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
github.com/naoina/go-stringutil => github.com/naoina/go-stringutil v0.1.0
github.com/naoina/toml => github.com/naoina/toml v0.1.1
github.com/oklog/ulid => github.com/oklog/ulid v1.3.1
github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.1
github.com/onsi/ginkgo => github.com/onsi/ginkgo v1.8.0
github.com/onsi/gomega => github.com/onsi/gomega v1.5.0
......@@ -311,7 +292,6 @@ replace (
github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.1
github.com/openshift/api => github.com/openshift/api v0.0.0-20180801171038-322a19404e37
github.com/openshift/build-machinery-go => github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160
github.com/openshift/generic-admission-server => github.com/openshift/generic-admission-server v1.14.0
github.com/opentracing/opentracing-go => github.com/opentracing/opentracing-go v1.1.0
github.com/pborman/uuid => github.com/pborman/uuid v1.2.0
......@@ -333,7 +313,6 @@ replace (
github.com/prometheus/common => github.com/prometheus/common v0.4.0
github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.2
github.com/prometheus/prometheus => github.com/prometheus/prometheus v1.8.2
github.com/prometheus/tsdb => github.com/prometheus/tsdb v0.7.1
github.com/rcrowley/go-metrics => github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a
github.com/remyoudompheng/bigfft => github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446
github.com/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af
......@@ -400,7 +379,6 @@ replace (
gopkg.in/go-playground/assert.v1 => gopkg.in/go-playground/assert.v1 v1.2.1
gopkg.in/go-playground/validator.v9 => gopkg.in/go-playground/validator.v9 v9.29.1
gopkg.in/inf.v0 => gopkg.in/inf.v0 v0.9.1
gopkg.in/mcuadros/go-syslog.v2 => gopkg.in/mcuadros/go-syslog.v2 v2.2.1
gopkg.in/natefinch/lumberjack.v2 => gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/resty.v1 => gopkg.in/resty.v1 v1.12.0
gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.3.1
......@@ -424,7 +402,6 @@ replace (
k8s.io/apiserver => k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682
k8s.io/cli-runtime => k8s.io/cli-runtime v0.17.3
k8s.io/client-go => k8s.io/client-go v0.0.0-20191114101535-6c5935290e33
k8s.io/cluster-registry => k8s.io/cluster-registry v0.0.6
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894
k8s.io/component-base => k8s.io/component-base v0.0.0-20191114102325-35a9586014f7
k8s.io/gengo => k8s.io/gengo v0.0.0-20191120174120-e74f70b9b27e
......
......@@ -51,12 +51,14 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&User{},
&UserList{},
&Role{},
&RoleList{},
&RoleBinding{},
&RoleBindingList{},
&PolicyRule{},
&PolicyRuleList{},
&GlobalRole{},
&GlobalRoleList{},
&GlobalRoleBinding{},
&GlobalRoleBindingList{},
&WorkspaceRole{},
&WorkspaceRoleList{},
&WorkspaceRoleBinding{},
&WorkspaceRoleBindingList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
......
......@@ -17,9 +17,39 @@ limitations under the License.
package v1alpha2
import (
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
ResourceKindUser = "User"
ResourcesSingularUser = "user"
ResourcesPluralUser = "users"
ResourceKindGlobalRoleBinding = "GlobalRoleBinding"
ResourcesSingularGlobalRoleBinding = "globalrolebinding"
ResourcesPluralGlobalRoleBinding = "globalrolebindings"
ResourceKindGlobalRole = "GlobalRole"
ResourcesSingularGlobalRole = "globalrole"
ResourcesPluralGlobalRole = "globalroles"
ResourceKindWorkspaceRoleBinding = "WorkspaceRoleBinding"
ResourcesSingularWorkspaceRoleBinding = "workspacerolebinding"
ResourcesPluralWorkspaceRoleBinding = "workspacerolebindings"
ResourceKindWorkspaceRole = "WorkspaceRole"
ResourcesSingularWorkspaceRole = "workspacerole"
ResourcesPluralWorkspaceRole = "workspaceroles"
ResourceKindClusterRole = "ClusterRole"
ResourcesSingularClusterRole = "clusterrole"
ResourcesPluralClusterRole = "clusterroles"
ResourceKindRole = "Role"
ResourcesSingularRole = "role"
ResourcesPluralRole = "roles"
RegoOverrideAnnotation = "iam.kubesphere.io/rego-override"
GlobalScope = "Global"
ClusterScope = "Cluster"
WorkspaceScope = "Workspace"
NamespaceScope = "Namespace"
)
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
......@@ -30,7 +60,9 @@ import (
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.state"
// +kubebuilder:resource:categories="iam",scope="Cluster"
type User struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec UserSpec `json:"spec"`
......@@ -53,9 +85,9 @@ type UserSpec struct {
// +optional
DisplayName string `json:"displayName,omitempty"`
// +optional
Groups []string `json:"groups,omitempty"`
EncryptedPassword string `json:"password"`
Groups []string `json:"groups,omitempty"`
// password will be encrypted by mutating admission webhook
EncryptedPassword string `json:"password"`
// Finalizers is an opaque list of values that must be empty to permanently remove object from storage.
// +optional
Finalizers []FinalizerName `json:"finalizers,omitempty"`
......@@ -102,7 +134,7 @@ type UserConditionType string
// These are valid conditions of a user.
const (
// UserLoginFailure contains information about user login.
UserLoginFailure UserConditionType = "UserLoginFailure"
LoginFailure UserConditionType = "LoginFailure"
)
type ConditionStatus string
......@@ -121,6 +153,8 @@ const (
// UserList contains a list of User
type UserList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []User `json:"items"`
}
......@@ -129,128 +163,131 @@ type UserList struct {
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:printcolumn:name="Scope",type="string",JSONPath=".target.scope"
// +kubebuilder:printcolumn:name="Target",type="string",JSONPath=".target.name"
// +kubebuilder:resource:categories="iam",scope="Cluster"
type Role struct {
metav1.TypeMeta `json:",inline"`
type GlobalRole struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
Target Target `json:"target"`
Rules []RuleRef `json:"rules"`
// 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"`
}
type Target struct {
Scope Scope `json:"scope"`
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"`
}
type Scope string
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
const (
GlobalScope Scope = "Global"
ClusterScope Scope = "Cluster"
WorkspaceScope Scope = "Workspace"
NamespaceScope Scope = "Namespace"
UserKind = "User"
PolicyRuleKind = "PolicyRule"
RoleKind = "Role"
RoleBindingKind = "RoleBinding"
)
// GlobalRoleList contains a list of GlobalRole
type GlobalRoleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []GlobalRole `json:"items"`
}
// 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"`
// +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
// RoleList contains a list of Role
type RoleList struct {
// GlobalRoleBindingList contains a list of GlobalRoleBinding
type GlobalRoleBindingList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []Role `json:"items"`
Items []GlobalRoleBinding `json:"items"`
}
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:printcolumn:name="Scope",type="string",JSONPath=".scope"
// +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 PolicyRule struct {
metav1.TypeMeta `json:",inline"`
type WorkspaceRole struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
Scope Scope `json:"scope"`
Rego string `json:"rego"`
// 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
// PolicyRuleList contains a list of PolicyRule
type PolicyRuleList struct {
// WorkspaceRoleList contains a list of WorkspaceRole
type WorkspaceRoleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []PolicyRule `json:"items"`
Items []WorkspaceRole `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"
// 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 RoleBinding struct {
type WorkspaceRoleBinding 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.
// Subjects holds references to the objects the role applies to.
// +optional
Subjects []Subject `json:"subjects,omitempty"`
}
// 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"`
}
Subjects []rbacv1.Subject `json:"subjects,omitempty" protobuf:"bytes,2,rep,name=subjects"`
// 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"`
// 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
// RoleBindingList contains a list of RoleBinding
type RoleBindingList struct {
// WorkspaceRoleBindingList contains a list of WorkspaceRoleBinding
type WorkspaceRoleBindingList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []RoleBinding `json:"items"`
Items []WorkspaceRoleBinding `json:"items"`
}
type UserDetail struct {
*User
GlobalRole *Role `json:"globalRole"`
GlobalRole *GlobalRole `json:"globalRole"`
}
......@@ -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
}
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"fmt"
"strings"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func RoleRefGroupKind(roleRef rbacv1.RoleRef) schema.GroupKind {
return schema.GroupKind{Group: roleRef.APIGroup, Kind: roleRef.Kind}
}
func VerbMatches(rule *rbacv1.PolicyRule, requestedVerb string) bool {
for _, ruleVerb := range rule.Verbs {
if ruleVerb == rbacv1.VerbAll {
return true
}
if ruleVerb == requestedVerb {
return true
}
}
return false
}
func APIGroupMatches(rule *rbacv1.PolicyRule, requestedGroup string) bool {
for _, ruleGroup := range rule.APIGroups {
if ruleGroup == rbacv1.APIGroupAll {
return true
}
if ruleGroup == requestedGroup {
return true
}
}
return false
}
func ResourceMatches(rule *rbacv1.PolicyRule, combinedRequestedResource, requestedSubresource string) bool {
for _, ruleResource := range rule.Resources {
// if everything is allowed, we match
if ruleResource == rbacv1.ResourceAll {
return true
}
// if we have an exact match, we match
if ruleResource == combinedRequestedResource {
return true
}
// We can also match a */subresource.
// if there isn't a subresource, then continue
if len(requestedSubresource) == 0 {
continue
}
// if the rule isn't in the format */subresource, then we don't match, continue
if len(ruleResource) == len(requestedSubresource)+2 &&
strings.HasPrefix(ruleResource, "*/") &&
strings.HasSuffix(ruleResource, requestedSubresource) {
return true
}
}
return false
}
func ResourceNameMatches(rule *rbacv1.PolicyRule, requestedName string) bool {
if len(rule.ResourceNames) == 0 {
return true
}
for _, ruleName := range rule.ResourceNames {
if ruleName == requestedName {
return true
}
}
return false
}
func NonResourceURLMatches(rule *rbacv1.PolicyRule, requestedURL string) bool {
for _, ruleURL := range rule.NonResourceURLs {
if ruleURL == rbacv1.NonResourceAll {
return true
}
if ruleURL == requestedURL {
return true
}
if strings.HasSuffix(ruleURL, "*") && strings.HasPrefix(requestedURL, strings.TrimRight(ruleURL, "*")) {
return true
}
}
return false
}
// subjectsStrings returns users, groups, serviceaccounts, unknown for display purposes.
func SubjectsStrings(subjects []rbacv1.Subject) ([]string, []string, []string, []string) {
users := []string{}
groups := []string{}
sas := []string{}
others := []string{}
for _, subject := range subjects {
switch subject.Kind {
case rbacv1.ServiceAccountKind:
sas = append(sas, fmt.Sprintf("%s/%s", subject.Namespace, subject.Name))
case rbacv1.UserKind:
users = append(users, subject.Name)
case rbacv1.GroupKind:
groups = append(groups, subject.Name)
default:
others = append(others, fmt.Sprintf("%s/%s/%s", subject.Kind, subject.Namespace, subject.Name))
}
}
return users, groups, sas, others
}
func String(r rbacv1.PolicyRule) string {
return "PolicyRule" + CompactString(r)
}
// CompactString exposes a compact string representation for use in escalation error messages
func CompactString(r rbacv1.PolicyRule) string {
formatStringParts := []string{}
formatArgs := []interface{}{}
if len(r.APIGroups) > 0 {
formatStringParts = append(formatStringParts, "APIGroups:%q")
formatArgs = append(formatArgs, r.APIGroups)
}
if len(r.Resources) > 0 {
formatStringParts = append(formatStringParts, "Resources:%q")
formatArgs = append(formatArgs, r.Resources)
}
if len(r.NonResourceURLs) > 0 {
formatStringParts = append(formatStringParts, "NonResourceURLs:%q")
formatArgs = append(formatArgs, r.NonResourceURLs)
}
if len(r.ResourceNames) > 0 {
formatStringParts = append(formatStringParts, "ResourceNames:%q")
formatArgs = append(formatArgs, r.ResourceNames)
}
if len(r.Verbs) > 0 {
formatStringParts = append(formatStringParts, "Verbs:%q")
formatArgs = append(formatArgs, r.Verbs)
}
formatString := "{" + strings.Join(formatStringParts, ", ") + "}"
return fmt.Sprintf(formatString, formatArgs...)
}
type SortableRuleSlice []rbacv1.PolicyRule
func (s SortableRuleSlice) Len() int { return len(s) }
func (s SortableRuleSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s SortableRuleSlice) Less(i, j int) bool {
return strings.Compare(s[i].String(), s[j].String()) < 0
}
......@@ -26,6 +26,7 @@ const (
ResourceKindWorkspace = "Workspace"
ResourceSingularWorkspace = "workspace"
ResourcePluralWorkspace = "workspaces"
WorkspaceLabel = "kubesphere.io/workspace"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
......
......@@ -11,13 +11,18 @@ import (
unionauth "k8s.io/apiserver/pkg/authentication/request/union"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
"k8s.io/klog"
clusterv1alpha1 "kubesphere.io/kubesphere/pkg/apis/cluster/v1alpha1"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/authenticators/basic"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/authenticators/jwttoken"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/request/anonymous"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/request/basictoken"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/request/bearertoken"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/token"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizerfactory"
authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/path"
unionauthorizer "kubesphere.io/kubesphere/pkg/apiserver/authorization/union"
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
......@@ -27,7 +32,7 @@ import (
"kubesphere.io/kubesphere/pkg/informers"
configv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/config/v1alpha2"
devopsv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/devops/v1alpha2"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
iamapi "kubesphere.io/kubesphere/pkg/kapis/iam/v1alpha2"
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/logging/v1alpha2"
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
networkv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/network/v1alpha2"
......@@ -94,7 +99,7 @@ type APIServer struct {
// monitoring client set
MonitoringClient monitoring.Interface
// openpitrix client
//
OpenpitrixClient openpitrix.Client
//
......@@ -143,11 +148,10 @@ func (s *APIServer) installKubeSphereAPIs() {
urlruntime.Must(networkv1alpha2.AddToContainer(s.container, s.Config.NetworkOptions.WeaveScopeHost))
urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes()))
urlruntime.Must(resourcesv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.InformerFactory))
urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.KubernetesClient, s.InformerFactory))
urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.InformerFactory))
urlruntime.Must(terminalv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.KubernetesClient.Config()))
urlruntime.Must(iamv1alpha2.AddToContainer(s.container, im.NewOperator(s.KubernetesClient.KubeSphere(),
s.InformerFactory.KubeSphereSharedInformerFactory()),
am.NewAMOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory.KubeSphereSharedInformerFactory()),
urlruntime.Must(iamapi.AddToContainer(s.container, im.NewOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory),
am.NewAMOperator(s.InformerFactory),
s.Config.AuthenticationOptions))
urlruntime.Must(oauth.AddToContainer(s.container, token.NewJwtTokenIssuer(token.DefaultIssuerName, s.Config.AuthenticationOptions, s.CacheClient), s.Config.AuthenticationOptions))
urlruntime.Must(servicemeshv1alpha2.AddToContainer(s.container))
......@@ -183,6 +187,13 @@ func (s *APIServer) buildHandlerChain() {
requestInfoResolver := &request.RequestInfoFactory{
APIPrefixes: sets.NewString("api", "apis", "kapis", "kapi"),
GrouplessAPIPrefixes: sets.NewString("api", "kapi"),
GlobalResources: []schema.GroupResource{
{Group: iamv1alpha2.SchemeGroupVersion.Group, Resource: iamv1alpha2.ResourcesPluralUser},
{Group: iamv1alpha2.SchemeGroupVersion.Group, Resource: iamv1alpha2.ResourcesPluralGlobalRole},
{Group: iamv1alpha2.SchemeGroupVersion.Group, Resource: iamv1alpha2.ResourcesPluralGlobalRoleBinding},
{Group: tenantv1alpha1.SchemeGroupVersion.Group, Resource: tenantv1alpha1.ResourcePluralWorkspace},
{Group: clusterv1alpha1.SchemeGroupVersion.Group, Resource: clusterv1alpha1.ResourcesPluralCluster},
},
}
handler := s.Server.Handler
......@@ -193,16 +204,26 @@ func (s *APIServer) buildHandlerChain() {
handler = filters.WithMultipleClusterDispatcher(handler, clusterDispatcher)
}
excludedPaths := []string{"/oauth/*", "/kapis/config.kubesphere.io/*"}
pathAuthorizer, _ := path.NewAuthorizer(excludedPaths)
var authorizers authorizer.Authorizer
switch s.Config.AuthorizationOptions.Mode {
case authorizationoptions.AlwaysAllow:
authorizers = authorizerfactory.NewAlwaysAllowAuthorizer()
case authorizationoptions.AlwaysDeny:
authorizers = authorizerfactory.NewAlwaysDenyAuthorizer()
default:
fallthrough
case authorizationoptions.RBAC:
excludedPaths := []string{"/oauth/*", "/kapis/config.kubesphere.io/*"}
pathAuthorizer, _ := path.NewAuthorizer(excludedPaths)
authorizers = unionauthorizer.New(pathAuthorizer, authorizerfactory.NewOPAAuthorizer(am.NewAMOperator(s.InformerFactory)), authorizerfactory.NewRBACAuthorizer(am.NewAMOperator(s.InformerFactory)))
}
// union authorizers are ordered, don't change the order here
authorizers := unionauthorizer.New(pathAuthorizer, authorizerfactory.NewOPAAuthorizer(am.NewAMOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory.KubeSphereSharedInformerFactory())))
handler = filters.WithAuthorization(handler, authorizers)
// authenticators are unordered
authn := unionauth.New(anonymous.NewAuthenticator(),
basictoken.New(basic.NewBasicAuthenticator(im.NewOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory.KubeSphereSharedInformerFactory()))),
basictoken.New(basic.NewBasicAuthenticator(im.NewOperator(s.KubernetesClient.KubeSphere(), s.InformerFactory))),
bearertoken.New(jwttoken.NewTokenAuthenticator(token.NewJwtTokenIssuer(token.DefaultIssuerName, s.Config.AuthenticationOptions, s.CacheClient))))
handler = filters.WithAuthentication(handler, authn)
handler = filters.WithRequestInfo(handler, requestInfoResolver)
......@@ -283,9 +304,10 @@ func (s *APIServer) waitForResourceSync(stopCh <-chan struct{}) error {
ksGVRs := []schema.GroupVersionResource{
{Group: "tenant.kubesphere.io", Version: "v1alpha1", Resource: "workspaces"},
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "users"},
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "roles"},
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "rolebindings"},
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "policyrules"},
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "globalroles"},
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "globalrolebindings"},
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "workspaceroles"},
{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "workspacerolebindings"},
{Group: "cluster.kubesphere.io", Version: "v1alpha1", Resource: "clusters"},
}
......
......@@ -68,6 +68,9 @@ type Attributes interface {
// and false for non-resource endpoints like /api, /healthz
IsResourceRequest() bool
// GetResourceScope returns the scope of the resource requested, if a request is for a REST object.
GetResourceScope() string
// GetPath returns the path of the request
GetPath() string
}
......@@ -111,6 +114,7 @@ type AttributesRecord struct {
KubernetesRequest bool
ResourceRequest bool
Path string
ResourceScope string
}
func (a AttributesRecord) GetUser() user.Info {
......@@ -169,6 +173,10 @@ func (a AttributesRecord) GetPath() string {
return a.Path
}
func (a AttributesRecord) GetResourceScope() string {
return a.ResourceScope
}
type Decision int
const (
......
/*
*
* 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)
}
/*
*
* Copyright 2020 The KubeSphere Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* /
*/
package authorizerfactory
import (
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"testing"
)
func TestNewAlwaysAllowAuthorizer(t *testing.T) {
aaa := NewAlwaysAllowAuthorizer()
if decision, _, _ := aaa.Authorize(nil); decision != authorizer.DecisionAllow {
t.Errorf("AlwaysAllowAuthorizer.Authorize did not authorize successfully.")
}
}
func TestNewAlwaysDenyAuthorizer(t *testing.T) {
ada := NewAlwaysDenyAuthorizer()
if decision, _, _ := ada.Authorize(nil); decision == authorizer.DecisionAllow {
t.Errorf("AlwaysDenyAuthorizer.Authorize returned nil instead of error.")
}
}
......@@ -21,6 +21,7 @@ package authorizerfactory
import (
"context"
"github.com/open-policy-agent/opa/rego"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/klog"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
......@@ -33,125 +34,140 @@ type opaAuthorizer struct {
}
const (
permissionUndefined = "permission undefined"
defaultRegoQuery = "data.authz.allow"
defaultRegoQuery = "data.authz.allow"
)
// Make decision by request attributes
func (o *opaAuthorizer) Authorize(attr authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
// Make decisions based on the authorization policy of different levels of roles
// Error returned when an internal error occurs
// Reason must be returned when access is denied
globalRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.GlobalScope, "", attr.GetUser().GetName())
globalRole, err := o.am.GetGlobalRoleOfUser(attr.GetUser().GetName())
if err != nil {
if errors.IsNotFound(err) {
return authorizer.DecisionDeny, err.Error(), nil
return authorizer.DecisionNoOpinion, "", nil
}
return authorizer.DecisionDeny, "", err
return authorizer.DecisionNoOpinion, "", err
}
// check global role policy rules
// check global policy rules
if authorized, reason, err = o.makeDecision(globalRole, attr); authorized == authorizer.DecisionAllow {
return authorized, reason, nil
}
// it's not in cluster resource, permission denied
if attr.GetCluster() == "" {
return authorizer.DecisionDeny, permissionUndefined, nil
// it's global resource, permission denied
if attr.GetResourceScope() == iamv1alpha2.GlobalScope {
return authorizer.DecisionNoOpinion, "", nil
}
clusterRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.ClusterScope, attr.GetCluster(), attr.GetUser().GetName())
if err != nil {
if errors.IsNotFound(err) {
return authorizer.DecisionDeny, err.Error(), nil
if attr.GetResourceScope() == iamv1alpha2.WorkspaceScope {
workspaceRole, err := o.am.GetWorkspaceRoleOfUser(attr.GetUser().GetName(), attr.GetWorkspace())
if err != nil {
if errors.IsNotFound(err) {
return authorizer.DecisionNoOpinion, "", nil
}
return authorizer.DecisionNoOpinion, "", err
}
return authorizer.DecisionDeny, "", err
}
// check 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
}
// 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
}
// it's not in cluster resource, permission denied
if attr.GetWorkspace() == "" && attr.GetNamespace() == "" {
return authorizer.DecisionDeny, permissionUndefined, nil
return authorizer.DecisionNoOpinion, "", 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
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.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
return authorizer.DecisionNoOpinion, "", nil
}
// it's not in workspace resource, permission denied
if attr.GetNamespace() == "" {
return authorizer.DecisionDeny, permissionUndefined, nil
clusterRole, err := o.am.GetClusterRoleOfUser(attr.GetUser().GetName(), attr.GetCluster())
if errors.IsNotFound(err) {
return authorizer.DecisionNoOpinion, "", 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
return authorizer.DecisionNoOpinion, "", err
}
// check namespace role policy rules
if authorized, reason, err := o.makeDecision(namespaceRole, attr); authorized == authorizer.DecisionAllow {
return authorized, reason, 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
}
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
}
// 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())
regoPolicy := ""
if err != nil {
klog.Errorf("rule syntax error:%s", err)
continue
// override
if globalRole, ok := role.(*iamv1alpha2.GlobalRole); ok {
if overrideRego, ok := globalRole.Annotations[iamv1alpha2.RegoOverrideAnnotation]; ok {
regoPolicy = overrideRego
}
} else if workspaceRole, ok := role.(*iamv1alpha2.WorkspaceRole); ok {
if overrideRego, ok := workspaceRole.Annotations[iamv1alpha2.RegoOverrideAnnotation]; ok {
regoPolicy = overrideRego
}
} else if clusterRole, ok := role.(*rbacv1.ClusterRole); ok {
if overrideRego, ok := clusterRole.Annotations[iamv1alpha2.RegoOverrideAnnotation]; ok {
regoPolicy = overrideRego
}
} else if role, ok := role.(*rbacv1.Role); ok {
if overrideRego, ok := role.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 regoPolicy == "" {
return authorizer.DecisionNoOpinion, "", nil
}
if err != nil {
klog.Errorf("rule syntax error:%s", err)
continue
}
// 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 len(results) > 0 && results[0].Expressions[0].Value == true {
return authorizer.DecisionAllow, "", nil
}
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.DecisionDeny, permissionUndefined, nil
return authorizer.DecisionNoOpinion, "", nil
}
func NewOPAAuthorizer(am am.AccessManagementInterface) *opaAuthorizer {
......
......@@ -20,209 +20,22 @@ package authorizerfactory
import (
"fmt"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/authentication/user"
fakek8s "k8s.io/client-go/kubernetes/fake"
iamvealpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
factory "kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"testing"
)
func prepare() (am.AccessManagementInterface, error) {
rules := []*iamvealpha2.PolicyRule{
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.PolicyRuleKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "always-allow",
},
Rego: "package authz\ndefault allow = true",
}, {
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.PolicyRuleKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "always-deny",
},
Rego: "package authz\ndefault allow = false",
}, {
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.PolicyRuleKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "manage-cluster1-resources",
},
Rego: `package authz
default allow = false
allow {
resources_in_cluster1
}
resources_in_cluster1 {
input.Cluster == "cluster1"
}`,
},
}
roles := []*iamvealpha2.Role{
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.RoleKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "global-admin",
},
Target: iamvealpha2.Target{
Scope: iamvealpha2.GlobalScope,
Name: "",
},
Rules: []iamvealpha2.RuleRef{
{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.PolicyRuleKind,
Name: "always-allow",
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.RoleKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "anonymous",
},
Target: iamvealpha2.Target{
Scope: iamvealpha2.GlobalScope,
Name: "",
},
Rules: []iamvealpha2.RuleRef{
{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.PolicyRuleKind,
Name: "always-deny",
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.RoleKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "cluster1-admin",
},
Target: iamvealpha2.Target{
Scope: iamvealpha2.GlobalScope,
Name: "",
},
Rules: []iamvealpha2.RuleRef{
{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.PolicyRuleKind,
Name: "manage-cluster1-resources",
},
},
},
}
roleBindings := []*iamvealpha2.RoleBinding{
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.RoleBindingKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "global-admin",
},
Scope: iamvealpha2.GlobalScope,
RoleRef: iamvealpha2.RoleRef{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.RoleKind,
Name: "global-admin",
},
Subjects: []iamvealpha2.Subject{
{
Kind: iamvealpha2.UserKind,
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Name: "admin",
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.RoleBindingKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "anonymous",
},
Scope: iamvealpha2.GlobalScope,
RoleRef: iamvealpha2.RoleRef{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.RoleKind,
Name: "anonymous",
},
Subjects: []iamvealpha2.Subject{
{
Kind: iamvealpha2.UserKind,
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Name: user.Anonymous,
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.RoleBindingKind,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "cluster1-admin",
},
Scope: iamvealpha2.GlobalScope,
RoleRef: iamvealpha2.RoleRef{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.RoleKind,
Name: "cluster1-admin",
},
Subjects: []iamvealpha2.Subject{
{
Kind: iamvealpha2.UserKind,
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Name: "tom",
},
},
},
}
ksClient := fake.NewSimpleClientset()
informerFactory := externalversions.NewSharedInformerFactory(ksClient, 0)
for _, rule := range rules {
err := informerFactory.Iam().V1alpha2().PolicyRules().Informer().GetIndexer().Add(rule)
if err != nil {
return nil, fmt.Errorf("add rule:%s", err)
}
}
for _, role := range roles {
err := informerFactory.Iam().V1alpha2().Roles().Informer().GetIndexer().Add(role)
if err != nil {
return nil, fmt.Errorf("add role:%s", err)
}
}
for _, roleBinding := range roleBindings {
err := informerFactory.Iam().V1alpha2().RoleBindings().Informer().GetIndexer().Add(roleBinding)
if err != nil {
return nil, fmt.Errorf("add role binding:%s", err)
}
}
operator := am.NewAMOperator(ksClient, informerFactory)
return operator, nil
}
func TestGlobalRole(t *testing.T) {
operator, err := prepare()
if err != nil {
t.Fatal(err)
}
......@@ -244,14 +57,8 @@ func TestGlobalRole(t *testing.T) {
Extra: nil,
},
Verb: "list",
Cluster: "",
Workspace: "",
Namespace: "",
APIGroup: "",
APIVersion: "v1",
Resource: "nodes",
Subresource: "",
Name: "",
KubernetesRequest: true,
ResourceRequest: true,
Path: "/api/v1/nodes",
......@@ -268,19 +75,13 @@ func TestGlobalRole(t *testing.T) {
Extra: nil,
},
Verb: "list",
Cluster: "",
Workspace: "",
Namespace: "",
APIGroup: "",
APIVersion: "v1",
Resource: "nodes",
Subresource: "",
Name: "",
KubernetesRequest: true,
ResourceRequest: true,
Path: "/api/v1/nodes",
},
expectedDecision: authorizer.DecisionDeny,
expectedDecision: authorizer.DecisionNoOpinion,
}, {
name: "tom can list nodes in cluster1",
request: authorizer.AttributesRecord{
......@@ -289,13 +90,8 @@ func TestGlobalRole(t *testing.T) {
},
Verb: "list",
Cluster: "cluster1",
Workspace: "",
Namespace: "",
APIGroup: "",
APIVersion: "v1",
Resource: "nodes",
Subresource: "",
Name: "",
KubernetesRequest: true,
ResourceRequest: true,
Path: "/api/v1/clusters/cluster1/nodes",
......@@ -310,18 +106,13 @@ func TestGlobalRole(t *testing.T) {
},
Verb: "list",
Cluster: "cluster2",
Workspace: "",
Namespace: "",
APIGroup: "",
APIVersion: "v1",
Resource: "nodes",
Subresource: "",
Name: "",
KubernetesRequest: true,
ResourceRequest: true,
Path: "/api/v1/clusters/cluster2/nodes",
},
expectedDecision: authorizer.DecisionDeny,
expectedDecision: authorizer.DecisionNoOpinion,
},
}
......@@ -335,3 +126,127 @@ func TestGlobalRole(t *testing.T) {
}
}
}
func prepare() (am.AccessManagementInterface, error) {
globalRoles := []*iamvealpha2.GlobalRole{
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.ResourceKindGlobalRole,
APIVersion: iamvealpha2.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "global-admin",
Annotations: map[string]string{iamvealpha2.RegoOverrideAnnotation: "package authz\ndefault allow = true"},
},
}, {
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.ResourceKindGlobalRole,
APIVersion: iamvealpha2.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "anonymous",
Annotations: map[string]string{iamvealpha2.RegoOverrideAnnotation: "package authz\ndefault allow = false"},
},
}, {
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.ResourceKindGlobalRole,
APIVersion: iamvealpha2.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "cluster1-admin",
Annotations: map[string]string{iamvealpha2.RegoOverrideAnnotation: `package authz
default allow = false
allow {
resources_in_cluster1
}
resources_in_cluster1 {
input.Cluster == "cluster1"
}`},
},
},
}
roleBindings := []*iamvealpha2.GlobalRoleBinding{
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.ResourceKindGlobalRoleBinding,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "global-admin",
},
RoleRef: rbacv1.RoleRef{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.ResourceKindGlobalRole,
Name: "global-admin",
},
Subjects: []rbacv1.Subject{
{
Kind: iamvealpha2.ResourceKindUser,
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Name: "admin",
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.ResourceKindGlobalRoleBinding,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "anonymous",
},
RoleRef: rbacv1.RoleRef{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.ResourceKindGlobalRole,
Name: "anonymous",
},
Subjects: []rbacv1.Subject{
{
Kind: iamvealpha2.ResourceKindUser,
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Name: user.Anonymous,
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: iamvealpha2.ResourceKindGlobalRoleBinding,
APIVersion: iamvealpha2.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Name: "cluster1-admin",
},
RoleRef: rbacv1.RoleRef{
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Kind: iamvealpha2.ResourceKindGlobalRole,
Name: "cluster1-admin",
},
Subjects: []rbacv1.Subject{
{
Kind: iamvealpha2.ResourceKindUser,
APIGroup: iamvealpha2.SchemeGroupVersion.String(),
Name: "tom",
},
},
},
}
ksClient := fake.NewSimpleClientset()
k8sClient := fakek8s.NewSimpleClientset()
factory := factory.NewInformerFactories(k8sClient, ksClient, nil, nil)
for _, role := range globalRoles {
err := factory.KubeSphereSharedInformerFactory().Iam().V1alpha2().GlobalRoles().Informer().GetIndexer().Add(role)
if err != nil {
return nil, fmt.Errorf("add role:%s", err)
}
}
for _, roleBinding := range roleBindings {
err := factory.KubeSphereSharedInformerFactory().Iam().V1alpha2().GlobalRoleBindings().Informer().GetIndexer().Add(roleBinding)
if err != nil {
return nil, fmt.Errorf("add role binding:%s", err)
}
}
operator := am.NewAMOperator(factory)
return operator, nil
}
/*
*
* 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)
}
}
/*
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)
}
}
}
/*
*
* Copyright 2020 The KubeSphere Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* /
*/
package options
import (
"fmt"
"github.com/spf13/pflag"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
)
type AuthorizationOptions struct {
Mode string `json:"mode" yaml:"mode"`
}
func NewAuthorizationOptions() *AuthorizationOptions {
return &AuthorizationOptions{Mode: RBAC}
}
var (
AlwaysDeny = "AlwaysDeny"
AlwaysAllow = "AlwaysAllow"
RBAC = "RBAC"
)
func (o *AuthorizationOptions) AddFlags(fs *pflag.FlagSet, s *AuthorizationOptions) {
fs.StringVar(&o.Mode, "authorization", s.Mode, "Authorization setting, allowed values: AlwaysDeny, AlwaysAllow, RBAC.")
}
func (o AuthorizationOptions) Validate() []error {
errs := make([]error, 0)
if !sliceutil.HasString([]string{AlwaysAllow, AlwaysDeny, RBAC}, o.Mode) {
err := fmt.Errorf("authorization mode %s not support", o.Mode)
klog.Error(err)
errs = append(errs, err)
}
return errs
}
......@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/spf13/viper"
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options"
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
......@@ -59,19 +60,20 @@ const (
// Config defines everything needed for apiserver to deal with external services
type Config struct {
DevopsOptions *jenkins.Options `json:"devops,omitempty" yaml:"devops,omitempty" mapstructure:"devops"`
SonarQubeOptions *sonarqube.Options `json:"sonarqube,omitempty" yaml:"sonarQube,omitempty" mapstructure:"sonarqube"`
KubernetesOptions *k8s.KubernetesOptions `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty" mapstructure:"kubernetes"`
ServiceMeshOptions *servicemesh.Options `json:"servicemesh,omitempty" yaml:"servicemesh,omitempty" mapstructure:"servicemesh"`
NetworkOptions *network.Options `json:"network,omitempty" yaml:"network,omitempty" mapstructure:"network"`
LdapOptions *ldap.Options `json:"-" yaml:"ldap,omitempty" mapstructure:"ldap"`
RedisOptions *cache.Options `json:"-" yaml:"redis,omitempty" mapstructure:"redis"`
S3Options *s3.Options `json:"s3,omitempty" yaml:"s3,omitempty" mapstructure:"s3"`
OpenPitrixOptions *openpitrix.Options `json:"openpitrix,omitempty" yaml:"openpitrix,omitempty" mapstructure:"openpitrix"`
MonitoringOptions *prometheus.Options `json:"monitoring,omitempty" yaml:"monitoring,omitempty" mapstructure:"monitoring"`
LoggingOptions *elasticsearch.Options `json:"logging,omitempty" yaml:"logging,omitempty" mapstructure:"logging"`
AuthenticationOptions *authoptions.AuthenticationOptions `json:"-" yaml:"authentication,omitempty" mapstructure:"authentication"`
MultiClusterOptions *multicluster.Options `json:"multicluster,omitempty" yaml:"multicluster,omitempty" mapstructure:"multicluster"`
DevopsOptions *jenkins.Options `json:"devops,omitempty" yaml:"devops,omitempty" mapstructure:"devops"`
SonarQubeOptions *sonarqube.Options `json:"sonarqube,omitempty" yaml:"sonarQube,omitempty" mapstructure:"sonarqube"`
KubernetesOptions *k8s.KubernetesOptions `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty" mapstructure:"kubernetes"`
ServiceMeshOptions *servicemesh.Options `json:"servicemesh,omitempty" yaml:"servicemesh,omitempty" mapstructure:"servicemesh"`
NetworkOptions *network.Options `json:"network,omitempty" yaml:"network,omitempty" mapstructure:"network"`
LdapOptions *ldap.Options `json:"-,omitempty" yaml:"ldap,omitempty" mapstructure:"ldap"`
RedisOptions *cache.Options `json:"redis,omitempty" yaml:"redis,omitempty" mapstructure:"redis"`
S3Options *s3.Options `json:"s3,omitempty" yaml:"s3,omitempty" mapstructure:"s3"`
OpenPitrixOptions *openpitrix.Options `json:"openpitrix,omitempty" yaml:"openpitrix,omitempty" mapstructure:"openpitrix"`
MonitoringOptions *prometheus.Options `json:"monitoring,omitempty" yaml:"monitoring,omitempty" mapstructure:"monitoring"`
LoggingOptions *elasticsearch.Options `json:"logging,omitempty" yaml:"logging,omitempty" mapstructure:"logging"`
AuthenticationOptions *authoptions.AuthenticationOptions `json:"authentication,omitempty" yaml:"authentication,omitempty" mapstructure:"authentication"`
AuthorizationOptions *authorizationoptions.AuthorizationOptions `json:"authorization,omitempty" yaml:"authorization,omitempty" mapstructure:"authorization"`
MultiClusterOptions *multicluster.Options `json:"multicluster,omitempty" yaml:"multicluster,omitempty" mapstructure:"multicluster"`
// Options used for enabling components, not actually used now. Once we switch Alerting/Notification API to kubesphere,
// we can add these options to kubesphere command lines
AlertingOptions *alerting.Options `json:"alerting,omitempty" yaml:"alerting,omitempty" mapstructure:"alerting"`
......@@ -95,6 +97,8 @@ func New() *Config {
NotificationOptions: notification.NewNotificationOptions(),
LoggingOptions: elasticsearch.NewElasticSearchOptions(),
AuthenticationOptions: authoptions.NewAuthenticateOptions(),
AuthorizationOptions: authorizationoptions.NewAuthorizationOptions(),
MultiClusterOptions: multicluster.NewOptions(),
}
}
......@@ -209,5 +213,4 @@ func (conf *Config) stripEmptyOptions() {
if conf.MultiClusterOptions != nil && !conf.MultiClusterOptions.Enable {
conf.MultiClusterOptions = nil
}
}
......@@ -7,6 +7,7 @@ import (
"io/ioutil"
"kubesphere.io/kubesphere/pkg/apiserver/authentication/oauth"
authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options"
authorizationoptions "kubesphere.io/kubesphere/pkg/apiserver/authorization/options"
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
......@@ -99,6 +100,7 @@ func newTestConfig() (*Config, error) {
NotificationOptions: &notification.Options{
Endpoint: "http://notification.kubesphere-alerting-system.svc:9200",
},
AuthorizationOptions: authorizationoptions.NewAuthorizationOptions(),
AuthenticationOptions: &authoptions.AuthenticationOptions{
AuthenticateRateLimiterMaxTries: 5,
AuthenticateRateLimiterDuration: 30 * time.Minute,
......
......@@ -59,6 +59,7 @@ func getAuthorizerAttributes(ctx context.Context) (authorizer.Attributes, error)
}
// Start with common attributes that apply to resource and non-resource requests
attribs.ResourceScope = requestInfo.ResourceScope
attribs.ResourceRequest = requestInfo.IsResourceRequest
attribs.Path = requestInfo.Path
attribs.Verb = requestInfo.Verb
......
......@@ -7,7 +7,9 @@ const (
FieldName = "name"
FieldUID = "uid"
FieldCreationTimeStamp = "creationTimestamp"
FieldCreateTime = "createTime"
FieldLastUpdateTimestamp = "lastUpdateTimestamp"
FieldUpdateTime = "updateTime"
FieldLabel = "label"
FieldAnnotation = "annotation"
FieldNamespace = "namespace"
......@@ -18,6 +20,8 @@ const (
var SortableFields = []Field{
FieldCreationTimeStamp,
FieldCreateTime,
FieldUpdateTime,
FieldLastUpdateTimestamp,
FieldName,
}
......
......@@ -2,6 +2,8 @@ package query
import (
"github.com/emicklei/go-restful"
"k8s.io/apimachinery/pkg/labels"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"strconv"
)
......@@ -26,7 +28,9 @@ type Query struct {
Ascending bool
//
Filters []Filter
Filters map[Field]Value
LabelSelector string
}
type Pagination struct {
......@@ -47,17 +51,27 @@ func newPagination(limit int, offset int) *Pagination {
}
}
func (q *Query) Selector() labels.Selector {
if selector, err := labels.Parse(q.LabelSelector); err != nil {
return labels.Everything()
} else {
return selector
}
}
func (p *Pagination) GetValidPagination(total int) (startIndex, endIndex int) {
// no pagination
if p.Limit == NoPagination.Limit {
return 0, total
}
if p.Limit < 0 || p.Offset < 0 || total == 0 {
// out of range
if p.Limit < 0 || p.Offset < 0 || p.Offset > total {
return 0, 0
}
startIndex = p.Limit * p.Offset
startIndex = p.Offset
endIndex = startIndex + p.Limit
if endIndex > total {
......@@ -72,7 +86,7 @@ func New() *Query {
Pagination: NoPagination,
SortBy: "",
Ascending: false,
Filters: []Filter{},
Filters: map[Field]Value{},
}
}
......@@ -84,35 +98,36 @@ type Filter struct {
func ParseQueryParameter(request *restful.Request) *Query {
query := New()
limit, err := strconv.Atoi(request.QueryParameter("limit"))
limit, err := strconv.Atoi(request.QueryParameter(ParameterLimit))
// equivalent to undefined, use the default value
if err != nil {
limit = -1
}
page, err := strconv.Atoi(request.QueryParameter("page"))
page, err := strconv.Atoi(request.QueryParameter(ParameterPage))
// equivalent to undefined, use the default value
if err != nil {
page = 1
}
query.Pagination = newPagination(limit, page-1)
query.Pagination = newPagination(limit, (page-1)*limit)
query.SortBy = Field(defaultString(request.QueryParameter("sortBy"), FieldCreationTimeStamp))
query.SortBy = Field(defaultString(request.QueryParameter(ParameterOrderBy), FieldCreationTimeStamp))
ascending, err := strconv.ParseBool(defaultString(request.QueryParameter("ascending"), "false"))
ascending, err := strconv.ParseBool(defaultString(request.QueryParameter(ParameterAscending), "false"))
if err != nil {
query.Ascending = false
} else {
query.Ascending = ascending
}
for _, field := range ComparableFields {
f := request.QueryParameter(string(field))
if len(f) != 0 {
query.Filters = append(query.Filters, Filter{
Field: field,
Value: Value(f),
})
query.LabelSelector = request.QueryParameter(ParameterLabelSelector)
for key, values := range request.Request.URL.Query() {
if !sliceutil.HasString([]string{ParameterPage, ParameterLimit, ParameterOrderBy, ParameterAscending, ParameterLabelSelector}, key) {
// support multiple query condition
for _, value := range values {
query.Filters[Field(key)] = Value(value)
}
}
}
......
......@@ -16,24 +16,15 @@ func TestParseQueryParameter(t *testing.T) {
}{
{
"test normal case",
"label=app.kubernetes.io/name:book&name=foo&status=Running&page=1&limit=10&ascending=true",
"label=app.kubernetes.io/name=book&name=foo&status=Running&page=1&limit=10&ascending=true",
&Query{
Pagination: newPagination(10, 0),
SortBy: FieldCreationTimeStamp,
Ascending: true,
Filters: []Filter{
{
FieldName,
Value("foo"),
},
{
FieldLabel,
Value("app.kubernetes.io/name:book"),
},
{
FieldStatus,
Value("Running"),
},
Filters: map[Field]Value{
FieldLabel: Value("app.kubernetes.io/name=book"),
FieldName: Value("foo"),
FieldStatus: Value("Running"),
},
},
},
......@@ -44,7 +35,10 @@ func TestParseQueryParameter(t *testing.T) {
Pagination: NoPagination,
SortBy: FieldCreationTimeStamp,
Ascending: false,
Filters: []Filter{},
Filters: map[Field]Value{
Field("xxxx"): Value("xxxx"),
Field("dsfsw"): Value("xxxx"),
},
},
},
}
......@@ -61,6 +55,7 @@ func TestParseQueryParameter(t *testing.T) {
got := ParseQueryParameter(request)
if diff := cmp.Diff(got, test.expected); diff != "" {
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
return
}
......
......@@ -6,9 +6,11 @@ import (
"k8s.io/apimachinery/pkg/api/validation/path"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api"
iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
"net/http"
"strings"
......@@ -46,11 +48,15 @@ type RequestInfo struct {
// Cluster of requested resource, this is empty in single-cluster environment
Cluster string
// Scope of requested resource.
ResourceScope string
}
type RequestInfoFactory struct {
APIPrefixes sets.String
GrouplessAPIPrefixes sets.String
GlobalResources []schema.GroupResource
}
// NewRequestInfo returns the information from the http request. If error is not nil, RequestInfo holds the information as best it is known before the failure
......@@ -188,6 +194,8 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
// parsing successful, so we now know the proper value for .Parts
requestInfo.Parts = currentParts
requestInfo.ResourceScope = r.resolveResourceScope(requestInfo)
// parts look like: resource/resourceName/subresource/other/stuff/we/don't/interpret
switch {
case len(requestInfo.Parts) >= 3 && !specialVerbsNoSubresources.Has(requestInfo.Verb):
......@@ -264,3 +272,21 @@ func splitPath(path string) []string {
}
return strings.Split(path, "/")
}
func (r *RequestInfoFactory) resolveResourceScope(request RequestInfo) string {
for _, globalResource := range r.GlobalResources {
if globalResource.Group == request.APIGroup &&
globalResource.Resource == request.Resource {
return iamv1alpha2.GlobalScope
}
}
if request.Namespace != "" {
return iamv1alpha2.NamespaceScope
}
if request.Workspace != "" {
return iamv1alpha2.WorkspaceScope
}
return iamv1alpha2.ClusterScope
}
......@@ -28,29 +28,29 @@ import (
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
)
// FakePolicyRules implements PolicyRuleInterface
type FakePolicyRules struct {
// FakeGlobalRoles implements GlobalRoleInterface
type FakeGlobalRoles struct {
Fake *FakeIamV1alpha2
}
var policyrulesResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "policyrules"}
var globalrolesResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "globalroles"}
var policyrulesKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "PolicyRule"}
var globalrolesKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "GlobalRole"}
// 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) {
// 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(policyrulesResource, name), &v1alpha2.PolicyRule{})
Invokes(testing.NewRootGetAction(globalrolesResource, name), &v1alpha2.GlobalRole{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.PolicyRule), err
return obj.(*v1alpha2.GlobalRole), 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) {
// 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(policyrulesResource, policyrulesKind, opts), &v1alpha2.PolicyRuleList{})
Invokes(testing.NewRootListAction(globalrolesResource, globalrolesKind, opts), &v1alpha2.GlobalRoleList{})
if obj == nil {
return nil, err
}
......@@ -59,8 +59,8 @@ func (c *FakePolicyRules) List(opts v1.ListOptions) (result *v1alpha2.PolicyRule
if label == nil {
label = labels.Everything()
}
list := &v1alpha2.PolicyRuleList{ListMeta: obj.(*v1alpha2.PolicyRuleList).ListMeta}
for _, item := range obj.(*v1alpha2.PolicyRuleList).Items {
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)
}
......@@ -68,53 +68,53 @@ func (c *FakePolicyRules) List(opts v1.ListOptions) (result *v1alpha2.PolicyRule
return list, err
}
// Watch returns a watch.Interface that watches the requested policyRules.
func (c *FakePolicyRules) Watch(opts v1.ListOptions) (watch.Interface, error) {
// 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(policyrulesResource, opts))
InvokesWatch(testing.NewRootWatchAction(globalrolesResource, 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) {
// 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(policyrulesResource, policyRule), &v1alpha2.PolicyRule{})
Invokes(testing.NewRootCreateAction(globalrolesResource, globalRole), &v1alpha2.GlobalRole{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.PolicyRule), err
return obj.(*v1alpha2.GlobalRole), 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) {
// 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(policyrulesResource, policyRule), &v1alpha2.PolicyRule{})
Invokes(testing.NewRootUpdateAction(globalrolesResource, globalRole), &v1alpha2.GlobalRole{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.PolicyRule), err
return obj.(*v1alpha2.GlobalRole), 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 {
// 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(policyrulesResource, name), &v1alpha2.PolicyRule{})
Invokes(testing.NewRootDeleteAction(globalrolesResource, name), &v1alpha2.GlobalRole{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakePolicyRules) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(policyrulesResource, listOptions)
func (c *FakeGlobalRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(globalrolesResource, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha2.PolicyRuleList{})
_, err := c.Fake.Invokes(action, &v1alpha2.GlobalRoleList{})
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) {
// 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(policyrulesResource, name, pt, data, subresources...), &v1alpha2.PolicyRule{})
Invokes(testing.NewRootPatchSubresourceAction(globalrolesResource, name, pt, data, subresources...), &v1alpha2.GlobalRole{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.PolicyRule), err
return obj.(*v1alpha2.GlobalRole), err
}
......@@ -28,29 +28,29 @@ import (
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
)
// FakeRoles implements RoleInterface
type FakeRoles struct {
// FakeGlobalRoleBindings implements GlobalRoleBindingInterface
type FakeGlobalRoleBindings struct {
Fake *FakeIamV1alpha2
}
var rolesResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "roles"}
var globalrolebindingsResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "globalrolebindings"}
var rolesKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "Role"}
var globalrolebindingsKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "GlobalRoleBinding"}
// 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) {
// 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(rolesResource, name), &v1alpha2.Role{})
Invokes(testing.NewRootGetAction(globalrolebindingsResource, name), &v1alpha2.GlobalRoleBinding{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Role), err
return obj.(*v1alpha2.GlobalRoleBinding), 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) {
// 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(rolesResource, rolesKind, opts), &v1alpha2.RoleList{})
Invokes(testing.NewRootListAction(globalrolebindingsResource, globalrolebindingsKind, opts), &v1alpha2.GlobalRoleBindingList{})
if obj == nil {
return nil, err
}
......@@ -59,8 +59,8 @@ func (c *FakeRoles) List(opts v1.ListOptions) (result *v1alpha2.RoleList, err er
if label == nil {
label = labels.Everything()
}
list := &v1alpha2.RoleList{ListMeta: obj.(*v1alpha2.RoleList).ListMeta}
for _, item := range obj.(*v1alpha2.RoleList).Items {
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)
}
......@@ -68,53 +68,53 @@ func (c *FakeRoles) List(opts v1.ListOptions) (result *v1alpha2.RoleList, err er
return list, err
}
// Watch returns a watch.Interface that watches the requested roles.
func (c *FakeRoles) Watch(opts v1.ListOptions) (watch.Interface, error) {
// 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(rolesResource, opts))
InvokesWatch(testing.NewRootWatchAction(globalrolebindingsResource, 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) {
// 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(rolesResource, role), &v1alpha2.Role{})
Invokes(testing.NewRootCreateAction(globalrolebindingsResource, globalRoleBinding), &v1alpha2.GlobalRoleBinding{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Role), err
return obj.(*v1alpha2.GlobalRoleBinding), 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) {
// 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(rolesResource, role), &v1alpha2.Role{})
Invokes(testing.NewRootUpdateAction(globalrolebindingsResource, globalRoleBinding), &v1alpha2.GlobalRoleBinding{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Role), err
return obj.(*v1alpha2.GlobalRoleBinding), 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 {
// 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(rolesResource, name), &v1alpha2.Role{})
Invokes(testing.NewRootDeleteAction(globalrolebindingsResource, name), &v1alpha2.GlobalRoleBinding{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(rolesResource, listOptions)
func (c *FakeGlobalRoleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(globalrolebindingsResource, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha2.RoleList{})
_, err := c.Fake.Invokes(action, &v1alpha2.GlobalRoleBindingList{})
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) {
// 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(rolesResource, name, pt, data, subresources...), &v1alpha2.Role{})
Invokes(testing.NewRootPatchSubresourceAction(globalrolebindingsResource, name, pt, data, subresources...), &v1alpha2.GlobalRoleBinding{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.Role), err
return obj.(*v1alpha2.GlobalRoleBinding), err
}
......@@ -28,22 +28,26 @@ type FakeIamV1alpha2 struct {
*testing.Fake
}
func (c *FakeIamV1alpha2) PolicyRules() v1alpha2.PolicyRuleInterface {
return &FakePolicyRules{c}
func (c *FakeIamV1alpha2) GlobalRoles() v1alpha2.GlobalRoleInterface {
return &FakeGlobalRoles{c}
}
func (c *FakeIamV1alpha2) Roles() v1alpha2.RoleInterface {
return &FakeRoles{c}
}
func (c *FakeIamV1alpha2) RoleBindings() v1alpha2.RoleBindingInterface {
return &FakeRoleBindings{c}
func (c *FakeIamV1alpha2) GlobalRoleBindings() v1alpha2.GlobalRoleBindingInterface {
return &FakeGlobalRoleBindings{c}
}
func (c *FakeIamV1alpha2) Users() v1alpha2.UserInterface {
return &FakeUsers{c}
}
func (c *FakeIamV1alpha2) WorkspaceRoles() v1alpha2.WorkspaceRoleInterface {
return &FakeWorkspaceRoles{c}
}
func (c *FakeIamV1alpha2) WorkspaceRoleBindings() v1alpha2.WorkspaceRoleBindingInterface {
return &FakeWorkspaceRoleBindings{c}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeIamV1alpha2) RESTClient() rest.Interface {
......
......@@ -28,29 +28,29 @@ import (
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
)
// FakeRoleBindings implements RoleBindingInterface
type FakeRoleBindings struct {
// FakeWorkspaceRoles implements WorkspaceRoleInterface
type FakeWorkspaceRoles struct {
Fake *FakeIamV1alpha2
}
var rolebindingsResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "rolebindings"}
var workspacerolesResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "workspaceroles"}
var rolebindingsKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "RoleBinding"}
var workspacerolesKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "WorkspaceRole"}
// 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) {
// 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(rolebindingsResource, name), &v1alpha2.RoleBinding{})
Invokes(testing.NewRootGetAction(workspacerolesResource, name), &v1alpha2.WorkspaceRole{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.RoleBinding), err
return obj.(*v1alpha2.WorkspaceRole), 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) {
// 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(rolebindingsResource, rolebindingsKind, opts), &v1alpha2.RoleBindingList{})
Invokes(testing.NewRootListAction(workspacerolesResource, workspacerolesKind, opts), &v1alpha2.WorkspaceRoleList{})
if obj == nil {
return nil, err
}
......@@ -59,8 +59,8 @@ func (c *FakeRoleBindings) List(opts v1.ListOptions) (result *v1alpha2.RoleBindi
if label == nil {
label = labels.Everything()
}
list := &v1alpha2.RoleBindingList{ListMeta: obj.(*v1alpha2.RoleBindingList).ListMeta}
for _, item := range obj.(*v1alpha2.RoleBindingList).Items {
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)
}
......@@ -68,53 +68,53 @@ func (c *FakeRoleBindings) List(opts v1.ListOptions) (result *v1alpha2.RoleBindi
return list, err
}
// Watch returns a watch.Interface that watches the requested roleBindings.
func (c *FakeRoleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
// 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(rolebindingsResource, opts))
InvokesWatch(testing.NewRootWatchAction(workspacerolesResource, 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) {
// 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(rolebindingsResource, roleBinding), &v1alpha2.RoleBinding{})
Invokes(testing.NewRootCreateAction(workspacerolesResource, workspaceRole), &v1alpha2.WorkspaceRole{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.RoleBinding), err
return obj.(*v1alpha2.WorkspaceRole), 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) {
// 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(rolebindingsResource, roleBinding), &v1alpha2.RoleBinding{})
Invokes(testing.NewRootUpdateAction(workspacerolesResource, workspaceRole), &v1alpha2.WorkspaceRole{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.RoleBinding), err
return obj.(*v1alpha2.WorkspaceRole), 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 {
// 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(rolebindingsResource, name), &v1alpha2.RoleBinding{})
Invokes(testing.NewRootDeleteAction(workspacerolesResource, name), &v1alpha2.WorkspaceRole{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeRoleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(rolebindingsResource, listOptions)
func (c *FakeWorkspaceRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(workspacerolesResource, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha2.RoleBindingList{})
_, err := c.Fake.Invokes(action, &v1alpha2.WorkspaceRoleList{})
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) {
// 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(rolebindingsResource, name, pt, data, subresources...), &v1alpha2.RoleBinding{})
Invokes(testing.NewRootPatchSubresourceAction(workspacerolesResource, name, pt, data, subresources...), &v1alpha2.WorkspaceRole{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.RoleBinding), err
return obj.(*v1alpha2.WorkspaceRole), err
}
/*
Copyright 2019 The KubeSphere authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2"
)
// FakeWorkspaceRoleBindings implements WorkspaceRoleBindingInterface
type FakeWorkspaceRoleBindings struct {
Fake *FakeIamV1alpha2
}
var workspacerolebindingsResource = schema.GroupVersionResource{Group: "iam.kubesphere.io", Version: "v1alpha2", Resource: "workspacerolebindings"}
var workspacerolebindingsKind = schema.GroupVersionKind{Group: "iam.kubesphere.io", Version: "v1alpha2", Kind: "WorkspaceRoleBinding"}
// Get takes name of the workspaceRoleBinding, and returns the corresponding workspaceRoleBinding object, and an error if there is any.
func (c *FakeWorkspaceRoleBindings) Get(name string, options v1.GetOptions) (result *v1alpha2.WorkspaceRoleBinding, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(workspacerolebindingsResource, name), &v1alpha2.WorkspaceRoleBinding{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.WorkspaceRoleBinding), err
}
// List takes label and field selectors, and returns the list of WorkspaceRoleBindings that match those selectors.
func (c *FakeWorkspaceRoleBindings) List(opts v1.ListOptions) (result *v1alpha2.WorkspaceRoleBindingList, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootListAction(workspacerolebindingsResource, workspacerolebindingsKind, opts), &v1alpha2.WorkspaceRoleBindingList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha2.WorkspaceRoleBindingList{ListMeta: obj.(*v1alpha2.WorkspaceRoleBindingList).ListMeta}
for _, item := range obj.(*v1alpha2.WorkspaceRoleBindingList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested workspaceRoleBindings.
func (c *FakeWorkspaceRoleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(workspacerolebindingsResource, opts))
}
// Create takes the representation of a workspaceRoleBinding and creates it. Returns the server's representation of the workspaceRoleBinding, and an error, if there is any.
func (c *FakeWorkspaceRoleBindings) Create(workspaceRoleBinding *v1alpha2.WorkspaceRoleBinding) (result *v1alpha2.WorkspaceRoleBinding, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(workspacerolebindingsResource, workspaceRoleBinding), &v1alpha2.WorkspaceRoleBinding{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.WorkspaceRoleBinding), err
}
// Update takes the representation of a workspaceRoleBinding and updates it. Returns the server's representation of the workspaceRoleBinding, and an error, if there is any.
func (c *FakeWorkspaceRoleBindings) Update(workspaceRoleBinding *v1alpha2.WorkspaceRoleBinding) (result *v1alpha2.WorkspaceRoleBinding, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(workspacerolebindingsResource, workspaceRoleBinding), &v1alpha2.WorkspaceRoleBinding{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.WorkspaceRoleBinding), err
}
// Delete takes name of the workspaceRoleBinding and deletes it. Returns an error if one occurs.
func (c *FakeWorkspaceRoleBindings) Delete(name string, options *v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewRootDeleteAction(workspacerolebindingsResource, name), &v1alpha2.WorkspaceRoleBinding{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeWorkspaceRoleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(workspacerolebindingsResource, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha2.WorkspaceRoleBindingList{})
return err
}
// Patch applies the patch and returns the patched workspaceRoleBinding.
func (c *FakeWorkspaceRoleBindings) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.WorkspaceRoleBinding, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(workspacerolebindingsResource, name, pt, data, subresources...), &v1alpha2.WorkspaceRoleBinding{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.WorkspaceRoleBinding), err
}
......@@ -18,10 +18,12 @@ limitations under the License.
package v1alpha2
type PolicyRuleExpansion interface{}
type GlobalRoleExpansion interface{}
type RoleExpansion interface{}
type RoleBindingExpansion interface{}
type GlobalRoleBindingExpansion interface{}
type UserExpansion interface{}
type WorkspaceRoleExpansion interface{}
type WorkspaceRoleBindingExpansion interface{}
......@@ -29,42 +29,42 @@ import (
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
// PolicyRulesGetter has a method to return a PolicyRuleInterface.
// GlobalRolesGetter has a method to return a GlobalRoleInterface.
// A group's client should implement this interface.
type PolicyRulesGetter interface {
PolicyRules() PolicyRuleInterface
type GlobalRolesGetter interface {
GlobalRoles() GlobalRoleInterface
}
// PolicyRuleInterface has methods to work with PolicyRule resources.
type PolicyRuleInterface interface {
Create(*v1alpha2.PolicyRule) (*v1alpha2.PolicyRule, error)
Update(*v1alpha2.PolicyRule) (*v1alpha2.PolicyRule, error)
// GlobalRoleInterface has methods to work with GlobalRole resources.
type GlobalRoleInterface interface {
Create(*v1alpha2.GlobalRole) (*v1alpha2.GlobalRole, error)
Update(*v1alpha2.GlobalRole) (*v1alpha2.GlobalRole, error)
Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options v1.GetOptions) (*v1alpha2.PolicyRule, error)
List(opts v1.ListOptions) (*v1alpha2.PolicyRuleList, error)
Get(name string, options v1.GetOptions) (*v1alpha2.GlobalRole, error)
List(opts v1.ListOptions) (*v1alpha2.GlobalRoleList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.PolicyRule, err error)
PolicyRuleExpansion
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRole, err error)
GlobalRoleExpansion
}
// policyRules implements PolicyRuleInterface
type policyRules struct {
// globalRoles implements GlobalRoleInterface
type globalRoles struct {
client rest.Interface
}
// newPolicyRules returns a PolicyRules
func newPolicyRules(c *IamV1alpha2Client) *policyRules {
return &policyRules{
// newGlobalRoles returns a GlobalRoles
func newGlobalRoles(c *IamV1alpha2Client) *globalRoles {
return &globalRoles{
client: c.RESTClient(),
}
}
// Get takes name of the policyRule, and returns the corresponding policyRule object, and an error if there is any.
func (c *policyRules) Get(name string, options v1.GetOptions) (result *v1alpha2.PolicyRule, err error) {
result = &v1alpha2.PolicyRule{}
// Get takes name of the globalRole, and returns the corresponding globalRole object, and an error if there is any.
func (c *globalRoles) Get(name string, options v1.GetOptions) (result *v1alpha2.GlobalRole, err error) {
result = &v1alpha2.GlobalRole{}
err = c.client.Get().
Resource("policyrules").
Resource("globalroles").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
......@@ -72,15 +72,15 @@ func (c *policyRules) Get(name string, options v1.GetOptions) (result *v1alpha2.
return
}
// List takes label and field selectors, and returns the list of PolicyRules that match those selectors.
func (c *policyRules) List(opts v1.ListOptions) (result *v1alpha2.PolicyRuleList, err error) {
// List takes label and field selectors, and returns the list of GlobalRoles that match those selectors.
func (c *globalRoles) List(opts v1.ListOptions) (result *v1alpha2.GlobalRoleList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha2.PolicyRuleList{}
result = &v1alpha2.GlobalRoleList{}
err = c.client.Get().
Resource("policyrules").
Resource("globalroles").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do().
......@@ -88,47 +88,47 @@ func (c *policyRules) List(opts v1.ListOptions) (result *v1alpha2.PolicyRuleList
return
}
// Watch returns a watch.Interface that watches the requested policyRules.
func (c *policyRules) Watch(opts v1.ListOptions) (watch.Interface, error) {
// Watch returns a watch.Interface that watches the requested globalRoles.
func (c *globalRoles) Watch(opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Resource("policyrules").
Resource("globalroles").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch()
}
// Create takes the representation of a policyRule and creates it. Returns the server's representation of the policyRule, and an error, if there is any.
func (c *policyRules) Create(policyRule *v1alpha2.PolicyRule) (result *v1alpha2.PolicyRule, err error) {
result = &v1alpha2.PolicyRule{}
// Create takes the representation of a globalRole and creates it. Returns the server's representation of the globalRole, and an error, if there is any.
func (c *globalRoles) Create(globalRole *v1alpha2.GlobalRole) (result *v1alpha2.GlobalRole, err error) {
result = &v1alpha2.GlobalRole{}
err = c.client.Post().
Resource("policyrules").
Body(policyRule).
Resource("globalroles").
Body(globalRole).
Do().
Into(result)
return
}
// Update takes the representation of a policyRule and updates it. Returns the server's representation of the policyRule, and an error, if there is any.
func (c *policyRules) Update(policyRule *v1alpha2.PolicyRule) (result *v1alpha2.PolicyRule, err error) {
result = &v1alpha2.PolicyRule{}
// Update takes the representation of a globalRole and updates it. Returns the server's representation of the globalRole, and an error, if there is any.
func (c *globalRoles) Update(globalRole *v1alpha2.GlobalRole) (result *v1alpha2.GlobalRole, err error) {
result = &v1alpha2.GlobalRole{}
err = c.client.Put().
Resource("policyrules").
Name(policyRule.Name).
Body(policyRule).
Resource("globalroles").
Name(globalRole.Name).
Body(globalRole).
Do().
Into(result)
return
}
// Delete takes name of the policyRule and deletes it. Returns an error if one occurs.
func (c *policyRules) Delete(name string, options *v1.DeleteOptions) error {
// Delete takes name of the globalRole and deletes it. Returns an error if one occurs.
func (c *globalRoles) Delete(name string, options *v1.DeleteOptions) error {
return c.client.Delete().
Resource("policyrules").
Resource("globalroles").
Name(name).
Body(options).
Do().
......@@ -136,13 +136,13 @@ func (c *policyRules) Delete(name string, options *v1.DeleteOptions) error {
}
// DeleteCollection deletes a collection of objects.
func (c *policyRules) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
func (c *globalRoles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
var timeout time.Duration
if listOptions.TimeoutSeconds != nil {
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Resource("policyrules").
Resource("globalroles").
VersionedParams(&listOptions, scheme.ParameterCodec).
Timeout(timeout).
Body(options).
......@@ -150,11 +150,11 @@ func (c *policyRules) DeleteCollection(options *v1.DeleteOptions, listOptions v1
Error()
}
// Patch applies the patch and returns the patched policyRule.
func (c *policyRules) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.PolicyRule, err error) {
result = &v1alpha2.PolicyRule{}
// Patch applies the patch and returns the patched globalRole.
func (c *globalRoles) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRole, err error) {
result = &v1alpha2.GlobalRole{}
err = c.client.Patch(pt).
Resource("policyrules").
Resource("globalroles").
SubResource(subresources...).
Name(name).
Body(data).
......
......@@ -29,42 +29,42 @@ import (
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
// RoleBindingsGetter has a method to return a RoleBindingInterface.
// GlobalRoleBindingsGetter has a method to return a GlobalRoleBindingInterface.
// A group's client should implement this interface.
type RoleBindingsGetter interface {
RoleBindings() RoleBindingInterface
type GlobalRoleBindingsGetter interface {
GlobalRoleBindings() GlobalRoleBindingInterface
}
// RoleBindingInterface has methods to work with RoleBinding resources.
type RoleBindingInterface interface {
Create(*v1alpha2.RoleBinding) (*v1alpha2.RoleBinding, error)
Update(*v1alpha2.RoleBinding) (*v1alpha2.RoleBinding, error)
// 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.RoleBinding, error)
List(opts v1.ListOptions) (*v1alpha2.RoleBindingList, 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.RoleBinding, err error)
RoleBindingExpansion
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.GlobalRoleBinding, err error)
GlobalRoleBindingExpansion
}
// roleBindings implements RoleBindingInterface
type roleBindings struct {
// globalRoleBindings implements GlobalRoleBindingInterface
type globalRoleBindings struct {
client rest.Interface
}
// newRoleBindings returns a RoleBindings
func newRoleBindings(c *IamV1alpha2Client) *roleBindings {
return &roleBindings{
// newGlobalRoleBindings returns a GlobalRoleBindings
func newGlobalRoleBindings(c *IamV1alpha2Client) *globalRoleBindings {
return &globalRoleBindings{
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{}
// 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("rolebindings").
Resource("globalrolebindings").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
......@@ -72,15 +72,15 @@ func (c *roleBindings) Get(name string, options v1.GetOptions) (result *v1alpha2
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) {
// 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.RoleBindingList{}
result = &v1alpha2.GlobalRoleBindingList{}
err = c.client.Get().
Resource("rolebindings").
Resource("globalrolebindings").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do().
......@@ -88,47 +88,47 @@ func (c *roleBindings) List(opts v1.ListOptions) (result *v1alpha2.RoleBindingLi
return
}
// Watch returns a watch.Interface that watches the requested roleBindings.
func (c *roleBindings) Watch(opts v1.ListOptions) (watch.Interface, error) {
// 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("rolebindings").
Resource("globalrolebindings").
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{}
// 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("rolebindings").
Body(roleBinding).
Resource("globalrolebindings").
Body(globalRoleBinding).
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{}
// 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("rolebindings").
Name(roleBinding.Name).
Body(roleBinding).
Resource("globalrolebindings").
Name(globalRoleBinding.Name).
Body(globalRoleBinding).
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 {
// 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("rolebindings").
Resource("globalrolebindings").
Name(name).
Body(options).
Do().
......@@ -136,13 +136,13 @@ func (c *roleBindings) Delete(name string, options *v1.DeleteOptions) error {
}
// DeleteCollection deletes a collection of objects.
func (c *roleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
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("rolebindings").
Resource("globalrolebindings").
VersionedParams(&listOptions, scheme.ParameterCodec).
Timeout(timeout).
Body(options).
......@@ -150,11 +150,11 @@ func (c *roleBindings) DeleteCollection(options *v1.DeleteOptions, listOptions v
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{}
// 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("rolebindings").
Resource("globalrolebindings").
SubResource(subresources...).
Name(name).
Body(data).
......
......@@ -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
......
......@@ -29,42 +29,42 @@ import (
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
// RolesGetter has a method to return a RoleInterface.
// WorkspaceRolesGetter has a method to return a WorkspaceRoleInterface.
// A group's client should implement this interface.
type RolesGetter interface {
Roles() RoleInterface
type WorkspaceRolesGetter interface {
WorkspaceRoles() WorkspaceRoleInterface
}
// RoleInterface has methods to work with Role resources.
type RoleInterface interface {
Create(*v1alpha2.Role) (*v1alpha2.Role, error)
Update(*v1alpha2.Role) (*v1alpha2.Role, error)
// 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.Role, error)
List(opts v1.ListOptions) (*v1alpha2.RoleList, 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.Role, err error)
RoleExpansion
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.WorkspaceRole, err error)
WorkspaceRoleExpansion
}
// roles implements RoleInterface
type roles struct {
// workspaceRoles implements WorkspaceRoleInterface
type workspaceRoles struct {
client rest.Interface
}
// newRoles returns a Roles
func newRoles(c *IamV1alpha2Client) *roles {
return &roles{
// newWorkspaceRoles returns a WorkspaceRoles
func newWorkspaceRoles(c *IamV1alpha2Client) *workspaceRoles {
return &workspaceRoles{
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{}
// 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("roles").
Resource("workspaceroles").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
......@@ -72,15 +72,15 @@ func (c *roles) Get(name string, options v1.GetOptions) (result *v1alpha2.Role,
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) {
// 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.RoleList{}
result = &v1alpha2.WorkspaceRoleList{}
err = c.client.Get().
Resource("roles").
Resource("workspaceroles").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do().
......@@ -88,47 +88,47 @@ func (c *roles) List(opts v1.ListOptions) (result *v1alpha2.RoleList, err error)
return
}
// Watch returns a watch.Interface that watches the requested roles.
func (c *roles) Watch(opts v1.ListOptions) (watch.Interface, error) {
// 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("roles").
Resource("workspaceroles").
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{}
// 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("roles").
Body(role).
Resource("workspaceroles").
Body(workspaceRole).
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{}
// 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("roles").
Name(role.Name).
Body(role).
Resource("workspaceroles").
Name(workspaceRole.Name).
Body(workspaceRole).
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 {
// 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("roles").
Resource("workspaceroles").
Name(name).
Body(options).
Do().
......@@ -136,13 +136,13 @@ func (c *roles) Delete(name string, options *v1.DeleteOptions) error {
}
// DeleteCollection deletes a collection of objects.
func (c *roles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
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("roles").
Resource("workspaceroles").
VersionedParams(&listOptions, scheme.ParameterCodec).
Timeout(timeout).
Body(options).
......@@ -150,11 +150,11 @@ func (c *roles) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListO
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{}
// 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("roles").
Resource("workspaceroles").
SubResource(subresources...).
Name(name).
Body(data).
......
......@@ -79,14 +79,16 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
return &genericInformer{resource: resource.GroupResource(), informer: f.Devops().V1alpha3().Pipelines().Informer()}, nil
// Group=iam.kubesphere.io, Version=v1alpha2
case v1alpha2.SchemeGroupVersion.WithResource("policyrules"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().PolicyRules().Informer()}, nil
case v1alpha2.SchemeGroupVersion.WithResource("roles"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().Roles().Informer()}, nil
case v1alpha2.SchemeGroupVersion.WithResource("rolebindings"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().RoleBindings().Informer()}, nil
case v1alpha2.SchemeGroupVersion.WithResource("globalroles"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().GlobalRoles().Informer()}, nil
case v1alpha2.SchemeGroupVersion.WithResource("globalrolebindings"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().GlobalRoleBindings().Informer()}, nil
case v1alpha2.SchemeGroupVersion.WithResource("users"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().Users().Informer()}, nil
case v1alpha2.SchemeGroupVersion.WithResource("workspaceroles"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().WorkspaceRoles().Informer()}, nil
case v1alpha2.SchemeGroupVersion.WithResource("workspacerolebindings"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Iam().V1alpha2().WorkspaceRoleBindings().Informer()}, nil
// Group=network.kubesphere.io, Version=v1alpha1
case networkv1alpha1.SchemeGroupVersion.WithResource("namespacenetworkpolicies"):
......
......@@ -31,58 +31,58 @@ import (
v1alpha2 "kubesphere.io/kubesphere/pkg/client/listers/iam/v1alpha2"
)
// PolicyRuleInformer provides access to a shared informer and lister for
// PolicyRules.
type PolicyRuleInformer interface {
// GlobalRoleInformer provides access to a shared informer and lister for
// GlobalRoles.
type GlobalRoleInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha2.PolicyRuleLister
Lister() v1alpha2.GlobalRoleLister
}
type policyRuleInformer struct {
type globalRoleInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// NewPolicyRuleInformer constructs a new informer for PolicyRule type.
// NewGlobalRoleInformer constructs a new informer for GlobalRole type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewPolicyRuleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredPolicyRuleInformer(client, resyncPeriod, indexers, nil)
func NewGlobalRoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredGlobalRoleInformer(client, resyncPeriod, indexers, nil)
}
// NewFilteredPolicyRuleInformer constructs a new informer for PolicyRule type.
// NewFilteredGlobalRoleInformer constructs a new informer for GlobalRole type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredPolicyRuleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
func NewFilteredGlobalRoleInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.IamV1alpha2().PolicyRules().List(options)
return client.IamV1alpha2().GlobalRoles().List(options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.IamV1alpha2().PolicyRules().Watch(options)
return client.IamV1alpha2().GlobalRoles().Watch(options)
},
},
&iamv1alpha2.PolicyRule{},
&iamv1alpha2.GlobalRole{},
resyncPeriod,
indexers,
)
}
func (f *policyRuleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredPolicyRuleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
func (f *globalRoleInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredGlobalRoleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *policyRuleInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&iamv1alpha2.PolicyRule{}, f.defaultInformer)
func (f *globalRoleInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&iamv1alpha2.GlobalRole{}, f.defaultInformer)
}
func (f *policyRuleInformer) Lister() v1alpha2.PolicyRuleLister {
return v1alpha2.NewPolicyRuleLister(f.Informer().GetIndexer())
func (f *globalRoleInformer) Lister() v1alpha2.GlobalRoleLister {
return v1alpha2.NewGlobalRoleLister(f.Informer().GetIndexer())
}
......@@ -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{}
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -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").
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -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{}{
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册