Skip to content

Commit 2949b78

Browse files
authored
Add tool enabling static users generation for Dex (#1235)
* Add static-users-generator tool * Make dex acceptance test use user credentials from env variables instead of hardcoded values * Remove default user credentials from ui-api-layer-acceptance-tests * Add static-users-generator tool to CODEOWNERS * Fix base64 padding related problems in reading JWT token payload in dex acceptance test * Add kubadz and sjanota to service mesh & security related components in CODEOWNERS
1 parent 2dc3ac0 commit 2949b78

File tree

9 files changed

+197
-13
lines changed

9 files changed

+197
-13
lines changed

CODEOWNERS

+10-7
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@
3838
/resources/core/charts/azure-broker/ @Tomasz-Smelcerz-SAP @strekm @jakkab @crabtree
3939

4040
# The `cluster-users` subchart
41-
/resources/core/charts/cluster-users/ @piotrmsc
41+
/resources/core/charts/cluster-users/ @piotrmsc @kubadz @sjanota
4242

4343
# The `configurations-generator` subchart
44-
/resources/core/charts/configurations-generator @piotrmsc @kubadz
44+
/resources/core/charts/configurations-generator @piotrmsc @kubadz @sjanota
4545

4646
# The `connector-service` subchart
4747
/resources/application-connector/charts/connector-service/ @lszymik @akgalwas @janmedrek @Szymongib @franpog859 @Maladie @crabtree
@@ -59,7 +59,7 @@
5959
/resources/core/charts/console/ @pekura @maxmarkus @jesusreal @kwiatekus @dariadomagala @hardl @y-kkamil @antiheld
6060

6161
# The `dex` subchart
62-
/resources/core/charts/dex/ @piotrmsc @kubadz
62+
/resources/core/charts/dex/ @piotrmsc @kubadz @sjanota
6363

6464
# The `istio-rbac` subchart
6565
/resources/core/charts/istio-rbac/ @piotrmsc @kubadz @sjanota
@@ -147,7 +147,7 @@
147147
/components/apiserver-proxy/ @piotrmsc @kubadz @sjanota
148148

149149
# Api controller Component
150-
/components/api-controller/ @piotrmsc @kubadz
150+
/components/api-controller/ @piotrmsc @kubadz @sjanota
151151

152152
# Binding usage controller Component
153153
/components/binding-usage-controller/ @aszecowka @PK85 @mszostok @piotrmiskiewicz @polskikiel @jasiu001
@@ -162,7 +162,7 @@
162162
/components/environments/ @Tomasz-Smelcerz-SAP @strekm @jakkab @crabtree
163163

164164
# Istio Extensions Component
165-
/components/istio-webhook/ @piotrmsc
165+
/components/istio-webhook/ @piotrmsc @sjanota @kubadz
166166

167167
# Istio Extensions Component
168168
/components/istio-kyma-patch/ @piotrmsc @sjanota @kubadz
@@ -200,7 +200,7 @@
200200
# Tests
201201
# acceptance tests
202202
/tests/acceptance/ @mszostok @polskikiel @piotrmiskiewicz @aszecowka @PK85 @jasiu001
203-
/tests/acceptance/dex @pssap @piotrmsc
203+
/tests/acceptance/dex @sjanota @piotrmsc @kubadz
204204

205205
# test-environments
206206
/tests/test-environemnts/ @Tomasz-Smelcerz-SAP @strekm @jakkab @crabtree
@@ -212,7 +212,7 @@
212212
/tests/logging/ @rakesh-garimella @joek @sayanh @venturasr @lilitgh
213213

214214
# api-controller acceptance tests
215-
/tests/api-controller-acceptance-tests/ @piotrmsc
215+
/tests/api-controller-acceptance-tests/ @piotrmsc @kubadz @sjanota
216216

217217
# UI API Layer acceptance tests
218218
/tests/ui-api-layer-acceptance-tests/ @akucharska @michal-hudy @pkosiec @mjasinski5 @aerfio @magicmatatjahu @aszecowka @PK85 @mszostok @piotrmiskiewicz @polskikiel @jasiu001
@@ -245,6 +245,9 @@
245245
# The changelog-generator directory
246246
/tools/changelog-generator/ @akucharska @michal-hudy @pkosiec @mjasinski5 @aerfio @magicmatatjahu
247247

248+
# The static-users-generator directory
249+
/tools/static-users-generator/ @piotrmsc @sjanota @kubadz
250+
248251
# kubeless-test-client tests
249252
/tests/kubeless-test-client/ @rakesh-garimella @joek @sayanh @venturasr @lilitgh
250253

orchestrator.Jenkinsfile

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ projects = [
5252
"tools/stability-checker": "stability-checker",
5353
"tools/etcd-backup": "etcd-backup",
5454
"tools/etcd-tls-setup": "etcd-tls-setup",
55+
"tools/static-users-generator": "static-users-generator",
5556
"tests/test-logging-monitoring": "test-logging-monitoring",
5657
"tests/logging": "test-logging",
5758
"tests/acceptance": "acceptance-tests",

release.Jenkinsfile

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ projects = [
5555
"tools/stability-checker",
5656
"tools/etcd-backup",
5757
"tools/etcd-tls-setup",
58+
"tools/static-users-generator",
5859
"tests/test-logging-monitoring",
5960
"tests/logging",
6061
"tests/acceptance",

tests/acceptance/dex/dex_test.go

+16-3
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ const (
2424
domainEnvName = "KYMA_DOMAIN"
2525
isLocalEnvEnvName = "IS_LOCAL_ENV"
2626
clientId = "kyma-client"
27-
username = "[email protected]"
28-
password = "nimda123"
27+
usernameEnvName = "DEX_USER_EMAIL"
28+
passwordEnvName = "DEX_USER_PASSWORD"
2929
)
3030

3131
func TestSpec(t *testing.T) {
@@ -66,6 +66,16 @@ func TestSpec(t *testing.T) {
6666
t.Fatal(domainEnvName + " env variable not set")
6767
}
6868

69+
username, envFound := os.LookupEnv(usernameEnvName)
70+
if !envFound {
71+
t.Fatal(usernameEnvName + " env variable not set")
72+
}
73+
74+
password, envFound := os.LookupEnv(passwordEnvName)
75+
if !envFound {
76+
t.Fatal(passwordEnvName + " env variable not set")
77+
}
78+
6979
tr := &http.Transport{
7080
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
7181
}
@@ -117,7 +127,10 @@ func TestSpec(t *testing.T) {
117127

118128
tokenParts := strings.Split(idToken, ".")
119129

120-
tokenPayloadEncoded := tokenParts[1] + "="
130+
tokenPayloadEncoded := tokenParts[1]
131+
132+
missingTokenBytes := (3 - len(tokenPayloadEncoded)%3) % 3
133+
tokenPayloadEncoded += strings.Repeat("=", missingTokenBytes)
121134

122135
tokenPayloadDecoded, err := base64.StdEncoding.DecodeString(tokenPayloadEncoded)
123136
if err != nil {

tests/ui-api-layer-acceptance-tests/graphql/config.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import (
1111
type envConfig struct {
1212
Domain string `envconfig:"default=kyma.local"`
1313
GraphQLEndpoint string `envconfig:"optional,GRAPHQL_ENDPOINT"`
14-
Username string `envconfig:"[email protected]"`
15-
Password string `envconfig:"default=nimda123"`
16-
IsLocalCluster bool `envconfig:"default=true"`
14+
Username string
15+
Password string
16+
IsLocalCluster bool `envconfig:"default=true"`
1717
}
1818

1919
type config struct {
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM alpine:3.8
2+
3+
ENV KUBE_VERSION="v1.11.3"
4+
5+
RUN apk add --no-cache jq apache2-utils bash
6+
RUN wget -q https://storage.googleapis.com/kubernetes-release/release/${KUBE_VERSION}/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl \
7+
&& chmod +x /usr/local/bin/kubectl
8+
9+
COPY ./scripts/config_replace.sh /
10+
11+
LABEL [email protected]:kyma-project/kyma.git
12+
13+
ENTRYPOINT ["/bin/bash", "/config_replace.sh"]
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env groovy
2+
def label = "kyma-${UUID.randomUUID().toString()}"
3+
def application = 'static-users-generator'
4+
def dockerPushRoot = "${env.DOCKER_REGISTRY}${params.PUSH_DIR}"
5+
def dockerImageTag = params.APP_VERSION
6+
7+
echo """
8+
********************************
9+
Job started with the following parameters:
10+
DOCKER_REGISTRY=${env.DOCKER_REGISTRY}
11+
PUSH_DIR=${params.PUSH_DIR}
12+
DOCKER_CREDENTIALS=${env.DOCKER_CREDENTIALS}
13+
GIT_REVISION=${params.GIT_REVISION}
14+
GIT_BRANCH=${params.GIT_BRANCH}
15+
APP_VERSION=${params.APP_VERSION}
16+
APP_FOLDER=${env.APP_FOLDER}
17+
FULL_BUILD=${params.FULL_BUILD}
18+
********************************
19+
"""
20+
21+
podTemplate(label: label) {
22+
node(label) {
23+
try {
24+
timestamps {
25+
timeout(time:20, unit:"MINUTES") {
26+
ansiColor('xterm') {
27+
stage("setup") {
28+
checkout scm
29+
30+
if(dockerImageTag == ""){
31+
error("No version for docker tag defined, please set APP_VERSION parameter for master branch or GIT_BRANCH parameter for any branch")
32+
}
33+
34+
withCredentials([usernamePassword(credentialsId: env.DOCKER_CREDENTIALS, passwordVariable: 'pwd', usernameVariable: 'uname')]) {
35+
sh "docker login -u $uname -p '$pwd' $env.DOCKER_REGISTRY"
36+
}
37+
}
38+
39+
stage("build image $application") {
40+
dir(env.APP_FOLDER){
41+
sh "docker build -t ${dockerPushRoot}${application}:latest . --label version=${dockerImageTag} --label component=${application}"
42+
}
43+
}
44+
45+
stage("push image $application") {
46+
sh "docker tag ${dockerPushRoot}${application}:latest ${dockerPushRoot}${application}:${dockerImageTag}"
47+
sh "docker push ${dockerPushRoot}${application}:${dockerImageTag}"
48+
if (params.GIT_BRANCH == 'master') {
49+
sh "docker push ${dockerPushRoot}${application}:latest"
50+
}
51+
}
52+
}
53+
}
54+
}
55+
} catch (ex) {
56+
echo "Got exception: ${ex}"
57+
currentBuild.result = "FAILURE"
58+
def body = "${currentBuild.currentResult} ${env.JOB_NAME}${env.BUILD_DISPLAY_NAME}: on branch: ${params.GIT_BRANCH}. See details: ${env.BUILD_URL}"
59+
emailext body: body, recipientProviders: [[$class: 'DevelopersRecipientProvider'], [$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']], subject: "${currentBuild.currentResult}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
60+
}
61+
}
62+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Static users generator
2+
3+
## Overview
4+
5+
The tool used to configure static users in Dex. Reads users from secrets labelled `"dex-user-config": "true"` and appends them into the Dex config-map.
6+
7+
## Installation
8+
9+
The tool is a Dex init-container used by default in a Kyma installation.
10+
11+
## Development
12+
13+
To build the image of static-users-generator execute:
14+
15+
```bash
16+
docker build -t static-users-generator:latest .
17+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/bin/bash
2+
3+
set -e #terminate script immediately in case of errors
4+
5+
TEMPDIR=$(mktemp -d)
6+
7+
cp "/config/src/config.yaml" ${TEMPDIR}
8+
9+
TEMP_FILE_PATH="${TEMPDIR}/config.yaml"
10+
DEST_FILE_PATH="/config/dst/config.yaml"
11+
PLACEHOLDER="#__STATIC_PASSWORDS__"
12+
13+
NEWLINE="%"
14+
15+
NUM=0
16+
for secret in $(kubectl get secrets -l dex-user-config=true --all-namespaces -o json | jq -r -c '.items | .[] | .data')
17+
do
18+
19+
EMAIL=$(echo -n ${secret} | jq -r '.email')
20+
if [ "${EMAIL}" == "null" ]
21+
then
22+
continue
23+
fi
24+
25+
EMAIL=$(echo -n ${EMAIL} | base64 -d)
26+
27+
USERNAME=$(echo -n ${secret} | jq -r '.username')
28+
if [ "${USERNAME}" == "null" ]
29+
then
30+
continue
31+
fi
32+
33+
USERNAME=$(echo -n ${USERNAME} | base64 -d)
34+
35+
PASSWORD=$(echo -n ${secret} | jq -r '.password')
36+
37+
if [ "${PASSWORD}" == "null" ]
38+
then
39+
continue
40+
fi
41+
42+
PASSWORD=$(echo -n ${PASSWORD} | base64 -d)
43+
44+
HASH=$(htpasswd -bnBC 12 "" ${PASSWORD} | tr -d ':\n')
45+
46+
echo "successfully created user: ${USERNAME}"
47+
48+
NUM=$(( NUM + 1 ))
49+
50+
# generate userID
51+
USER_ID=$(cat /dev/urandom | LC_ALL=C tr -dc 'a-z0-9' | fold -w 32 | head -n 1)
52+
53+
# prepare config map to enable static users
54+
if [ $NUM -eq 1 ]
55+
then
56+
sed -i "s;${PLACEHOLDER};staticPasswords:${NEWLINE}${PLACEHOLDER};g" "${TEMP_FILE_PATH}"
57+
fi
58+
59+
VALUE="- email: ${EMAIL}${NEWLINE} hash: ${HASH}${NEWLINE} username: ${USERNAME}${NEWLINE} userID: ${USER_ID}${NEWLINE}${PLACEHOLDER}"
60+
sed -i "s;${PLACEHOLDER};${VALUE};g" "${TEMP_FILE_PATH}"
61+
done
62+
63+
# remove placeholder
64+
sed -i "s;${PLACEHOLDER};"";g" "${TEMP_FILE_PATH}"
65+
66+
# if there were static users created
67+
if [ $NUM -gt 0 ]
68+
then
69+
# replace newline placeholders with the real newline and save the configuration file in directory which will be mounted to dex container
70+
cat ${TEMP_FILE_PATH} | tr "${NEWLINE}" "\n" > ${DEST_FILE_PATH}
71+
else
72+
# copy the configuration file to directory which will be mounted to dex container
73+
cp ${TEMP_FILE_PATH} ${DEST_FILE_PATH}
74+
fi

0 commit comments

Comments
 (0)