feat: Advanced authorization (#1789)
* feat: Advanced authorization Signed-off-by: Anatolii Bazko <abazko@redhat.com>pull/1795/head
parent
038eaa55f4
commit
d99f8923f8
|
|
@ -21,16 +21,26 @@ che-operator Development Guide: https://github.com/eclipse-che/che-operator/#dev
|
||||||
- steps to reproduce
|
- steps to reproduce
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
1. Prepare a patch file if needed:
|
||||||
```bash
|
```bash
|
||||||
cat > /tmp/patch.yaml <<EOF
|
cat > /tmp/cr-patch.yaml <<EOF
|
||||||
<PATCH_CONTENT>
|
apiVersion: org.eclipse.che/v2
|
||||||
|
kind: CheCluster
|
||||||
|
spec: {}
|
||||||
EOF
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
chectl server:deploy \
|
2. Deploy the operator:
|
||||||
--installer operator \
|
|
||||||
--platform <PLATFORM_TO_DEPLOY> \
|
#### OpenShift
|
||||||
--che-operator-image <CUSTOM_OPERATOR_IMAGE> \
|
```bash
|
||||||
--che-operator-cr-patch-yaml /tmp/patch.yaml
|
./build/scripts/olm/test-catalog-from-sources.sh --cr-patch-yaml /tmp/cr-patch.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### on Minikube
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build/scripts/minikube-tests/test-operator-from-sources.sh --cr-patch-yaml /tmp/cr-patch.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
### PR Checklist
|
### PR Checklist
|
||||||
|
|
|
||||||
|
|
@ -524,6 +524,28 @@ type Auth struct {
|
||||||
// +optional
|
// +optional
|
||||||
// +kubebuilder:default:={configLabels: {app: che, component: che-gateway-config}}
|
// +kubebuilder:default:={configLabels: {app: che, component: che-gateway-config}}
|
||||||
Gateway Gateway `json:"gateway,omitempty"`
|
Gateway Gateway `json:"gateway,omitempty"`
|
||||||
|
// Advance authorization settings. Determines which users and groups are allowed to access Che.
|
||||||
|
// User is allowed to access Che if he/she is either in the `allowUsers` list or is member of group from `allowGroups` list
|
||||||
|
// and not in neither the `denyUsers` list nor is member of group from `denyGroups` list.
|
||||||
|
// If `allowUsers` and `allowGroups` are empty, then all users are allowed to access Che.
|
||||||
|
// if `denyUsers` and `denyGroups` are empty, then no users are denied to access Che.
|
||||||
|
// +optional
|
||||||
|
AdvancedAuthorization *AdvancedAuthorization `json:"advancedAuthorization,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdvancedAuthorization struct {
|
||||||
|
// List of users allowed to access Che.
|
||||||
|
// +optional
|
||||||
|
AllowUsers []string `json:"allowUsers,omitempty"`
|
||||||
|
// List of groups allowed to access Che (currently supported in OpenShift only).
|
||||||
|
// +optional
|
||||||
|
AllowGroups []string `json:"allowGroups,omitempty"`
|
||||||
|
// List of users denied to access Che.
|
||||||
|
// +optional
|
||||||
|
DenyUsers []string `json:"denyUsers,omitempty"`
|
||||||
|
// List of groups denied to access Che (currently supported in OpenShift only).
|
||||||
|
// +optional
|
||||||
|
DenyGroups []string `json:"denyGroups,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gateway settings.
|
// Gateway settings.
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,41 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *AdvancedAuthorization) DeepCopyInto(out *AdvancedAuthorization) {
|
||||||
|
*out = *in
|
||||||
|
if in.AllowUsers != nil {
|
||||||
|
in, out := &in.AllowUsers, &out.AllowUsers
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
if in.AllowGroups != nil {
|
||||||
|
in, out := &in.AllowGroups, &out.AllowGroups
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
if in.DenyUsers != nil {
|
||||||
|
in, out := &in.DenyUsers, &out.DenyUsers
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
if in.DenyGroups != nil {
|
||||||
|
in, out := &in.DenyGroups, &out.DenyGroups
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdvancedAuthorization.
|
||||||
|
func (in *AdvancedAuthorization) DeepCopy() *AdvancedAuthorization {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(AdvancedAuthorization)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Auth) DeepCopyInto(out *Auth) {
|
func (in *Auth) DeepCopyInto(out *Auth) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|
@ -38,6 +73,11 @@ func (in *Auth) DeepCopyInto(out *Auth) {
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
in.Gateway.DeepCopyInto(&out.Gateway)
|
in.Gateway.DeepCopyInto(&out.Gateway)
|
||||||
|
if in.AdvancedAuthorization != nil {
|
||||||
|
in, out := &in.AdvancedAuthorization, &out.AdvancedAuthorization
|
||||||
|
*out = new(AdvancedAuthorization)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019-2023 Red Hat, Inc.
|
||||||
|
# This program and the accompanying materials are made
|
||||||
|
# available under the terms of the Eclipse Public License 2.0
|
||||||
|
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: EPL-2.0
|
||||||
|
#
|
||||||
|
# Contributors:
|
||||||
|
# Red Hat, Inc. - initial API and implementation
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
OPERATOR_REPO=$(dirname "$(dirname "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")")")
|
||||||
|
source "${OPERATOR_REPO}/build/scripts/minikube-tests/common.sh"
|
||||||
|
|
||||||
|
init() {
|
||||||
|
unset CR_PATCH_YAML
|
||||||
|
|
||||||
|
while [[ "$#" -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
'--help'|'-h') usage; exit;;
|
||||||
|
'--cr-patch-yaml') CR_PATCH_YAML=$2; shift 1;;
|
||||||
|
esac
|
||||||
|
shift 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
echo "Deploy Eclipse Che from sources"
|
||||||
|
echo
|
||||||
|
echo "Usage:"
|
||||||
|
echo -e "\t$0 [--cr-patch-yaml <path_to_cr_patch>]"
|
||||||
|
echo
|
||||||
|
echo "OPTIONS:"
|
||||||
|
echo -e "\t--cr-patch-yaml CheCluster CR patch yaml file"
|
||||||
|
echo
|
||||||
|
echo "Example:"
|
||||||
|
echo -e "\t$0"
|
||||||
|
}
|
||||||
|
|
||||||
|
runTest() {
|
||||||
|
buildAndCopyCheOperatorImageToMinikube
|
||||||
|
yq -riSY '.spec.template.spec.containers[0].image = "'${OPERATOR_IMAGE}'"' "${CURRENT_OPERATOR_VERSION_TEMPLATE_PATH}/che-operator/kubernetes/operator.yaml"
|
||||||
|
yq -riSY '.spec.template.spec.containers[0].imagePullPolicy = "IfNotPresent"' "${CURRENT_OPERATOR_VERSION_TEMPLATE_PATH}/che-operator/kubernetes/operator.yaml"
|
||||||
|
|
||||||
|
if [[ -n "${CR_PATCH_YAML}" ]]; then
|
||||||
|
chectl server:deploy --batch --platform minikube \
|
||||||
|
--templates "${CURRENT_OPERATOR_VERSION_TEMPLATE_PATH}" \
|
||||||
|
--che-operator-cr-patch-yaml "${CR_PATCH_YAML}"
|
||||||
|
else
|
||||||
|
chectl server:deploy --batch --platform minikube \
|
||||||
|
--templates "${CURRENT_OPERATOR_VERSION_TEMPLATE_PATH}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
pushd ${OPERATOR_REPO} >/dev/null
|
||||||
|
initDefaults
|
||||||
|
init "$@"
|
||||||
|
initTemplates
|
||||||
|
runTest
|
||||||
|
popd >/dev/null
|
||||||
|
|
@ -34,11 +34,13 @@ unset CATALOG_IMAGE
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
unset VERBOSE
|
unset VERBOSE
|
||||||
|
unset CR_PATCH_YAML
|
||||||
|
|
||||||
while [[ "$#" -gt 0 ]]; do
|
while [[ "$#" -gt 0 ]]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
'--help'|'-h') usage; exit;;
|
'--help'|'-h') usage; exit;;
|
||||||
'--verbose'|'-v') VERBOSE=1;;
|
'--verbose'|'-v') VERBOSE=1;;
|
||||||
|
'--cr-patch-yaml') CR_PATCH_YAML=$2; shift 1;;
|
||||||
esac
|
esac
|
||||||
shift 1
|
shift 1
|
||||||
done
|
done
|
||||||
|
|
@ -53,10 +55,11 @@ usage () {
|
||||||
echo "Deploy Eclipse Che from sources"
|
echo "Deploy Eclipse Che from sources"
|
||||||
echo
|
echo
|
||||||
echo "Usage:"
|
echo "Usage:"
|
||||||
echo -e "\t$0 [--verbose]"
|
echo -e "\t$0 [--verbose] [--cr-patch-yaml <path_to_cr_patch>]"
|
||||||
echo
|
echo
|
||||||
echo "OPTIONS:"
|
echo "OPTIONS:"
|
||||||
echo -e "\t-v,--verbose Verbose mode"
|
echo -e "\t-v,--verbose Verbose mode"
|
||||||
|
echo -e "\t--cr-patch-yaml CheCluster CR patch yaml file"
|
||||||
echo
|
echo
|
||||||
echo "Example:"
|
echo "Example:"
|
||||||
echo -e "\t$0"
|
echo -e "\t$0"
|
||||||
|
|
@ -163,8 +166,12 @@ run() {
|
||||||
VERBOSE=${VERBOSE}
|
VERBOSE=${VERBOSE}
|
||||||
make wait-pod-running NAMESPACE="${NAMESPACE}" SELECTOR="app.kubernetes.io/component=che-operator"
|
make wait-pod-running NAMESPACE="${NAMESPACE}" SELECTOR="app.kubernetes.io/component=che-operator"
|
||||||
|
|
||||||
if [[ $(oc get checluster -n eclipse-che --no-headers | wc -l) == 0 ]]; then
|
if [[ $(oc get checluster -n "${NAMESPACE}" --no-headers | wc -l) == 0 ]]; then
|
||||||
getCheClusterCRFromInstalledCSV | oc apply -n "${NAMESPACE}" -f -
|
getCheClusterCRFromInstalledCSV | oc apply -n "${NAMESPACE}" -f -
|
||||||
|
if [[ -n ${CR_PATCH_YAML} ]]; then
|
||||||
|
patch=$(yq -r "." "${CR_PATCH_YAML}" | tr -d "\n" )
|
||||||
|
oc patch checluster eclipse-che -n "${NAMESPACE}" --type='merge' -p "${patch}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
make wait-eclipseche-version VERSION="$(getCheVersionFromInstalledCSV)" NAMESPACE="${NAMESPACE}" VERBOSE=${VERBOSE}
|
make wait-eclipseche-version VERSION="$(getCheVersionFromInstalledCSV)" NAMESPACE="${NAMESPACE}" VERBOSE=${VERBOSE}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ metadata:
|
||||||
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
|
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
|
||||||
repository: https://github.com/eclipse-che/che-operator
|
repository: https://github.com/eclipse-che/che-operator
|
||||||
support: Eclipse Foundation
|
support: Eclipse Foundation
|
||||||
name: eclipse-che.v7.78.0-817.next
|
name: eclipse-che.v7.78.0-826.next
|
||||||
namespace: placeholder
|
namespace: placeholder
|
||||||
spec:
|
spec:
|
||||||
apiservicedefinitions: {}
|
apiservicedefinitions: {}
|
||||||
|
|
@ -527,6 +527,12 @@ spec:
|
||||||
verbs:
|
verbs:
|
||||||
- list
|
- list
|
||||||
- delete
|
- delete
|
||||||
|
- apiGroups:
|
||||||
|
- user.openshift.io
|
||||||
|
resources:
|
||||||
|
- groups
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- user.openshift.io
|
- user.openshift.io
|
||||||
resources:
|
resources:
|
||||||
|
|
@ -1234,7 +1240,7 @@ spec:
|
||||||
minKubeVersion: 1.19.0
|
minKubeVersion: 1.19.0
|
||||||
provider:
|
provider:
|
||||||
name: Eclipse Foundation
|
name: Eclipse Foundation
|
||||||
version: 7.78.0-817.next
|
version: 7.78.0-826.next
|
||||||
webhookdefinitions:
|
webhookdefinitions:
|
||||||
- admissionReviewVersions:
|
- admissionReviewVersions:
|
||||||
- v1
|
- v1
|
||||||
|
|
|
||||||
|
|
@ -7917,6 +7917,40 @@ spec:
|
||||||
component: che-gateway-config
|
component: che-gateway-config
|
||||||
description: Authentication settings.
|
description: Authentication settings.
|
||||||
properties:
|
properties:
|
||||||
|
advancedAuthorization:
|
||||||
|
description: Advance authorization settings. Determines
|
||||||
|
which users and groups are allowed to access Che. User
|
||||||
|
is allowed to access Che if he/she is either in the `allowUsers`
|
||||||
|
list or is member of group from `allowGroups` list and
|
||||||
|
not in neither the `denyUsers` list nor is member of group
|
||||||
|
from `denyGroups` list. If `allowUsers` and `allowGroups`
|
||||||
|
are empty, then all users are allowed to access Che. if
|
||||||
|
`denyUsers` and `denyGroups` are empty, then no users
|
||||||
|
are denied to access Che.
|
||||||
|
properties:
|
||||||
|
allowGroups:
|
||||||
|
description: List of groups allowed to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
allowUsers:
|
||||||
|
description: List of users allowed to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyGroups:
|
||||||
|
description: List of groups denied to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyUsers:
|
||||||
|
description: List of users denied to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
gateway:
|
gateway:
|
||||||
default:
|
default:
|
||||||
configLabels:
|
configLabels:
|
||||||
|
|
|
||||||
|
|
@ -7709,6 +7709,40 @@ spec:
|
||||||
component: che-gateway-config
|
component: che-gateway-config
|
||||||
description: Authentication settings.
|
description: Authentication settings.
|
||||||
properties:
|
properties:
|
||||||
|
advancedAuthorization:
|
||||||
|
description: Advance authorization settings. Determines which
|
||||||
|
users and groups are allowed to access Che. User is allowed
|
||||||
|
to access Che if he/she is either in the `allowUsers` list
|
||||||
|
or is member of group from `allowGroups` list and not in
|
||||||
|
neither the `denyUsers` list nor is member of group from
|
||||||
|
`denyGroups` list. If `allowUsers` and `allowGroups` are
|
||||||
|
empty, then all users are allowed to access Che. if `denyUsers`
|
||||||
|
and `denyGroups` are empty, then no users are denied to
|
||||||
|
access Che.
|
||||||
|
properties:
|
||||||
|
allowGroups:
|
||||||
|
description: List of groups allowed to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
allowUsers:
|
||||||
|
description: List of users allowed to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyGroups:
|
||||||
|
description: List of groups denied to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyUsers:
|
||||||
|
description: List of users denied to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
gateway:
|
gateway:
|
||||||
default:
|
default:
|
||||||
configLabels:
|
configLabels:
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,12 @@ rules:
|
||||||
verbs:
|
verbs:
|
||||||
- list
|
- list
|
||||||
- delete
|
- delete
|
||||||
|
- apiGroups:
|
||||||
|
- user.openshift.io
|
||||||
|
resources:
|
||||||
|
- groups
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- user.openshift.io
|
- user.openshift.io
|
||||||
resources:
|
resources:
|
||||||
|
|
|
||||||
|
|
@ -7728,6 +7728,40 @@ spec:
|
||||||
component: che-gateway-config
|
component: che-gateway-config
|
||||||
description: Authentication settings.
|
description: Authentication settings.
|
||||||
properties:
|
properties:
|
||||||
|
advancedAuthorization:
|
||||||
|
description: Advance authorization settings. Determines which
|
||||||
|
users and groups are allowed to access Che. User is allowed
|
||||||
|
to access Che if he/she is either in the `allowUsers` list
|
||||||
|
or is member of group from `allowGroups` list and not in
|
||||||
|
neither the `denyUsers` list nor is member of group from
|
||||||
|
`denyGroups` list. If `allowUsers` and `allowGroups` are
|
||||||
|
empty, then all users are allowed to access Che. if `denyUsers`
|
||||||
|
and `denyGroups` are empty, then no users are denied to
|
||||||
|
access Che.
|
||||||
|
properties:
|
||||||
|
allowGroups:
|
||||||
|
description: List of groups allowed to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
allowUsers:
|
||||||
|
description: List of users allowed to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyGroups:
|
||||||
|
description: List of groups denied to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyUsers:
|
||||||
|
description: List of users denied to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
gateway:
|
gateway:
|
||||||
default:
|
default:
|
||||||
configLabels:
|
configLabels:
|
||||||
|
|
@ -8432,6 +8466,12 @@ rules:
|
||||||
verbs:
|
verbs:
|
||||||
- list
|
- list
|
||||||
- delete
|
- delete
|
||||||
|
- apiGroups:
|
||||||
|
- user.openshift.io
|
||||||
|
resources:
|
||||||
|
- groups
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- user.openshift.io
|
- user.openshift.io
|
||||||
resources:
|
resources:
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,12 @@ rules:
|
||||||
verbs:
|
verbs:
|
||||||
- list
|
- list
|
||||||
- delete
|
- delete
|
||||||
|
- apiGroups:
|
||||||
|
- user.openshift.io
|
||||||
|
resources:
|
||||||
|
- groups
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- user.openshift.io
|
- user.openshift.io
|
||||||
resources:
|
resources:
|
||||||
|
|
|
||||||
|
|
@ -7723,6 +7723,40 @@ spec:
|
||||||
component: che-gateway-config
|
component: che-gateway-config
|
||||||
description: Authentication settings.
|
description: Authentication settings.
|
||||||
properties:
|
properties:
|
||||||
|
advancedAuthorization:
|
||||||
|
description: Advance authorization settings. Determines which
|
||||||
|
users and groups are allowed to access Che. User is allowed
|
||||||
|
to access Che if he/she is either in the `allowUsers` list
|
||||||
|
or is member of group from `allowGroups` list and not in
|
||||||
|
neither the `denyUsers` list nor is member of group from
|
||||||
|
`denyGroups` list. If `allowUsers` and `allowGroups` are
|
||||||
|
empty, then all users are allowed to access Che. if `denyUsers`
|
||||||
|
and `denyGroups` are empty, then no users are denied to
|
||||||
|
access Che.
|
||||||
|
properties:
|
||||||
|
allowGroups:
|
||||||
|
description: List of groups allowed to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
allowUsers:
|
||||||
|
description: List of users allowed to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyGroups:
|
||||||
|
description: List of groups denied to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyUsers:
|
||||||
|
description: List of users denied to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
gateway:
|
gateway:
|
||||||
default:
|
default:
|
||||||
configLabels:
|
configLabels:
|
||||||
|
|
|
||||||
|
|
@ -7728,6 +7728,40 @@ spec:
|
||||||
component: che-gateway-config
|
component: che-gateway-config
|
||||||
description: Authentication settings.
|
description: Authentication settings.
|
||||||
properties:
|
properties:
|
||||||
|
advancedAuthorization:
|
||||||
|
description: Advance authorization settings. Determines which
|
||||||
|
users and groups are allowed to access Che. User is allowed
|
||||||
|
to access Che if he/she is either in the `allowUsers` list
|
||||||
|
or is member of group from `allowGroups` list and not in
|
||||||
|
neither the `denyUsers` list nor is member of group from
|
||||||
|
`denyGroups` list. If `allowUsers` and `allowGroups` are
|
||||||
|
empty, then all users are allowed to access Che. if `denyUsers`
|
||||||
|
and `denyGroups` are empty, then no users are denied to
|
||||||
|
access Che.
|
||||||
|
properties:
|
||||||
|
allowGroups:
|
||||||
|
description: List of groups allowed to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
allowUsers:
|
||||||
|
description: List of users allowed to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyGroups:
|
||||||
|
description: List of groups denied to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyUsers:
|
||||||
|
description: List of users denied to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
gateway:
|
gateway:
|
||||||
default:
|
default:
|
||||||
configLabels:
|
configLabels:
|
||||||
|
|
@ -8432,6 +8466,12 @@ rules:
|
||||||
verbs:
|
verbs:
|
||||||
- list
|
- list
|
||||||
- delete
|
- delete
|
||||||
|
- apiGroups:
|
||||||
|
- user.openshift.io
|
||||||
|
resources:
|
||||||
|
- groups
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- user.openshift.io
|
- user.openshift.io
|
||||||
resources:
|
resources:
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,12 @@ rules:
|
||||||
verbs:
|
verbs:
|
||||||
- list
|
- list
|
||||||
- delete
|
- delete
|
||||||
|
- apiGroups:
|
||||||
|
- user.openshift.io
|
||||||
|
resources:
|
||||||
|
- groups
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- user.openshift.io
|
- user.openshift.io
|
||||||
resources:
|
resources:
|
||||||
|
|
|
||||||
|
|
@ -7723,6 +7723,40 @@ spec:
|
||||||
component: che-gateway-config
|
component: che-gateway-config
|
||||||
description: Authentication settings.
|
description: Authentication settings.
|
||||||
properties:
|
properties:
|
||||||
|
advancedAuthorization:
|
||||||
|
description: Advance authorization settings. Determines which
|
||||||
|
users and groups are allowed to access Che. User is allowed
|
||||||
|
to access Che if he/she is either in the `allowUsers` list
|
||||||
|
or is member of group from `allowGroups` list and not in
|
||||||
|
neither the `denyUsers` list nor is member of group from
|
||||||
|
`denyGroups` list. If `allowUsers` and `allowGroups` are
|
||||||
|
empty, then all users are allowed to access Che. if `denyUsers`
|
||||||
|
and `denyGroups` are empty, then no users are denied to
|
||||||
|
access Che.
|
||||||
|
properties:
|
||||||
|
allowGroups:
|
||||||
|
description: List of groups allowed to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
allowUsers:
|
||||||
|
description: List of users allowed to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyGroups:
|
||||||
|
description: List of groups denied to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyUsers:
|
||||||
|
description: List of users denied to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
gateway:
|
gateway:
|
||||||
default:
|
default:
|
||||||
configLabels:
|
configLabels:
|
||||||
|
|
|
||||||
|
|
@ -7723,6 +7723,40 @@ spec:
|
||||||
component: che-gateway-config
|
component: che-gateway-config
|
||||||
description: Authentication settings.
|
description: Authentication settings.
|
||||||
properties:
|
properties:
|
||||||
|
advancedAuthorization:
|
||||||
|
description: Advance authorization settings. Determines which
|
||||||
|
users and groups are allowed to access Che. User is allowed
|
||||||
|
to access Che if he/she is either in the `allowUsers` list
|
||||||
|
or is member of group from `allowGroups` list and not in
|
||||||
|
neither the `denyUsers` list nor is member of group from
|
||||||
|
`denyGroups` list. If `allowUsers` and `allowGroups` are
|
||||||
|
empty, then all users are allowed to access Che. if `denyUsers`
|
||||||
|
and `denyGroups` are empty, then no users are denied to
|
||||||
|
access Che.
|
||||||
|
properties:
|
||||||
|
allowGroups:
|
||||||
|
description: List of groups allowed to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
allowUsers:
|
||||||
|
description: List of users allowed to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyGroups:
|
||||||
|
description: List of groups denied to access Che (currently
|
||||||
|
supported in OpenShift only).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
denyUsers:
|
||||||
|
description: List of users denied to access Che.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
gateway:
|
gateway:
|
||||||
default:
|
default:
|
||||||
configLabels:
|
configLabels:
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,12 @@ rules:
|
||||||
verbs:
|
verbs:
|
||||||
- list
|
- list
|
||||||
- delete
|
- delete
|
||||||
|
- apiGroups:
|
||||||
|
- user.openshift.io
|
||||||
|
resources:
|
||||||
|
- groups
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- user.openshift.io
|
- user.openshift.io
|
||||||
resources:
|
resources:
|
||||||
|
|
|
||||||
|
|
@ -28,18 +28,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
commonPermissionsTemplateName = "%s-cheworkspaces-clusterrole"
|
userCommonPermissionsTemplateName = "%s-cheworkspaces-clusterrole"
|
||||||
namespacePermissionsTemplateName = "%s-cheworkspaces-namespaces-clusterrole"
|
userDevWorkspacePermissionsTemplateName = "%s-cheworkspaces-devworkspace-clusterrole"
|
||||||
devWorkspacePermissionsTemplateName = "%s-cheworkspaces-devworkspace-clusterrole"
|
cheSASpecificPermissionsTemplateName = "%s-cheworkspaces-namespaces-clusterrole"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create ClusterRole and ClusterRoleBinding for "che" service account.
|
// Create ClusterRole and ClusterRoleBinding for "che" service account.
|
||||||
// che-server uses "che" service account for creation RBAC for a user in his namespace.
|
// che-server uses "che" service account for creation RBAC for a user in his namespace.
|
||||||
func (s *CheServerReconciler) syncPermissions(ctx *chetypes.DeployContext) (bool, error) {
|
func (s *CheServerReconciler) syncPermissions(ctx *chetypes.DeployContext) (bool, error) {
|
||||||
policies := map[string][]rbacv1.PolicyRule{
|
policies := map[string][]rbacv1.PolicyRule{
|
||||||
fmt.Sprintf(commonPermissionsTemplateName, ctx.CheCluster.Namespace): s.getCommonPolicies(),
|
fmt.Sprintf(userCommonPermissionsTemplateName, ctx.CheCluster.Namespace): s.getUserCommonPolicies(),
|
||||||
fmt.Sprintf(namespacePermissionsTemplateName, ctx.CheCluster.Namespace): s.getNamespaceEditorPolicies(),
|
fmt.Sprintf(cheSASpecificPermissionsTemplateName, ctx.CheCluster.Namespace): s.getCheSASpecificPolicies(),
|
||||||
fmt.Sprintf(devWorkspacePermissionsTemplateName, ctx.CheCluster.Namespace): s.getDevWorkspacePolicies(),
|
fmt.Sprintf(userDevWorkspacePermissionsTemplateName, ctx.CheCluster.Namespace): s.getUserDevWorkspacePolicies(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, policy := range policies {
|
for name, policy := range policies {
|
||||||
|
|
@ -87,9 +87,9 @@ func (s *CheServerReconciler) syncPermissions(ctx *chetypes.DeployContext) (bool
|
||||||
|
|
||||||
func (s *CheServerReconciler) deletePermissions(ctx *chetypes.DeployContext) bool {
|
func (s *CheServerReconciler) deletePermissions(ctx *chetypes.DeployContext) bool {
|
||||||
names := []string{
|
names := []string{
|
||||||
fmt.Sprintf(commonPermissionsTemplateName, ctx.CheCluster.Namespace),
|
fmt.Sprintf(userCommonPermissionsTemplateName, ctx.CheCluster.Namespace),
|
||||||
fmt.Sprintf(namespacePermissionsTemplateName, ctx.CheCluster.Namespace),
|
fmt.Sprintf(cheSASpecificPermissionsTemplateName, ctx.CheCluster.Namespace),
|
||||||
fmt.Sprintf(devWorkspacePermissionsTemplateName, ctx.CheCluster.Namespace),
|
fmt.Sprintf(userDevWorkspacePermissionsTemplateName, ctx.CheCluster.Namespace),
|
||||||
}
|
}
|
||||||
|
|
||||||
done := true
|
done := true
|
||||||
|
|
@ -126,7 +126,7 @@ func (s *CheServerReconciler) deletePermissions(ctx *chetypes.DeployContext) boo
|
||||||
return done
|
return done
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CheServerReconciler) getDevWorkspacePolicies() []rbacv1.PolicyRule {
|
func (s *CheServerReconciler) getUserDevWorkspacePolicies() []rbacv1.PolicyRule {
|
||||||
k8sPolicies := []rbacv1.PolicyRule{
|
k8sPolicies := []rbacv1.PolicyRule{
|
||||||
{
|
{
|
||||||
APIGroups: []string{"workspace.devfile.io"},
|
APIGroups: []string{"workspace.devfile.io"},
|
||||||
|
|
@ -138,13 +138,28 @@ func (s *CheServerReconciler) getDevWorkspacePolicies() []rbacv1.PolicyRule {
|
||||||
return k8sPolicies
|
return k8sPolicies
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CheServerReconciler) getNamespaceEditorPolicies() []rbacv1.PolicyRule {
|
func (s *CheServerReconciler) getCheSASpecificPolicies() []rbacv1.PolicyRule {
|
||||||
k8sPolicies := []rbacv1.PolicyRule{
|
k8sPolicies := []rbacv1.PolicyRule{
|
||||||
{
|
{
|
||||||
APIGroups: []string{""},
|
APIGroups: []string{""},
|
||||||
Resources: []string{"namespaces"},
|
Resources: []string{"namespaces"},
|
||||||
Verbs: []string{"get", "create", "update", "list"},
|
Verbs: []string{"get", "create", "update", "list"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
APIGroups: []string{""},
|
||||||
|
Resources: []string{"serviceaccounts"},
|
||||||
|
Verbs: []string{"get", "watch", "create"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
APIGroups: []string{"rbac.authorization.k8s.io"},
|
||||||
|
Resources: []string{"roles"},
|
||||||
|
Verbs: []string{"get", "create", "update"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
APIGroups: []string{"rbac.authorization.k8s.io"},
|
||||||
|
Resources: []string{"rolebindings"},
|
||||||
|
Verbs: []string{"get", "create", "update", "delete"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
openshiftPolicies := []rbacv1.PolicyRule{
|
openshiftPolicies := []rbacv1.PolicyRule{
|
||||||
|
|
@ -158,6 +173,21 @@ func (s *CheServerReconciler) getNamespaceEditorPolicies() []rbacv1.PolicyRule {
|
||||||
Resources: []string{"projects"},
|
Resources: []string{"projects"},
|
||||||
Verbs: []string{"get", "list"},
|
Verbs: []string{"get", "list"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
APIGroups: []string{"user.openshift.io"},
|
||||||
|
Resources: []string{"groups"},
|
||||||
|
Verbs: []string{"get"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
APIGroups: []string{"authorization.openshift.io"},
|
||||||
|
Resources: []string{"roles"},
|
||||||
|
Verbs: []string{"get", "create", "update"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
APIGroups: []string{"authorization.openshift.io"},
|
||||||
|
Resources: []string{"rolebindings"},
|
||||||
|
Verbs: []string{"get", "create", "update", "delete"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if infrastructure.IsOpenShift() {
|
if infrastructure.IsOpenShift() {
|
||||||
|
|
@ -166,13 +196,8 @@ func (s *CheServerReconciler) getNamespaceEditorPolicies() []rbacv1.PolicyRule {
|
||||||
return k8sPolicies
|
return k8sPolicies
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CheServerReconciler) getCommonPolicies() []rbacv1.PolicyRule {
|
func (s *CheServerReconciler) getUserCommonPolicies() []rbacv1.PolicyRule {
|
||||||
k8sPolicies := []rbacv1.PolicyRule{
|
k8sPolicies := []rbacv1.PolicyRule{
|
||||||
{
|
|
||||||
APIGroups: []string{""},
|
|
||||||
Resources: []string{"serviceaccounts"},
|
|
||||||
Verbs: []string{"get", "watch", "create"},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
APIGroups: []string{""},
|
APIGroups: []string{""},
|
||||||
Resources: []string{"pods/exec"},
|
Resources: []string{"pods/exec"},
|
||||||
|
|
@ -238,16 +263,6 @@ func (s *CheServerReconciler) getCommonPolicies() []rbacv1.PolicyRule {
|
||||||
Resources: []string{"ingresses"},
|
Resources: []string{"ingresses"},
|
||||||
Verbs: []string{"get", "list", "watch", "create", "delete"},
|
Verbs: []string{"get", "list", "watch", "create", "delete"},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
APIGroups: []string{"rbac.authorization.k8s.io"},
|
|
||||||
Resources: []string{"roles"},
|
|
||||||
Verbs: []string{"get", "create", "update"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
APIGroups: []string{"rbac.authorization.k8s.io"},
|
|
||||||
Resources: []string{"rolebindings"},
|
|
||||||
Verbs: []string{"get", "create", "update"},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
APIGroups: []string{"metrics.k8s.io"},
|
APIGroups: []string{"metrics.k8s.io"},
|
||||||
Resources: []string{"pods", "nodes"},
|
Resources: []string{"pods", "nodes"},
|
||||||
|
|
@ -270,16 +285,6 @@ func (s *CheServerReconciler) getCommonPolicies() []rbacv1.PolicyRule {
|
||||||
Resources: []string{"routes"},
|
Resources: []string{"routes"},
|
||||||
Verbs: []string{"get", "list", "create", "delete"},
|
Verbs: []string{"get", "list", "create", "delete"},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
APIGroups: []string{"authorization.openshift.io"},
|
|
||||||
Resources: []string{"roles"},
|
|
||||||
Verbs: []string{"get", "create", "update"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
APIGroups: []string{"authorization.openshift.io"},
|
|
||||||
Resources: []string{"rolebindings"},
|
|
||||||
Verbs: []string{"get", "create", "update"},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
APIGroups: []string{"project.openshift.io"},
|
APIGroups: []string{"project.openshift.io"},
|
||||||
Resources: []string{"projects"},
|
Resources: []string{"projects"},
|
||||||
|
|
@ -293,9 +298,9 @@ func (s *CheServerReconciler) getCommonPolicies() []rbacv1.PolicyRule {
|
||||||
return k8sPolicies
|
return k8sPolicies
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CheServerReconciler) getUserClusterRoles(ctx *chetypes.DeployContext) []string {
|
func (s *CheServerReconciler) getDefaultUserClusterRoles(ctx *chetypes.DeployContext) []string {
|
||||||
return []string{
|
return []string{
|
||||||
fmt.Sprintf(commonPermissionsTemplateName, ctx.CheCluster.Namespace),
|
fmt.Sprintf(userCommonPermissionsTemplateName, ctx.CheCluster.Namespace),
|
||||||
fmt.Sprintf(devWorkspacePermissionsTemplateName, ctx.CheCluster.Namespace),
|
fmt.Sprintf(userDevWorkspacePermissionsTemplateName, ctx.CheCluster.Namespace),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,9 +68,9 @@ func TestSyncPermissions(t *testing.T) {
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
names := []string{
|
names := []string{
|
||||||
fmt.Sprintf(commonPermissionsTemplateName, ctx.CheCluster.Namespace),
|
fmt.Sprintf(userCommonPermissionsTemplateName, ctx.CheCluster.Namespace),
|
||||||
fmt.Sprintf(namespacePermissionsTemplateName, ctx.CheCluster.Namespace),
|
fmt.Sprintf(cheSASpecificPermissionsTemplateName, ctx.CheCluster.Namespace),
|
||||||
fmt.Sprintf(devWorkspacePermissionsTemplateName, ctx.CheCluster.Namespace),
|
fmt.Sprintf(userDevWorkspacePermissionsTemplateName, ctx.CheCluster.Namespace),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,14 @@ func (s *CheServerReconciler) getCheConfigMapData(ctx *chetypes.DeployContext) (
|
||||||
}
|
}
|
||||||
err = json.Unmarshal(out, &cheEnv)
|
err = json.Unmarshal(out, &cheEnv)
|
||||||
|
|
||||||
|
// Advanced authorization
|
||||||
|
if ctx.CheCluster.Spec.Networking.Auth.AdvancedAuthorization != nil {
|
||||||
|
cheEnv["CHE_INFRA_KUBERNETES_ADVANCED__AUTHORIZATION_ALLOW__USERS"] = strings.Join(ctx.CheCluster.Spec.Networking.Auth.AdvancedAuthorization.AllowUsers, ",")
|
||||||
|
cheEnv["CHE_INFRA_KUBERNETES_ADVANCED__AUTHORIZATION_ALLOW__GROUPS"] = strings.Join(ctx.CheCluster.Spec.Networking.Auth.AdvancedAuthorization.AllowGroups, ",")
|
||||||
|
cheEnv["CHE_INFRA_KUBERNETES_ADVANCED__AUTHORIZATION_DENY__USERS"] = strings.Join(ctx.CheCluster.Spec.Networking.Auth.AdvancedAuthorization.DenyUsers, ",")
|
||||||
|
cheEnv["CHE_INFRA_KUBERNETES_ADVANCED__AUTHORIZATION_DENY__GROUPS"] = strings.Join(ctx.CheCluster.Spec.Networking.Auth.AdvancedAuthorization.DenyGroups, ",")
|
||||||
|
}
|
||||||
|
|
||||||
// k8s specific envs
|
// k8s specific envs
|
||||||
if !infrastructure.IsOpenShift() {
|
if !infrastructure.IsOpenShift() {
|
||||||
k8sCheEnv := map[string]string{
|
k8sCheEnv := map[string]string{
|
||||||
|
|
@ -298,7 +306,7 @@ func GetCheConfigMapVersion(deployContext *chetypes.DeployContext) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CheServerReconciler) updateUserClusterRoles(ctx *chetypes.DeployContext, cheEnv map[string]string) {
|
func (s *CheServerReconciler) updateUserClusterRoles(ctx *chetypes.DeployContext, cheEnv map[string]string) {
|
||||||
userClusterRoles := strings.Join(s.getUserClusterRoles(ctx), ", ")
|
userClusterRoles := strings.Join(s.getDefaultUserClusterRoles(ctx), ", ")
|
||||||
|
|
||||||
for _, role := range strings.Split(cheEnv["CHE_INFRA_KUBERNETES_USER__CLUSTER__ROLES"], ",") {
|
for _, role := range strings.Split(cheEnv["CHE_INFRA_KUBERNETES_USER__CLUSTER__ROLES"], ",") {
|
||||||
role := strings.TrimSpace(role)
|
role := strings.TrimSpace(role)
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ func (s *CheServerReconciler) Reconcile(ctx *chetypes.DeployContext) (reconcile.
|
||||||
}
|
}
|
||||||
|
|
||||||
if done, err := s.syncPermissions(ctx); !done {
|
if done, err := s.syncPermissions(ctx); !done {
|
||||||
return reconcile.Result{}, false, err
|
return reconcile.Result{Requeue: true}, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
done, err = s.syncDeployment(ctx)
|
done, err = s.syncDeployment(ctx)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue